Merge branch 'master' into watchOptions

This commit is contained in:
Sheetal Nandi
2018-01-22 11:16:47 -08:00
13 changed files with 157 additions and 28 deletions

2
.gitignore vendored
View File

@@ -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

View File

@@ -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");

View File

@@ -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();

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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] : "";

View File

@@ -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:

View File

@@ -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(

View 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();

View File

@@ -6,5 +6,5 @@
////var f = function () { return new/**/; }
goTo.marker();
verify.completionListCount(116);
verify.completionListCount(107);
verify.completionListContains('new');

View File

@@ -5,5 +5,5 @@
////var f = function (s) { return this/**/; }
goTo.marker();
verify.completionListCount(117);
verify.completionListCount(108);
verify.completionListContains('this')

View File

@@ -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"]);

View 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);
}
}`
);