mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-07-04 14:56:16 -05:00
Merge branch 'master' into watchOptions
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -39,7 +39,7 @@ scripts/word2md.js
|
||||
scripts/buildProtocol.js
|
||||
scripts/ior.js
|
||||
scripts/authors.js
|
||||
scripts/configureNightly.js
|
||||
scripts/configurePrerelease.js
|
||||
scripts/processDiagnosticMessages.d.ts
|
||||
scripts/processDiagnosticMessages.js
|
||||
scripts/importDefinitelyTypedTests/importDefinitelyTypedTests.js
|
||||
|
||||
29
Jakefile.js
29
Jakefile.js
@@ -556,16 +556,16 @@ desc("Generates a diagnostic file in TypeScript based on an input JSON file");
|
||||
task("generate-diagnostics", [diagnosticInfoMapTs]);
|
||||
|
||||
// Publish nightly
|
||||
var configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js");
|
||||
var configureNightlyTs = path.join(scriptsDirectory, "configureNightly.ts");
|
||||
var configurePrereleaseJs = path.join(scriptsDirectory, "configurePrerelease.js");
|
||||
var configurePrereleaseTs = path.join(scriptsDirectory, "configurePrerelease.ts");
|
||||
var packageJson = "package.json";
|
||||
var versionFile = path.join(compilerDirectory, "core.ts");
|
||||
|
||||
file(configureNightlyTs);
|
||||
file(configurePrereleaseTs);
|
||||
|
||||
compileFile(/*outfile*/configureNightlyJs,
|
||||
/*sources*/[configureNightlyTs],
|
||||
/*prereqs*/[configureNightlyTs],
|
||||
compileFile(/*outfile*/configurePrereleaseJs,
|
||||
/*sources*/[configurePrereleaseTs],
|
||||
/*prereqs*/[configurePrereleaseTs],
|
||||
/*prefixes*/[],
|
||||
/*useBuiltCompiler*/ false,
|
||||
{ noOutFile: false, generateDeclarations: false, keepComments: false, noResolve: false, stripInternal: false });
|
||||
@@ -574,8 +574,8 @@ task("setDebugMode", function () {
|
||||
useDebugMode = true;
|
||||
});
|
||||
|
||||
task("configure-nightly", [configureNightlyJs], function () {
|
||||
var cmd = host + " " + configureNightlyJs + " " + packageJson + " " + versionFile;
|
||||
task("configure-nightly", [configurePrereleaseJs], function () {
|
||||
var cmd = host + " " + configurePrereleaseJs + " dev " + packageJson + " " + versionFile;
|
||||
console.log(cmd);
|
||||
exec(cmd);
|
||||
}, { async: true });
|
||||
@@ -587,6 +587,19 @@ task("publish-nightly", ["configure-nightly", "LKG", "clean", "setDebugMode", "r
|
||||
exec(cmd);
|
||||
});
|
||||
|
||||
task("configure-insiders", [configurePrereleaseJs], function () {
|
||||
var cmd = host + " " + configurePrereleaseJs + " insiders " + packageJson + " " + versionFile;
|
||||
console.log(cmd);
|
||||
exec(cmd);
|
||||
}, { async: true });
|
||||
|
||||
desc("Configure, build, test, and publish the insiders release.");
|
||||
task("publish-insiders", ["configure-nightly", "LKG", "clean", "setDebugMode", "runtests-parallel"], function () {
|
||||
var cmd = "npm publish --tag insiders";
|
||||
console.log(cmd);
|
||||
exec(cmd);
|
||||
});
|
||||
|
||||
var importDefinitelyTypedTestsDirectory = path.join(scriptsDirectory, "importDefinitelyTypedTests");
|
||||
var importDefinitelyTypedTestsJs = path.join(importDefinitelyTypedTestsDirectory, "importDefinitelyTypedTests.js");
|
||||
var importDefinitelyTypedTestsTs = path.join(importDefinitelyTypedTestsDirectory, "importDefinitelyTypedTests.ts");
|
||||
|
||||
@@ -11,34 +11,39 @@ interface PackageJson {
|
||||
|
||||
function main(): void {
|
||||
const sys = ts.sys;
|
||||
if (sys.args.length < 2) {
|
||||
if (sys.args.length < 3) {
|
||||
sys.write("Usage:" + sys.newLine)
|
||||
sys.write("\tnode configureNightly.js <package.json location> <file containing version>" + sys.newLine);
|
||||
sys.write("\tnode configureNightly.js <dev|insiders> <package.json location> <file containing version>" + sys.newLine);
|
||||
return;
|
||||
}
|
||||
|
||||
const tag = sys.args[0];
|
||||
if (tag !== "dev" && tag !== "insiders") {
|
||||
throw new Error(`Unexpected tag name '${tag}'.`);
|
||||
}
|
||||
|
||||
// Acquire the version from the package.json file and modify it appropriately.
|
||||
const packageJsonFilePath = ts.normalizePath(sys.args[0]);
|
||||
const packageJsonFilePath = ts.normalizePath(sys.args[1]);
|
||||
const packageJsonValue: PackageJson = JSON.parse(sys.readFile(packageJsonFilePath));
|
||||
|
||||
const { majorMinor, patch } = parsePackageJsonVersion(packageJsonValue.version);
|
||||
const nightlyPatch = getNightlyPatch(patch);
|
||||
const prereleasePatch = getPrereleasePatch(tag, patch);
|
||||
|
||||
// Acquire and modify the source file that exposes the version string.
|
||||
const tsFilePath = ts.normalizePath(sys.args[1]);
|
||||
const tsFilePath = ts.normalizePath(sys.args[2]);
|
||||
const tsFileContents = ts.sys.readFile(tsFilePath);
|
||||
const modifiedTsFileContents = updateTsFile(tsFilePath, tsFileContents, majorMinor, patch, nightlyPatch);
|
||||
const modifiedTsFileContents = updateTsFile(tsFilePath, tsFileContents, majorMinor, patch, prereleasePatch);
|
||||
|
||||
// Ensure we are actually changing something - the user probably wants to know that the update failed.
|
||||
if (tsFileContents === modifiedTsFileContents) {
|
||||
let err = `\n '${tsFilePath}' was not updated while configuring for a nightly publish.\n `;
|
||||
let err = `\n '${tsFilePath}' was not updated while configuring for a prerelease publish for '${tag}'.\n `;
|
||||
err += `Ensure that you have not already run this script; otherwise, erase your changes using 'git checkout -- "${tsFilePath}"'.`;
|
||||
throw err + "\n";
|
||||
throw new Error(err + "\n");
|
||||
}
|
||||
|
||||
// Finally write the changes to disk.
|
||||
// Modify the package.json structure
|
||||
packageJsonValue.version = `${majorMinor}.${nightlyPatch}`;
|
||||
packageJsonValue.version = `${majorMinor}.${prereleasePatch}`;
|
||||
sys.writeFile(packageJsonFilePath, JSON.stringify(packageJsonValue, /*replacer:*/ undefined, /*space:*/ 4))
|
||||
sys.writeFile(tsFilePath, modifiedTsFileContents);
|
||||
}
|
||||
@@ -69,7 +74,7 @@ function parsePackageJsonVersion(versionString: string): { majorMinor: string, p
|
||||
}
|
||||
|
||||
/** e.g. 0-dev.20170707 */
|
||||
function getNightlyPatch(plainPatch: string): string {
|
||||
function getPrereleasePatch(tag: string, plainPatch: string): string {
|
||||
// We're going to append a representation of the current time at the end of the current version.
|
||||
// String.prototype.toISOString() returns a 24-character string formatted as 'YYYY-MM-DDTHH:mm:ss.sssZ',
|
||||
// but we'd prefer to just remove separators and limit ourselves to YYYYMMDD.
|
||||
@@ -77,7 +82,7 @@ function getNightlyPatch(plainPatch: string): string {
|
||||
const now = new Date();
|
||||
const timeStr = now.toISOString().replace(/:|T|\.|-/g, "").slice(0, 8);
|
||||
|
||||
return `${plainPatch}-dev.${timeStr}`;
|
||||
return `${plainPatch}-${tag}.${timeStr}`;
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -5995,7 +5995,9 @@ namespace ts {
|
||||
for (const memberType of types) {
|
||||
for (const { escapedName } of getAugmentedPropertiesOfType(memberType)) {
|
||||
if (!props.has(escapedName)) {
|
||||
props.set(escapedName, createUnionOrIntersectionProperty(unionType as UnionType, escapedName));
|
||||
const prop = createUnionOrIntersectionProperty(unionType as UnionType, escapedName);
|
||||
// May be undefined if the property is private
|
||||
if (prop) props.set(escapedName, prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6177,7 +6179,7 @@ namespace ts {
|
||||
t;
|
||||
}
|
||||
|
||||
function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String): Symbol {
|
||||
function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String): Symbol | undefined {
|
||||
let props: Symbol[];
|
||||
const isUnion = containingType.flags & TypeFlags.Union;
|
||||
const excludeModifiers = isUnion ? ModifierFlags.NonPublicAccessibilityModifier : 0;
|
||||
|
||||
@@ -4704,7 +4704,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function isTypeOfExpression(node: Node): node is TypeOfExpression {
|
||||
return node.kind === SyntaxKind.AwaitExpression;
|
||||
return node.kind === SyntaxKind.TypeOfExpression;
|
||||
}
|
||||
|
||||
export function isVoidExpression(node: Node): node is VoidExpression {
|
||||
|
||||
@@ -131,13 +131,13 @@ function removeExpectedErrors(errors: string, cwd: string): string {
|
||||
function isUnexpectedError(cwd: string) {
|
||||
return (error: string[]) => {
|
||||
ts.Debug.assertGreaterThanOrEqual(error.length, 1);
|
||||
const match = error[0].match(/(.+\.ts)\((\d+),\d+\): error TS/);
|
||||
const match = error[0].match(/(.+\.tsx?)\((\d+),\d+\): error TS/);
|
||||
if (!match) {
|
||||
return true;
|
||||
}
|
||||
const [, errorFile, lineNumberString] = match;
|
||||
const lines = fs.readFileSync(path.join(cwd, errorFile), { encoding: "utf8" }).split("\n");
|
||||
const lineNumber = parseInt(lineNumberString);
|
||||
const lineNumber = parseInt(lineNumberString) - 1;
|
||||
ts.Debug.assertGreaterThanOrEqual(lineNumber, 0);
|
||||
ts.Debug.assertLessThan(lineNumber, lines.length);
|
||||
const previousLine = lineNumber - 1 > 0 ? lines[lineNumber - 1] : "";
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace ts.Completions {
|
||||
None,
|
||||
ClassElementKeywords, // Keywords at class keyword
|
||||
ConstructorParameterKeywords, // Keywords at constructor parameter
|
||||
FunctionLikeBodyKeywords // Keywords at function like body
|
||||
}
|
||||
|
||||
export function getCompletionsAtPosition(
|
||||
@@ -1060,6 +1061,10 @@ namespace ts.Completions {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tryGetFunctionLikeBodyCompletionContainer(contextToken)) {
|
||||
keywordFilters = KeywordCompletionFilters.FunctionLikeBodyKeywords;
|
||||
}
|
||||
|
||||
if (classLikeContainer = tryGetClassLikeCompletionContainer(contextToken)) {
|
||||
// cursor inside class declaration
|
||||
getGetClassLikeCompletionSymbols(classLikeContainer);
|
||||
@@ -1688,6 +1693,22 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function tryGetFunctionLikeBodyCompletionContainer(contextToken: Node): FunctionLikeDeclaration {
|
||||
if (contextToken) {
|
||||
let prev: Node;
|
||||
const container = findAncestor(contextToken.parent, (node: Node) => {
|
||||
if (isClassLike(node)) {
|
||||
return "quit";
|
||||
}
|
||||
if (isFunctionLikeDeclaration(node) && prev === node.body) {
|
||||
return true;
|
||||
}
|
||||
prev = node;
|
||||
});
|
||||
return container && container as FunctionLikeDeclaration;
|
||||
}
|
||||
}
|
||||
|
||||
function tryGetContainingJsxElement(contextToken: Node): JsxOpeningLikeElement {
|
||||
if (contextToken) {
|
||||
const parent = contextToken.parent;
|
||||
@@ -2126,6 +2147,8 @@ namespace ts.Completions {
|
||||
return getFilteredKeywordCompletions(isClassMemberCompletionKeywordText);
|
||||
case KeywordCompletionFilters.ConstructorParameterKeywords:
|
||||
return getFilteredKeywordCompletions(isConstructorParameterCompletionKeywordText);
|
||||
case KeywordCompletionFilters.FunctionLikeBodyKeywords:
|
||||
return getFilteredKeywordCompletions(isFunctionLikeBodyCompletionKeywordText);
|
||||
default:
|
||||
Debug.assertNever(keywordFilter);
|
||||
}
|
||||
@@ -2188,6 +2211,26 @@ namespace ts.Completions {
|
||||
return isConstructorParameterCompletionKeyword(stringToToken(text));
|
||||
}
|
||||
|
||||
function isFunctionLikeBodyCompletionKeyword(kind: SyntaxKind) {
|
||||
switch (kind) {
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.ReadonlyKeyword:
|
||||
case SyntaxKind.ConstructorKeyword:
|
||||
case SyntaxKind.StaticKeyword:
|
||||
case SyntaxKind.AbstractKeyword:
|
||||
case SyntaxKind.GetKeyword:
|
||||
case SyntaxKind.SetKeyword:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function isFunctionLikeBodyCompletionKeywordText(text: string) {
|
||||
return isFunctionLikeBodyCompletionKeyword(stringToToken(text));
|
||||
}
|
||||
|
||||
function isEqualityOperatorKind(kind: ts.SyntaxKind): kind is EqualityOperator {
|
||||
switch (kind) {
|
||||
case ts.SyntaxKind.EqualsEqualsEqualsToken:
|
||||
|
||||
@@ -321,6 +321,9 @@ namespace ts.formatting {
|
||||
rule("NoSpaceAfterCloseBracket", SyntaxKind.CloseBracketToken, anyToken, [isNonJsxSameLineTokenContext, isNotBeforeBlockInFunctionDeclarationContext], RuleAction.Delete),
|
||||
rule("SpaceAfterSemicolon", SyntaxKind.SemicolonToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Space),
|
||||
|
||||
// Remove extra space between for and await
|
||||
rule("SpaceBetweenForAndAwaitKeyword", SyntaxKind.ForKeyword, SyntaxKind.AwaitKeyword, [isNonJsxSameLineTokenContext], RuleAction.Space),
|
||||
|
||||
// Add a space between statements. All keywords except (do,else,case) has open/close parens after them.
|
||||
// So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any]
|
||||
rule(
|
||||
|
||||
43
tests/cases/fourslash/completionInFunctionLikeBody.ts
Normal file
43
tests/cases/fourslash/completionInFunctionLikeBody.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
//// class Foo {
|
||||
//// bar () {
|
||||
//// /*1*/
|
||||
//// class Foo1 {
|
||||
//// bar1 () {
|
||||
//// /*2*/
|
||||
//// }
|
||||
//// /*3*/
|
||||
//// }
|
||||
//// }
|
||||
//// /*4*/
|
||||
//// }
|
||||
|
||||
|
||||
goTo.marker("1");
|
||||
verify.not.completionListContains("public", "public", /*documentation*/ undefined, "keyword");
|
||||
verify.not.completionListContains("private", "private", /*documentation*/ undefined, "keyword");
|
||||
verify.not.completionListContains("protected", "protected", /*documentation*/ undefined, "keyword");
|
||||
verify.not.completionListContains("constructor", "constructor", /*documentation*/ undefined, "keyword");
|
||||
verify.not.completionListContains("readonly", "readonly", /*documentation*/ undefined, "keyword");
|
||||
verify.not.completionListContains("static", "static", /*documentation*/ undefined, "keyword");
|
||||
verify.not.completionListContains("abstract", "abstract", /*documentation*/ undefined, "keyword");
|
||||
verify.not.completionListContains("get", "get", /*documentation*/ undefined, "keyword");
|
||||
verify.not.completionListContains("set", "set", /*documentation*/ undefined, "keyword");
|
||||
|
||||
goTo.marker("2");
|
||||
verify.not.completionListContains("public", "public", /*documentation*/ undefined, "keyword");
|
||||
verify.not.completionListContains("private", "private", /*documentation*/ undefined, "keyword");
|
||||
verify.not.completionListContains("protected", "protected", /*documentation*/ undefined, "keyword");
|
||||
verify.not.completionListContains("constructor", "constructor", /*documentation*/ undefined, "keyword");
|
||||
verify.not.completionListContains("readonly", "readonly", /*documentation*/ undefined, "keyword");
|
||||
verify.not.completionListContains("static", "static", /*documentation*/ undefined, "keyword");
|
||||
verify.not.completionListContains("abstract", "abstract", /*documentation*/ undefined, "keyword");
|
||||
verify.not.completionListContains("get", "get", /*documentation*/ undefined, "keyword");
|
||||
verify.not.completionListContains("set", "set", /*documentation*/ undefined, "keyword");
|
||||
|
||||
goTo.marker("3");
|
||||
verify.completionListContainsClassElementKeywords();
|
||||
|
||||
goTo.marker("4");
|
||||
verify.completionListContainsClassElementKeywords();
|
||||
@@ -6,5 +6,5 @@
|
||||
////var f = function () { return new/**/; }
|
||||
|
||||
goTo.marker();
|
||||
verify.completionListCount(116);
|
||||
verify.completionListCount(107);
|
||||
verify.completionListContains('new');
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
////var f = function (s) { return this/**/; }
|
||||
|
||||
goTo.marker();
|
||||
verify.completionListCount(117);
|
||||
verify.completionListCount(108);
|
||||
verify.completionListContains('this')
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
////interface I { x: number; }
|
||||
////interface Many<T> extends ReadonlyArray<T> { extra: number; }
|
||||
////const x: I | I[] | Many<string> = { /**/ };
|
||||
////class C { private priv: number; }
|
||||
////const x: I | I[] | Many<string> | C = { /**/ };
|
||||
|
||||
// We specifically filter out any array-like types.
|
||||
// Private members will be excluded by `createUnionOrIntersectionProperty`.
|
||||
verify.completionsAt("", ["x"]);
|
||||
|
||||
18
tests/cases/fourslash/formattingAwait.ts
Normal file
18
tests/cases/fourslash/formattingAwait.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////async function f() {
|
||||
//// for await (const x of g()) {
|
||||
//// console.log(x);
|
||||
//// }
|
||||
////}
|
||||
|
||||
|
||||
format.document();
|
||||
|
||||
verify.currentFileContentIs(
|
||||
`async function f() {
|
||||
for await (const x of g()) {
|
||||
console.log(x);
|
||||
}
|
||||
}`
|
||||
);
|
||||
Reference in New Issue
Block a user