diff --git a/Gulpfile.ts b/Gulpfile.ts
index bea8eb30de8..ebedfd43c23 100644
--- a/Gulpfile.ts
+++ b/Gulpfile.ts
@@ -725,16 +725,16 @@ declare module "convert-source-map" {
}
gulp.task("browserify", "Runs browserify on run.js to produce a file suitable for running tests in the browser", [servicesFile], (done) => {
- const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: "built/local/bundle.js" }, /*useBuiltCompiler*/ true));
+ const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: "../../built/local/bundle.js" }, /*useBuiltCompiler*/ true));
return testProject.src()
.pipe(newer("built/local/bundle.js"))
.pipe(sourcemaps.init())
- .pipe(testProject)
+ .pipe(testProject())
.pipe(through2.obj((file, enc, next) => {
const originalMap = file.sourceMap;
const prebundledContent = file.contents.toString();
// Make paths absolute to help sorcery deal with all the terrible paths being thrown around
- originalMap.sources = originalMap.sources.map(s => path.resolve("src", s));
+ originalMap.sources = originalMap.sources.map(s => path.resolve(s));
// intoStream (below) makes browserify think the input file is named this, so this is what it puts in the sourcemap
originalMap.file = "built/local/_stream_0.js";
diff --git a/Jakefile.js b/Jakefile.js
index 6f86ef35b09..76ac1b19b2c 100644
--- a/Jakefile.js
+++ b/Jakefile.js
@@ -176,7 +176,7 @@ var serverCoreSources = [
"lsHost.ts",
"project.ts",
"editorServices.ts",
- "protocol.d.ts",
+ "protocol.ts",
"session.ts",
"server.ts"
].map(function (f) {
@@ -200,14 +200,13 @@ var typingsInstallerSources = [
var serverSources = serverCoreSources.concat(servicesSources);
var languageServiceLibrarySources = [
- "protocol.d.ts",
+ "protocol.ts",
"utilities.ts",
"scriptVersionCache.ts",
"scriptInfo.ts",
"lsHost.ts",
"project.ts",
"editorServices.ts",
- "protocol.d.ts",
"session.ts",
].map(function (f) {
@@ -261,7 +260,7 @@ var harnessSources = harnessCoreSources.concat([
].map(function (f) {
return path.join(unittestsDirectory, f);
})).concat([
- "protocol.d.ts",
+ "protocol.ts",
"utilities.ts",
"scriptVersionCache.ts",
"scriptInfo.ts",
@@ -269,7 +268,6 @@ var harnessSources = harnessCoreSources.concat([
"project.ts",
"typingsCache.ts",
"editorServices.ts",
- "protocol.d.ts",
"session.ts",
].map(function (f) {
return path.join(serverDirectory, f);
@@ -520,6 +518,40 @@ compileFile(processDiagnosticMessagesJs,
[],
/*useBuiltCompiler*/ false);
+var buildProtocolTs = path.join(scriptsDirectory, "buildProtocol.ts");
+var buildProtocolJs = path.join(scriptsDirectory, "buildProtocol.js");
+var buildProtocolDts = path.join(builtLocalDirectory, "protocol.d.ts");
+var typescriptServicesDts = path.join(builtLocalDirectory, "typescriptServices.d.ts");
+
+file(buildProtocolTs);
+
+compileFile(buildProtocolJs,
+ [buildProtocolTs],
+ [buildProtocolTs],
+ [],
+ /*useBuiltCompiler*/ false,
+ {noOutFile: true});
+
+file(buildProtocolDts, [buildProtocolTs, buildProtocolJs, typescriptServicesDts], function() {
+
+ var protocolTs = path.join(serverDirectory, "protocol.ts");
+
+ var cmd = host + " " + buildProtocolJs + " "+ protocolTs + " " + typescriptServicesDts + " " + buildProtocolDts;
+ console.log(cmd);
+ var ex = jake.createExec([cmd]);
+ // Add listeners for output and error
+ ex.addListener("stdout", function (output) {
+ process.stdout.write(output);
+ });
+ ex.addListener("stderr", function (error) {
+ process.stderr.write(error);
+ });
+ ex.addListener("cmdEnd", function () {
+ complete();
+ });
+ ex.run();
+}, { async: true })
+
// The generated diagnostics map; built for the compiler and for the 'generate-diagnostics' task
file(diagnosticInfoMapTs, [processDiagnosticMessagesJs, diagnosticMessagesJson], function () {
var cmd = host + " " + processDiagnosticMessagesJs + " " + diagnosticMessagesJson;
@@ -657,6 +689,8 @@ compileFile(
inlineSourceMap: true
});
+file(typescriptServicesDts, [servicesFile]);
+
var cancellationTokenFile = path.join(builtLocalDirectory, "cancellationToken.js");
compileFile(cancellationTokenFile, cancellationTokenSources, [builtLocalDirectory].concat(cancellationTokenSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { outDir: builtLocalDirectory, noOutFile: true });
@@ -691,7 +725,7 @@ task("build-fold-end", [], function () {
// Local target to build the compiler and services
desc("Builds the full compiler and services");
-task("local", ["build-fold-start", "generate-diagnostics", "lib", tscFile, servicesFile, nodeDefinitionsFile, serverFile, builtGeneratedDiagnosticMessagesJSON, "lssl", "build-fold-end"]);
+task("local", ["build-fold-start", "generate-diagnostics", "lib", tscFile, servicesFile, nodeDefinitionsFile, serverFile, buildProtocolDts, builtGeneratedDiagnosticMessagesJSON, "lssl", "build-fold-end"]);
// Local target to build only tsc.js
desc("Builds only the compiler");
@@ -747,7 +781,7 @@ task("generate-spec", [specMd]);
// Makes a new LKG. This target does not build anything, but errors if not all the outputs are present in the built/local directory
desc("Makes a new LKG out of the built js files");
task("LKG", ["clean", "release", "local"].concat(libraryTargets), function () {
- var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile].concat(libraryTargets);
+ var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile, buildProtocolDts].concat(libraryTargets);
var missingFiles = expectedFiles.filter(function (f) {
return !fs.existsSync(f);
});
diff --git a/scripts/buildProtocol.ts b/scripts/buildProtocol.ts
new file mode 100644
index 00000000000..8d49262a470
--- /dev/null
+++ b/scripts/buildProtocol.ts
@@ -0,0 +1,143 @@
+///
+
+import * as ts from "../lib/typescript";
+import * as path from "path";
+
+function endsWith(s: string, suffix: string) {
+ return s.lastIndexOf(suffix, s.length - suffix.length) !== -1;
+}
+
+class DeclarationsWalker {
+ private visitedTypes: ts.Type[] = [];
+ private text = "";
+ private constructor(private typeChecker: ts.TypeChecker, private protocolFile: ts.SourceFile) {
+ }
+
+ static getExtraDeclarations(typeChecker: ts.TypeChecker, protocolFile: ts.SourceFile): string {
+ let text = "declare namespace ts.server.protocol {\n";
+ var walker = new DeclarationsWalker(typeChecker, protocolFile);
+ walker.visitTypeNodes(protocolFile);
+ return walker.text
+ ? `declare namespace ts.server.protocol {\n${walker.text}}`
+ : "";
+ }
+
+ private processType(type: ts.Type): void {
+ if (this.visitedTypes.indexOf(type) >= 0) {
+ return;
+ }
+ this.visitedTypes.push(type);
+ let s = type.aliasSymbol || type.getSymbol();
+ if (!s) {
+ return;
+ }
+ if (s.name === "Array") {
+ // we should process type argument instead
+ return this.processType((type).typeArguments[0]);
+ }
+ else {
+ for (const decl of s.getDeclarations()) {
+ const sourceFile = decl.getSourceFile();
+ if (sourceFile === this.protocolFile || path.basename(sourceFile.fileName) === "lib.d.ts") {
+ return;
+ }
+ // splice declaration in final d.ts file
+ const text = decl.getFullText();
+ this.text += `${text}\n`;
+
+ // recursively pull all dependencies into result dts file
+ this.visitTypeNodes(decl);
+ }
+ }
+ }
+
+ private visitTypeNodes(node: ts.Node) {
+ if (node.parent) {
+ switch (node.parent.kind) {
+ case ts.SyntaxKind.VariableDeclaration:
+ case ts.SyntaxKind.MethodDeclaration:
+ case ts.SyntaxKind.MethodSignature:
+ case ts.SyntaxKind.PropertyDeclaration:
+ case ts.SyntaxKind.PropertySignature:
+ case ts.SyntaxKind.Parameter:
+ case ts.SyntaxKind.IndexSignature:
+ if (((node.parent).type) === node) {
+ const type = this.typeChecker.getTypeAtLocation(node);
+ if (type && !(type.flags & ts.TypeFlags.TypeParameter)) {
+ this.processType(type);
+ }
+ }
+ break;
+ }
+ }
+ ts.forEachChild(node, n => this.visitTypeNodes(n));
+ }
+}
+
+function generateProtocolFile(protocolTs: string, typeScriptServicesDts: string): string {
+ const options = { target: ts.ScriptTarget.ES5, declaration: true, noResolve: true, types: [], stripInternal: true };
+
+ /**
+ * 1st pass - generate a program from protocol.ts and typescriptservices.d.ts and emit core version of protocol.d.ts with all internal members stripped
+ * @return text of protocol.d.t.s
+ */
+ function getInitialDtsFileForProtocol() {
+ const program = ts.createProgram([protocolTs, typeScriptServicesDts], options);
+
+ let protocolDts: string;
+ program.emit(program.getSourceFile(protocolTs), (file, content) => {
+ if (endsWith(file, ".d.ts")) {
+ protocolDts = content;
+ }
+ });
+ if (protocolDts === undefined) {
+ throw new Error(`Declaration file for protocol.ts is not generated`)
+ }
+ return protocolDts;
+ }
+
+ const protocolFileName = "protocol.d.ts";
+ /**
+ * Second pass - generate a program from protocol.d.ts and typescriptservices.d.ts, then augment core protocol.d.ts with extra types from typescriptservices.d.ts
+ */
+ function getProgramWithProtocolText(protocolDts: string, includeTypeScriptServices: boolean) {
+ const host = ts.createCompilerHost(options);
+ const originalGetSourceFile = host.getSourceFile;
+ host.getSourceFile = (fileName) => {
+ if (fileName === protocolFileName) {
+ return ts.createSourceFile(fileName, protocolDts, options.target);
+ }
+ return originalGetSourceFile.apply(host, [fileName]);
+ }
+ const rootFiles = includeTypeScriptServices ? [protocolFileName, typeScriptServicesDts] : [protocolFileName];
+ return ts.createProgram(rootFiles, options, host);
+ }
+
+ let protocolDts = getInitialDtsFileForProtocol();
+ const program = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ true);
+
+ const protocolFile = program.getSourceFile("protocol.d.ts");
+ const extraDeclarations = DeclarationsWalker.getExtraDeclarations(program.getTypeChecker(), protocolFile);
+ if (extraDeclarations) {
+ protocolDts += extraDeclarations;
+ }
+ // do sanity check and try to compile generated text as standalone program
+ const sanityCheckProgram = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ false);
+ const diagnostics = [...program.getSyntacticDiagnostics(), ...program.getSemanticDiagnostics(), ...program.getGlobalDiagnostics()];
+ if (diagnostics.length) {
+ const flattenedDiagnostics = diagnostics.map(d => ts.flattenDiagnosticMessageText(d.messageText, "\n")).join("\n");
+ throw new Error(`Unexpected errors during sanity check: ${flattenedDiagnostics}`);
+ }
+ return protocolDts;
+}
+
+if (process.argv.length < 5) {
+ console.log(`Expected 3 arguments: path to 'protocol.ts', path to 'typescriptservices.d.ts' and path to output file`);
+ process.exit(1);
+}
+
+const protocolTs = process.argv[2];
+const typeScriptServicesDts = process.argv[3];
+const outputFile = process.argv[4];
+const generatedProtocolDts = generateProtocolFile(protocolTs, typeScriptServicesDts);
+ts.sys.writeFile(outputFile, generatedProtocolDts);
diff --git a/scripts/tslint/preferConstRule.ts b/scripts/tslint/preferConstRule.ts
index 9425d2b6079..445fbe2e72a 100644
--- a/scripts/tslint/preferConstRule.ts
+++ b/scripts/tslint/preferConstRule.ts
@@ -126,7 +126,7 @@ class PreferConstWalker extends Lint.RuleWalker {
visitModuleDeclaration(node: ts.ModuleDeclaration) {
if (node.body.kind === ts.SyntaxKind.ModuleBlock) {
// For some reason module blocks are left out of the visit block traversal
- this.visitBlock(node.body as ts.ModuleBlock);
+ this.visitBlock(node.body as any as ts.Block);
}
super.visitModuleDeclaration(node);
}
diff --git a/scripts/tslint/typeOperatorSpacingRule.ts b/scripts/tslint/typeOperatorSpacingRule.ts
index 7ceef2372bf..559d1b34937 100644
--- a/scripts/tslint/typeOperatorSpacingRule.ts
+++ b/scripts/tslint/typeOperatorSpacingRule.ts
@@ -18,8 +18,13 @@ class TypeOperatorSpacingWalker extends Lint.RuleWalker {
for (let i = 1; i < types.length; i++) {
const currentType = types[i];
if (expectedStart !== currentType.pos || currentType.getLeadingTriviaWidth() !== 1) {
- const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING);
- this.addFailure(failure);
+ const sourceFile = currentType.getSourceFile();
+ const previousTypeEndPos = sourceFile.getLineAndCharacterOfPosition(types[i - 1].end);
+ const currentTypeStartPos = sourceFile.getLineAndCharacterOfPosition(currentType.pos);
+ if (previousTypeEndPos.line === currentTypeStartPos.line) {
+ const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING);
+ this.addFailure(failure);
+ }
}
expectedStart = currentType.end + 2;
}
diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts
index 970e481faaa..16152584b81 100644
--- a/src/compiler/binder.ts
+++ b/src/compiler/binder.ts
@@ -355,11 +355,24 @@ namespace ts {
? Diagnostics.Cannot_redeclare_block_scoped_variable_0
: Diagnostics.Duplicate_identifier_0;
- forEach(symbol.declarations, declaration => {
- if (hasModifier(declaration, ModifierFlags.Default)) {
+ if (symbol.declarations && symbol.declarations.length) {
+ // If the current node is a default export of some sort, then check if
+ // there are any other default exports that we need to error on.
+ // We'll know whether we have other default exports depending on if `symbol` already has a declaration list set.
+ if (isDefaultExport) {
message = Diagnostics.A_module_cannot_have_multiple_default_exports;
}
- });
+ else {
+ // This is to properly report an error in the case "export default { }" is after export default of class declaration or function declaration.
+ // Error on multiple export default in the following case:
+ // 1. multiple export default of class declaration or function declaration by checking NodeFlags.Default
+ // 2. multiple export default of export assignment. This one doesn't have NodeFlags.Default on (as export default doesn't considered as modifiers)
+ if (symbol.declarations && symbol.declarations.length &&
+ (isDefaultExport || (node.kind === SyntaxKind.ExportAssignment && !(node).isExportEquals))) {
+ message = Diagnostics.A_module_cannot_have_multiple_default_exports;
+ }
+ }
+ }
forEach(symbol.declarations, declaration => {
file.bindDiagnostics.push(createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration)));
@@ -1111,7 +1124,7 @@ namespace ts {
}
else {
forEachChild(node, bind);
- if (node.operator === SyntaxKind.PlusEqualsToken || node.operator === SyntaxKind.MinusMinusToken) {
+ if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) {
bindAssignmentTargetFlow(node.operand);
}
}
@@ -1360,7 +1373,7 @@ namespace ts {
function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean {
const body = node.kind === SyntaxKind.SourceFile ? node : (node).body;
if (body && (body.kind === SyntaxKind.SourceFile || body.kind === SyntaxKind.ModuleBlock)) {
- for (const stat of (body).statements) {
+ for (const stat of (body).statements) {
if (stat.kind === SyntaxKind.ExportDeclaration || stat.kind === SyntaxKind.ExportAssignment) {
return true;
}
@@ -1944,12 +1957,15 @@ namespace ts {
bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node));
}
else {
+ // An export default clause with an expression exports a value
+ // We want to exclude both class and function here, this is necessary to issue an error when there are both
+ // default export-assignment and default export function and class declaration.
const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node)
// An export default clause with an EntityNameExpression exports all meanings of that identifier
? SymbolFlags.Alias
// An export default clause with any other expression exports a value
: SymbolFlags.Property;
- declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes);
+ declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.Property | SymbolFlags.AliasExcludes | SymbolFlags.Class | SymbolFlags.Function);
}
}
@@ -2207,9 +2223,9 @@ namespace ts {
if (currentFlow) {
node.flowNode = currentFlow;
}
- checkStrictModeFunctionName(node);
- const bindingName = (node).name ? (node).name.text : "__function";
- return bindAnonymousDeclaration(node, SymbolFlags.Function, bindingName);
+ checkStrictModeFunctionName(node);
+ const bindingName = node.name ? node.name.text : "__function";
+ return bindAnonymousDeclaration(node, SymbolFlags.Function, bindingName);
}
function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
@@ -2432,8 +2448,7 @@ namespace ts {
}
// If the parameter's name is 'this', then it is TypeScript syntax.
- if (subtreeFlags & TransformFlags.ContainsDecorators
- || (name && isIdentifier(name) && name.originalKeywordKind === SyntaxKind.ThisKeyword)) {
+ if (subtreeFlags & TransformFlags.ContainsDecorators || isThisIdentifier(name)) {
transformFlags |= TransformFlags.AssertTypeScript;
}
diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index cecf2964f3c..dc596bed8a0 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -120,6 +120,7 @@ namespace ts {
const resolvingSymbol = createSymbol(SymbolFlags.Transient, "__resolving__");
const anyType = createIntrinsicType(TypeFlags.Any, "any");
+ const autoType = createIntrinsicType(TypeFlags.Any, "any");
const unknownType = createIntrinsicType(TypeFlags.Any, "unknown");
const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined");
const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsWideningType, "undefined");
@@ -921,7 +922,7 @@ namespace ts {
if (result && isInExternalModule && (meaning & SymbolFlags.Value) === SymbolFlags.Value) {
const decls = result.declarations;
if (decls && decls.length === 1 && decls[0].kind === SyntaxKind.NamespaceExportDeclaration) {
- error(errorLocation, Diagnostics.Identifier_0_must_be_imported_from_a_module, name);
+ error(errorLocation, Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead, name);
}
}
}
@@ -1464,6 +1465,10 @@ namespace ts {
function getExportsForModule(moduleSymbol: Symbol): SymbolTable {
const visitedSymbols: Symbol[] = [];
+
+ // A module defined by an 'export=' consists on one export that needs to be resolved
+ moduleSymbol = resolveExternalModuleSymbol(moduleSymbol);
+
return visit(moduleSymbol) || moduleSymbol.exports;
// The ES6 spec permits export * declarations in a module to circularly reference the module itself. For example,
@@ -2183,9 +2188,14 @@ namespace ts {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
}
- else if (!(flags & TypeFormatFlags.InTypeAlias) && type.flags & (TypeFlags.Anonymous | TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
+ else if (!(flags & TypeFormatFlags.InTypeAlias) && ((type.flags & TypeFlags.Anonymous && !(type).target) || type.flags & TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
- // Only write out inferred type with its corresponding type-alias if type-alias is visible
+ // We emit inferred type as type-alias at the current localtion if all the following is true
+ // the input type is has alias symbol that is accessible
+ // the input type is a union, intersection or anonymous type that is fully instantiated (if not we want to keep dive into)
+ // e.g.: export type Bar = () => [X, Y];
+ // export type Foo = Bar;
+ // export const y = (x: Foo) => 1 // we want to emit as ...x: () => [any, string])
const typeArguments = type.aliasTypeArguments;
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, nextFlags);
}
@@ -3051,6 +3061,11 @@ namespace ts {
return undefined;
}
+ function isAutoVariableInitializer(initializer: Expression) {
+ const expr = initializer && skipParentheses(initializer);
+ return !expr || expr.kind === SyntaxKind.NullKeyword || expr.kind === SyntaxKind.Identifier && getResolvedSymbol(expr) === undefinedSymbol;
+ }
+
function addOptionality(type: Type, optional: boolean): Type {
return strictNullChecks && optional ? includeFalsyTypes(type, TypeFlags.Undefined) : type;
}
@@ -3089,6 +3104,14 @@ namespace ts {
return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ declaration.questionToken && includeOptionality);
}
+ // Use control flow type inference for non-ambient, non-exported var or let variables with no initializer
+ // or a 'null' or 'undefined' initializer.
+ if (declaration.kind === SyntaxKind.VariableDeclaration && !isBindingPattern(declaration.name) &&
+ !(getCombinedNodeFlags(declaration) & NodeFlags.Const) && !(getCombinedModifierFlags(declaration) & ModifierFlags.Export) &&
+ !isInAmbientContext(declaration) && isAutoVariableInitializer(declaration.initializer)) {
+ return autoType;
+ }
+
if (declaration.kind === SyntaxKind.Parameter) {
const func = declaration.parent;
// For a parameter of a set accessor, use the type of the get accessor if one is present
@@ -3887,7 +3910,7 @@ namespace ts {
if (!links.declaredType) {
const enumType = getDeclaredTypeOfEnum(getParentOfSymbol(symbol));
links.declaredType = enumType.flags & TypeFlags.Union ?
- enumType.memberTypes[getEnumMemberValue(symbol.valueDeclaration)] :
+ enumType.memberTypes[getEnumMemberValue(symbol.valueDeclaration)] :
enumType;
}
return links.declaredType;
@@ -6070,7 +6093,7 @@ namespace ts {
return !node.typeParameters && areAllParametersUntyped && !isNullaryArrow;
}
- function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | MethodDeclaration {
+ function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | ArrowFunction | MethodDeclaration {
return (isFunctionExpressionOrArrowFunction(func) || isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func);
}
@@ -8455,7 +8478,9 @@ namespace ts {
if (!reference.flowNode || assumeInitialized && !(declaredType.flags & TypeFlags.Narrowable)) {
return declaredType;
}
- const initialType = assumeInitialized ? declaredType : includeFalsyTypes(declaredType, TypeFlags.Undefined);
+ const initialType = assumeInitialized ? declaredType :
+ declaredType === autoType ? undefinedType :
+ includeFalsyTypes(declaredType, TypeFlags.Undefined);
const visitedFlowStart = visitedFlowCount;
const result = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode));
visitedFlowCount = visitedFlowStart;
@@ -8529,9 +8554,12 @@ namespace ts {
// Assignments only narrow the computed type if the declared type is a union type. Thus, we
// only need to evaluate the assigned type if the declared type is a union type.
if (isMatchingReference(reference, node)) {
- const isIncrementOrDecrement = node.parent.kind === SyntaxKind.PrefixUnaryExpression || node.parent.kind === SyntaxKind.PostfixUnaryExpression;
- return declaredType.flags & TypeFlags.Union && !isIncrementOrDecrement ?
- getAssignmentReducedType(declaredType, getInitialOrAssignedType(node)) :
+ if (node.parent.kind === SyntaxKind.PrefixUnaryExpression || node.parent.kind === SyntaxKind.PostfixUnaryExpression) {
+ const flowType = getTypeAtFlowNode(flow.antecedent);
+ return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType));
+ }
+ return declaredType === autoType ? getBaseTypeOfLiteralType(getInitialOrAssignedType(node)) :
+ declaredType.flags & TypeFlags.Union ? getAssignmentReducedType(declaredType, getInitialOrAssignedType(node)) :
declaredType;
}
// We didn't have a direct match. However, if the reference is a dotted name, this
@@ -8975,7 +9003,7 @@ namespace ts {
if (isRightSideOfQualifiedNameOrPropertyAccess(location)) {
location = location.parent;
}
- if (isExpression(location) && !isAssignmentTarget(location)) {
+ if (isPartOfExpression(location) && !isAssignmentTarget(location)) {
const type = checkExpression(location);
if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) {
return type;
@@ -9146,13 +9174,23 @@ namespace ts {
// We only look for uninitialized variables in strict null checking mode, and only when we can analyze
// the entire control flow graph from the variable's declaration (i.e. when the flow container and
// declaration container are the same).
- const assumeInitialized = !strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || isParameter ||
- isOuterVariable || isInAmbientContext(declaration);
+ const assumeInitialized = isParameter || isOuterVariable ||
+ type !== autoType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0) ||
+ isInAmbientContext(declaration);
const flowType = getFlowTypeOfReference(node, type, assumeInitialized, flowContainer);
// A variable is considered uninitialized when it is possible to analyze the entire control flow graph
// from declaration to use, and when the variable's declared type doesn't include undefined but the
// control flow based type does include undefined.
- if (!assumeInitialized && !(getFalsyFlags(type) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) {
+ if (type === autoType) {
+ if (flowType === autoType) {
+ if (compilerOptions.noImplicitAny) {
+ error(declaration.name, Diagnostics.Variable_0_implicitly_has_type_any_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol));
+ error(node, Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(anyType));
+ }
+ return anyType;
+ }
+ }
+ else if (!assumeInitialized && !(getFalsyFlags(type) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) {
error(node, Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol));
// Return the declared type to reduce follow-on errors
return type;
@@ -9266,7 +9304,7 @@ namespace ts {
}
function findFirstSuperCall(n: Node): Node {
- if (isSuperCallExpression(n)) {
+ if (isSuperCall(n)) {
return n;
}
else if (isFunctionLike(n)) {
@@ -9373,7 +9411,7 @@ namespace ts {
captureLexicalThis(node, container);
}
if (isFunctionLike(container) &&
- (!isInParameterInitializerBeforeContainingFunction(node) || getFunctionLikeThisParameter(container))) {
+ (!isInParameterInitializerBeforeContainingFunction(node) || getThisParameter(container))) {
// Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated.
// If this is a function in a JS file, it might be a class method. Check if it's the RHS
@@ -9775,7 +9813,7 @@ namespace ts {
// corresponding set accessor has a type annotation, return statements in the function are contextually typed
if (functionDecl.type ||
functionDecl.kind === SyntaxKind.Constructor ||
- functionDecl.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind(functionDecl.symbol, SyntaxKind.SetAccessor))) {
+ functionDecl.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind(functionDecl.symbol, SyntaxKind.SetAccessor))) {
return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl));
}
@@ -10044,7 +10082,7 @@ namespace ts {
}
}
- function isFunctionExpressionOrArrowFunction(node: Node): node is FunctionExpression {
+ function isFunctionExpressionOrArrowFunction(node: Node): node is FunctionExpression | ArrowFunction {
return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction;
}
@@ -10055,7 +10093,7 @@ namespace ts {
: undefined;
}
- function getContextualTypeForFunctionLikeDeclaration(node: FunctionExpression | MethodDeclaration) {
+ function getContextualTypeForFunctionLikeDeclaration(node: FunctionExpression | ArrowFunction | MethodDeclaration) {
return isObjectLiteralMethod(node) ?
getContextualTypeForObjectLiteralMethod(node) :
getApparentTypeOfContextualType(node);
@@ -10066,7 +10104,7 @@ namespace ts {
// If the contextual type is a union type, get the signature from each type possible and if they are
// all identical ignoring their return type, the result is same signature but with return type as
// union type of return types from these signatures
- function getContextualSignature(node: FunctionExpression | MethodDeclaration): Signature {
+ function getContextualSignature(node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature {
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
const type = getContextualTypeForFunctionLikeDeclaration(node);
if (!type) {
@@ -11418,7 +11456,7 @@ namespace ts {
argCount = getEffectiveArgumentCount(node, /*args*/ undefined, signature);
}
else {
- const callExpression = node;
+ const callExpression = node;
if (!callExpression.arguments) {
// This only happens when we have something of the form: 'new C'
Debug.assert(callExpression.kind === SyntaxKind.NewExpression);
@@ -11429,7 +11467,7 @@ namespace ts {
argCount = signatureHelpTrailingComma ? args.length + 1 : args.length;
// If we are missing the close paren, the call is incomplete.
- callIsIncomplete = (callExpression).arguments.end === callExpression.end;
+ callIsIncomplete = callExpression.arguments.end === callExpression.end;
typeArguments = callExpression.typeArguments;
spreadArgIndex = getSpreadArgumentIndex(args);
@@ -12516,7 +12554,7 @@ namespace ts {
* @param node The call/new expression to be checked.
* @returns On success, the expression's signature's return type. On failure, anyType.
*/
- function checkCallExpression(node: CallExpression): Type {
+ function checkCallExpression(node: CallExpression | NewExpression): Type {
// Grammar checking; stop grammar-checking if checkGrammarTypeArguments return true
checkGrammarTypeArguments(node, node.typeArguments) || checkGrammarArguments(node, node.arguments);
@@ -12766,7 +12804,10 @@ namespace ts {
if (!contextualSignature) {
reportErrorsFromWidening(func, type);
}
- if (isUnitType(type) && !(contextualSignature && isLiteralContextualType(getReturnTypeOfSignature(contextualSignature)))) {
+ if (isUnitType(type) &&
+ !(contextualSignature &&
+ isLiteralContextualType(
+ contextualSignature === getSignatureFromDeclaration(func) ? type : getReturnTypeOfSignature(contextualSignature)))) {
type = getWidenedLiteralType(type);
}
@@ -12971,7 +13012,7 @@ namespace ts {
}
}
- if (produceDiagnostics && node.kind !== SyntaxKind.MethodDeclaration && node.kind !== SyntaxKind.MethodSignature) {
+ if (produceDiagnostics && node.kind !== SyntaxKind.MethodDeclaration) {
checkCollisionWithCapturedSuperVariable(node, (node).name);
checkCollisionWithCapturedThisVariable(node, (node).name);
}
@@ -14433,7 +14474,7 @@ namespace ts {
}
function containsSuperCall(n: Node): boolean {
- if (isSuperCallExpression(n)) {
+ if (isSuperCall(n)) {
return true;
}
else if (isFunctionLike(n)) {
@@ -14489,7 +14530,7 @@ namespace ts {
let superCallStatement: ExpressionStatement;
for (const statement of statements) {
- if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((statement).expression)) {
+ if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCall((statement).expression)) {
superCallStatement = statement;
break;
}
@@ -15557,10 +15598,6 @@ namespace ts {
}
}
- function parameterIsThisKeyword(parameter: ParameterDeclaration) {
- return parameter.name && (parameter.name).originalKeywordKind === SyntaxKind.ThisKeyword;
- }
-
function parameterNameStartsWithUnderscore(parameter: ParameterDeclaration) {
return parameter.name && parameter.name.kind === SyntaxKind.Identifier && (parameter.name).text.charCodeAt(0) === CharacterCodes._;
}
@@ -15902,6 +15939,10 @@ namespace ts {
}
}
+ function convertAutoToAny(type: Type) {
+ return type === autoType ? anyType : type;
+ }
+
// Check variable, parameter, or property declaration
function checkVariableLikeDeclaration(node: VariableLikeDeclaration) {
checkDecorators(node);
@@ -15952,7 +15993,7 @@ namespace ts {
return;
}
const symbol = getSymbolOfNode(node);
- const type = getTypeOfVariableOrParameterOrProperty(symbol);
+ const type = convertAutoToAny(getTypeOfVariableOrParameterOrProperty(symbol));
if (node === symbol.valueDeclaration) {
// Node is the primary declaration of the symbol, just validate the initializer
// Don't validate for-in initializer as it is already an error
@@ -15964,7 +16005,7 @@ namespace ts {
else {
// Node is a secondary declaration, check that type is identical to primary declaration and check that
// initializer is consistent with type associated with the node
- const declarationType = getWidenedTypeForVariableLikeDeclaration(node);
+ const declarationType = convertAutoToAny(getWidenedTypeForVariableLikeDeclaration(node));
if (type !== unknownType && declarationType !== unknownType && !isTypeIdenticalTo(type, declarationType)) {
error(node.name, Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2, declarationNameToString(node.name), typeToString(type), typeToString(declarationType));
}
@@ -16453,7 +16494,7 @@ namespace ts {
}
function isGetAccessorWithAnnotatedSetAccessor(node: FunctionLikeDeclaration) {
- return !!(node.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind(node.symbol, SyntaxKind.SetAccessor)));
+ return !!(node.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind(node.symbol, SyntaxKind.SetAccessor)));
}
function isUnwrappedReturnTypeVoidOrAny(func: FunctionLikeDeclaration, returnType: Type): boolean {
@@ -17445,9 +17486,12 @@ namespace ts {
}
}
- checkCollisionWithCapturedThisVariable(node, node.name);
- checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
- checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
+ if (isIdentifier(node.name)) {
+ checkCollisionWithCapturedThisVariable(node, node.name);
+ checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
+ checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
+ }
+
checkExportsOnMergedDeclarations(node);
const symbol = getSymbolOfNode(node);
@@ -17849,7 +17893,8 @@ namespace ts {
}
function isNotOverload(declaration: Declaration): boolean {
- return declaration.kind !== SyntaxKind.FunctionDeclaration || !!(declaration as FunctionDeclaration).body;
+ return (declaration.kind !== SyntaxKind.FunctionDeclaration && declaration.kind !== SyntaxKind.MethodDeclaration) ||
+ !!(declaration as FunctionDeclaration).body;
}
}
@@ -18455,6 +18500,9 @@ namespace ts {
(node.parent).moduleSpecifier === node)) {
return resolveExternalModuleName(node, node);
}
+ if (isInJavaScriptFile(node) && isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false)) {
+ return resolveExternalModuleName(node, node);
+ }
// Fall through
case SyntaxKind.NumericLiteral:
@@ -19066,7 +19114,7 @@ namespace ts {
return undefined;
}
- function isLiteralConstDeclaration(node: VariableDeclaration): boolean {
+ function isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean {
if (isConst(node)) {
const type = getTypeOfSymbol(getSymbolOfNode(node));
return !!(type.flags & TypeFlags.StringOrNumberLiteral && type.flags & TypeFlags.FreshLiteral);
@@ -19074,7 +19122,7 @@ namespace ts {
return false;
}
- function writeLiteralConstValue(node: VariableDeclaration, writer: SymbolWriter) {
+ function writeLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, writer: SymbolWriter) {
const type = getTypeOfSymbol(getSymbolOfNode(node));
writer.writeStringLiteral(literalTypeToString(type));
}
@@ -19811,7 +19859,7 @@ namespace ts {
checkGrammarForAtLeastOneTypeArgument(node, typeArguments);
}
- function checkGrammarForOmittedArgument(node: CallExpression, args: NodeArray): boolean {
+ function checkGrammarForOmittedArgument(node: CallExpression | NewExpression, args: NodeArray): boolean {
if (args) {
const sourceFile = getSourceFileOfNode(node);
for (const arg of args) {
@@ -19822,7 +19870,7 @@ namespace ts {
}
}
- function checkGrammarArguments(node: CallExpression, args: NodeArray): boolean {
+ function checkGrammarArguments(node: CallExpression | NewExpression, args: NodeArray): boolean {
return checkGrammarForOmittedArgument(node, args);
}
@@ -19944,8 +19992,7 @@ namespace ts {
for (const prop of node.properties) {
const name = prop.name;
- if (prop.kind === SyntaxKind.OmittedExpression ||
- name.kind === SyntaxKind.ComputedPropertyName) {
+ if (name.kind === SyntaxKind.ComputedPropertyName) {
// If the name is not a ComputedPropertyName, the grammar checking will skip it
checkGrammarComputedPropertyName(name);
}
@@ -19992,7 +20039,7 @@ namespace ts {
currentKind = SetAccessor;
}
else {
- Debug.fail("Unexpected syntax kind:" + prop.kind);
+ Debug.fail("Unexpected syntax kind:" + (prop).kind);
}
const effectiveName = getPropertyNameForPropertyNameNode(name);
@@ -20141,18 +20188,8 @@ namespace ts {
}
function getAccessorThisParameter(accessor: AccessorDeclaration): ParameterDeclaration {
- if (accessor.parameters.length === (accessor.kind === SyntaxKind.GetAccessor ? 1 : 2) &&
- accessor.parameters[0].name.kind === SyntaxKind.Identifier &&
- (accessor.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword) {
- return accessor.parameters[0];
- }
- }
-
- function getFunctionLikeThisParameter(func: FunctionLikeDeclaration) {
- if (func.parameters.length &&
- func.parameters[0].name.kind === SyntaxKind.Identifier &&
- (func.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword) {
- return func.parameters[0];
+ if (accessor.parameters.length === (accessor.kind === SyntaxKind.GetAccessor ? 1 : 2)) {
+ return getThisParameter(accessor);
}
}
diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts
index b77f6898b3c..553efa9e3af 100644
--- a/src/compiler/commandLineParser.ts
+++ b/src/compiler/commandLineParser.ts
@@ -977,7 +977,7 @@ namespace ts {
basePath: string, errors: Diagnostic[], configFileName?: string): CompilerOptions {
const options: CompilerOptions = getBaseFileName(configFileName) === "jsconfig.json"
- ? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true }
+ ? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true }
: {};
convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_compiler_option_0, errors);
return options;
diff --git a/src/compiler/core.ts b/src/compiler/core.ts
index 3f60ec62c2b..4a94e5ff142 100644
--- a/src/compiler/core.ts
+++ b/src/compiler/core.ts
@@ -1097,7 +1097,9 @@ namespace ts {
return path.replace(/\\/g, "/");
}
- // Returns length of path root (i.e. length of "/", "x:/", "//server/share/, file:///user/files")
+ /**
+ * Returns length of path root (i.e. length of "/", "x:/", "//server/share/, file:///user/files")
+ */
export function getRootLength(path: string): number {
if (path.charCodeAt(0) === CharacterCodes.slash) {
if (path.charCodeAt(1) !== CharacterCodes.slash) return 1;
@@ -1126,9 +1128,14 @@ namespace ts {
return 0;
}
+ /**
+ * Internally, we represent paths as strings with '/' as the directory separator.
+ * When we make system calls (eg: LanguageServiceHost.getDirectory()),
+ * we expect the host to correctly handle paths in our specified format.
+ */
export const directorySeparator = "/";
const directorySeparatorCharCode = CharacterCodes.slash;
- function getNormalizedParts(normalizedSlashedPath: string, rootLength: number) {
+ function getNormalizedParts(normalizedSlashedPath: string, rootLength: number): string[] {
const parts = normalizedSlashedPath.substr(rootLength).split(directorySeparator);
const normalized: string[] = [];
for (const part of parts) {
@@ -1168,6 +1175,11 @@ namespace ts {
return path.charCodeAt(path.length - 1) === directorySeparatorCharCode;
}
+ /**
+ * Returns the path except for its basename. Eg:
+ *
+ * /path/to/file.ext -> /path/to
+ */
export function getDirectoryPath(path: Path): Path;
export function getDirectoryPath(path: string): string;
export function getDirectoryPath(path: string): any {
@@ -1813,9 +1825,9 @@ namespace ts {
export interface ObjectAllocator {
getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node;
- getTokenConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Token;
- getIdentifierConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Token;
- getSourceFileConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => SourceFile;
+ getTokenConstructor(): new (kind: TKind, pos?: number, end?: number) => Token;
+ getIdentifierConstructor(): new (kind: SyntaxKind.Identifier, pos?: number, end?: number) => Identifier;
+ getSourceFileConstructor(): new (kind: SyntaxKind.SourceFile, pos?: number, end?: number) => SourceFile;
getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol;
getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type;
getSignatureConstructor(): new (checker: TypeChecker) => Signature;
diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts
index 4e19aafa484..8bcce86c31f 100644
--- a/src/compiler/declarationEmitter.ts
+++ b/src/compiler/declarationEmitter.ts
@@ -1121,7 +1121,7 @@ namespace ts {
writeLine();
}
- function emitVariableDeclaration(node: VariableDeclaration) {
+ function emitVariableDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration) {
// If we are emitting property it isn't moduleElement and hence we already know it needs to be emitted
// so there is no check needed to see if declaration is visible
if (node.kind !== SyntaxKind.VariableDeclaration || resolver.isDeclarationVisible(node)) {
@@ -1136,7 +1136,7 @@ namespace ts {
// If optional property emit ? but in the case of parameterProperty declaration with "?" indicating optional parameter for the constructor
// we don't want to emit property declaration with "?"
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature ||
- (node.kind === SyntaxKind.Parameter && !isParameterPropertyDeclaration(node))) && hasQuestionToken(node)) {
+ (node.kind === SyntaxKind.Parameter && !isParameterPropertyDeclaration(node))) && hasQuestionToken(node)) {
write("?");
}
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && node.parent.kind === SyntaxKind.TypeLiteral) {
@@ -1626,8 +1626,7 @@ namespace ts {
}
}
- function emitBindingElement(bindingElement: BindingElement) {
-
+ function emitBindingElement(bindingElement: BindingElement | OmittedExpression) {
if (bindingElement.kind === SyntaxKind.OmittedExpression) {
// If bindingElement is an omittedExpression (i.e. containing elision),
// we will emit blank space (although this may differ from users' original code,
diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json
index 71d7a978d1b..554bcc50865 100644
--- a/src/compiler/diagnosticMessages.json
+++ b/src/compiler/diagnosticMessages.json
@@ -1923,7 +1923,7 @@
"category": "Error",
"code": 2685
},
- "Identifier '{0}' must be imported from a module": {
+ "'{0}' refers to a UMD global, but the current file is a module. Consider adding an import instead.": {
"category": "Error",
"code": 2686
},
@@ -2957,6 +2957,10 @@
"category": "Error",
"code": 7033
},
+ "Variable '{0}' implicitly has type 'any' in some locations where its type cannot be determined.": {
+ "category": "Error",
+ "code": 7034
+ },
"You cannot rename this element.": {
"category": "Error",
"code": 8000
@@ -3069,7 +3073,6 @@
"category": "Error",
"code": 17010
},
-
"Circularity detected while resolving configuration: {0}": {
"category": "Error",
"code": 18000
@@ -3077,5 +3080,33 @@
"The path in an 'extends' options must be relative or rooted.": {
"category": "Error",
"code": 18001
+ },
+ "Add missing 'super()' call.": {
+ "category": "Message",
+ "code": 90001
+ },
+ "Make 'super()' call the first statement in the constructor.": {
+ "category": "Message",
+ "code": 90002
+ },
+ "Change 'extends' to 'implements'": {
+ "category": "Message",
+ "code": 90003
+ },
+ "Remove unused identifiers": {
+ "category": "Message",
+ "code": 90004
+ },
+ "Implement interface on reference": {
+ "category": "Message",
+ "code": 90005
+ },
+ "Implement interface on class": {
+ "category": "Message",
+ "code": 90006
+ },
+ "Implement inherited abstract class": {
+ "category": "Message",
+ "code": 90007
}
}
diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts
index 734fe2778e5..8ece815178f 100644
--- a/src/compiler/emitter.ts
+++ b/src/compiler/emitter.ts
@@ -68,7 +68,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments)).next());
});
@@ -655,7 +655,7 @@ const _super = (function (geti, seti) {
case SyntaxKind.ModuleDeclaration:
return emitModuleDeclaration(node);
case SyntaxKind.ModuleBlock:
- return emitModuleBlock(node);
+ return emitModuleBlock(node);
case SyntaxKind.CaseBlock:
return emitCaseBlock(node);
case SyntaxKind.ImportEqualsDeclaration:
@@ -1394,7 +1394,7 @@ const _super = (function (geti, seti) {
}
}
- function emitBlockStatements(node: Block) {
+ function emitBlockStatements(node: BlockLike) {
if (getEmitFlags(node) & EmitFlags.SingleLine) {
emitList(node, node.statements, ListFormat.SingleLineBlockStatements);
}
@@ -1795,7 +1795,7 @@ const _super = (function (geti, seti) {
}
function emitModuleBlock(node: ModuleBlock) {
- if (isSingleLineEmptyBlock(node)) {
+ if (isEmptyBlock(node)) {
write("{ }");
}
else {
@@ -2618,7 +2618,11 @@ const _super = (function (geti, seti) {
function isSingleLineEmptyBlock(block: Block) {
return !block.multiLine
- && block.statements.length === 0
+ && isEmptyBlock(block);
+ }
+
+ function isEmptyBlock(block: BlockLike) {
+ return block.statements.length === 0
&& rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile);
}
diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts
index 57007619c62..9fc7924da8e 100644
--- a/src/compiler/factory.ts
+++ b/src/compiler/factory.ts
@@ -105,6 +105,7 @@ namespace ts {
export function createLiteral(textSource: StringLiteral | Identifier, location?: TextRange): StringLiteral;
export function createLiteral(value: string, location?: TextRange): StringLiteral;
export function createLiteral(value: number, location?: TextRange): NumericLiteral;
+ export function createLiteral(value: boolean, location?: TextRange): BooleanLiteral;
export function createLiteral(value: string | number | boolean, location?: TextRange): PrimaryExpression;
export function createLiteral(value: string | number | boolean | StringLiteral | Identifier, location?: TextRange): PrimaryExpression {
if (typeof value === "number") {
@@ -120,7 +121,7 @@ namespace ts {
node.text = value;
return node;
}
- else {
+ else if (value) {
const node = createNode(SyntaxKind.StringLiteral, location, /*flags*/ undefined);
node.textSourceNode = value;
node.text = value.text;
@@ -187,8 +188,8 @@ namespace ts {
// Punctuation
- export function createToken(token: SyntaxKind) {
- return createNode(token);
+ export function createToken(token: TKind) {
+ return >createNode(token);
}
// Reserved words
@@ -238,7 +239,7 @@ namespace ts {
);
}
- export function createParameterDeclaration(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: Node, name: string | Identifier | BindingPattern, questionToken: Node, type: TypeNode, initializer: Expression, location?: TextRange, flags?: NodeFlags) {
+ export function createParameterDeclaration(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: string | Identifier | BindingPattern, questionToken: QuestionToken, type: TypeNode, initializer: Expression, location?: TextRange, flags?: NodeFlags) {
const node = createNode(SyntaxKind.Parameter, location, flags);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
@@ -260,7 +261,7 @@ namespace ts {
// Type members
- export function createProperty(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, questionToken: Node, type: TypeNode, initializer: Expression, location?: TextRange) {
+ export function createProperty(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, questionToken: QuestionToken, type: TypeNode, initializer: Expression, location?: TextRange) {
const node = createNode(SyntaxKind.PropertyDeclaration, location);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
@@ -278,7 +279,7 @@ namespace ts {
return node;
}
- export function createMethod(decorators: Decorator[], modifiers: Modifier[], asteriskToken: Node, name: string | PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
+ export function createMethod(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
const node = createNode(SyntaxKind.MethodDeclaration, location, flags);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
@@ -381,7 +382,7 @@ namespace ts {
return node;
}
- export function createBindingElement(propertyName: string | PropertyName, dotDotDotToken: Node, name: string | BindingName, initializer?: Expression, location?: TextRange) {
+ export function createBindingElement(propertyName: string | PropertyName, dotDotDotToken: DotDotDotToken, name: string | BindingName, initializer?: Expression, location?: TextRange) {
const node = createNode(SyntaxKind.BindingElement, location);
node.propertyName = typeof propertyName === "string" ? createIdentifier(propertyName) : propertyName;
node.dotDotDotToken = dotDotDotToken;
@@ -497,14 +498,14 @@ namespace ts {
return node;
}
- export function createTaggedTemplate(tag: Expression, template: Template, location?: TextRange) {
+ export function createTaggedTemplate(tag: Expression, template: TemplateLiteral, location?: TextRange) {
const node = createNode(SyntaxKind.TaggedTemplateExpression, location);
node.tag = parenthesizeForAccess(tag);
node.template = template;
return node;
}
- export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: Template) {
+ export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral) {
if (node.tag !== tag || node.template !== template) {
return updateNode(createTaggedTemplate(tag, template, node), node);
}
@@ -524,7 +525,7 @@ namespace ts {
return node;
}
- export function createFunctionExpression(modifiers: Modifier[], asteriskToken: Node, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
+ export function createFunctionExpression(modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
const node = createNode(SyntaxKind.FunctionExpression, location, flags);
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.asteriskToken = asteriskToken;
@@ -543,13 +544,13 @@ namespace ts {
return node;
}
- export function createArrowFunction(modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, equalsGreaterThanToken: Node, body: ConciseBody, location?: TextRange, flags?: NodeFlags) {
+ export function createArrowFunction(modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, equalsGreaterThanToken: EqualsGreaterThanToken, body: ConciseBody, location?: TextRange, flags?: NodeFlags) {
const node = createNode(SyntaxKind.ArrowFunction, location, flags);
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined;
node.parameters = createNodeArray(parameters);
node.type = type;
- node.equalsGreaterThanToken = equalsGreaterThanToken || createNode(SyntaxKind.EqualsGreaterThanToken);
+ node.equalsGreaterThanToken = equalsGreaterThanToken || createToken(SyntaxKind.EqualsGreaterThanToken);
node.body = parenthesizeConciseBody(body);
return node;
}
@@ -613,7 +614,7 @@ namespace ts {
return node;
}
- export function createPrefix(operator: SyntaxKind, operand: Expression, location?: TextRange) {
+ export function createPrefix(operator: PrefixUnaryOperator, operand: Expression, location?: TextRange) {
const node = createNode(SyntaxKind.PrefixUnaryExpression, location);
node.operator = operator;
node.operand = parenthesizePrefixOperand(operand);
@@ -627,7 +628,7 @@ namespace ts {
return node;
}
- export function createPostfix(operand: Expression, operator: SyntaxKind, location?: TextRange) {
+ export function createPostfix(operand: Expression, operator: PostfixUnaryOperator, location?: TextRange) {
const node = createNode(SyntaxKind.PostfixUnaryExpression, location);
node.operand = parenthesizePostfixOperand(operand);
node.operator = operator;
@@ -641,8 +642,8 @@ namespace ts {
return node;
}
- export function createBinary(left: Expression, operator: SyntaxKind | Node, right: Expression, location?: TextRange) {
- const operatorToken = typeof operator === "number" ? createSynthesizedNode(operator) : operator;
+ export function createBinary(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression, location?: TextRange) {
+ const operatorToken = typeof operator === "number" ? createToken(operator) : operator;
const operatorKind = operatorToken.kind;
const node = createNode(SyntaxKind.BinaryExpression, location);
node.left = parenthesizeBinaryOperand(operatorKind, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined);
@@ -658,7 +659,7 @@ namespace ts {
return node;
}
- export function createConditional(condition: Expression, questionToken: Node, whenTrue: Expression, colonToken: Node, whenFalse: Expression, location?: TextRange) {
+ export function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression, location?: TextRange) {
const node = createNode(SyntaxKind.ConditionalExpression, location);
node.condition = condition;
node.questionToken = questionToken;
@@ -675,21 +676,21 @@ namespace ts {
return node;
}
- export function createTemplateExpression(head: TemplateLiteralFragment, templateSpans: TemplateSpan[], location?: TextRange) {
+ export function createTemplateExpression(head: TemplateHead, templateSpans: TemplateSpan[], location?: TextRange) {
const node = createNode(SyntaxKind.TemplateExpression, location);
node.head = head;
node.templateSpans = createNodeArray(templateSpans);
return node;
}
- export function updateTemplateExpression(node: TemplateExpression, head: TemplateLiteralFragment, templateSpans: TemplateSpan[]) {
+ export function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: TemplateSpan[]) {
if (node.head !== head || node.templateSpans !== templateSpans) {
return updateNode(createTemplateExpression(head, templateSpans, node), node);
}
return node;
}
- export function createYield(asteriskToken: Node, expression: Expression, location?: TextRange) {
+ export function createYield(asteriskToken: AsteriskToken, expression: Expression, location?: TextRange) {
const node = createNode(SyntaxKind.YieldExpression, location);
node.asteriskToken = asteriskToken;
node.expression = expression;
@@ -756,14 +757,14 @@ namespace ts {
// Misc
- export function createTemplateSpan(expression: Expression, literal: TemplateLiteralFragment, location?: TextRange) {
+ export function createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail, location?: TextRange) {
const node = createNode(SyntaxKind.TemplateSpan, location);
node.expression = expression;
node.literal = literal;
return node;
}
- export function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateLiteralFragment) {
+ export function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail) {
if (node.expression !== expression || node.literal !== literal) {
return updateNode(createTemplateSpan(expression, literal, node), node);
}
@@ -932,14 +933,14 @@ namespace ts {
return node;
}
- export function updateForOf(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement) {
+ export function updateForOf(node: ForOfStatement, initializer: ForInitializer, expression: Expression, statement: Statement) {
if (node.initializer !== initializer || node.expression !== expression || node.statement !== statement) {
return updateNode(createForOf(initializer, expression, statement, node), node);
}
return node;
}
- export function createContinue(label?: Identifier, location?: TextRange): BreakStatement {
+ export function createContinue(label?: Identifier, location?: TextRange): ContinueStatement {
const node = createNode(SyntaxKind.ContinueStatement, location);
if (label) {
node.label = label;
@@ -1065,7 +1066,7 @@ namespace ts {
return node;
}
- export function createFunctionDeclaration(decorators: Decorator[], modifiers: Modifier[], asteriskToken: Node, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
+ export function createFunctionDeclaration(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) {
const node = createNode(SyntaxKind.FunctionDeclaration, location, flags);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
@@ -1560,7 +1561,7 @@ namespace ts {
return createParameterDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
- createSynthesizedNode(SyntaxKind.DotDotDotToken),
+ createToken(SyntaxKind.DotDotDotToken),
name,
/*questionToken*/ undefined,
/*type*/ undefined,
@@ -1736,7 +1737,7 @@ namespace ts {
export function createAwaiterHelper(externalHelpersModuleName: Identifier | undefined, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) {
const generatorFunc = createFunctionExpression(
/*modifiers*/ undefined,
- createNode(SyntaxKind.AsteriskToken),
+ createToken(SyntaxKind.AsteriskToken),
/*name*/ undefined,
/*typeParameters*/ undefined,
/*parameters*/ [],
diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts
index ca702173e79..4ebdc59e6dd 100644
--- a/src/compiler/moduleNameResolver.ts
+++ b/src/compiler/moduleNameResolver.ts
@@ -95,7 +95,7 @@ namespace ts {
currentDirectory = host.getCurrentDirectory();
}
- return currentDirectory && getDefaultTypeRoots(currentDirectory, host);
+ return currentDirectory !== undefined && getDefaultTypeRoots(currentDirectory, host);
}
/**
@@ -675,23 +675,33 @@ namespace ts {
/* @internal */
export function loadModuleFromNodeModules(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean): string {
+ return loadModuleFromNodeModulesWorker(moduleName, directory, failedLookupLocations, state, checkOneLevel, /*typesOnly*/ false);
+ }
+
+ function loadModuleFromNodeModulesAtTypes(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): string {
+ return loadModuleFromNodeModulesWorker(moduleName, directory, failedLookupLocations, state, /*checkOneLevel*/ false, /*typesOnly*/ true);
+ }
+
+ function loadModuleFromNodeModulesWorker(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean, typesOnly: boolean): string {
directory = normalizeSlashes(directory);
while (true) {
const baseName = getBaseFileName(directory);
if (baseName !== "node_modules") {
- // Try to load source from the package
- const packageResult = loadModuleFromNodeModulesFolder(moduleName, directory, failedLookupLocations, state);
- if (packageResult && hasTypeScriptFileExtension(packageResult)) {
- // Always prefer a TypeScript (.ts, .tsx, .d.ts) file shipped with the package
- return packageResult;
- }
- else {
- // Else prefer a types package over non-TypeScript results (e.g. JavaScript files)
- const typesResult = loadModuleFromNodeModulesFolder(combinePaths("@types", moduleName), directory, failedLookupLocations, state);
- if (typesResult || packageResult) {
- return typesResult || packageResult;
+ let packageResult: string | undefined;
+ if (!typesOnly) {
+ // Try to load source from the package
+ packageResult = loadModuleFromNodeModulesFolder(moduleName, directory, failedLookupLocations, state);
+ if (packageResult && hasTypeScriptFileExtension(packageResult)) {
+ // Always prefer a TypeScript (.ts, .tsx, .d.ts) file shipped with the package
+ return packageResult;
}
}
+
+ // Else prefer a types package over non-TypeScript results (e.g. JavaScript files)
+ const typesResult = loadModuleFromNodeModulesFolder(combinePaths("@types", moduleName), directory, failedLookupLocations, state);
+ if (typesResult || packageResult) {
+ return typesResult || packageResult;
+ }
}
const parentPath = getDirectoryPath(directory);
@@ -709,7 +719,7 @@ namespace ts {
const state = { compilerOptions, host, traceEnabled, skipTsx: !compilerOptions.jsx };
const failedLookupLocations: string[] = [];
const supportedExtensions = getSupportedExtensions(compilerOptions);
- let containingDirectory = getDirectoryPath(containingFile);
+ const containingDirectory = getDirectoryPath(containingFile);
const resolvedFileName = tryLoadModuleUsingOptionalResolutionSettings(moduleName, containingDirectory, loadModuleFromFile, failedLookupLocations, supportedExtensions, state);
if (resolvedFileName) {
@@ -718,18 +728,9 @@ namespace ts {
let referencedSourceFile: string;
if (moduleHasNonRelativeName(moduleName)) {
- while (true) {
- const searchName = normalizePath(combinePaths(containingDirectory, moduleName));
- referencedSourceFile = loadModuleFromFile(searchName, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
- if (referencedSourceFile) {
- break;
- }
- const parentPath = getDirectoryPath(containingDirectory);
- if (parentPath === containingDirectory) {
- break;
- }
- containingDirectory = parentPath;
- }
+ referencedSourceFile = referencedSourceFile = loadModuleFromAncestorDirectories(moduleName, containingDirectory, supportedExtensions, failedLookupLocations, state) ||
+ // If we didn't find the file normally, look it up in @types.
+ loadModuleFromNodeModulesAtTypes(moduleName, containingDirectory, failedLookupLocations, state);
}
else {
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
@@ -741,4 +742,20 @@ namespace ts {
? { resolvedModule: { resolvedFileName: referencedSourceFile }, failedLookupLocations }
: { resolvedModule: undefined, failedLookupLocations };
}
+
+ /** Climb up parent directories looking for a module. */
+ function loadModuleFromAncestorDirectories(moduleName: string, containingDirectory: string, supportedExtensions: string[], failedLookupLocations: string[], state: ModuleResolutionState): string | undefined {
+ while (true) {
+ const searchName = normalizePath(combinePaths(containingDirectory, moduleName));
+ const referencedSourceFile = loadModuleFromFile(searchName, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
+ if (referencedSourceFile) {
+ return referencedSourceFile;
+ }
+ const parentPath = getDirectoryPath(containingDirectory);
+ if (parentPath === containingDirectory) {
+ return undefined;
+ }
+ containingDirectory = parentPath;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts
index 9bd9311b749..62ae61e4cb4 100644
--- a/src/compiler/parser.ts
+++ b/src/compiler/parser.ts
@@ -637,7 +637,7 @@ namespace ts {
sourceFile.statements = parseList(ParsingContext.SourceElements, parseStatement);
Debug.assert(token() === SyntaxKind.EndOfFileToken);
- sourceFile.endOfFileToken = parseTokenNode();
+ sourceFile.endOfFileToken = parseTokenNode();
setExternalModuleIndicator(sourceFile);
@@ -1004,6 +1004,7 @@ namespace ts {
return false;
}
+ function parseOptionalToken(t: TKind): Token;
function parseOptionalToken(t: SyntaxKind): Node {
if (token() === t) {
return parseTokenNode();
@@ -1011,6 +1012,7 @@ namespace ts {
return undefined;
}
+ function parseExpectedToken(t: TKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Token;
function parseExpectedToken(t: SyntaxKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Node {
return parseOptionalToken(t) ||
createMissingNode(t, reportAtCurrentPosition, diagnosticMessage, arg0);
@@ -1047,7 +1049,7 @@ namespace ts {
}
// note: this function creates only node
- function createNode(kind: SyntaxKind, pos?: number): Node | Token | Identifier {
+ function createNode(kind: TKind, pos?: number): Node | Token | Identifier {
nodeCount++;
if (!(pos >= 0)) {
pos = scanner.getStartPos();
@@ -1394,8 +1396,8 @@ namespace ts {
// Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery
return token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.CloseBracketToken /*|| token === SyntaxKind.OpenBraceToken*/;
case ParsingContext.TypeArguments:
- // Tokens other than '>' are here for better error recovery
- return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.OpenParenToken;
+ // All other tokens should cause the type-argument to terminate except comma token
+ return token() !== SyntaxKind.CommaToken;
case ParsingContext.HeritageClauses:
return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.CloseBraceToken;
case ParsingContext.JsxAttributes:
@@ -1920,7 +1922,7 @@ namespace ts {
function parseTemplateExpression(): TemplateExpression {
const template = createNode(SyntaxKind.TemplateExpression);
- template.head = parseTemplateLiteralFragment();
+ template.head = parseTemplateHead();
Debug.assert(template.head.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind");
const templateSpans = createNodeArray();
@@ -1940,14 +1942,13 @@ namespace ts {
const span = createNode(SyntaxKind.TemplateSpan);
span.expression = allowInAnd(parseExpression);
- let literal: TemplateLiteralFragment;
-
+ let literal: TemplateMiddle | TemplateTail;
if (token() === SyntaxKind.CloseBraceToken) {
reScanTemplateToken();
- literal = parseTemplateLiteralFragment();
+ literal = parseTemplateMiddleOrTemplateTail();
}
else {
- literal = parseExpectedToken(SyntaxKind.TemplateTail, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken));
+ literal = parseExpectedToken(SyntaxKind.TemplateTail, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken));
}
span.literal = literal;
@@ -1958,8 +1959,16 @@ namespace ts {
return parseLiteralLikeNode(token(), internName);
}
- function parseTemplateLiteralFragment(): TemplateLiteralFragment {
- return parseLiteralLikeNode(token(), /*internName*/ false);
+ function parseTemplateHead(): TemplateHead {
+ const fragment = parseLiteralLikeNode(token(), /*internName*/ false);
+ Debug.assert(fragment.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind");
+ return fragment;
+ }
+
+ function parseTemplateMiddleOrTemplateTail(): TemplateMiddle | TemplateTail {
+ const fragment = parseLiteralLikeNode(token(), /*internName*/ false);
+ Debug.assert(fragment.kind === SyntaxKind.TemplateMiddle || fragment.kind === SyntaxKind.TemplateTail, "Template fragment has wrong token kind");
+ return fragment;
}
function parseLiteralLikeNode(kind: SyntaxKind, internName: boolean): LiteralLikeNode {
@@ -2719,7 +2728,7 @@ namespace ts {
}
let expr = parseAssignmentExpressionOrHigher();
- let operatorToken: Node;
+ let operatorToken: BinaryOperatorToken;
while ((operatorToken = parseOptionalToken(SyntaxKind.CommaToken))) {
expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher());
}
@@ -2812,7 +2821,7 @@ namespace ts {
// Note: we call reScanGreaterToken so that we get an appropriately merged token
// for cases like > > = becoming >>=
if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) {
- return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher());
+ return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher());
}
// It wasn't an assignment or a lambda. This is a conditional expression:
@@ -3247,7 +3256,7 @@ namespace ts {
}
}
else {
- leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
+ leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
}
}
@@ -3307,7 +3316,7 @@ namespace ts {
return -1;
}
- function makeBinaryExpression(left: Expression, operatorToken: Node, right: Expression): BinaryExpression {
+ function makeBinaryExpression(left: Expression, operatorToken: BinaryOperatorToken, right: Expression): BinaryExpression {
const node = createNode(SyntaxKind.BinaryExpression, left.pos);
node.left = left;
node.operatorToken = operatorToken;
@@ -3324,7 +3333,7 @@ namespace ts {
function parsePrefixUnaryExpression() {
const node = createNode(SyntaxKind.PrefixUnaryExpression);
- node.operator = token();
+ node.operator = token();
nextToken();
node.operand = parseSimpleUnaryExpression();
@@ -3511,7 +3520,7 @@ namespace ts {
function parseIncrementExpression(): IncrementExpression {
if (token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) {
const node = createNode(SyntaxKind.PrefixUnaryExpression);
- node.operator = token();
+ node.operator = token();
nextToken();
node.operand = parseLeftHandSideExpressionOrHigher();
return finishNode(node);
@@ -3527,7 +3536,7 @@ namespace ts {
if ((token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) && !scanner.hasPrecedingLineBreak()) {
const node = createNode(SyntaxKind.PostfixUnaryExpression, expression.pos);
node.operand = expression;
- node.operator = token();
+ node.operator = token();
nextToken();
return finishNode(node);
}
@@ -3700,7 +3709,7 @@ namespace ts {
badNode.end = invalidElement.end;
badNode.left = result;
badNode.right = invalidElement;
- badNode.operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
+ badNode.operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
return badNode;
}
@@ -3836,7 +3845,7 @@ namespace ts {
if (token() === SyntaxKind.EqualsToken) {
switch (scanJsxAttributeValue()) {
case SyntaxKind.StringLiteral:
- node.initializer = parseLiteralNode();
+ node.initializer = parseLiteralNode();
break;
default:
node.initializer = parseJsxExpression(/*inExpressionContext*/ true);
@@ -3921,7 +3930,7 @@ namespace ts {
const tagExpression = createNode(SyntaxKind.TaggedTemplateExpression, expression.pos);
tagExpression.tag = expression;
tagExpression.template = token() === SyntaxKind.NoSubstitutionTemplateLiteral
- ? parseLiteralNode()
+ ? parseLiteralNode()
: parseTemplateExpression();
expression = finishNode(tagExpression);
continue;
@@ -4959,7 +4968,7 @@ namespace ts {
return addJSDocComment(finishNode(node));
}
- function parseMethodDeclaration(fullStart: number, decorators: NodeArray, modifiers: NodeArray, asteriskToken: Node, name: PropertyName, questionToken: Node, diagnosticMessage?: DiagnosticMessage): MethodDeclaration {
+ function parseMethodDeclaration(fullStart: number, decorators: NodeArray, modifiers: NodeArray, asteriskToken: AsteriskToken, name: PropertyName, questionToken: QuestionToken, diagnosticMessage?: DiagnosticMessage): MethodDeclaration {
const method = createNode(SyntaxKind.MethodDeclaration, fullStart);
method.decorators = decorators;
method.modifiers = modifiers;
@@ -4973,7 +4982,7 @@ namespace ts {
return addJSDocComment(finishNode(method));
}
- function parsePropertyDeclaration(fullStart: number, decorators: NodeArray, modifiers: NodeArray, name: PropertyName, questionToken: Node): ClassElement {
+ function parsePropertyDeclaration(fullStart: number, decorators: NodeArray, modifiers: NodeArray, name: PropertyName, questionToken: QuestionToken): ClassElement {
const property = createNode(SyntaxKind.PropertyDeclaration, fullStart);
property.decorators = decorators;
property.modifiers = modifiers;
@@ -5343,7 +5352,7 @@ namespace ts {
parseExpected(SyntaxKind.EqualsToken);
node.type = parseType();
parseSemicolon();
- return finishNode(node);
+ return addJSDocComment(finishNode(node));
}
// In an ambient declaration, the grammar only allows integer literals as initializers.
@@ -5395,7 +5404,7 @@ namespace ts {
node.flags |= flags;
node.name = parseIdentifier();
node.body = parseOptional(SyntaxKind.DotToken)
- ? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.NestedNamespace | namespaceFlag)
+ ? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.NestedNamespace | namespaceFlag)
: parseModuleBlock();
return addJSDocComment(finishNode(node));
}
@@ -5574,8 +5583,10 @@ namespace ts {
return finishNode(namespaceImport);
}
+ function parseNamedImportsOrExports(kind: SyntaxKind.NamedImports): NamedImports;
+ function parseNamedImportsOrExports(kind: SyntaxKind.NamedExports): NamedExports;
function parseNamedImportsOrExports(kind: SyntaxKind): NamedImportsOrExports {
- const node = createNode(kind);
+ const node = createNode(kind);
// NamedImports:
// { }
@@ -5585,7 +5596,7 @@ namespace ts {
// ImportsList:
// ImportSpecifier
// ImportsList, ImportSpecifier
- node.elements = parseBracketedList(ParsingContext.ImportOrExportSpecifiers,
+ node.elements = | NodeArray>parseBracketedList(ParsingContext.ImportOrExportSpecifiers,
kind === SyntaxKind.NamedImports ? parseImportSpecifier : parseExportSpecifier,
SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken);
return finishNode(node);
@@ -5969,14 +5980,15 @@ namespace ts {
const parameter = createNode(SyntaxKind.Parameter);
parameter.type = parseJSDocType();
if (parseOptional(SyntaxKind.EqualsToken)) {
- parameter.questionToken = createNode(SyntaxKind.EqualsToken);
+ // TODO(rbuckton): Can this be changed to SyntaxKind.QuestionToken?
+ parameter.questionToken = createNode(SyntaxKind.EqualsToken);
}
return finishNode(parameter);
}
function parseJSDocTypeReference(): JSDocTypeReference {
const result = createNode(SyntaxKind.JSDocTypeReference);
- result.name = parseSimplePropertyName();
+ result.name = parseSimplePropertyName();
if (token() === SyntaxKind.LessThanToken) {
result.typeArguments = parseTypeArguments();
@@ -6304,7 +6316,7 @@ namespace ts {
function parseTag(indent: number) {
Debug.assert(token() === SyntaxKind.AtToken);
- const atToken = createNode(SyntaxKind.AtToken, scanner.getTokenPos());
+ const atToken = createNode(SyntaxKind.AtToken, scanner.getTokenPos());
atToken.end = scanner.getTextPos();
nextJSDocToken();
@@ -6410,7 +6422,7 @@ namespace ts {
return comments;
}
- function parseUnknownTag(atToken: Node, tagName: Identifier) {
+ function parseUnknownTag(atToken: AtToken, tagName: Identifier) {
const result = createNode(SyntaxKind.JSDocTag, atToken.pos);
result.atToken = atToken;
result.tagName = tagName;
@@ -6440,7 +6452,7 @@ namespace ts {
});
}
- function parseParamTag(atToken: Node, tagName: Identifier) {
+ function parseParamTag(atToken: AtToken, tagName: Identifier) {
let typeExpression = tryParseTypeExpression();
skipWhitespace();
@@ -6491,7 +6503,7 @@ namespace ts {
return finishNode(result);
}
- function parseReturnTag(atToken: Node, tagName: Identifier): JSDocReturnTag {
+ function parseReturnTag(atToken: AtToken, tagName: Identifier): JSDocReturnTag {
if (forEach(tags, t => t.kind === SyntaxKind.JSDocReturnTag)) {
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
}
@@ -6503,7 +6515,7 @@ namespace ts {
return finishNode(result);
}
- function parseTypeTag(atToken: Node, tagName: Identifier): JSDocTypeTag {
+ function parseTypeTag(atToken: AtToken, tagName: Identifier): JSDocTypeTag {
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTypeTag)) {
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
}
@@ -6515,7 +6527,7 @@ namespace ts {
return finishNode(result);
}
- function parsePropertyTag(atToken: Node, tagName: Identifier): JSDocPropertyTag {
+ function parsePropertyTag(atToken: AtToken, tagName: Identifier): JSDocPropertyTag {
const typeExpression = tryParseTypeExpression();
skipWhitespace();
const name = parseJSDocIdentifierName();
@@ -6533,7 +6545,7 @@ namespace ts {
return finishNode(result);
}
- function parseTypedefTag(atToken: Node, tagName: Identifier): JSDocTypedefTag {
+ function parseTypedefTag(atToken: AtToken, tagName: Identifier): JSDocTypedefTag {
const typeExpression = tryParseTypeExpression();
skipWhitespace();
@@ -6555,7 +6567,7 @@ namespace ts {
}
}
if (!typedefTag.jsDocTypeLiteral) {
- typedefTag.jsDocTypeLiteral = typeExpression.type;
+ typedefTag.jsDocTypeLiteral = typeExpression.type;
}
}
else {
@@ -6607,7 +6619,7 @@ namespace ts {
function tryParseChildTag(parentTag: JSDocTypeLiteral): boolean {
Debug.assert(token() === SyntaxKind.AtToken);
- const atToken = createNode(SyntaxKind.AtToken, scanner.getStartPos());
+ const atToken = createNode(SyntaxKind.AtToken, scanner.getStartPos());
atToken.end = scanner.getTextPos();
nextJSDocToken();
@@ -6637,7 +6649,7 @@ namespace ts {
return false;
}
- function parseTemplateTag(atToken: Node, tagName: Identifier): JSDocTemplateTag {
+ function parseTemplateTag(atToken: AtToken, tagName: Identifier): JSDocTemplateTag {
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTemplateTag)) {
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text);
}
diff --git a/src/compiler/program.ts b/src/compiler/program.ts
index dfe65fc0860..35cbeb28305 100644
--- a/src/compiler/program.ts
+++ b/src/compiler/program.ts
@@ -358,7 +358,7 @@ namespace ts {
// load type declarations specified via 'types' argument or implicitly from types/ and node_modules/@types folders
const typeReferences: string[] = getAutomaticTypeDirectiveNames(options, host);
- if (typeReferences) {
+ if (typeReferences.length) {
// This containingFilename needs to match with the one used in managed-side
const containingFilename = combinePaths(host.getCurrentDirectory(), "__inferred type names__.ts");
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);
@@ -473,6 +473,7 @@ namespace ts {
(oldOptions.configFilePath !== options.configFilePath) ||
(oldOptions.baseUrl !== options.baseUrl) ||
(oldOptions.maxNodeModuleJsDepth !== options.maxNodeModuleJsDepth) ||
+ !arrayIsEqualTo(oldOptions.lib, options.lib) ||
!arrayIsEqualTo(oldOptions.typeRoots, oldOptions.typeRoots) ||
!arrayIsEqualTo(oldOptions.rootDirs, options.rootDirs) ||
!equalOwnProperties(oldOptions.paths, options.paths)) {
@@ -1310,7 +1311,6 @@ namespace ts {
for (let i = 0; i < moduleNames.length; i++) {
const resolution = resolutions[i];
setResolvedModule(file, moduleNames[i], resolution);
- const resolvedPath = resolution ? toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName) : undefined;
// add file to program only if:
// - resolution was successful
@@ -1332,7 +1332,7 @@ namespace ts {
}
else if (shouldAddFile) {
findSourceFile(resolution.resolvedFileName,
- resolvedPath,
+ toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName),
/*isDefaultLib*/ false, /*isReference*/ false,
file,
skipTrivia(file.text, file.imports[i].pos),
diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts
index 3bfa778cf9b..c7219866df7 100644
--- a/src/compiler/transformers/destructuring.ts
+++ b/src/compiler/transformers/destructuring.ts
@@ -220,7 +220,7 @@ namespace ts {
function flattenDestructuring(
context: TransformationContext,
- root: BindingElement | BinaryExpression,
+ root: VariableDeclaration | ParameterDeclaration | BindingElement | BinaryExpression,
value: Expression,
location: TextRange,
emitAssignment: (name: Identifier, value: Expression, location: TextRange, original: Node) => void,
@@ -320,7 +320,7 @@ namespace ts {
}
}
- function emitBindingElement(target: BindingElement, value: Expression) {
+ function emitBindingElement(target: VariableDeclaration | ParameterDeclaration | BindingElement, value: Expression) {
// Any temporary assignments needed to emit target = value should point to target
const initializer = visitor ? visitNode(target.initializer, visitor, isExpression) : target.initializer;
if (initializer) {
diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts
index 101c34a8199..75d28a6727b 100644
--- a/src/compiler/transformers/es2015.ts
+++ b/src/compiler/transformers/es2015.ts
@@ -983,7 +983,7 @@ namespace ts {
if (statementOffset < ctorStatements.length) {
firstStatement = ctorStatements[statementOffset];
- if (firstStatement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((firstStatement as ExpressionStatement).expression)) {
+ if (firstStatement.kind === SyntaxKind.ExpressionStatement && isSuperCall((firstStatement as ExpressionStatement).expression)) {
const superCall = (firstStatement as ExpressionStatement).expression as CallExpression;
superCallExpression = setOriginalNode(
saveStateAndInvoke(superCall, visitImmediateSuperCallInBody),
@@ -3201,7 +3201,7 @@ namespace ts {
* @param node The declaration.
* @param allowComments Allow comments for the name.
*/
- function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
+ function getDeclarationName(node: ClassDeclaration | ClassExpression | FunctionDeclaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
if (node.name && !isGeneratedIdentifier(node.name)) {
const name = getMutableClone(node.name);
emitFlags |= getEmitFlags(node.name);
diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts
index 88788022ef8..aaf9014c5cc 100644
--- a/src/compiler/transformers/generators.ts
+++ b/src/compiler/transformers/generators.ts
@@ -529,7 +529,7 @@ namespace ts {
*
* @param node The node to visit.
*/
- function visitAccessorDeclaration(node: GetAccessorDeclaration) {
+ function visitAccessorDeclaration(node: AccessorDeclaration) {
const savedInGeneratorFunctionBody = inGeneratorFunctionBody;
const savedInStatementContainingYield = inStatementContainingYield;
inGeneratorFunctionBody = false;
@@ -661,12 +661,12 @@ namespace ts {
}
}
- function isCompoundAssignment(kind: SyntaxKind) {
+ function isCompoundAssignment(kind: BinaryOperator): kind is CompoundAssignmentOperator {
return kind >= SyntaxKind.FirstCompoundAssignment
&& kind <= SyntaxKind.LastCompoundAssignment;
}
- function getOperatorForCompoundAssignment(kind: SyntaxKind) {
+ function getOperatorForCompoundAssignment(kind: CompoundAssignmentOperator): BitwiseOperatorOrHigher {
switch (kind) {
case SyntaxKind.PlusEqualsToken: return SyntaxKind.PlusToken;
case SyntaxKind.MinusEqualsToken: return SyntaxKind.MinusToken;
diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts
index 989efbfd53f..1bcdefc7d3c 100644
--- a/src/compiler/transformers/module/module.ts
+++ b/src/compiler/transformers/module/module.ts
@@ -600,7 +600,7 @@ namespace ts {
}
else {
statements.push(
- createExportStatement(node.name, setEmitFlags(getSynthesizedClone(node.name), EmitFlags.LocalName), /*location*/ node)
+ createExportStatement(node.name, setEmitFlags(getSynthesizedClone(node.name), EmitFlags.LocalName), /*location*/ node)
);
}
}
@@ -799,7 +799,7 @@ namespace ts {
addVarForExportedEnumOrNamespaceDeclaration(statements, original);
}
- addExportMemberAssignments(statements, original.name);
+ addExportMemberAssignments(statements, original.name);
return statements;
}
@@ -822,7 +822,7 @@ namespace ts {
}
function getDeclarationName(node: DeclarationStatement) {
- return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node);
+ return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node);
}
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
@@ -919,7 +919,7 @@ namespace ts {
if (node.kind === SyntaxKind.PostfixUnaryExpression) {
transformedUnaryExpression = createBinary(
operand,
- createNode(operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken),
+ createToken(operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken),
createLiteral(1),
/*location*/ node
);
diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts
index e7b441f4c9b..30f0cdfbe71 100644
--- a/src/compiler/transformers/module/system.ts
+++ b/src/compiler/transformers/module/system.ts
@@ -1206,7 +1206,7 @@ namespace ts {
* @param node The declaration statement.
*/
function getDeclarationName(node: DeclarationStatement) {
- return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node);
+ return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node);
}
function addExportStarFunction(statements: Statement[], localNames: Identifier) {
diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts
index 868c371e00f..fc64ab705c6 100644
--- a/src/compiler/transformers/ts.ts
+++ b/src/compiler/transformers/ts.ts
@@ -972,7 +972,7 @@ namespace ts {
}
const statement = statements[index];
- if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((statement).expression)) {
+ if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCall((statement).expression)) {
result.push(visitNode(statement, visitor, isStatement));
return index + 1;
}
@@ -1784,10 +1784,41 @@ namespace ts {
case SyntaxKind.TypeReference:
return serializeTypeReferenceNode(node);
+ case SyntaxKind.IntersectionType:
+ case SyntaxKind.UnionType:
+ {
+ const unionOrIntersection = node;
+ let serializedUnion: Identifier;
+ for (const typeNode of unionOrIntersection.types) {
+ const serializedIndividual = serializeTypeNode(typeNode) as Identifier;
+ // Non identifier
+ if (serializedIndividual.kind !== SyntaxKind.Identifier) {
+ serializedUnion = undefined;
+ break;
+ }
+
+ // One of the individual is global object, return immediately
+ if (serializedIndividual.text === "Object") {
+ return serializedIndividual;
+ }
+
+ // Different types
+ if (serializedUnion && serializedUnion.text !== serializedIndividual.text) {
+ serializedUnion = undefined;
+ break;
+ }
+
+ serializedUnion = serializedIndividual;
+ }
+
+ // If we were able to find common type
+ if (serializedUnion) {
+ return serializedUnion;
+ }
+ }
+ // Fallthrough
case SyntaxKind.TypeQuery:
case SyntaxKind.TypeLiteral:
- case SyntaxKind.UnionType:
- case SyntaxKind.IntersectionType:
case SyntaxKind.AnyKeyword:
case SyntaxKind.ThisType:
break;
@@ -2284,7 +2315,7 @@ namespace ts {
* @param node The parameter declaration node.
*/
function visitParameter(node: ParameterDeclaration) {
- if (node.name && isIdentifier(node.name) && node.name.originalKeywordKind === SyntaxKind.ThisKeyword) {
+ if (parameterIsThisKeyword(node)) {
return undefined;
}
@@ -2963,7 +2994,7 @@ namespace ts {
return createStatement(expression, /*location*/ undefined);
}
- function addExportMemberAssignment(statements: Statement[], node: DeclarationStatement) {
+ function addExportMemberAssignment(statements: Statement[], node: ClassDeclaration | FunctionDeclaration) {
const expression = createAssignment(
getExportName(node),
getLocalName(node, /*noSourceMaps*/ true)
@@ -3041,7 +3072,7 @@ namespace ts {
* @param noSourceMaps A value indicating whether source maps may not be emitted for the name.
* @param allowComments A value indicating whether comments may be emitted for the name.
*/
- function getLocalName(node: DeclarationStatement | ClassExpression, noSourceMaps?: boolean, allowComments?: boolean) {
+ function getLocalName(node: FunctionDeclaration | ClassDeclaration | ClassExpression | ModuleDeclaration | EnumDeclaration, noSourceMaps?: boolean, allowComments?: boolean) {
return getDeclarationName(node, allowComments, !noSourceMaps, EmitFlags.LocalName);
}
@@ -3055,7 +3086,7 @@ namespace ts {
* @param noSourceMaps A value indicating whether source maps may not be emitted for the name.
* @param allowComments A value indicating whether comments may be emitted for the name.
*/
- function getExportName(node: DeclarationStatement | ClassExpression, noSourceMaps?: boolean, allowComments?: boolean) {
+ function getExportName(node: FunctionDeclaration | ClassDeclaration | ClassExpression | ModuleDeclaration | EnumDeclaration, noSourceMaps?: boolean, allowComments?: boolean) {
if (isNamespaceExport(node)) {
return getNamespaceMemberName(getDeclarationName(node), allowComments, !noSourceMaps);
}
@@ -3071,9 +3102,9 @@ namespace ts {
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
* @param emitFlags Additional NodeEmitFlags to specify for the name.
*/
- function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
+ function getDeclarationName(node: FunctionDeclaration | ClassDeclaration | ClassExpression | ModuleDeclaration | EnumDeclaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
if (node.name) {
- const name = getMutableClone(node.name);
+ const name = getMutableClone(node.name);
emitFlags |= getEmitFlags(node.name);
if (!allowSourceMaps) {
emitFlags |= EmitFlags.NoSourceMap;
diff --git a/src/compiler/types.ts b/src/compiler/types.ts
index 55200b29676..ae9502c21d2 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -436,8 +436,6 @@ namespace ts {
TypeExcludesFlags = YieldContext | AwaitContext,
}
- export type ModifiersArray = NodeArray;
-
export const enum ModifierFlags {
None = 0,
Export = 1 << 0, // Declarations
@@ -501,21 +499,34 @@ namespace ts {
hasTrailingComma?: boolean;
}
- export interface Token extends Node {
- __tokenTag: any;
+ export interface Token extends Node {
+ kind: TKind;
}
- // @kind(SyntaxKind.AbstractKeyword)
- // @kind(SyntaxKind.AsyncKeyword)
- // @kind(SyntaxKind.ConstKeyword)
- // @kind(SyntaxKind.DeclareKeyword)
- // @kind(SyntaxKind.DefaultKeyword)
- // @kind(SyntaxKind.ExportKeyword)
- // @kind(SyntaxKind.PublicKeyword)
- // @kind(SyntaxKind.PrivateKeyword)
- // @kind(SyntaxKind.ProtectedKeyword)
- // @kind(SyntaxKind.StaticKeyword)
- export interface Modifier extends Token { }
+ export type DotDotDotToken = Token;
+ export type QuestionToken = Token;
+ export type ColonToken = Token;
+ export type EqualsToken = Token;
+ export type AsteriskToken = Token;
+ export type EqualsGreaterThanToken = Token;
+ export type EndOfFileToken = Token;
+ export type AtToken = Token;
+
+ export type Modifier
+ = Token
+ | Token
+ | Token
+ | Token
+ | Token
+ | Token
+ | Token
+ | Token
+ | Token
+ | Token
+ | Token
+ ;
+
+ export type ModifiersArray = NodeArray;
/*@internal*/
export const enum GeneratedIdentifierKind {
@@ -526,8 +537,8 @@ namespace ts {
Node, // Unique name based on the node in the 'original' property.
}
- // @kind(SyntaxKind.Identifier)
export interface Identifier extends PrimaryExpression {
+ kind: SyntaxKind.Identifier;
text: string; // Text of identifier (with escapes converted to characters)
originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later
/*@internal*/ autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier.
@@ -539,9 +550,8 @@ namespace ts {
resolvedSymbol: Symbol;
}
- // @kind(SyntaxKind.QualifiedName)
export interface QualifiedName extends Node {
- // Must have same layout as PropertyAccess
+ kind: SyntaxKind.QualifiedName;
left: EntityName;
right: Identifier;
}
@@ -558,21 +568,21 @@ namespace ts {
}
export interface DeclarationStatement extends Declaration, Statement {
- name?: Identifier;
+ name?: Identifier | LiteralExpression;
}
- // @kind(SyntaxKind.ComputedPropertyName)
export interface ComputedPropertyName extends Node {
+ kind: SyntaxKind.ComputedPropertyName;
expression: Expression;
}
- // @kind(SyntaxKind.Decorator)
export interface Decorator extends Node {
+ kind: SyntaxKind.Decorator;
expression: LeftHandSideExpression;
}
- // @kind(SyntaxKind.TypeParameter)
export interface TypeParameterDeclaration extends Declaration {
+ kind: SyntaxKind.TypeParameter;
name: Identifier;
constraint?: TypeNode;
@@ -587,55 +597,57 @@ namespace ts {
type?: TypeNode;
}
- // @kind(SyntaxKind.CallSignature)
- export interface CallSignatureDeclaration extends SignatureDeclaration, TypeElement { }
+ export interface CallSignatureDeclaration extends SignatureDeclaration, TypeElement {
+ kind: SyntaxKind.CallSignature;
+ }
- // @kind(SyntaxKind.ConstructSignature)
- export interface ConstructSignatureDeclaration extends SignatureDeclaration, TypeElement { }
+ export interface ConstructSignatureDeclaration extends SignatureDeclaration, TypeElement {
+ kind: SyntaxKind.ConstructSignature;
+ }
export type BindingName = Identifier | BindingPattern;
- // @kind(SyntaxKind.VariableDeclaration)
export interface VariableDeclaration extends Declaration {
+ kind: SyntaxKind.VariableDeclaration;
parent?: VariableDeclarationList;
name: BindingName; // Declared variable name
type?: TypeNode; // Optional type annotation
initializer?: Expression; // Optional initializer
}
- // @kind(SyntaxKind.VariableDeclarationList)
export interface VariableDeclarationList extends Node {
+ kind: SyntaxKind.VariableDeclarationList;
declarations: NodeArray;
}
- // @kind(SyntaxKind.Parameter)
export interface ParameterDeclaration extends Declaration {
- dotDotDotToken?: Node; // Present on rest parameter
+ kind: SyntaxKind.Parameter;
+ dotDotDotToken?: DotDotDotToken; // Present on rest parameter
name: BindingName; // Declared parameter name
- questionToken?: Node; // Present on optional parameter
+ questionToken?: QuestionToken; // Present on optional parameter
type?: TypeNode; // Optional type annotation
initializer?: Expression; // Optional initializer
}
- // @kind(SyntaxKind.BindingElement)
export interface BindingElement extends Declaration {
+ kind: SyntaxKind.BindingElement;
propertyName?: PropertyName; // Binding property name (in object binding pattern)
- dotDotDotToken?: Node; // Present on rest binding element
+ dotDotDotToken?: DotDotDotToken; // Present on rest binding element
name: BindingName; // Declared binding element name
initializer?: Expression; // Optional initializer
}
- // @kind(SyntaxKind.PropertySignature)
export interface PropertySignature extends TypeElement {
+ kind: SyntaxKind.PropertySignature | SyntaxKind.JSDocRecordMember;
name: PropertyName; // Declared property name
- questionToken?: Node; // Present on optional property
+ questionToken?: QuestionToken; // Present on optional property
type?: TypeNode; // Optional type annotation
initializer?: Expression; // Optional initializer
}
- // @kind(SyntaxKind.PropertyDeclaration)
export interface PropertyDeclaration extends ClassElement {
- questionToken?: Node; // Present for use with reporting a grammar error
+ kind: SyntaxKind.PropertyDeclaration;
+ questionToken?: QuestionToken; // Present for use with reporting a grammar error
name: PropertyName;
type?: TypeNode;
initializer?: Expression; // Optional initializer
@@ -644,25 +656,24 @@ namespace ts {
export interface ObjectLiteralElement extends Declaration {
_objectLiteralBrandBrand: any;
name?: PropertyName;
- }
+ }
export type ObjectLiteralElementLike = PropertyAssignment | ShorthandPropertyAssignment | MethodDeclaration | AccessorDeclaration;
- // @kind(SyntaxKind.PropertyAssignment)
export interface PropertyAssignment extends ObjectLiteralElement {
- _propertyAssignmentBrand: any;
+ kind: SyntaxKind.PropertyAssignment;
name: PropertyName;
- questionToken?: Node;
+ questionToken?: QuestionToken;
initializer: Expression;
}
- // @kind(SyntaxKind.ShorthandPropertyAssignment)
export interface ShorthandPropertyAssignment extends ObjectLiteralElement {
+ kind: SyntaxKind.ShorthandPropertyAssignment;
name: Identifier;
- questionToken?: Node;
+ questionToken?: QuestionToken;
// used when ObjectLiteralExpression is used in ObjectAssignmentPattern
// it is grammar error to appear in actual object initializer
- equalsToken?: Node;
+ equalsToken?: Token;
objectAssignmentInitializer?: Expression;
}
@@ -676,9 +687,9 @@ namespace ts {
// SyntaxKind.JSDocPropertyTag
export interface VariableLikeDeclaration extends Declaration {
propertyName?: PropertyName;
- dotDotDotToken?: Node;
+ dotDotDotToken?: DotDotDotToken;
name: DeclarationName;
- questionToken?: Node;
+ questionToken?: QuestionToken;
type?: TypeNode;
initializer?: Expression;
}
@@ -691,15 +702,15 @@ namespace ts {
elements: NodeArray;
}
- // @kind(SyntaxKind.ObjectBindingPattern)
export interface ObjectBindingPattern extends BindingPattern {
+ kind: SyntaxKind.ObjectBindingPattern;
elements: NodeArray;
}
export type ArrayBindingElement = BindingElement | OmittedExpression;
- // @kind(SyntaxKind.ArrayBindingPattern)
export interface ArrayBindingPattern extends BindingPattern {
+ kind: SyntaxKind.ArrayBindingPattern;
elements: NodeArray;
}
@@ -714,19 +725,19 @@ namespace ts {
export interface FunctionLikeDeclaration extends SignatureDeclaration {
_functionLikeDeclarationBrand: any;
- asteriskToken?: Node;
- questionToken?: Node;
+ asteriskToken?: AsteriskToken;
+ questionToken?: QuestionToken;
body?: Block | Expression;
}
- // @kind(SyntaxKind.FunctionDeclaration)
export interface FunctionDeclaration extends FunctionLikeDeclaration, DeclarationStatement {
+ kind: SyntaxKind.FunctionDeclaration;
name?: Identifier;
body?: FunctionBody;
}
- // @kind(SyntaxKind.MethodSignature)
export interface MethodSignature extends SignatureDeclaration, TypeElement {
+ kind: SyntaxKind.MethodSignature;
name: PropertyName;
}
@@ -739,126 +750,132 @@ namespace ts {
// Because of this, it may be necessary to determine what sort of MethodDeclaration you have
// at later stages of the compiler pipeline. In that case, you can either check the parent kind
// of the method, or use helpers like isObjectLiteralMethodDeclaration
- // @kind(SyntaxKind.MethodDeclaration)
export interface MethodDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement {
+ kind: SyntaxKind.MethodDeclaration;
name: PropertyName;
body?: FunctionBody;
}
- // @kind(SyntaxKind.Constructor)
export interface ConstructorDeclaration extends FunctionLikeDeclaration, ClassElement {
+ kind: SyntaxKind.Constructor;
body?: FunctionBody;
}
// For when we encounter a semicolon in a class declaration. ES6 allows these as class elements.
- // @kind(SyntaxKind.SemicolonClassElement)
export interface SemicolonClassElement extends ClassElement {
- _semicolonClassElementBrand: any;
+ kind: SyntaxKind.SemicolonClassElement;
}
- // See the comment on MethodDeclaration for the intuition behind AccessorDeclaration being a
+ // See the comment on MethodDeclaration for the intuition behind GetAccessorDeclaration being a
// ClassElement and an ObjectLiteralElement.
- export interface AccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement {
- _accessorDeclarationBrand: any;
+ export interface GetAccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement {
+ kind: SyntaxKind.GetAccessor;
name: PropertyName;
body: FunctionBody;
}
- // @kind(SyntaxKind.GetAccessor)
- export interface GetAccessorDeclaration extends AccessorDeclaration { }
-
- // @kind(SyntaxKind.SetAccessor)
- export interface SetAccessorDeclaration extends AccessorDeclaration { }
-
- // @kind(SyntaxKind.IndexSignature)
- export interface IndexSignatureDeclaration extends SignatureDeclaration, ClassElement, TypeElement {
- _indexSignatureDeclarationBrand: any;
+ // See the comment on MethodDeclaration for the intuition behind SetAccessorDeclaration being a
+ // ClassElement and an ObjectLiteralElement.
+ export interface SetAccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement {
+ kind: SyntaxKind.SetAccessor;
+ name: PropertyName;
+ body: FunctionBody;
+ }
+
+ export type AccessorDeclaration = GetAccessorDeclaration | SetAccessorDeclaration;
+
+ export interface IndexSignatureDeclaration extends SignatureDeclaration, ClassElement, TypeElement {
+ kind: SyntaxKind.IndexSignature;
}
- // @kind(SyntaxKind.AnyKeyword)
- // @kind(SyntaxKind.NumberKeyword)
- // @kind(SyntaxKind.BooleanKeyword)
- // @kind(SyntaxKind.StringKeyword)
- // @kind(SyntaxKind.SymbolKeyword)
- // @kind(SyntaxKind.VoidKeyword)
export interface TypeNode extends Node {
_typeNodeBrand: any;
}
- // @kind(SyntaxKind.ThisType)
+ export interface KeywordTypeNode extends TypeNode {
+ kind: SyntaxKind.AnyKeyword
+ | SyntaxKind.NumberKeyword
+ | SyntaxKind.BooleanKeyword
+ | SyntaxKind.StringKeyword
+ | SyntaxKind.SymbolKeyword
+ | SyntaxKind.VoidKeyword;
+ }
+
export interface ThisTypeNode extends TypeNode {
- _thisTypeNodeBrand: any;
+ kind: SyntaxKind.ThisType;
}
export interface FunctionOrConstructorTypeNode extends TypeNode, SignatureDeclaration {
- _functionOrConstructorTypeNodeBrand: any;
+ kind: SyntaxKind.FunctionType | SyntaxKind.ConstructorType;
}
- // @kind(SyntaxKind.FunctionType)
- export interface FunctionTypeNode extends FunctionOrConstructorTypeNode { }
+ export interface FunctionTypeNode extends FunctionOrConstructorTypeNode {
+ kind: SyntaxKind.FunctionType;
+ }
- // @kind(SyntaxKind.ConstructorType)
- export interface ConstructorTypeNode extends FunctionOrConstructorTypeNode { }
+ export interface ConstructorTypeNode extends FunctionOrConstructorTypeNode {
+ kind: SyntaxKind.ConstructorType;
+ }
- // @kind(SyntaxKind.TypeReference)
export interface TypeReferenceNode extends TypeNode {
+ kind: SyntaxKind.TypeReference;
typeName: EntityName;
typeArguments?: NodeArray;
}
- // @kind(SyntaxKind.TypePredicate)
export interface TypePredicateNode extends TypeNode {
+ kind: SyntaxKind.TypePredicate;
parameterName: Identifier | ThisTypeNode;
type: TypeNode;
}
- // @kind(SyntaxKind.TypeQuery)
export interface TypeQueryNode extends TypeNode {
+ kind: SyntaxKind.TypeQuery;
exprName: EntityName;
}
// A TypeLiteral is the declaration node for an anonymous symbol.
- // @kind(SyntaxKind.TypeLiteral)
export interface TypeLiteralNode extends TypeNode, Declaration {
+ kind: SyntaxKind.TypeLiteral;
members: NodeArray;
}
- // @kind(SyntaxKind.ArrayType)
export interface ArrayTypeNode extends TypeNode {
+ kind: SyntaxKind.ArrayType;
elementType: TypeNode;
}
- // @kind(SyntaxKind.TupleType)
export interface TupleTypeNode extends TypeNode {
+ kind: SyntaxKind.TupleType;
elementTypes: NodeArray;
}
export interface UnionOrIntersectionTypeNode extends TypeNode {
+ kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType;
types: NodeArray;
}
- // @kind(SyntaxKind.UnionType)
- export interface UnionTypeNode extends UnionOrIntersectionTypeNode { }
+ export interface UnionTypeNode extends UnionOrIntersectionTypeNode {
+ kind: SyntaxKind.UnionType;
+ }
- // @kind(SyntaxKind.IntersectionType)
- export interface IntersectionTypeNode extends UnionOrIntersectionTypeNode { }
+ export interface IntersectionTypeNode extends UnionOrIntersectionTypeNode {
+ kind: SyntaxKind.IntersectionType;
+ }
- // @kind(SyntaxKind.ParenthesizedType)
export interface ParenthesizedTypeNode extends TypeNode {
+ kind: SyntaxKind.ParenthesizedType;
type: TypeNode;
}
- // @kind(SyntaxKind.StringLiteralType)
export interface LiteralTypeNode extends TypeNode {
- _stringLiteralTypeBrand: any;
+ kind: SyntaxKind.LiteralType;
literal: Expression;
}
- // @kind(SyntaxKind.StringLiteral)
export interface StringLiteral extends LiteralExpression {
- _stringLiteralBrand: any;
- /* @internal */
- textSourceNode?: Identifier | StringLiteral; // Allows a StringLiteral to get its text from another node (used by transforms).
+ kind: SyntaxKind.StringLiteral;
+ /* @internal */ textSourceNode?: Identifier | StringLiteral; // Allows a StringLiteral to get its text from another node (used by transforms).
}
// Note: 'brands' in our syntax nodes serve to give us a small amount of nominal typing.
@@ -873,16 +890,15 @@ namespace ts {
contextualType?: Type; // Used to temporarily assign a contextual type during overload resolution
}
- // @kind(SyntaxKind.OmittedExpression)
export interface OmittedExpression extends Expression {
- _omittedExpressionBrand: any;
+ kind: SyntaxKind.OmittedExpression;
}
// Represents an expression that is elided as part of a transformation to emit comments on a
// not-emitted node. The 'expression' property of a NotEmittedExpression should be emitted.
// @internal
- // @kind(SyntaxKind.NotEmittedExpression)
export interface PartiallyEmittedExpression extends LeftHandSideExpression {
+ kind: SyntaxKind.PartiallyEmittedExpression;
expression: Expression;
}
@@ -894,16 +910,33 @@ namespace ts {
_incrementExpressionBrand: any;
}
- // @kind(SyntaxKind.PrefixUnaryExpression)
+ // see: https://tc39.github.io/ecma262/#prod-UpdateExpression
+ // see: https://tc39.github.io/ecma262/#prod-UnaryExpression
+ export type PrefixUnaryOperator
+ = SyntaxKind.PlusPlusToken
+ | SyntaxKind.MinusMinusToken
+ | SyntaxKind.PlusToken
+ | SyntaxKind.MinusToken
+ | SyntaxKind.TildeToken
+ | SyntaxKind.ExclamationToken
+ ;
+
export interface PrefixUnaryExpression extends IncrementExpression {
- operator: SyntaxKind;
+ kind: SyntaxKind.PrefixUnaryExpression;
+ operator: PrefixUnaryOperator;
operand: UnaryExpression;
}
- // @kind(SyntaxKind.PostfixUnaryExpression)
+ // see: https://tc39.github.io/ecma262/#prod-UpdateExpression
+ export type PostfixUnaryOperator
+ = SyntaxKind.PlusPlusToken
+ | SyntaxKind.MinusMinusToken
+ ;
+
export interface PostfixUnaryExpression extends IncrementExpression {
+ kind: SyntaxKind.PostfixUnaryExpression;
operand: LeftHandSideExpression;
- operator: SyntaxKind;
+ operator: PostfixUnaryOperator;
}
export interface PostfixExpression extends UnaryExpression {
@@ -918,73 +951,226 @@ namespace ts {
_memberExpressionBrand: any;
}
- // @kind(SyntaxKind.TrueKeyword)
- // @kind(SyntaxKind.FalseKeyword)
- // @kind(SyntaxKind.NullKeyword)
- // @kind(SyntaxKind.ThisKeyword)
- // @kind(SyntaxKind.SuperKeyword)
export interface PrimaryExpression extends MemberExpression {
_primaryExpressionBrand: any;
}
- // @kind(SyntaxKind.DeleteExpression)
+ export interface NullLiteral extends PrimaryExpression {
+ kind: SyntaxKind.NullKeyword;
+ }
+
+ export interface BooleanLiteral extends PrimaryExpression {
+ kind: SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword;
+ }
+
+ export interface ThisExpression extends PrimaryExpression {
+ kind: SyntaxKind.ThisKeyword;
+ }
+
+ export interface SuperExpression extends PrimaryExpression {
+ kind: SyntaxKind.SuperKeyword;
+ }
+
export interface DeleteExpression extends UnaryExpression {
+ kind: SyntaxKind.DeleteExpression;
expression: UnaryExpression;
}
- // @kind(SyntaxKind.TypeOfExpression)
export interface TypeOfExpression extends UnaryExpression {
+ kind: SyntaxKind.TypeOfExpression;
expression: UnaryExpression;
}
- // @kind(SyntaxKind.VoidExpression)
export interface VoidExpression extends UnaryExpression {
+ kind: SyntaxKind.VoidExpression;
expression: UnaryExpression;
}
- // @kind(SyntaxKind.AwaitExpression)
export interface AwaitExpression extends UnaryExpression {
+ kind: SyntaxKind.AwaitExpression;
expression: UnaryExpression;
}
- // @kind(SyntaxKind.YieldExpression)
export interface YieldExpression extends Expression {
- asteriskToken?: Node;
+ kind: SyntaxKind.YieldExpression;
+ asteriskToken?: AsteriskToken;
expression?: Expression;
}
- // @kind(SyntaxKind.BinaryExpression)
+ // see: https://tc39.github.io/ecma262/#prod-ExponentiationExpression
+ export type ExponentiationOperator
+ = SyntaxKind.AsteriskAsteriskToken
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-MultiplicativeOperator
+ export type MultiplicativeOperator
+ = SyntaxKind.AsteriskToken
+ | SyntaxKind.SlashToken
+ | SyntaxKind.PercentToken
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-MultiplicativeExpression
+ export type MultiplicativeOperatorOrHigher
+ = ExponentiationOperator
+ | MultiplicativeOperator
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-AdditiveExpression
+ export type AdditiveOperator
+ = SyntaxKind.PlusToken
+ | SyntaxKind.MinusToken
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-AdditiveExpression
+ export type AdditiveOperatorOrHigher
+ = MultiplicativeOperatorOrHigher
+ | AdditiveOperator
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-ShiftExpression
+ export type ShiftOperator
+ = SyntaxKind.LessThanLessThanToken
+ | SyntaxKind.GreaterThanGreaterThanToken
+ | SyntaxKind.GreaterThanGreaterThanGreaterThanToken
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-ShiftExpression
+ export type ShiftOperatorOrHigher
+ = AdditiveOperatorOrHigher
+ | ShiftOperator
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-RelationalExpression
+ export type RelationalOperator
+ = SyntaxKind.LessThanToken
+ | SyntaxKind.LessThanEqualsToken
+ | SyntaxKind.GreaterThanToken
+ | SyntaxKind.GreaterThanEqualsToken
+ | SyntaxKind.InstanceOfKeyword
+ | SyntaxKind.InKeyword
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-RelationalExpression
+ export type RelationalOperatorOrHigher
+ = ShiftOperatorOrHigher
+ | RelationalOperator
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-EqualityExpression
+ export type EqualityOperator
+ = SyntaxKind.EqualsEqualsToken
+ | SyntaxKind.EqualsEqualsEqualsToken
+ | SyntaxKind.ExclamationEqualsEqualsToken
+ | SyntaxKind.ExclamationEqualsToken
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-EqualityExpression
+ export type EqualityOperatorOrHigher
+ = RelationalOperatorOrHigher
+ | EqualityOperator;
+
+ // see: https://tc39.github.io/ecma262/#prod-BitwiseANDExpression
+ // see: https://tc39.github.io/ecma262/#prod-BitwiseXORExpression
+ // see: https://tc39.github.io/ecma262/#prod-BitwiseORExpression
+ export type BitwiseOperator
+ = SyntaxKind.AmpersandToken
+ | SyntaxKind.BarToken
+ | SyntaxKind.CaretToken
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-BitwiseANDExpression
+ // see: https://tc39.github.io/ecma262/#prod-BitwiseXORExpression
+ // see: https://tc39.github.io/ecma262/#prod-BitwiseORExpression
+ export type BitwiseOperatorOrHigher
+ = EqualityOperatorOrHigher
+ | BitwiseOperator
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-LogicalANDExpression
+ // see: https://tc39.github.io/ecma262/#prod-LogicalORExpression
+ export type LogicalOperator
+ = SyntaxKind.AmpersandAmpersandToken
+ | SyntaxKind.BarBarToken
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-LogicalANDExpression
+ // see: https://tc39.github.io/ecma262/#prod-LogicalORExpression
+ export type LogicalOperatorOrHigher
+ = BitwiseOperatorOrHigher
+ | LogicalOperator
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-AssignmentOperator
+ export type CompoundAssignmentOperator
+ = SyntaxKind.PlusEqualsToken
+ | SyntaxKind.MinusEqualsToken
+ | SyntaxKind.AsteriskAsteriskEqualsToken
+ | SyntaxKind.AsteriskEqualsToken
+ | SyntaxKind.SlashEqualsToken
+ | SyntaxKind.PercentEqualsToken
+ | SyntaxKind.AmpersandEqualsToken
+ | SyntaxKind.BarEqualsToken
+ | SyntaxKind.CaretEqualsToken
+ | SyntaxKind.LessThanLessThanEqualsToken
+ | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken
+ | SyntaxKind.GreaterThanGreaterThanEqualsToken
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-AssignmentExpression
+ export type AssignmentOperator
+ = SyntaxKind.EqualsToken
+ | CompoundAssignmentOperator
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-AssignmentExpression
+ export type AssignmentOperatorOrHigher
+ = LogicalOperatorOrHigher
+ | AssignmentOperator
+ ;
+
+ // see: https://tc39.github.io/ecma262/#prod-Expression
+ export type BinaryOperator
+ = AssignmentOperatorOrHigher
+ | SyntaxKind.CommaToken
+ ;
+
+ export type BinaryOperatorToken = Token;
+
// Binary expressions can be declarations if they are 'exports.foo = bar' expressions in JS files
export interface BinaryExpression extends Expression, Declaration {
+ kind: SyntaxKind.BinaryExpression;
left: Expression;
- operatorToken: Node;
+ operatorToken: BinaryOperatorToken;
right: Expression;
}
- // @kind(SyntaxKind.ConditionalExpression)
export interface ConditionalExpression extends Expression {
+ kind: SyntaxKind.ConditionalExpression;
condition: Expression;
- questionToken: Node;
+ questionToken: QuestionToken;
whenTrue: Expression;
- colonToken: Node;
+ colonToken: ColonToken;
whenFalse: Expression;
}
export type FunctionBody = Block;
export type ConciseBody = FunctionBody | Expression;
- // @kind(SyntaxKind.FunctionExpression)
export interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclaration {
+ kind: SyntaxKind.FunctionExpression;
name?: Identifier;
body: FunctionBody; // Required, whereas the member inherited from FunctionDeclaration is optional
}
- // @kind(SyntaxKind.ArrowFunction)
export interface ArrowFunction extends Expression, FunctionLikeDeclaration {
- equalsGreaterThanToken: Node;
+ kind: SyntaxKind.ArrowFunction;
+ equalsGreaterThanToken: EqualsGreaterThanToken;
body: ConciseBody;
}
+ // The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral,
+ // or any literal of a template, this means quotes have been removed and escapes have been converted to actual characters.
+ // For a NumericLiteral, the stored value is the toString() representation of the number. For example 1, 1.00, and 1e0 are all stored as just "1".
export interface LiteralLikeNode extends Node {
text: string;
isUnterminated?: boolean;
@@ -996,55 +1182,65 @@ namespace ts {
// The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral,
// or any literal of a template, this means quotes have been removed and escapes have been converted to actual characters.
// For a NumericLiteral, the stored value is the toString() representation of the number. For example 1, 1.00, and 1e0 are all stored as just "1".
- // @kind(SyntaxKind.RegularExpressionLiteral)
- // @kind(SyntaxKind.NoSubstitutionTemplateLiteral)
export interface LiteralExpression extends LiteralLikeNode, PrimaryExpression {
_literalExpressionBrand: any;
}
- // @kind(SyntaxKind.NumericLiteral)
+ export interface RegularExpressionLiteral extends LiteralExpression {
+ kind: SyntaxKind.RegularExpressionLiteral;
+ }
+
+ export interface NoSubstitutionTemplateLiteral extends LiteralExpression {
+ kind: SyntaxKind.NoSubstitutionTemplateLiteral;
+ }
+
export interface NumericLiteral extends LiteralExpression {
- _numericLiteralBrand: any;
+ kind: SyntaxKind.NumericLiteral;
trailingComment?: string;
}
- // @kind(SyntaxKind.TemplateHead)
- // @kind(SyntaxKind.TemplateMiddle)
- // @kind(SyntaxKind.TemplateTail)
- export interface TemplateLiteralFragment extends LiteralLikeNode {
- _templateLiteralFragmentBrand: any;
+ export interface TemplateHead extends LiteralLikeNode {
+ kind: SyntaxKind.TemplateHead;
}
- export type Template = TemplateExpression | LiteralExpression;
+ export interface TemplateMiddle extends LiteralLikeNode {
+ kind: SyntaxKind.TemplateMiddle;
+ }
+
+ export interface TemplateTail extends LiteralLikeNode {
+ kind: SyntaxKind.TemplateTail;
+ }
+
+ export type TemplateLiteral = TemplateExpression | NoSubstitutionTemplateLiteral;
- // @kind(SyntaxKind.TemplateExpression)
export interface TemplateExpression extends PrimaryExpression {
- head: TemplateLiteralFragment;
+ kind: SyntaxKind.TemplateExpression;
+ head: TemplateHead;
templateSpans: NodeArray;
}
// Each of these corresponds to a substitution expression and a template literal, in that order.
// The template literal must have kind TemplateMiddleLiteral or TemplateTailLiteral.
- // @kind(SyntaxKind.TemplateSpan)
export interface TemplateSpan extends Node {
+ kind: SyntaxKind.TemplateSpan;
expression: Expression;
- literal: TemplateLiteralFragment;
+ literal: TemplateMiddle | TemplateTail;
}
- // @kind(SyntaxKind.ParenthesizedExpression)
export interface ParenthesizedExpression extends PrimaryExpression {
+ kind: SyntaxKind.ParenthesizedExpression;
expression: Expression;
}
- // @kind(SyntaxKind.ArrayLiteralExpression)
export interface ArrayLiteralExpression extends PrimaryExpression {
+ kind: SyntaxKind.ArrayLiteralExpression;
elements: NodeArray;
/* @internal */
multiLine?: boolean;
}
- // @kind(SyntaxKind.SpreadElementExpression)
export interface SpreadElementExpression extends Expression {
+ kind: SyntaxKind.SpreadElementExpression;
expression: Expression;
}
@@ -1059,8 +1255,8 @@ namespace ts {
}
// An ObjectLiteralExpression is the declaration node for an anonymous symbol.
- // @kind(SyntaxKind.ObjectLiteralExpression)
export interface ObjectLiteralExpression extends ObjectLiteralExpressionBase {
+ kind: SyntaxKind.ObjectLiteralExpression;
/* @internal */
multiLine?: boolean;
}
@@ -1068,69 +1264,93 @@ namespace ts {
export type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression;
export type EntityNameOrEntityNameExpression = EntityName | EntityNameExpression;
- // @kind(SyntaxKind.PropertyAccessExpression)
export interface PropertyAccessExpression extends MemberExpression, Declaration {
+ kind: SyntaxKind.PropertyAccessExpression;
expression: LeftHandSideExpression;
name: Identifier;
}
+
+ export interface SuperPropertyAccessExpression extends PropertyAccessExpression {
+ expression: SuperExpression;
+ }
+
/** Brand for a PropertyAccessExpression which, like a QualifiedName, consists of a sequence of identifiers separated by dots. */
export interface PropertyAccessEntityNameExpression extends PropertyAccessExpression {
_propertyAccessExpressionLikeQualifiedNameBrand?: any;
expression: EntityNameExpression;
}
- // @kind(SyntaxKind.ElementAccessExpression)
export interface ElementAccessExpression extends MemberExpression {
+ kind: SyntaxKind.ElementAccessExpression;
expression: LeftHandSideExpression;
argumentExpression?: Expression;
}
- // @kind(SyntaxKind.CallExpression)
+ export interface SuperElementAccessExpression extends ElementAccessExpression {
+ expression: SuperExpression;
+ }
+
+ // see: https://tc39.github.io/ecma262/#prod-SuperProperty
+ export type SuperProperty
+ = SuperPropertyAccessExpression
+ | SuperElementAccessExpression
+ ;
+
export interface CallExpression extends LeftHandSideExpression, Declaration {
+ kind: SyntaxKind.CallExpression;
expression: LeftHandSideExpression;
typeArguments?: NodeArray;
arguments: NodeArray;
}
- // @kind(SyntaxKind.ExpressionWithTypeArguments)
+ // see: https://tc39.github.io/ecma262/#prod-SuperCall
+ export interface SuperCall extends CallExpression {
+ expression: SuperExpression;
+ }
+
export interface ExpressionWithTypeArguments extends TypeNode {
+ kind: SyntaxKind.ExpressionWithTypeArguments;
expression: LeftHandSideExpression;
typeArguments?: NodeArray;
}
- // @kind(SyntaxKind.NewExpression)
- export interface NewExpression extends CallExpression, PrimaryExpression { }
+ export interface NewExpression extends PrimaryExpression, Declaration {
+ kind: SyntaxKind.NewExpression;
+ expression: LeftHandSideExpression;
+ typeArguments?: NodeArray;
+ arguments: NodeArray;
+ }
- // @kind(SyntaxKind.TaggedTemplateExpression)
export interface TaggedTemplateExpression extends MemberExpression {
+ kind: SyntaxKind.TaggedTemplateExpression;
tag: LeftHandSideExpression;
- template: Template;
+ template: TemplateLiteral;
}
export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator;
- // @kind(SyntaxKind.AsExpression)
export interface AsExpression extends Expression {
+ kind: SyntaxKind.AsExpression;
expression: Expression;
type: TypeNode;
}
- // @kind(SyntaxKind.TypeAssertionExpression)
export interface TypeAssertion extends UnaryExpression {
+ kind: SyntaxKind.TypeAssertionExpression;
type: TypeNode;
expression: UnaryExpression;
}
export type AssertionExpression = TypeAssertion | AsExpression;
- // @kind(SyntaxKind.NonNullExpression)
export interface NonNullExpression extends LeftHandSideExpression {
+ kind: SyntaxKind.NonNullExpression;
expression: Expression;
}
/// A JSX expression of the form ...
- // @kind(SyntaxKind.JsxElement)
export interface JsxElement extends PrimaryExpression {
+ kind: SyntaxKind.JsxElement;
openingElement: JsxOpeningElement;
children: NodeArray;
closingElement: JsxClosingElement;
@@ -1139,17 +1359,17 @@ namespace ts {
export type JsxTagNameExpression = PrimaryExpression | PropertyAccessExpression;
/// The opening element of a ... JsxElement
- // @kind(SyntaxKind.JsxOpeningElement)
export interface JsxOpeningElement extends Expression {
- _openingElementBrand?: any;
+ kind: SyntaxKind.JsxOpeningElement;
tagName: JsxTagNameExpression;
attributes: NodeArray;
}
/// A JSX expression of the form
- // @kind(SyntaxKind.JsxSelfClosingElement)
- export interface JsxSelfClosingElement extends PrimaryExpression, JsxOpeningElement {
- _selfClosingElementBrand?: any;
+ export interface JsxSelfClosingElement extends PrimaryExpression {
+ kind: SyntaxKind.JsxSelfClosingElement;
+ tagName: JsxTagNameExpression;
+ attributes: NodeArray;
}
/// Either the opening tag in a ... pair, or the lone in a self-closing form
@@ -1157,31 +1377,30 @@ namespace ts {
export type JsxAttributeLike = JsxAttribute | JsxSpreadAttribute;
- // @kind(SyntaxKind.JsxAttribute)
export interface JsxAttribute extends Node {
+ kind: SyntaxKind.JsxAttribute;
name: Identifier;
/// JSX attribute initializers are optional; is sugar for
initializer?: StringLiteral | JsxExpression;
}
- // @kind(SyntaxKind.JsxSpreadAttribute)
export interface JsxSpreadAttribute extends Node {
+ kind: SyntaxKind.JsxSpreadAttribute;
expression: Expression;
}
- // @kind(SyntaxKind.JsxClosingElement)
export interface JsxClosingElement extends Node {
+ kind: SyntaxKind.JsxClosingElement;
tagName: JsxTagNameExpression;
}
- // @kind(SyntaxKind.JsxExpression)
export interface JsxExpression extends Expression {
+ kind: SyntaxKind.JsxExpression;
expression?: Expression;
}
- // @kind(SyntaxKind.JsxText)
export interface JsxText extends Node {
- _jsxTextExpressionBrand: any;
+ kind: SyntaxKind.JsxText;
}
export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement;
@@ -1193,41 +1412,43 @@ namespace ts {
// Represents a statement that is elided as part of a transformation to emit comments on a
// not-emitted node.
// @internal
- // @kind(SyntaxKind.NotEmittedStatement)
export interface NotEmittedStatement extends Statement {
+ kind: SyntaxKind.NotEmittedStatement;
}
- // @kind(SyntaxKind.EmptyStatement)
- export interface EmptyStatement extends Statement { }
+ export interface EmptyStatement extends Statement {
+ kind: SyntaxKind.EmptyStatement;
+ }
- // @kind(SyntaxKind.DebuggerStatement)
- export interface DebuggerStatement extends Statement { }
+ export interface DebuggerStatement extends Statement {
+ kind: SyntaxKind.DebuggerStatement;
+ }
- // @kind(SyntaxKind.MissingDeclaration)
export interface MissingDeclaration extends DeclarationStatement, ClassElement, ObjectLiteralElement, TypeElement {
+ kind: SyntaxKind.MissingDeclaration;
name?: Identifier;
}
export type BlockLike = SourceFile | Block | ModuleBlock | CaseClause;
- // @kind(SyntaxKind.Block)
export interface Block extends Statement {
+ kind: SyntaxKind.Block;
statements: NodeArray;
/*@internal*/ multiLine?: boolean;
}
- // @kind(SyntaxKind.VariableStatement)
export interface VariableStatement extends Statement {
+ kind: SyntaxKind.VariableStatement;
declarationList: VariableDeclarationList;
}
- // @kind(SyntaxKind.ExpressionStatement)
export interface ExpressionStatement extends Statement {
+ kind: SyntaxKind.ExpressionStatement;
expression: Expression;
}
- // @kind(SyntaxKind.IfStatement)
export interface IfStatement extends Statement {
+ kind: SyntaxKind.IfStatement;
expression: Expression;
thenStatement: Statement;
elseStatement?: Statement;
@@ -1237,105 +1458,105 @@ namespace ts {
statement: Statement;
}
- // @kind(SyntaxKind.DoStatement)
export interface DoStatement extends IterationStatement {
+ kind: SyntaxKind.DoStatement;
expression: Expression;
}
- // @kind(SyntaxKind.WhileStatement)
export interface WhileStatement extends IterationStatement {
+ kind: SyntaxKind.WhileStatement;
expression: Expression;
}
export type ForInitializer = VariableDeclarationList | Expression;
- // @kind(SyntaxKind.ForStatement)
export interface ForStatement extends IterationStatement {
+ kind: SyntaxKind.ForStatement;
initializer?: ForInitializer;
condition?: Expression;
incrementor?: Expression;
}
- // @kind(SyntaxKind.ForInStatement)
export interface ForInStatement extends IterationStatement {
+ kind: SyntaxKind.ForInStatement;
initializer: ForInitializer;
expression: Expression;
}
- // @kind(SyntaxKind.ForOfStatement)
export interface ForOfStatement extends IterationStatement {
+ kind: SyntaxKind.ForOfStatement;
initializer: ForInitializer;
expression: Expression;
}
- // @kind(SyntaxKind.BreakStatement)
export interface BreakStatement extends Statement {
+ kind: SyntaxKind.BreakStatement;
label?: Identifier;
}
- // @kind(SyntaxKind.ContinueStatement)
export interface ContinueStatement extends Statement {
+ kind: SyntaxKind.ContinueStatement;
label?: Identifier;
}
export type BreakOrContinueStatement = BreakStatement | ContinueStatement;
- // @kind(SyntaxKind.ReturnStatement)
export interface ReturnStatement extends Statement {
+ kind: SyntaxKind.ReturnStatement;
expression?: Expression;
}
- // @kind(SyntaxKind.WithStatement)
export interface WithStatement extends Statement {
+ kind: SyntaxKind.WithStatement;
expression: Expression;
statement: Statement;
}
- // @kind(SyntaxKind.SwitchStatement)
export interface SwitchStatement extends Statement {
+ kind: SyntaxKind.SwitchStatement;
expression: Expression;
caseBlock: CaseBlock;
possiblyExhaustive?: boolean;
}
- // @kind(SyntaxKind.CaseBlock)
export interface CaseBlock extends Node {
+ kind: SyntaxKind.CaseBlock;
clauses: NodeArray;
}
- // @kind(SyntaxKind.CaseClause)
export interface CaseClause extends Node {
+ kind: SyntaxKind.CaseClause;
expression: Expression;
statements: NodeArray;
}
- // @kind(SyntaxKind.DefaultClause)
export interface DefaultClause extends Node {
+ kind: SyntaxKind.DefaultClause;
statements: NodeArray;
}
export type CaseOrDefaultClause = CaseClause | DefaultClause;
- // @kind(SyntaxKind.LabeledStatement)
export interface LabeledStatement extends Statement {
+ kind: SyntaxKind.LabeledStatement;
label: Identifier;
statement: Statement;
}
- // @kind(SyntaxKind.ThrowStatement)
export interface ThrowStatement extends Statement {
+ kind: SyntaxKind.ThrowStatement;
expression: Expression;
}
- // @kind(SyntaxKind.TryStatement)
export interface TryStatement extends Statement {
+ kind: SyntaxKind.TryStatement;
tryBlock: Block;
catchClause?: CatchClause;
finallyBlock?: Block;
}
- // @kind(SyntaxKind.CatchClause)
export interface CatchClause extends Node {
+ kind: SyntaxKind.CatchClause;
variableDeclaration: VariableDeclaration;
block: Block;
}
@@ -1349,13 +1570,13 @@ namespace ts {
members: NodeArray;
}
- // @kind(SyntaxKind.ClassDeclaration)
export interface ClassDeclaration extends ClassLikeDeclaration, DeclarationStatement {
+ kind: SyntaxKind.ClassDeclaration;
name?: Identifier;
}
- // @kind(SyntaxKind.ClassExpression)
export interface ClassExpression extends ClassLikeDeclaration, PrimaryExpression {
+ kind: SyntaxKind.ClassExpression;
}
export interface ClassElement extends Declaration {
@@ -1366,40 +1587,40 @@ namespace ts {
export interface TypeElement extends Declaration {
_typeElementBrand: any;
name?: PropertyName;
- questionToken?: Node;
+ questionToken?: QuestionToken;
}
- // @kind(SyntaxKind.InterfaceDeclaration)
export interface InterfaceDeclaration extends DeclarationStatement {
+ kind: SyntaxKind.InterfaceDeclaration;
name: Identifier;
typeParameters?: NodeArray;
heritageClauses?: NodeArray;
members: NodeArray;
}
- // @kind(SyntaxKind.HeritageClause)
export interface HeritageClause extends Node {
+ kind: SyntaxKind.HeritageClause;
token: SyntaxKind;
types?: NodeArray;
}
- // @kind(SyntaxKind.TypeAliasDeclaration)
export interface TypeAliasDeclaration extends DeclarationStatement {
+ kind: SyntaxKind.TypeAliasDeclaration;
name: Identifier;
typeParameters?: NodeArray;
type: TypeNode;
}
- // @kind(SyntaxKind.EnumMember)
export interface EnumMember extends Declaration {
+ kind: SyntaxKind.EnumMember;
// This does include ComputedPropertyName, but the parser will give an error
// if it parses a ComputedPropertyName in an EnumMember
name: PropertyName;
initializer?: Expression;
}
- // @kind(SyntaxKind.EnumDeclaration)
export interface EnumDeclaration extends DeclarationStatement {
+ kind: SyntaxKind.EnumDeclaration;
name: Identifier;
members: NodeArray;
}
@@ -1408,21 +1629,26 @@ namespace ts {
export type ModuleName = Identifier | StringLiteral;
- // @kind(SyntaxKind.ModuleDeclaration)
export interface ModuleDeclaration extends DeclarationStatement {
+ kind: SyntaxKind.ModuleDeclaration;
name: Identifier | LiteralExpression;
- body?: ModuleBlock | ModuleDeclaration;
+ body?: ModuleBlock | NamespaceDeclaration;
+ }
+
+ export interface NamespaceDeclaration extends ModuleDeclaration {
+ name: Identifier;
+ body: ModuleBlock | NamespaceDeclaration;
}
- // @kind(SyntaxKind.ModuleBlock)
export interface ModuleBlock extends Node, Statement {
+ kind: SyntaxKind.ModuleBlock;
statements: NodeArray;
}
export type ModuleReference = EntityName | ExternalModuleReference;
- // @kind(SyntaxKind.ImportEqualsDeclaration)
export interface ImportEqualsDeclaration extends DeclarationStatement {
+ kind: SyntaxKind.ImportEqualsDeclaration;
name: Identifier;
// 'EntityName' for an internal module reference, 'ExternalModuleReference' for an external
@@ -1430,8 +1656,8 @@ namespace ts {
moduleReference: ModuleReference;
}
- // @kind(SyntaxKind.ExternalModuleReference)
export interface ExternalModuleReference extends Node {
+ kind: SyntaxKind.ExternalModuleReference;
expression?: Expression;
}
@@ -1439,8 +1665,8 @@ namespace ts {
// import "mod" => importClause = undefined, moduleSpecifier = "mod"
// In rest of the cases, module specifier is string literal corresponding to module
// ImportClause information is shown at its declaration below.
- // @kind(SyntaxKind.ImportDeclaration)
export interface ImportDeclaration extends Statement {
+ kind: SyntaxKind.ImportDeclaration;
importClause?: ImportClause;
moduleSpecifier: Expression;
}
@@ -1453,57 +1679,57 @@ namespace ts {
// import d, * as ns from "mod" => name = d, namedBinding: NamespaceImport = { name: ns }
// import { a, b as x } from "mod" => name = undefined, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]}
// import d, { a, b as x } from "mod" => name = d, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]}
- // @kind(SyntaxKind.ImportClause)
export interface ImportClause extends Declaration {
+ kind: SyntaxKind.ImportClause;
name?: Identifier; // Default binding
namedBindings?: NamedImportBindings;
}
- // @kind(SyntaxKind.NamespaceImport)
export interface NamespaceImport extends Declaration {
+ kind: SyntaxKind.NamespaceImport;
name: Identifier;
}
- // @kind(SyntaxKind.NamespaceExportDeclaration)
export interface NamespaceExportDeclaration extends DeclarationStatement {
+ kind: SyntaxKind.NamespaceExportDeclaration;
name: Identifier;
moduleReference: LiteralLikeNode;
}
- // @kind(SyntaxKind.ExportDeclaration)
export interface ExportDeclaration extends DeclarationStatement {
+ kind: SyntaxKind.ExportDeclaration;
exportClause?: NamedExports;
moduleSpecifier?: Expression;
}
- // @kind(SyntaxKind.NamedImports)
export interface NamedImports extends Node {
+ kind: SyntaxKind.NamedImports;
elements: NodeArray;
}
- // @kind(SyntaxKind.NamedExports)
export interface NamedExports extends Node {
+ kind: SyntaxKind.NamedExports;
elements: NodeArray;
}
export type NamedImportsOrExports = NamedImports | NamedExports;
- // @kind(SyntaxKind.ImportSpecifier)
export interface ImportSpecifier extends Declaration {
+ kind: SyntaxKind.ImportSpecifier;
propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent)
name: Identifier; // Declared name
}
- // @kind(SyntaxKind.ExportSpecifier)
export interface ExportSpecifier extends Declaration {
+ kind: SyntaxKind.ExportSpecifier;
propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent)
name: Identifier; // Declared name
}
export type ImportOrExportSpecifier = ImportSpecifier | ExportSpecifier;
- // @kind(SyntaxKind.ExportAssignment)
export interface ExportAssignment extends DeclarationStatement {
+ kind: SyntaxKind.ExportAssignment;
isExportEquals?: boolean;
expression: Expression;
}
@@ -1518,8 +1744,8 @@ namespace ts {
}
// represents a top level: { type } expression in a JSDoc comment.
- // @kind(SyntaxKind.JSDocTypeExpression)
export interface JSDocTypeExpression extends Node {
+ kind: SyntaxKind.JSDocTypeExpression;
type: JSDocType;
}
@@ -1527,139 +1753,141 @@ namespace ts {
_jsDocTypeBrand: any;
}
- // @kind(SyntaxKind.JSDocAllType)
export interface JSDocAllType extends JSDocType {
- _JSDocAllTypeBrand: any;
+ kind: SyntaxKind.JSDocAllType;
}
- // @kind(SyntaxKind.JSDocUnknownType)
export interface JSDocUnknownType extends JSDocType {
- _JSDocUnknownTypeBrand: any;
+ kind: SyntaxKind.JSDocUnknownType;
}
- // @kind(SyntaxKind.JSDocArrayType)
export interface JSDocArrayType extends JSDocType {
+ kind: SyntaxKind.JSDocArrayType;
elementType: JSDocType;
}
- // @kind(SyntaxKind.JSDocUnionType)
export interface JSDocUnionType extends JSDocType {
+ kind: SyntaxKind.JSDocUnionType;
types: NodeArray;
}
- // @kind(SyntaxKind.JSDocTupleType)
export interface JSDocTupleType extends JSDocType {
+ kind: SyntaxKind.JSDocTupleType;
types: NodeArray;
}
- // @kind(SyntaxKind.JSDocNonNullableType)
export interface JSDocNonNullableType extends JSDocType {
+ kind: SyntaxKind.JSDocNonNullableType;
type: JSDocType;
}
- // @kind(SyntaxKind.JSDocNullableType)
export interface JSDocNullableType extends JSDocType {
+ kind: SyntaxKind.JSDocNullableType;
type: JSDocType;
}
- // @kind(SyntaxKind.JSDocRecordType)
- export interface JSDocRecordType extends JSDocType, TypeLiteralNode {
+ export interface JSDocRecordType extends JSDocType {
+ kind: SyntaxKind.JSDocRecordType;
literal: TypeLiteralNode;
}
- // @kind(SyntaxKind.JSDocTypeReference)
export interface JSDocTypeReference extends JSDocType {
+ kind: SyntaxKind.JSDocTypeReference;
name: EntityName;
typeArguments: NodeArray;
}
- // @kind(SyntaxKind.JSDocOptionalType)
export interface JSDocOptionalType extends JSDocType {
+ kind: SyntaxKind.JSDocOptionalType;
type: JSDocType;
}
- // @kind(SyntaxKind.JSDocFunctionType)
export interface JSDocFunctionType extends JSDocType, SignatureDeclaration {
+ kind: SyntaxKind.JSDocFunctionType;
parameters: NodeArray;
type: JSDocType;
}
- // @kind(SyntaxKind.JSDocVariadicType)
export interface JSDocVariadicType extends JSDocType {
+ kind: SyntaxKind.JSDocVariadicType;
type: JSDocType;
}
- // @kind(SyntaxKind.JSDocConstructorType)
export interface JSDocConstructorType extends JSDocType {
+ kind: SyntaxKind.JSDocConstructorType;
type: JSDocType;
}
- // @kind(SyntaxKind.JSDocThisType)
export interface JSDocThisType extends JSDocType {
+ kind: SyntaxKind.JSDocThisType;
type: JSDocType;
}
export interface JSDocLiteralType extends JSDocType {
+ kind: SyntaxKind.JSDocLiteralType;
literal: LiteralTypeNode;
}
export type JSDocTypeReferencingNode = JSDocThisType | JSDocConstructorType | JSDocVariadicType | JSDocOptionalType | JSDocNullableType | JSDocNonNullableType;
- // @kind(SyntaxKind.JSDocRecordMember)
export interface JSDocRecordMember extends PropertySignature {
+ kind: SyntaxKind.JSDocRecordMember;
name: Identifier | LiteralExpression;
type?: JSDocType;
}
- // @kind(SyntaxKind.JSDocComment)
export interface JSDoc extends Node {
+ kind: SyntaxKind.JSDocComment;
tags: NodeArray | undefined;
comment: string | undefined;
}
- // @kind(SyntaxKind.JSDocTag)
export interface JSDocTag extends Node {
- atToken: Node;
+ atToken: AtToken;
tagName: Identifier;
comment: string | undefined;
}
- // @kind(SyntaxKind.JSDocTemplateTag)
+ export interface JSDocUnknownTag extends JSDocTag {
+ kind: SyntaxKind.JSDocTag;
+ }
+
export interface JSDocTemplateTag extends JSDocTag {
+ kind: SyntaxKind.JSDocTemplateTag;
typeParameters: NodeArray;
}
- // @kind(SyntaxKind.JSDocReturnTag)
export interface JSDocReturnTag extends JSDocTag {
+ kind: SyntaxKind.JSDocReturnTag;
typeExpression: JSDocTypeExpression;
}
- // @kind(SyntaxKind.JSDocTypeTag)
export interface JSDocTypeTag extends JSDocTag {
+ kind: SyntaxKind.JSDocTypeTag;
typeExpression: JSDocTypeExpression;
}
- // @kind(SyntaxKind.JSDocTypedefTag)
export interface JSDocTypedefTag extends JSDocTag, Declaration {
+ kind: SyntaxKind.JSDocTypedefTag;
name?: Identifier;
typeExpression?: JSDocTypeExpression;
jsDocTypeLiteral?: JSDocTypeLiteral;
}
- // @kind(SyntaxKind.JSDocPropertyTag)
export interface JSDocPropertyTag extends JSDocTag, TypeElement {
+ kind: SyntaxKind.JSDocPropertyTag;
name: Identifier;
typeExpression: JSDocTypeExpression;
}
- // @kind(SyntaxKind.JSDocTypeLiteral)
export interface JSDocTypeLiteral extends JSDocType {
+ kind: SyntaxKind.JSDocTypeLiteral;
jsDocPropertyTags?: NodeArray;
jsDocTypeTag?: JSDocTypeTag;
}
- // @kind(SyntaxKind.JSDocParameterTag)
export interface JSDocParameterTag extends JSDocTag {
+ kind: SyntaxKind.JSDocParameterTag;
/** the parameter name, if provided *before* the type (TypeScript-style) */
preParameterName?: Identifier;
typeExpression?: JSDocTypeExpression;
@@ -1739,10 +1967,10 @@ namespace ts {
}
// Source files are declarations when they are external modules.
- // @kind(SyntaxKind.SourceFile)
export interface SourceFile extends Declaration {
+ kind: SyntaxKind.SourceFile;
statements: NodeArray;
- endOfFileToken: Node;
+ endOfFileToken: Token;
fileName: string;
/* internal */ path: Path;
@@ -2086,13 +2314,12 @@ namespace ts {
type: Type;
}
- // @kind (TypePredicateKind.This)
export interface ThisTypePredicate extends TypePredicateBase {
- _thisTypePredicateBrand: any;
+ kind: TypePredicateKind.This;
}
- // @kind (TypePredicateKind.Identifier)
export interface IdentifierTypePredicate extends TypePredicateBase {
+ kind: TypePredicateKind.Identifier;
parameterName: string;
parameterIndex: number;
}
@@ -2167,8 +2394,8 @@ namespace ts {
getExternalModuleFileFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration): SourceFile;
getTypeReferenceDirectivesForEntityName(name: EntityNameOrEntityNameExpression): string[];
getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): string[];
- isLiteralConstDeclaration(node: VariableDeclaration): boolean;
- writeLiteralConstValue(node: VariableDeclaration, writer: SymbolWriter): void;
+ isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean;
+ writeLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, writer: SymbolWriter): void;
}
export const enum SymbolFlags {
@@ -2690,11 +2917,7 @@ namespace ts {
NodeJs = 2
}
- export type RootPaths = string[];
- export type PathSubstitutions = MapLike;
- export type TsConfigOnlyOptions = RootPaths | PathSubstitutions;
-
- export type CompilerOptionsValue = string | number | boolean | (string | number)[] | TsConfigOnlyOptions;
+ export type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike;
export interface CompilerOptions {
allowJs?: boolean;
@@ -2746,14 +2969,14 @@ namespace ts {
out?: string;
outDir?: string;
outFile?: string;
- paths?: PathSubstitutions;
+ paths?: MapLike;
preserveConstEnums?: boolean;
project?: string;
/* @internal */ pretty?: DiagnosticStyle;
reactNamespace?: string;
removeComments?: boolean;
rootDir?: string;
- rootDirs?: RootPaths;
+ rootDirs?: string[];
skipLibCheck?: boolean;
skipDefaultLibCheck?: boolean;
sourceMap?: boolean;
diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts
index e10ab6a8add..b30a2fc5f71 100644
--- a/src/compiler/utilities.ts
+++ b/src/compiler/utilities.ts
@@ -609,7 +609,7 @@ namespace ts {
return !!(getCombinedNodeFlags(node) & NodeFlags.Let);
}
- export function isSuperCallExpression(n: Node): boolean {
+ export function isSuperCall(n: Node): n is SuperCall {
return n.kind === SyntaxKind.CallExpression && (n).expression.kind === SyntaxKind.SuperKeyword;
}
@@ -1047,7 +1047,7 @@ namespace ts {
/**
* Determines whether a node is a property or element access expression for super.
*/
- export function isSuperProperty(node: Node): node is (PropertyAccessExpression | ElementAccessExpression) {
+ export function isSuperProperty(node: Node): node is SuperProperty {
const kind = node.kind;
return (kind === SyntaxKind.PropertyAccessExpression || kind === SyntaxKind.ElementAccessExpression)
&& (node).expression.kind === SyntaxKind.SuperKeyword;
@@ -1375,7 +1375,7 @@ namespace ts {
}
}
- export function getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) {
+ export function getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration): ImportEqualsDeclaration | NamespaceImport {
if (node.kind === SyntaxKind.ImportEqualsDeclaration) {
return node;
}
@@ -2459,7 +2459,7 @@ namespace ts {
return file.moduleName || getExternalModuleNameFromPath(host, file.fileName);
}
- export function getExternalModuleNameFromDeclaration(host: EmitHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration): string {
+ export function getExternalModuleNameFromDeclaration(host: EmitHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration): string {
const file = resolver.getExternalModuleFileFromDeclaration(declaration);
if (!file || isDeclarationFile(file)) {
return undefined;
@@ -2707,15 +2707,35 @@ namespace ts {
});
}
- export function getSetAccessorTypeAnnotationNode(accessor: AccessorDeclaration): TypeNode {
+ /** Get the type annotaion for the value parameter. */
+ export function getSetAccessorTypeAnnotationNode(accessor: SetAccessorDeclaration): TypeNode {
if (accessor && accessor.parameters.length > 0) {
- const hasThis = accessor.parameters.length === 2 &&
- accessor.parameters[0].name.kind === SyntaxKind.Identifier &&
- (accessor.parameters[0].name as Identifier).originalKeywordKind === SyntaxKind.ThisKeyword;
+ const hasThis = accessor.parameters.length === 2 && parameterIsThisKeyword(accessor.parameters[0]);
return accessor.parameters[hasThis ? 1 : 0].type;
}
}
+ export function getThisParameter(signature: SignatureDeclaration): ParameterDeclaration | undefined {
+ if (signature.parameters.length) {
+ const thisParameter = signature.parameters[0];
+ if (parameterIsThisKeyword(thisParameter)) {
+ return thisParameter;
+ }
+ }
+ }
+
+ export function parameterIsThisKeyword(parameter: ParameterDeclaration): boolean {
+ return isThisIdentifier(parameter.name);
+ }
+
+ export function isThisIdentifier(node: Node | undefined): boolean {
+ return node && node.kind === SyntaxKind.Identifier && identifierIsThisKeyword(node as Identifier);
+ }
+
+ export function identifierIsThisKeyword(id: Identifier): boolean {
+ return id.originalKeywordKind === SyntaxKind.ThisKeyword;
+ }
+
export interface AllAccessorDeclarations {
firstAccessor: AccessorDeclaration;
secondAccessor: AccessorDeclaration;
@@ -3605,14 +3625,14 @@ namespace ts {
return SyntaxKind.FirstTemplateToken <= kind && kind <= SyntaxKind.LastTemplateToken;
}
- function isTemplateLiteralFragmentKind(kind: SyntaxKind) {
- return kind === SyntaxKind.TemplateHead
- || kind === SyntaxKind.TemplateMiddle
- || kind === SyntaxKind.TemplateTail;
+ export function isTemplateHead(node: Node): node is TemplateHead {
+ return node.kind === SyntaxKind.TemplateHead;
}
- export function isTemplateLiteralFragment(node: Node): node is TemplateLiteralFragment {
- return isTemplateLiteralFragmentKind(node.kind);
+ export function isTemplateMiddleOrTemplateTail(node: Node): node is TemplateMiddle | TemplateTail {
+ const kind = node.kind;
+ return kind === SyntaxKind.TemplateMiddle
+ || kind === SyntaxKind.TemplateTail;
}
// Identifiers
@@ -3777,7 +3797,7 @@ namespace ts {
return node.kind === SyntaxKind.CallExpression;
}
- export function isTemplate(node: Node): node is Template {
+ export function isTemplateLiteral(node: Node): node is TemplateLiteral {
const kind = node.kind;
return kind === SyntaxKind.TemplateExpression
|| kind === SyntaxKind.NoSubstitutionTemplateLiteral;
diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts
index 6910f5aac4d..8dca78fec97 100644
--- a/src/compiler/visitor.ts
+++ b/src/compiler/visitor.ts
@@ -799,7 +799,7 @@ namespace ts {
case SyntaxKind.TaggedTemplateExpression:
return updateTaggedTemplate(node,
visitNode((node).tag, visitor, isExpression),
- visitNode((node).template, visitor, isTemplate));
+ visitNode((node).template, visitor, isTemplateLiteral));
case SyntaxKind.ParenthesizedExpression:
return updateParen(node,
@@ -863,7 +863,7 @@ namespace ts {
case SyntaxKind.TemplateExpression:
return updateTemplateExpression(node,
- visitNode((node).head, visitor, isTemplateLiteralFragment),
+ visitNode((node).head, visitor, isTemplateHead),
visitNodes((node).templateSpans, visitor, isTemplateSpan));
case SyntaxKind.YieldExpression:
@@ -891,7 +891,7 @@ namespace ts {
case SyntaxKind.TemplateSpan:
return updateTemplateSpan(node,
visitNode((node).expression, visitor, isExpression),
- visitNode((node).literal, visitor, isTemplateLiteralFragment));
+ visitNode((node).literal, visitor, isTemplateMiddleOrTemplateTail));
// Element
case SyntaxKind.Block:
diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts
index 49f834963ee..af10f355e1f 100644
--- a/src/harness/fourslash.ts
+++ b/src/harness/fourslash.ts
@@ -1,4 +1,4 @@
-//
+//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -427,7 +427,7 @@ namespace FourSlash {
if (exists !== negative) {
this.printErrorLog(negative, this.getAllDiagnostics());
- throw new Error("Failure between markers: " + startMarkerName + ", " + endMarkerName);
+ throw new Error(`Failure between markers: '${startMarkerName}', '${endMarkerName}'`);
}
}
@@ -742,7 +742,6 @@ namespace FourSlash {
}
}
-
public verifyCompletionListAllowsNewIdentifier(negative: boolean) {
const completions = this.getCompletionListAtCaret();
@@ -1611,7 +1610,7 @@ namespace FourSlash {
if (isFormattingEdit) {
const newContent = this.getFileContent(fileName);
- if (newContent.replace(/\s/g, "") !== oldContent.replace(/\s/g, "")) {
+ if (this.removeWhitespace(newContent) !== this.removeWhitespace(oldContent)) {
this.raiseError("Formatting operation destroyed non-whitespace content");
}
}
@@ -1677,6 +1676,10 @@ namespace FourSlash {
}
}
+ private removeWhitespace(text: string): string {
+ return text.replace(/\s/g, "");
+ }
+
public goToBOF() {
this.goToPosition(0);
}
@@ -2038,6 +2041,47 @@ namespace FourSlash {
}
}
+ private getCodeFixes(errorCode?: number) {
+ const fileName = this.activeFile.fileName;
+ const diagnostics = this.getDiagnostics(fileName);
+
+ if (diagnostics.length === 0) {
+ this.raiseError("Errors expected.");
+ }
+
+ if (diagnostics.length > 1 && errorCode !== undefined) {
+ this.raiseError("When there's more than one error, you must specify the errror to fix.");
+ }
+
+ const diagnostic = !errorCode ? diagnostics[0] : ts.find(diagnostics, d => d.code == errorCode);
+
+ return this.languageService.getCodeFixesAtPosition(fileName, diagnostic.start, diagnostic.length, [diagnostic.code]);
+ }
+
+ public verifyCodeFixAtPosition(expectedText: string, errorCode?: number) {
+ const ranges = this.getRanges();
+ if (ranges.length == 0) {
+ this.raiseError("At least one range should be specified in the testfile.");
+ }
+
+ const actual = this.getCodeFixes(errorCode);
+
+ if (!actual || actual.length == 0) {
+ this.raiseError("No codefixes returned.");
+ }
+
+ if (actual.length > 1) {
+ this.raiseError("More than 1 codefix returned.");
+ }
+
+ this.applyEdits(actual[0].changes[0].fileName, actual[0].changes[0].textChanges, /*isFormattingEdit*/ false);
+ const actualText = this.rangeText(ranges[0]);
+
+ if (this.removeWhitespace(actualText) !== this.removeWhitespace(expectedText)) {
+ this.raiseError(`Actual text doesn't match expected text. Actual: '${actualText}' Expected: '${expectedText}'`);
+ }
+ }
+
public verifyDocCommentTemplate(expected?: ts.TextInsertion) {
const name = "verifyDocCommentTemplate";
const actual = this.languageService.getDocCommentTemplateAtPosition(this.activeFile.fileName, this.currentCaretPosition);
@@ -2211,6 +2255,18 @@ namespace FourSlash {
}
}
+ public verifyNavigationTree(json: any) {
+ const tree = this.languageService.getNavigationTree(this.activeFile.fileName);
+ if (JSON.stringify(tree, replacer) !== JSON.stringify(json)) {
+ this.raiseError(`verifyNavigationTree failed - expected: ${stringify(json)}, got: ${stringify(tree, replacer)}`);
+ }
+
+ function replacer(key: string, value: any) {
+ // Don't check "spans", and omit falsy values.
+ return key === "spans" ? undefined : (value || undefined);
+ }
+ }
+
public printNavigationItems(searchValue: string) {
const items = this.languageService.getNavigateToItems(searchValue);
const length = items && items.length;
@@ -2309,6 +2365,18 @@ namespace FourSlash {
}
}
+ public verifyCodeFixAvailable(negative: boolean, errorCode?: number) {
+ const fixes = this.getCodeFixes(errorCode);
+
+ if (negative && fixes && fixes.length > 0) {
+ this.raiseError(`verifyCodeFixAvailable failed - expected no fixes, actual: ${fixes.length}`);
+ }
+
+ if (!negative && (fixes === undefined || fixes.length === 0)) {
+ this.raiseError(`verifyCodeFixAvailable failed - expected code fixes, actual: 0`);
+ }
+ }
+
// Get the text of the entire line the caret is currently at
private getCurrentLineContent() {
const text = this.getFileContent(this.activeFile.fileName);
@@ -3096,6 +3164,10 @@ namespace FourSlashInterface {
public isValidBraceCompletionAtPosition(openingBrace: string) {
this.state.verifyBraceCompletionAtPosition(this.negative, openingBrace);
}
+
+ public codeFixAvailable(errorCode?: number) {
+ this.state.verifyCodeFixAvailable(this.negative, errorCode);
+ }
}
export class Verify extends VerifyNegatable {
@@ -3275,10 +3347,18 @@ namespace FourSlashInterface {
this.DocCommentTemplate(/*expectedText*/ undefined, /*expectedOffset*/ undefined, /*empty*/ true);
}
+ public codeFixAtPosition(expectedText: string, errorCode?: number): void {
+ this.state.verifyCodeFixAtPosition(expectedText, errorCode);
+ }
+
public navigationBar(json: any) {
this.state.verifyNavigationBar(json);
}
+ public navigationTree(json: any) {
+ this.state.verifyNavigationTree(json);
+ }
+
public navigationItemsListCount(count: number, searchValue: string, matchKind?: string, fileName?: string) {
this.state.verifyNavigationItemsCount(count, searchValue, matchKind, fileName);
}
diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts
index 8d90166ea84..7cc4c2044ef 100644
--- a/src/harness/harnessLanguageService.ts
+++ b/src/harness/harnessLanguageService.ts
@@ -459,6 +459,10 @@ namespace Harness.LanguageService {
getNavigationBarItems(fileName: string): ts.NavigationBarItem[] {
return unwrapJSONCallResult(this.shim.getNavigationBarItems(fileName));
}
+ getNavigationTree(fileName: string): ts.NavigationTree {
+ return unwrapJSONCallResult(this.shim.getNavigationTree(fileName));
+ }
+
getOutliningSpans(fileName: string): ts.OutliningSpan[] {
return unwrapJSONCallResult(this.shim.getOutliningSpans(fileName));
}
@@ -486,6 +490,9 @@ namespace Harness.LanguageService {
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean {
return unwrapJSONCallResult(this.shim.isValidBraceCompletionAtPosition(fileName, position, openingBrace));
}
+ getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[]): ts.CodeAction[] {
+ throw new Error("Not supported on the shim.");
+ }
getEmitOutput(fileName: string): ts.EmitOutput {
return unwrapJSONCallResult(this.shim.getEmitOutput(fileName));
}
diff --git a/src/harness/unittests/compileOnSave.ts b/src/harness/unittests/compileOnSave.ts
index 24fd47ee0cb..797268000eb 100644
--- a/src/harness/unittests/compileOnSave.ts
+++ b/src/harness/unittests/compileOnSave.ts
@@ -3,6 +3,8 @@
///
namespace ts.projectSystem {
+ import CommandNames = server.CommandNames;
+
function createTestTypingsInstaller(host: server.ServerHost) {
return new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host);
}
@@ -75,7 +77,7 @@ namespace ts.projectSystem {
};
// Change the content of file1 to `export var T: number;export function Foo() { };`
- changeModuleFile1ShapeRequest1 = makeSessionRequest(server.CommandNames.Change, {
+ changeModuleFile1ShapeRequest1 = makeSessionRequest(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 1,
@@ -85,7 +87,7 @@ namespace ts.projectSystem {
});
// Change the content of file1 to `export var T: number;export function Foo() { };`
- changeModuleFile1InternalRequest1 = makeSessionRequest(server.CommandNames.Change, {
+ changeModuleFile1InternalRequest1 = makeSessionRequest(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 1,
@@ -95,7 +97,7 @@ namespace ts.projectSystem {
});
// Change the content of file1 to `export var T: number;export function Foo() { };`
- changeModuleFile1ShapeRequest2 = makeSessionRequest(server.CommandNames.Change, {
+ changeModuleFile1ShapeRequest2 = makeSessionRequest(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 1,
@@ -104,7 +106,7 @@ namespace ts.projectSystem {
insertString: `export var T2: number;`
});
- moduleFile1FileListRequest = makeSessionRequest(server.CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path, projectFileName: configFile.path });
+ moduleFile1FileListRequest = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path, projectFileName: configFile.path });
});
it("should contains only itself if a module file's shape didn't change, and all files referencing it if its shape changed", () => {
@@ -120,7 +122,7 @@ namespace ts.projectSystem {
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]);
// Change the content of file1 to `export var T: number;export function Foo() { console.log('hi'); };`
- const changeFile1InternalRequest = makeSessionRequest(server.CommandNames.Change, {
+ const changeFile1InternalRequest = makeSessionRequest(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 46,
@@ -143,7 +145,7 @@ namespace ts.projectSystem {
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]);
// Change file2 content to `let y = Foo();`
- const removeFile1Consumer1ImportRequest = makeSessionRequest(server.CommandNames.Change, {
+ const removeFile1Consumer1ImportRequest = makeSessionRequest(CommandNames.Change, {
file: file1Consumer1.path,
line: 1,
offset: 1,
@@ -156,7 +158,7 @@ namespace ts.projectSystem {
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer2] }]);
// Add the import statements back to file2
- const addFile2ImportRequest = makeSessionRequest(server.CommandNames.Change, {
+ const addFile2ImportRequest = makeSessionRequest(CommandNames.Change, {
file: file1Consumer1.path,
line: 1,
offset: 1,
@@ -167,7 +169,7 @@ namespace ts.projectSystem {
session.executeCommand(addFile2ImportRequest);
// Change the content of file1 to `export var T2: string;export var T: number;export function Foo() { };`
- const changeModuleFile1ShapeRequest2 = makeSessionRequest(server.CommandNames.Change, {
+ const changeModuleFile1ShapeRequest2 = makeSessionRequest(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 1,
@@ -272,7 +274,7 @@ namespace ts.projectSystem {
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
openFilesForSession([globalFile3], session);
- const changeGlobalFile3ShapeRequest = makeSessionRequest(server.CommandNames.Change, {
+ const changeGlobalFile3ShapeRequest = makeSessionRequest(CommandNames.Change, {
file: globalFile3.path,
line: 1,
offset: 1,
@@ -283,7 +285,7 @@ namespace ts.projectSystem {
// check after file1 shape changes
session.executeCommand(changeGlobalFile3ShapeRequest);
- const globalFile3FileListRequest = makeSessionRequest(server.CommandNames.CompileOnSaveAffectedFileList, { file: globalFile3.path });
+ const globalFile3FileListRequest = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: globalFile3.path });
sendAffectedFileRequestAndCheckResult(session, globalFile3FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2] }]);
});
@@ -316,7 +318,7 @@ namespace ts.projectSystem {
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
openFilesForSession([moduleFile1], session);
- const file1ChangeShapeRequest = makeSessionRequest(server.CommandNames.Change, {
+ const file1ChangeShapeRequest = makeSessionRequest(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 27,
@@ -345,7 +347,7 @@ namespace ts.projectSystem {
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
openFilesForSession([moduleFile1], session);
- const file1ChangeShapeRequest = makeSessionRequest(server.CommandNames.Change, {
+ const file1ChangeShapeRequest = makeSessionRequest(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 27,
@@ -369,7 +371,7 @@ namespace ts.projectSystem {
openFilesForSession([moduleFile1, file1Consumer1], session);
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer1Consumer1] }]);
- const changeFile1Consumer1ShapeRequest = makeSessionRequest(server.CommandNames.Change, {
+ const changeFile1Consumer1ShapeRequest = makeSessionRequest(CommandNames.Change, {
file: file1Consumer1.path,
line: 2,
offset: 1,
@@ -400,7 +402,7 @@ namespace ts.projectSystem {
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
openFilesForSession([file1, file2], session);
- const file1AffectedListRequest = makeSessionRequest(server.CommandNames.CompileOnSaveAffectedFileList, { file: file1.path });
+ const file1AffectedListRequest = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: file1.path });
sendAffectedFileRequestAndCheckResult(session, file1AffectedListRequest, [{ projectFileName: configFile.path, files: [file1, file2] }]);
});
@@ -415,7 +417,7 @@ namespace ts.projectSystem {
const session = createSession(host);
openFilesForSession([file1, file2, file3], session);
- const file1AffectedListRequest = makeSessionRequest(server.CommandNames.CompileOnSaveAffectedFileList, { file: file1.path });
+ const file1AffectedListRequest = makeSessionRequest