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(CommandNames.CompileOnSaveAffectedFileList, { file: file1.path }); sendAffectedFileRequestAndCheckResult(session, file1AffectedListRequest, [ { projectFileName: configFile1.path, files: [file1, file2] }, @@ -437,11 +439,11 @@ namespace ts.projectSystem { host.reloadFS([referenceFile1, configFile]); host.triggerFileWatcherCallback(moduleFile1.path, /*removed*/ true); - const request = makeSessionRequest(server.CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path }); + const request = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path }); sendAffectedFileRequestAndCheckResult(session, request, [ { projectFileName: configFile.path, files: [referenceFile1] } ]); - const requestForMissingFile = makeSessionRequest(server.CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path }); + const requestForMissingFile = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path }); sendAffectedFileRequestAndCheckResult(session, requestForMissingFile, []); }); @@ -456,7 +458,7 @@ namespace ts.projectSystem { const session = createSession(host); openFilesForSession([referenceFile1], session); - const request = makeSessionRequest(server.CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path }); + const request = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path }); sendAffectedFileRequestAndCheckResult(session, request, [ { projectFileName: configFile.path, files: [referenceFile1] } ]); @@ -483,7 +485,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 compileFileRequest = makeSessionRequest(server.CommandNames.CompileOnSaveEmitFile, { file: file1.path, projectFileName: configFile.path }); + const compileFileRequest = makeSessionRequest(CommandNames.CompileOnSaveEmitFile, { file: file1.path, projectFileName: configFile.path }); session.executeCommand(compileFileRequest); const expectedEmittedFileName = "/a/b/f1.js"; diff --git a/src/harness/unittests/convertCompilerOptionsFromJson.ts b/src/harness/unittests/convertCompilerOptionsFromJson.ts index 13f54e369ed..a2174c17e41 100644 --- a/src/harness/unittests/convertCompilerOptionsFromJson.ts +++ b/src/harness/unittests/convertCompilerOptionsFromJson.ts @@ -405,6 +405,7 @@ namespace ts { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, + skipLibCheck: true, module: ModuleKind.CommonJS, target: ScriptTarget.ES5, noImplicitAny: false, @@ -433,6 +434,7 @@ namespace ts { allowJs: false, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, + skipLibCheck: true, module: ModuleKind.CommonJS, target: ScriptTarget.ES5, noImplicitAny: false, @@ -456,7 +458,8 @@ namespace ts { { allowJs: true, maxNodeModuleJsDepth: 2, - allowSyntheticDefaultImports: true + allowSyntheticDefaultImports: true, + skipLibCheck: true }, errors: [{ file: undefined, @@ -477,7 +480,8 @@ namespace ts { { allowJs: true, maxNodeModuleJsDepth: 2, - allowSyntheticDefaultImports: true + allowSyntheticDefaultImports: true, + skipLibCheck: true }, errors: [] } diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 5b934cc4b0b..08e4bac7b2c 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1,8 +1,10 @@ -/// +/// /// namespace ts.projectSystem { import TI = server.typingsInstaller; + import protocol = server.protocol; + import CommandNames = server.CommandNames; const safeList = { path: "/safeList.json", @@ -128,7 +130,7 @@ namespace ts.projectSystem { return combinePaths(getDirectoryPath(libFile.path), "tsc.js"); } - export function toExternalFile(fileName: string): server.protocol.ExternalFile { + export function toExternalFile(fileName: string): protocol.ExternalFile { return { fileName }; } @@ -136,6 +138,19 @@ namespace ts.projectSystem { return map(fileNames, toExternalFile); } + export class TestServerEventManager { + private events: server.ProjectServiceEvent[] = []; + + handler: server.ProjectServiceEventHandler = (event: server.ProjectServiceEvent) => { + this.events.push(event); + } + + checkEventCountOfType(eventType: "context" | "configFileDiag", expectedCount: number) { + const eventsOfType = filter(this.events, e => e.eventName === eventType); + assert.equal(eventsOfType.length, expectedCount, `The actual event counts of type ${eventType} is ${eventsOfType.length}, while expected ${expectedCount}`); + } + } + export interface TestServerHostCreationParameters { useCaseSensitiveFileNames?: boolean; executingFilePath?: string; @@ -159,11 +174,11 @@ namespace ts.projectSystem { return host; } - export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller) { + export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller, projectServiceEventHandler?: server.ProjectServiceEventHandler) { if (typingsInstaller === undefined) { typingsInstaller = new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host); } - return new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false); + return new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler); } export interface CreateProjectServiceParameters { @@ -514,7 +529,7 @@ namespace ts.projectSystem { } export function makeSessionRequest(command: string, args: T) { - const newRequest: server.protocol.Request = { + const newRequest: protocol.Request = { seq: 0, type: "request", command, @@ -525,7 +540,7 @@ namespace ts.projectSystem { export function openFilesForSession(files: FileOrFolder[], session: server.Session) { for (const file of files) { - const request = makeSessionRequest(server.CommandNames.Open, { file: file.path }); + const request = makeSessionRequest(CommandNames.Open, { file: file.path }); session.executeCommand(request); } } @@ -1738,7 +1753,7 @@ namespace ts.projectSystem { }); describe("navigate-to for javascript project", () => { - function containsNavToItem(items: server.protocol.NavtoItem[], itemName: string, itemKind: string) { + function containsNavToItem(items: protocol.NavtoItem[], itemName: string, itemKind: string) { return find(items, item => item.name === itemName && item.kind === itemKind) !== undefined; } @@ -1756,12 +1771,12 @@ namespace ts.projectSystem { openFilesForSession([file1], session); // Try to find some interface type defined in lib.d.ts - const libTypeNavToRequest = makeSessionRequest(server.CommandNames.Navto, { searchValue: "Document", file: file1.path, projectFileName: configFile.path }); - const items: server.protocol.NavtoItem[] = session.executeCommand(libTypeNavToRequest).response; + const libTypeNavToRequest = makeSessionRequest(CommandNames.Navto, { searchValue: "Document", file: file1.path, projectFileName: configFile.path }); + const items: protocol.NavtoItem[] = session.executeCommand(libTypeNavToRequest).response; assert.isFalse(containsNavToItem(items, "Document", "interface"), `Found lib.d.ts symbol in JavaScript project nav to request result.`); - const localFunctionNavToRequst = makeSessionRequest(server.CommandNames.Navto, { searchValue: "foo", file: file1.path, projectFileName: configFile.path }); - const items2: server.protocol.NavtoItem[] = session.executeCommand(localFunctionNavToRequst).response; + const localFunctionNavToRequst = makeSessionRequest(CommandNames.Navto, { searchValue: "foo", file: file1.path, projectFileName: configFile.path }); + const items2: protocol.NavtoItem[] = session.executeCommand(localFunctionNavToRequst).response; assert.isTrue(containsNavToItem(items2, "foo", "function"), `Cannot find function symbol "foo".`); }); }); @@ -1898,6 +1913,64 @@ namespace ts.projectSystem { projectService.closeExternalProject(projectName); projectService.checkNumberOfProjects({}); }); + + it("correctly handles changes in lib section of config file", () => { + const libES5 = { + path: "/compiler/lib.es5.d.ts", + content: "declare const eval: any" + }; + const libES2015Promise = { + path: "/compiler/lib.es2015.promise.d.ts", + content: "declare class Promise {}" + }; + const app = { + path: "/src/app.ts", + content: "var x: Promise;" + }; + const config1 = { + path: "/src/tsconfig.json", + content: JSON.stringify( + { + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "noImplicitAny": true, + "sourceMap": false, + "lib": [ + "es5" + ] + } + }) + }; + const config2 = { + path: config1.path, + content: JSON.stringify( + { + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "noImplicitAny": true, + "sourceMap": false, + "lib": [ + "es5", + "es2015.promise" + ] + } + }) + }; + const host = createServerHost([libES5, libES2015Promise, app, config1], { executingFilePath: "/compiler/tsc.js" }); + const projectService = createProjectService(host); + projectService.openClientFile(app.path); + + projectService.checkNumberOfProjects({ configuredProjects: 1 }); + checkProjectActualFiles(projectService.configuredProjects[0], [libES5.path, app.path]); + + host.reloadFS([libES5, libES2015Promise, app, config2]); + host.triggerFileWatcherCallback(config1.path); + + projectService.checkNumberOfProjects({ configuredProjects: 1 }); + checkProjectActualFiles(projectService.configuredProjects[0], [libES5.path, libES2015Promise.path, app.path]); + }); }); describe("prefer typings to js", () => { @@ -2026,7 +2099,7 @@ namespace ts.projectSystem { const projectFileName = "externalProject"; const host = createServerHost([f]); const projectService = createProjectService(host); - // create a project + // create a project projectService.openExternalProject({ projectFileName, rootFiles: [toExternalFile(f.path)], options: {} }); projectService.checkNumberOfProjects({ externalProjects: 1 }); @@ -2063,4 +2136,255 @@ namespace ts.projectSystem { projectService.inferredProjects[0].getLanguageService().getProgram(); }); }); + + describe("rename a module file and rename back", () => { + it("should restore the states for inferred projects", () => { + const moduleFile = { + path: "/a/b/moduleFile.ts", + content: "export function bar() { };" + }; + const file1 = { + path: "/a/b/file1.ts", + content: "import * as T from './moduleFile'; T.bar();" + }; + const host = createServerHost([moduleFile, file1]); + const session = createSession(host); + + openFilesForSession([file1], session); + const getErrRequest = makeSessionRequest( + server.CommandNames.SemanticDiagnosticsSync, + { file: file1.path } + ); + let diags = session.executeCommand(getErrRequest).response; + assert.equal(diags.length, 0); + + const moduleFileOldPath = moduleFile.path; + const moduleFileNewPath = "/a/b/moduleFile1.ts"; + moduleFile.path = moduleFileNewPath; + host.reloadFS([moduleFile, file1]); + host.triggerFileWatcherCallback(moduleFileOldPath); + host.triggerDirectoryWatcherCallback("/a/b", moduleFile.path); + host.runQueuedTimeoutCallbacks(); + diags = session.executeCommand(getErrRequest).response; + assert.equal(diags.length, 1); + + moduleFile.path = moduleFileOldPath; + host.reloadFS([moduleFile, file1]); + host.triggerFileWatcherCallback(moduleFileNewPath); + host.triggerDirectoryWatcherCallback("/a/b", moduleFile.path); + host.runQueuedTimeoutCallbacks(); + + // Make a change to trigger the program rebuild + const changeRequest = makeSessionRequest( + server.CommandNames.Change, + { file: file1.path, line: 1, offset: 44, endLine: 1, endOffset: 44, insertString: "\n" } + ); + session.executeCommand(changeRequest); + host.runQueuedTimeoutCallbacks(); + + diags = session.executeCommand(getErrRequest).response; + assert.equal(diags.length, 0); + }); + + it("should restore the states for configured projects", () => { + const moduleFile = { + path: "/a/b/moduleFile.ts", + content: "export function bar() { };" + }; + const file1 = { + path: "/a/b/file1.ts", + content: "import * as T from './moduleFile'; T.bar();" + }; + const configFile = { + path: "/a/b/tsconfig.json", + content: `{}` + }; + const host = createServerHost([moduleFile, file1, configFile]); + const session = createSession(host); + + openFilesForSession([file1], session); + const getErrRequest = makeSessionRequest( + server.CommandNames.SemanticDiagnosticsSync, + { file: file1.path } + ); + let diags = session.executeCommand(getErrRequest).response; + assert.equal(diags.length, 0); + + const moduleFileOldPath = moduleFile.path; + const moduleFileNewPath = "/a/b/moduleFile1.ts"; + moduleFile.path = moduleFileNewPath; + host.reloadFS([moduleFile, file1, configFile]); + host.triggerFileWatcherCallback(moduleFileOldPath); + host.triggerDirectoryWatcherCallback("/a/b", moduleFile.path); + host.runQueuedTimeoutCallbacks(); + diags = session.executeCommand(getErrRequest).response; + assert.equal(diags.length, 1); + + moduleFile.path = moduleFileOldPath; + host.reloadFS([moduleFile, file1, configFile]); + host.triggerFileWatcherCallback(moduleFileNewPath); + host.triggerDirectoryWatcherCallback("/a/b", moduleFile.path); + host.runQueuedTimeoutCallbacks(); + diags = session.executeCommand(getErrRequest).response; + assert.equal(diags.length, 0); + }); + + }); + + describe("add the missing module file for inferred project", () => { + it("should remove the `module not found` error", () => { + const moduleFile = { + path: "/a/b/moduleFile.ts", + content: "export function bar() { };" + }; + const file1 = { + path: "/a/b/file1.ts", + content: "import * as T from './moduleFile'; T.bar();" + }; + const host = createServerHost([file1]); + const session = createSession(host); + openFilesForSession([file1], session); + const getErrRequest = makeSessionRequest( + server.CommandNames.SemanticDiagnosticsSync, + { file: file1.path } + ); + let diags = session.executeCommand(getErrRequest).response; + assert.equal(diags.length, 1); + + host.reloadFS([file1, moduleFile]); + host.triggerDirectoryWatcherCallback(getDirectoryPath(file1.path), moduleFile.path); + host.runQueuedTimeoutCallbacks(); + + // Make a change to trigger the program rebuild + const changeRequest = makeSessionRequest( + server.CommandNames.Change, + { file: file1.path, line: 1, offset: 44, endLine: 1, endOffset: 44, insertString: "\n" } + ); + session.executeCommand(changeRequest); + + // Recheck + diags = session.executeCommand(getErrRequest).response; + assert.equal(diags.length, 0); + }); + }); + + describe("Configure file diagnostics events", () => { + + it("are generated when the config file has errors", () => { + const serverEventManager = new TestServerEventManager(); + const file = { + path: "/a/b/app.ts", + content: "let x = 10" + }; + const configFile = { + path: "/a/b/tsconfig.json", + content: `{ + "compilerOptions": { + "foo": "bar", + "allowJS": true + } + }` + }; + + const host = createServerHost([file, configFile]); + const session = createSession(host, /*typingsInstaller*/ undefined, serverEventManager.handler); + openFilesForSession([file], session); + serverEventManager.checkEventCountOfType("configFileDiag", 1); + }); + + it("are generated when the config file doesn't have errors", () => { + const serverEventManager = new TestServerEventManager(); + const file = { + path: "/a/b/app.ts", + content: "let x = 10" + }; + const configFile = { + path: "/a/b/tsconfig.json", + content: `{ + "compilerOptions": {} + }` + }; + + const host = createServerHost([file, configFile]); + const session = createSession(host, /*typingsInstaller*/ undefined, serverEventManager.handler); + openFilesForSession([file], session); + serverEventManager.checkEventCountOfType("configFileDiag", 1); + }); + }); + + describe("skipLibCheck", () => { + it("should be turned on for js-only inferred projects", () => { + const file1 = { + path: "/a/b/file1.js", + content: ` + /// + var x = 1;` + }; + const file2 = { + path: "/a/b/file2.d.ts", + content: ` + interface T { + name: string; + }; + interface T { + name: number; + };` + }; + const host = createServerHost([file1, file2]); + const session = createSession(host); + openFilesForSession([file1, file2], session); + + const file2GetErrRequest = makeSessionRequest( + CommandNames.SemanticDiagnosticsSync, + { file: file2.path } + ); + let errorResult = session.executeCommand(file2GetErrRequest).response; + assert.isTrue(errorResult.length === 0); + + const closeFileRequest = makeSessionRequest(CommandNames.Close, { file: file1.path }); + session.executeCommand(closeFileRequest); + errorResult = session.executeCommand(file2GetErrRequest).response; + assert.isTrue(errorResult.length !== 0); + + openFilesForSession([file1], session); + errorResult = session.executeCommand(file2GetErrRequest).response; + assert.isTrue(errorResult.length === 0); + }); + + it("should be turned on for js-only external projects", () => { + const jsFile = { + path: "/a/b/file1.js", + content: "let x =1;" + }; + const dTsFile = { + path: "/a/b/file2.d.ts", + content: ` + interface T { + name: string; + }; + interface T { + name: number; + };` + }; + const host = createServerHost([jsFile, dTsFile]); + const session = createSession(host); + + const openExternalProjectRequest = makeSessionRequest( + CommandNames.OpenExternalProject, + { + projectFileName: "project1", + rootFiles: toExternalFiles([jsFile.path, dTsFile.path]), + options: {} + } + ); + session.executeCommand(openExternalProjectRequest); + + const dTsFileGetErrRequest = makeSessionRequest( + CommandNames.SemanticDiagnosticsSync, + { file: dTsFile.path } + ); + const errorResult = session.executeCommand(dTsFileGetErrRequest).response; + assert.isTrue(errorResult.length === 0); + }); + }); } \ No newline at end of file diff --git a/src/server/builder.ts b/src/server/builder.ts index 639c41d2b63..475202a0aab 100644 --- a/src/server/builder.ts +++ b/src/server/builder.ts @@ -1,6 +1,5 @@ /// /// -/// /// /// diff --git a/src/server/client.ts b/src/server/client.ts index 688408dfb88..b0bc2c5dac0 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -1,7 +1,6 @@ /// namespace ts.server { - export interface SessionClientHost extends LanguageServiceHost { writeMessage(message: string): void; } @@ -425,11 +424,35 @@ namespace ts.server { } getSyntacticDiagnostics(fileName: string): Diagnostic[] { - throw new Error("Not Implemented Yet."); + const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file: fileName }; + + const request = this.processRequest(CommandNames.SyntacticDiagnosticsSync, args); + const response = this.processResponse(request); + + return (response.body).map(entry => this.convertDiagnostic(entry, fileName)); } getSemanticDiagnostics(fileName: string): Diagnostic[] { - throw new Error("Not Implemented Yet."); + const args: protocol.SemanticDiagnosticsSyncRequestArgs = { file: fileName }; + + const request = this.processRequest(CommandNames.SemanticDiagnosticsSync, args); + const response = this.processResponse(request); + + return (response.body).map(entry => this.convertDiagnostic(entry, fileName)); + } + + convertDiagnostic(entry: protocol.Diagnostic, fileName: string): Diagnostic { + const start = this.lineOffsetToPosition(fileName, entry.start); + const end = this.lineOffsetToPosition(fileName, entry.end); + + return { + file: undefined, + start: start, + length: end - start, + messageText: entry.text, + category: undefined, + code: entry.code + }; } getCompilerOptionsDiagnostics(): Diagnostic[] { @@ -488,7 +511,7 @@ namespace ts.server { return this.lastRenameEntry.locations; } - decodeNavigationBarItems(items: protocol.NavigationBarItem[], fileName: string, lineMap: number[]): NavigationBarItem[] { + private decodeNavigationBarItems(items: protocol.NavigationBarItem[], fileName: string, lineMap: number[]): NavigationBarItem[] { if (!items) { return []; } @@ -497,10 +520,7 @@ namespace ts.server { text: item.text, kind: item.kind, kindModifiers: item.kindModifiers || "", - spans: item.spans.map(span => - createTextSpanFromBounds( - this.lineOffsetToPosition(fileName, span.start, lineMap), - this.lineOffsetToPosition(fileName, span.end, lineMap))), + spans: item.spans.map(span => this.decodeSpan(span, fileName, lineMap)), childItems: this.decodeNavigationBarItems(item.childItems, fileName, lineMap), indent: item.indent, bolded: false, @@ -509,17 +529,37 @@ namespace ts.server { } getNavigationBarItems(fileName: string): NavigationBarItem[] { - const args: protocol.FileRequestArgs = { - file: fileName - }; - - const request = this.processRequest(CommandNames.NavBar, args); + const request = this.processRequest(CommandNames.NavBar, { file: fileName }); const response = this.processResponse(request); const lineMap = this.getLineMap(fileName); return this.decodeNavigationBarItems(response.body, fileName, lineMap); } + private decodeNavigationTree(tree: protocol.NavigationTree, fileName: string, lineMap: number[]): NavigationTree { + return { + text: tree.text, + kind: tree.kind, + kindModifiers: tree.kindModifiers, + spans: tree.spans.map(span => this.decodeSpan(span, fileName, lineMap)), + childItems: map(tree.childItems, item => this.decodeNavigationTree(item, fileName, lineMap)) + }; + } + + getNavigationTree(fileName: string): NavigationTree { + const request = this.processRequest(CommandNames.NavTree, { file: fileName }); + const response = this.processResponse(request); + + const lineMap = this.getLineMap(fileName); + return this.decodeNavigationTree(response.body, fileName, lineMap); + } + + private decodeSpan(span: protocol.TextSpan, fileName: string, lineMap: number[]) { + return createTextSpanFromBounds( + this.lineOffsetToPosition(fileName, span.start, lineMap), + this.lineOffsetToPosition(fileName, span.end, lineMap)); + } + getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan { throw new Error("Not Implemented Yet."); } @@ -630,6 +670,48 @@ namespace ts.server { throw new Error("Not Implemented Yet."); } + getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[]): CodeAction[] { + const startLineOffset = this.positionToOneBasedLineOffset(fileName, start); + const endLineOffset = this.positionToOneBasedLineOffset(fileName, end); + + const args: protocol.CodeFixRequestArgs = { + file: fileName, + startLine: startLineOffset.line, + startOffset: startLineOffset.offset, + endLine: endLineOffset.line, + endOffset: endLineOffset.offset, + errorCodes: errorCodes, + }; + + const request = this.processRequest(CommandNames.GetCodeFixes, args); + const response = this.processResponse(request); + + return response.body.map(entry => this.convertCodeActions(entry, fileName)); + } + + convertCodeActions(entry: protocol.CodeAction, fileName: string): CodeAction { + return { + description: entry.description, + changes: entry.changes.map(change => ({ + fileName: change.fileName, + textChanges: change.textChanges.map(textChange => this.convertTextChangeToCodeEdit(textChange, fileName)) + })) + }; + } + + convertTextChangeToCodeEdit(change: protocol.CodeEdit, fileName: string): ts.TextChange { + const start = this.lineOffsetToPosition(fileName, change.start); + const end = this.lineOffsetToPosition(fileName, change.end); + + return { + span: { + start: start, + length: end - start + }, + newText: change.newText ? change.newText : "" + }; + } + getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[] { const lineOffset = this.positionToOneBasedLineOffset(fileName, position); const args: protocol.FileLocationRequestArgs = { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 51310c90a6b..1a331c09320 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1,6 +1,5 @@ /// /// -/// /// /// /// @@ -180,6 +179,8 @@ namespace ts.server { private toCanonicalFileName: (f: string) => string; + public lastDeletedFile: ScriptInfo; + constructor(public readonly host: ServerHost, public readonly logger: Logger, public readonly cancellationToken: HostCancellationToken, @@ -272,7 +273,7 @@ namespace ts.server { else { projectsToUpdate = []; for (const f of this.changedFiles) { - projectsToUpdate = projectsToUpdate.concat(f.containingProjects); + projectsToUpdate = projectsToUpdate.concat(f.containingProjects); } } this.updateProjectGraphs(projectsToUpdate); @@ -342,6 +343,7 @@ namespace ts.server { if (!info.isOpen) { this.filenameToScriptInfo.remove(info.path); + this.lastDeletedFile = info; // capture list of projects since detachAllProjects will wipe out original list const containingProjects = info.containingProjects.slice(); @@ -350,6 +352,7 @@ namespace ts.server { // update projects to make sure that set of referenced files is correct this.updateProjectGraphs(containingProjects); + this.lastDeletedFile = undefined; if (!this.eventHandler) { return; @@ -755,12 +758,14 @@ namespace ts.server { } private reportConfigFileDiagnostics(configFileName: string, diagnostics: Diagnostic[], triggerFile?: string) { - if (diagnostics && diagnostics.length > 0) { - this.eventHandler({ - eventName: "configFileDiag", - data: { configFileName, diagnostics, triggerFile } - }); + if (!this.eventHandler) { + return; } + + this.eventHandler({ + eventName: "configFileDiag", + data: { configFileName, diagnostics: diagnostics || [], triggerFile } + }); } private createAndAddConfiguredProject(configFileName: NormalizedPath, projectOptions: ProjectOptions, configFileErrors: Diagnostic[], clientFileName?: string) { diff --git a/src/server/lsHost.ts b/src/server/lsHost.ts index 5b33770ce28..b36f73a19c5 100644 --- a/src/server/lsHost.ts +++ b/src/server/lsHost.ts @@ -52,7 +52,7 @@ namespace ts.server { }; } - private resolveNamesWithLocalCache( + private resolveNamesWithLocalCache( names: string[], containingFile: string, cache: ts.FileMap>, @@ -65,6 +65,7 @@ namespace ts.server { const newResolutions: Map = createMap(); const resolvedModules: R[] = []; const compilerOptions = this.getCompilationSettings(); + const lastDeletedFileName = this.project.projectService.lastDeletedFile && this.project.projectService.lastDeletedFile.fileName; for (const name of names) { // check if this is a duplicate entry in the list @@ -94,8 +95,11 @@ namespace ts.server { return false; } - if (getResult(resolution)) { - // TODO: consider checking failedLookupLocations + const result = getResult(resolution); + if (result) { + if (result.resolvedFileName && result.resolvedFileName === lastDeletedFileName) { + return false; + } return true; } @@ -171,12 +175,16 @@ namespace ts.server { return this.host.fileExists(path); } + readFile(fileName: string): string { + return this.host.readFile(fileName); + } + directoryExists(path: string): boolean { return this.host.directoryExists(path); } - readFile(fileName: string): string { - return this.host.readFile(fileName); + readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[]): string[] { + return this.host.readDirectory(path, extensions, exclude, include); } getDirectories(path: string): string[] { diff --git a/src/server/project.ts b/src/server/project.ts index b59efb03cfd..a355d75f942 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -20,16 +20,42 @@ namespace ts.server { } } - function isJsOrDtsFile(info: ScriptInfo) { - return info.scriptKind === ScriptKind.JS || info.scriptKind == ScriptKind.JSX || fileExtensionIs(info.fileName, ".d.ts"); + function countEachFileTypes(infos: ScriptInfo[]): { js: number, jsx: number, ts: number, tsx: number, dts: number } { + const result = { js: 0, jsx: 0, ts: 0, tsx: 0, dts: 0 }; + for (const info of infos) { + switch (info.scriptKind) { + case ScriptKind.JS: + result.js += 1; + break; + case ScriptKind.JSX: + result.jsx += 1; + break; + case ScriptKind.TS: + fileExtensionIs(info.fileName, ".d.ts") + ? result.dts += 1 + : result.ts += 1; + break; + case ScriptKind.TSX: + result.tsx += 1; + break; + } + } + return result; + } + + function hasOneOrMoreJsAndNoTsFiles(project: Project) { + const counts = countEachFileTypes(project.getScriptInfos()); + return counts.js > 0 && counts.ts === 0 && counts.tsx === 0; } export function allRootFilesAreJsOrDts(project: Project): boolean { - return project.getRootScriptInfos().every(isJsOrDtsFile); + const counts = countEachFileTypes(project.getRootScriptInfos()); + return counts.ts === 0 && counts.tsx === 0; } export function allFilesAreJsOrDts(project: Project): boolean { - return project.getScriptInfos().every(isJsOrDtsFile); + const counts = countEachFileTypes(project.getScriptInfos()); + return counts.ts === 0 && counts.tsx === 0; } export interface ProjectFilesWithTSDiagnostics extends protocol.ProjectFiles { @@ -71,11 +97,16 @@ namespace ts.server { public typesVersion = 0; - public isJsOnlyProject() { + public isNonTsProject() { this.updateGraph(); return allFilesAreJsOrDts(this); } + public isJsOnlyProject() { + this.updateGraph(); + return hasOneOrMoreJsAndNoTsFiles(this); + } + constructor( readonly projectKind: ProjectKind, readonly projectService: ProjectService, diff --git a/src/server/protocol.d.ts b/src/server/protocol.ts similarity index 63% rename from src/server/protocol.d.ts rename to src/server/protocol.ts index f0dfe4eb130..80623f05aec 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.ts @@ -1,7 +1,102 @@ -/** +/** * Declaration module describing the TypeScript Server protocol */ -declare namespace ts.server.protocol { +namespace ts.server.protocol { + export namespace CommandTypes { + export type Brace = "brace"; + /* @internal */ + export type BraceFull = "brace-full"; + export type BraceCompletion = "braceCompletion"; + export type Change = "change"; + export type Close = "close"; + export type Completions = "completions"; + /* @internal */ + export type CompletionsFull = "completions-full"; + export type CompletionDetails = "completionEntryDetails"; + export type CompileOnSaveAffectedFileList = "compileOnSaveAffectedFileList"; + export type CompileOnSaveEmitFile = "compileOnSaveEmitFile"; + export type Configure = "configure"; + export type Definition = "definition"; + /* @internal */ + export type DefinitionFull = "definition-full"; + export type Implementation = "implementation"; + /* @internal */ + export type ImplementationFull = "implementation-full"; + export type Exit = "exit"; + export type Format = "format"; + export type Formatonkey = "formatonkey"; + /* @internal */ + export type FormatFull = "format-full"; + /* @internal */ + export type FormatonkeyFull = "formatonkey-full"; + /* @internal */ + export type FormatRangeFull = "formatRange-full"; + export type Geterr = "geterr"; + export type GeterrForProject = "geterrForProject"; + export type SemanticDiagnosticsSync = "semanticDiagnosticsSync"; + export type SyntacticDiagnosticsSync = "syntacticDiagnosticsSync"; + export type NavBar = "navbar"; + /* @internal */ + export type NavBarFull = "navbar-full"; + export type Navto = "navto"; + /* @internal */ + export type NavtoFull = "navto-full"; + export type NavTree = "navtree"; + export type NavTreeFull = "navtree-full"; + export type Occurrences = "occurrences"; + export type DocumentHighlights = "documentHighlights"; + /* @internal */ + export type DocumentHighlightsFull = "documentHighlights-full"; + export type Open = "open"; + export type Quickinfo = "quickinfo"; + /* @internal */ + export type QuickinfoFull = "quickinfo-full"; + export type References = "references"; + /* @internal */ + export type ReferencesFull = "references-full"; + export type Reload = "reload"; + export type Rename = "rename"; + /* @internal */ + export type RenameInfoFull = "rename-full"; + /* @internal */ + export type RenameLocationsFull = "renameLocations-full"; + export type Saveto = "saveto"; + export type SignatureHelp = "signatureHelp"; + /* @internal */ + export type SignatureHelpFull = "signatureHelp-full"; + export type TypeDefinition = "typeDefinition"; + export type ProjectInfo = "projectInfo"; + export type ReloadProjects = "reloadProjects"; + export type Unknown = "unknown"; + export type OpenExternalProject = "openExternalProject"; + export type OpenExternalProjects = "openExternalProjects"; + export type CloseExternalProject = "closeExternalProject"; + /* @internal */ + export type SynchronizeProjectList = "synchronizeProjectList"; + /* @internal */ + export type ApplyChangedToOpenFiles = "applyChangedToOpenFiles"; + /* @internal */ + export type EncodedSemanticClassificationsFull = "encodedSemanticClassifications-full"; + /* @internal */ + export type Cleanup = "cleanup"; + /* @internal */ + export type OutliningSpans = "outliningSpans"; + export type TodoComments = "todoComments"; + export type Indentation = "indentation"; + export type DocCommentTemplate = "docCommentTemplate"; + /* @internal */ + export type CompilerOptionsDiagnosticsFull = "compilerOptionsDiagnostics-full"; + /* @internal */ + export type NameOrDottedNameSpan = "nameOrDottedNameSpan"; + /* @internal */ + export type BreakpointStatement = "breakpointStatement"; + export type CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects"; + export type GetCodeFixes = "getCodeFixes"; + /* @internal */ + export type GetCodeFixesFull = "getCodeFixes-full"; + export type GetSupportedCodeFixes = "getSupportedCodeFixes"; + } + /** * A TypeScript Server message */ @@ -36,6 +131,7 @@ declare namespace ts.server.protocol { * Request to reload the project structure for all the opened files */ export interface ReloadProjectsRequest extends Message { + command: CommandTypes.ReloadProjects; } /** @@ -98,19 +194,98 @@ declare namespace ts.server.protocol { projectFileName?: string; } + /** + * Requests a JS Doc comment template for a given position + */ + export interface DocCommentTemplateRequest extends FileLocationRequest { + command: CommandTypes.DocCommentTemplate; + } + + /** + * Response to DocCommentTemplateRequest + */ + export interface DocCommandTemplateResponse extends Response { + body?: TextInsertion; + } + + /** + * A request to get TODO comments from the file + */ export interface TodoCommentRequest extends FileRequest { + command: CommandTypes.TodoComments; arguments: TodoCommentRequestArgs; } + /** + * Arguments for TodoCommentRequest request. + */ export interface TodoCommentRequestArgs extends FileRequestArgs { + /** + * Array of target TodoCommentDescriptors that describes TODO comments to be found + */ descriptors: TodoCommentDescriptor[]; } + /** + * Response for TodoCommentRequest request. + */ + export interface TodoCommentsResponse extends Response { + body?: TodoComment[]; + } + + /** + * Request to obtain outlining spans in file. + */ + /* @internal */ + export interface OutliningSpansRequest extends FileRequest { + command: CommandTypes.OutliningSpans; + } + + /** + * Response to OutliningSpansRequest request. + */ + /* @internal */ + export interface OutliningSpansResponse extends Response { + body?: OutliningSpan[]; + } + + /** + * A request to get indentation for a location in file + */ export interface IndentationRequest extends FileLocationRequest { + command: CommandTypes.Indentation; arguments: IndentationRequestArgs; } + /** + * Response for IndentationRequest request. + */ + export interface IndentationResponse extends Response { + body?: IndentationResult; + } + + /** + * Indentation result representing where indentation should be placed + */ + export interface IndentationResult { + /** + * The base position in the document that the indent should be relative to + */ + position: number; + /** + * The number of columns the indent should be at relative to the position's column. + */ + indentation: number; + } + + /** + * Arguments for IndentationRequest request. + */ export interface IndentationRequestArgs extends FileLocationRequestArgs { + /** + * An optional set of settings to be used when computing indentation. + * If argument is omitted - then it will use settings for file that were previously set via 'configure' request or global settings. + */ options?: EditorSettings; } @@ -125,17 +300,27 @@ declare namespace ts.server.protocol { } /** - * A request to get the project information of the current file + * A request to get the project information of the current file. */ export interface ProjectInfoRequest extends Request { + command: CommandTypes.ProjectInfo; arguments: ProjectInfoRequestArgs; } - export interface ProjectRequest extends Request { - arguments: ProjectRequestArgs; + /** + * A request to retrieve compiler options diagnostics for a project + */ + export interface CompilerOptionsDiagnosticsRequest extends Request { + arguments: CompilerOptionsDiagnosticsRequestArgs; } - export interface ProjectRequestArgs { + /** + * Arguments for CompilerOptionsDiagnosticsRequest request. + */ + export interface CompilerOptionsDiagnosticsRequestArgs { + /** + * Name of the project to retrieve compiler options diagnostics. + */ projectFileName: string; } @@ -158,6 +343,11 @@ declare namespace ts.server.protocol { languageServiceDisabled?: boolean; } + /** + * Represents diagnostic info that includes location of diagnostic in two forms + * - start position and length of the error span + * - startLocation and endLocation - a pair of Location objects that store start/end line and offset of the error span. + */ export interface DiagnosticWithLinePosition { message: string; start: number; @@ -190,17 +380,75 @@ declare namespace ts.server.protocol { /** * The line number for the request (1-based). */ - line?: number; + line: number; /** * The character offset (on the line) for the request (1-based). */ - offset?: number; + offset: number; + + /** + * Position (can be specified instead of line/offset pair) + */ + /* @internal */ + position?: number; + } + + /** + * Request for the available codefixes at a specific position. + */ + export interface CodeFixRequest extends Request { + command: CommandTypes.GetCodeFixes; + arguments: CodeFixRequestArgs; + } + + /** + * Instances of this interface specify errorcodes on a specific location in a sourcefile. + */ + export interface CodeFixRequestArgs extends FileRequestArgs { + /** + * The line number for the request (1-based). + */ + startLine: number; + + /** + * The character offset (on the line) for the request (1-based). + */ + startOffset: number; /** * Position (can be specified instead of line/offset pair) */ - position?: number; + /* @internal */ + startPosition?: number; + + /** + * The line number for the request (1-based). + */ + endLine: number; + + /** + * The character offset (on the line) for the request (1-based). + */ + endOffset: number; + + /** + * Position (can be specified instead of line/offset pair) + */ + /* @internal */ + endPosition?: number; + + /** + * Errorcodes we want to get the fixes for. + */ + errorCodes?: number[]; + } + + /** + * Response for GetCodeFixes request. + */ + export interface GetCodeFixesResponse extends Response { + body?: CodeAction[]; } /** @@ -210,13 +458,43 @@ declare namespace ts.server.protocol { arguments: FileLocationRequestArgs; } - export interface FileSpanRequestArgs extends FileRequestArgs { - start: number; - length: number; + /** + * A request to get codes of supported code fixes. + */ + export interface GetSupportedCodeFixesRequest extends Request { + command: CommandTypes.GetSupportedCodeFixes; } - export interface FileSpanRequest extends FileRequest { - arguments: FileSpanRequestArgs; + /** + * A response for GetSupportedCodeFixesRequest request. + */ + export interface GetSupportedCodeFixesResponse extends Response { + /** + * List of error codes supported by the server. + */ + body?: string[]; + } + + /** + * A request to get encoded semantic classifications for a span in the file + */ + /** @internal */ + export interface EncodedSemanticClassificationsRequest extends FileRequest { + arguments: EncodedSemanticClassificationsRequestArgs; + } + + /** + * Arguments for EncodedSemanticClassificationsRequest request. + */ + export interface EncodedSemanticClassificationsRequestArgs extends FileRequestArgs { + /** + * Start position of the span. + */ + start: number; + /** + * Length of the span. + */ + length: number; } /** @@ -236,6 +514,7 @@ declare namespace ts.server.protocol { * define the symbol found in file at location line, col. */ export interface DefinitionRequest extends FileLocationRequest { + command: CommandTypes.Definition; } /** @@ -244,6 +523,7 @@ declare namespace ts.server.protocol { * define the type for the symbol found in file at location line, col. */ export interface TypeDefinitionRequest extends FileLocationRequest { + command: CommandTypes.TypeDefinition; } /** @@ -252,6 +532,7 @@ declare namespace ts.server.protocol { * implement the symbol found in file at location line, col. */ export interface ImplementationRequest extends FileLocationRequest { + command: CommandTypes.Implementation; } /** @@ -308,11 +589,21 @@ declare namespace ts.server.protocol { body?: FileSpan[]; } + /** + * Request to get brace completion for a location in the file. + */ export interface BraceCompletionRequest extends FileLocationRequest { + command: CommandTypes.BraceCompletion; arguments: BraceCompletionRequestArgs; } + /** + * Argument for BraceCompletionRequest request. + */ export interface BraceCompletionRequestArgs extends FileLocationRequestArgs { + /** + * Kind of opening brace + */ openingBrace: string; } @@ -322,6 +613,7 @@ declare namespace ts.server.protocol { * in the file at a given line and column. */ export interface OccurrencesRequest extends FileLocationRequest { + command: CommandTypes.Occurrences; } export interface OccurrencesResponseItem extends FileSpan { @@ -341,13 +633,21 @@ declare namespace ts.server.protocol { * in the file at a given line and column. */ export interface DocumentHighlightsRequest extends FileLocationRequest { + command: CommandTypes.DocumentHighlights; arguments: DocumentHighlightsRequestArgs; } + /** + * Span augmented with extra information that denotes the kind of the highlighting to be used for span. + * Kind is taken from HighlightSpanKind type. + */ export interface HighlightSpan extends TextSpan { kind: string; } + /** + * Represents a set of highligh spans for a give name + */ export interface DocumentHighlightsItem { /** * File containing highlight spans. @@ -360,6 +660,9 @@ declare namespace ts.server.protocol { highlightSpans: HighlightSpan[]; } + /** + * Response for a DocumentHighlightsRequest request. + */ export interface DocumentHighlightsResponse extends Response { body?: DocumentHighlightsItem[]; } @@ -370,6 +673,7 @@ declare namespace ts.server.protocol { * reference the symbol found in file at location line, col. */ export interface ReferencesRequest extends FileLocationRequest { + command: CommandTypes.References; } export interface ReferencesResponseItem extends FileSpan { @@ -423,12 +727,20 @@ declare namespace ts.server.protocol { body?: ReferencesResponseBody; } + /** + * Argument for RenameRequest request. + */ export interface RenameRequestArgs extends FileLocationRequestArgs { + /** + * Should text at specified location be found/changed in comments? + */ findInComments?: boolean; + /** + * Should text at specified location be found/changed in strings? + */ findInStrings?: boolean; } - /** * Rename request; value of command field is "rename". Return * response giving the file locations that reference the symbol @@ -436,6 +748,7 @@ declare namespace ts.server.protocol { * name of the symbol so that client can print it unambiguously. */ export interface RenameRequest extends FileLocationRequest { + command: CommandTypes.Rename; arguments: RenameRequestArgs; } @@ -503,17 +816,53 @@ declare namespace ts.server.protocol { body?: RenameResponseBody; } + /** + * Represents a file in external project. + * External project is project whose set of files, compilation options and open\close state + * is maintained by the client (i.e. if all this data come from .csproj file in Visual Studio). + * External project will exist even if all files in it are closed and should be closed explicity. + * If external project includes one or more tsconfig.json/jsconfig.json files then tsserver will + * create configured project for every config file but will maintain a link that these projects were created + * as a result of opening external project so they should be removed once external project is closed. + */ export interface ExternalFile { + /** + * Name of file file + */ fileName: string; + /** + * Script kind of the file + */ scriptKind?: ScriptKind; + /** + * Whether file has mixed content (i.e. .cshtml file that combines html markup with C#/JavaScript) + */ hasMixedContent?: boolean; + /** + * Content of the file + */ content?: string; } + /** + * Represent an external project + */ export interface ExternalProject { + /** + * Project name + */ projectFileName: string; + /** + * List of root files in project + */ rootFiles: ExternalFile[]; + /** + * Compiler options for the project + */ options: ExternalProjectCompilerOptions; + /** + * Explicitly specified typing options for the project + */ typingOptions?: TypingOptions; } @@ -522,18 +871,45 @@ declare namespace ts.server.protocol { * compiler settings. */ export interface ExternalProjectCompilerOptions extends CompilerOptions { + /** + * If compile on save is enabled for the project + */ compileOnSave?: boolean; } + /** + * Contains information about current project version + */ export interface ProjectVersionInfo { + /** + * Project name + */ projectName: string; + /** + * true if project is inferred or false if project is external or configured + */ isInferred: boolean; + /** + * Project version + */ version: number; + /** + * Current set of compiler options for project + */ options: CompilerOptions; } + /** + * Represents a set of changes that happen in project + */ export interface ProjectChanges { + /** + * List of added files + */ added: string[]; + /** + * List of removed files + */ removed: string[]; } @@ -545,73 +921,45 @@ declare namespace ts.server.protocol { * otherwise - assume that nothing is changed */ export interface ProjectFiles { + /** + * Information abount project verison + */ info?: ProjectVersionInfo; + /** + * List of files in project (might be omitted if current state of project can be computed using only information from 'changes') + */ files?: string[]; + /** + * Set of changes in project (omitted if the entire set of files in project should be replaced) + */ changes?: ProjectChanges; } + /** + * Combines project information with project level errors. + */ export interface ProjectFilesWithDiagnostics extends ProjectFiles { + /** + * List of errors in project + */ projectErrors: DiagnosticWithLinePosition[]; } + /** + * Represents set of changes in open file + */ + /* @internal */ export interface ChangedOpenFile { + /** + * Name of file + */ fileName: string; + /** + * List of changes that should be applied to known open file + */ changes: ts.TextChange[]; } - /** - * Editor options - */ - export interface EditorOptions { - - /** Number of spaces for each tab. Default value is 4. */ - tabSize?: number; - - /** Number of spaces to indent during formatting. Default value is 4. */ - indentSize?: number; - - /** Number of additional spaces to indent during formatting to preserve base indentation (ex. script block indentation). Default value is 0. */ - baseIndentSize?: number; - - /** The new line character to be used. Default value is the OS line delimiter. */ - newLineCharacter?: string; - - /** Whether tabs should be converted to spaces. Default value is true. */ - convertTabsToSpaces?: boolean; - } - - /** - * Format options - */ - export interface FormatOptions extends EditorOptions { - - /** Defines space handling after a comma delimiter. Default value is true. */ - insertSpaceAfterCommaDelimiter?: boolean; - - /** Defines space handling after a semicolon in a for statement. Default value is true */ - insertSpaceAfterSemicolonInForStatements?: boolean; - - /** Defines space handling after a binary operator. Default value is true. */ - insertSpaceBeforeAndAfterBinaryOperators?: boolean; - - /** Defines space handling after keywords in control flow statement. Default value is true. */ - insertSpaceAfterKeywordsInControlFlowStatements?: boolean; - - /** Defines space handling after function keyword for anonymous functions. Default value is false. */ - insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean; - - /** Defines space handling after opening and before closing non empty parenthesis. Default value is false. */ - insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean; - - /** Defines space handling after opening and before closing non empty brackets. Default value is false. */ - insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean; - - /** Defines whether an open brace is put onto a new line for functions or not. Default value is false. */ - placeOpenBraceOnNewLineForFunctions?: boolean; - - /** Defines whether an open brace is put onto a new line for control blocks or not. Default value is false. */ - placeOpenBraceOnNewLineForControlBlocks?: boolean; - } /** * Information found in a configure request. @@ -632,12 +980,7 @@ declare namespace ts.server.protocol { /** * The format options to use during formatting and other code editing features. */ - formatOptions?: FormatOptions; - - /** - * If set to true - then all loose files will land into one inferred project - */ - useOneInferredProject?: boolean; + formatOptions?: FormatCodeSettings; } /** @@ -645,6 +988,7 @@ declare namespace ts.server.protocol { * host information, such as host type, tab size, and indent size. */ export interface ConfigureRequest extends Request { + command: CommandTypes.Configure; arguments: ConfigureRequestArguments; } @@ -680,55 +1024,154 @@ declare namespace ts.server.protocol { * send a response to an open request. */ export interface OpenRequest extends Request { + command: CommandTypes.Open; arguments: OpenRequestArgs; } - type OpenExternalProjectArgs = ExternalProject; - + /** + * Request to open or update external project + */ export interface OpenExternalProjectRequest extends Request { + command: CommandTypes.OpenExternalProject; arguments: OpenExternalProjectArgs; } - export interface CloseExternalProjectRequestArgs { - projectFileName: string; - } + /** + * Arguments to OpenExternalProjectRequest request + */ + export type OpenExternalProjectArgs = ExternalProject; + /** + * Request to open multiple external projects + */ export interface OpenExternalProjectsRequest extends Request { + command: CommandTypes.OpenExternalProjects; arguments: OpenExternalProjectsArgs; } + /** + * Arguments to OpenExternalProjectsRequest + */ export interface OpenExternalProjectsArgs { + /** + * List of external projects to open or update + */ projects: ExternalProject[]; } + /** + * Response to OpenExternalProjectRequest request. This is just an acknowledgement, so + * no body field is required. + */ + export interface OpenExternalProjectResponse extends Response { + } + + /** + * Response to OpenExternalProjectsRequest request. This is just an acknowledgement, so + * no body field is required. + */ + export interface OpenExternalProjectsResponse extends Response { + } + + /** + * Request to close external project. + */ export interface CloseExternalProjectRequest extends Request { + command: CommandTypes.CloseExternalProject; arguments: CloseExternalProjectRequestArgs; } + /** + * Arguments to CloseExternalProjectRequest request + */ + export interface CloseExternalProjectRequestArgs { + /** + * Name of the project to close + */ + projectFileName: string; + } + + /** + * Response to CloseExternalProjectRequest request. This is just an acknowledgement, so + * no body field is required. + */ + export interface CloseExternalProjectResponse extends Response { + } + + /** + * Request to check if given list of projects is up-to-date and synchronize them if necessary + */ + /* @internal */ export interface SynchronizeProjectListRequest extends Request { arguments: SynchronizeProjectListRequestArgs; } + /** + * Arguments to SynchronizeProjectListRequest + */ export interface SynchronizeProjectListRequestArgs { + /** + * List of last known projects + */ knownProjects: protocol.ProjectVersionInfo[]; } + /** + * Request to synchronize list of open files with the client + */ + /* @internal */ export interface ApplyChangedToOpenFilesRequest extends Request { arguments: ApplyChangedToOpenFilesRequestArgs; } + /** + * Arguments to ApplyChangedToOpenFilesRequest + */ + /* @internal */ export interface ApplyChangedToOpenFilesRequestArgs { + /** + * List of newly open files + */ openFiles?: ExternalFile[]; + /** + * List of open files files that were changes + */ changedFiles?: ChangedOpenFile[]; + /** + * List of files that were closed + */ closedFiles?: string[]; } + /** + * Request to set compiler options for inferred projects. + * External projects are opened / closed explicitly. + * Configured projects are opened when user opens loose file that has 'tsconfig.json' or 'jsconfig.json' anywhere in one of containing folders. + * This configuration file will be used to obtain a list of files and configuration settings for the project. + * Inferred projects are created when user opens a loose file that is not the part of external project + * or configured project and will contain only open file and transitive closure of referenced files if 'useOneInferredProject' is false, + * or all open loose files and its transitive closure of referenced files if 'useOneInferredProject' is true. + */ + export interface SetCompilerOptionsForInferredProjectsRequest extends Request { + command: CommandTypes.CompilerOptionsForInferredProjects; + arguments: SetCompilerOptionsForInferredProjectsArgs; + } + + /** + * Argument for SetCompilerOptionsForInferredProjectsRequest request. + */ export interface SetCompilerOptionsForInferredProjectsArgs { + /** + * Compiler options to be used with inferred projects. + */ options: ExternalProjectCompilerOptions; } - export interface SetCompilerOptionsForInferredProjectsRequest extends Request { - arguments: SetCompilerOptionsForInferredProjectsArgs; + /** + * Response to SetCompilerOptionsForInferredProjectsResponse request. This is just an acknowledgement, so + * no body field is required. + */ + export interface SetCompilerOptionsForInferredProjectsResponse extends Response { } /** @@ -736,6 +1179,7 @@ declare namespace ts.server.protocol { * to exit. */ export interface ExitRequest extends Request { + command: CommandTypes.Exit; } /** @@ -746,25 +1190,53 @@ declare namespace ts.server.protocol { * currently send a response to a close request. */ export interface CloseRequest extends FileRequest { + command: CommandTypes.Close; } + /** + * Request to obtain the list of files that should be regenerated if target file is recompiled. + * NOTE: this us query-only operation and does not generate any output on disk. + */ export interface CompileOnSaveAffectedFileListRequest extends FileRequest { + command: CommandTypes.CompileOnSaveAffectedFileList; } + /** + * Contains a list of files that should be regenerated in a project + */ export interface CompileOnSaveAffectedFileListSingleProject { + /** + * Project name + */ projectFileName: string; + /** + * List of files names that should be recompiled + */ fileNames: string[]; } + /** + * Response for CompileOnSaveAffectedFileListRequest request; + */ export interface CompileOnSaveAffectedFileListResponse extends Response { body: CompileOnSaveAffectedFileListSingleProject[]; } + /** + * Request to recompile the file. All generated outputs (.js, .d.ts or .js.map files) is written on disk. + */ export interface CompileOnSaveEmitFileRequest extends FileRequest { - args: CompileOnSaveEmitFileRequestArgs; + command: CommandTypes.CompileOnSaveEmitFile; + arguments: CompileOnSaveEmitFileRequestArgs; } + /** + * Arguments for CompileOnSaveEmitFileRequest + */ export interface CompileOnSaveEmitFileRequestArgs extends FileRequestArgs { + /** + * if true - then file should be recompiled even if it does not have any changes. + */ forced?: boolean; } @@ -775,6 +1247,7 @@ declare namespace ts.server.protocol { * line, col. */ export interface QuickInfoRequest extends FileLocationRequest { + command: CommandTypes.Quickinfo; } /** @@ -833,8 +1306,15 @@ declare namespace ts.server.protocol { */ endOffset: number; + /** + * End position of the range for which to format text in file. + */ + /* @internal */ endPosition?: number; - options?: ts.FormatCodeOptions; + /** + * Format options to be used. + */ + options?: FormatCodeSettings; } /** @@ -845,6 +1325,7 @@ declare namespace ts.server.protocol { * reformatted text. */ export interface FormatRequest extends FileLocationRequest { + command: CommandTypes.Format; arguments: FormatRequestArgs; } @@ -873,6 +1354,23 @@ declare namespace ts.server.protocol { newText: string; } + export interface FileCodeEdits { + fileName: string; + textChanges: CodeEdit[]; + } + + export interface CodeFixResponse extends Response { + /** The code actions that are available */ + body?: CodeAction[]; + } + + export interface CodeAction { + /** Description of the code action to display in the UI of the editor */ + description: string; + /** Text changes to apply to each file as part of the code action */ + changes: FileCodeEdits[]; + } + /** * Format and format on key response message. */ @@ -889,7 +1387,7 @@ declare namespace ts.server.protocol { */ key: string; - options?: ts.FormatCodeOptions; + options?: FormatCodeSettings; } /** @@ -901,6 +1399,7 @@ declare namespace ts.server.protocol { * reformatted text. */ export interface FormatOnKeyRequest extends FileLocationRequest { + command: CommandTypes.Formatonkey; arguments: FormatOnKeyRequestArgs; } @@ -921,6 +1420,7 @@ declare namespace ts.server.protocol { * begin with prefix. */ export interface CompletionsRequest extends FileLocationRequest { + command: CommandTypes.Completions; arguments: CompletionsRequestArgs; } @@ -941,6 +1441,7 @@ declare namespace ts.server.protocol { * detailed information for each completion entry. */ export interface CompletionDetailsRequest extends FileLocationRequest { + command: CommandTypes.CompletionDetails; arguments: CompletionDetailsRequestArgs; } @@ -1127,6 +1628,7 @@ declare namespace ts.server.protocol { * help. */ export interface SignatureHelpRequest extends FileLocationRequest { + command: CommandTypes.SignatureHelp; arguments: SignatureHelpRequestArgs; } @@ -1141,6 +1643,7 @@ declare namespace ts.server.protocol { * Synchronous request for semantic diagnostics of one file. */ export interface SemanticDiagnosticsSyncRequest extends FileRequest { + command: CommandTypes.SemanticDiagnosticsSync; arguments: SemanticDiagnosticsSyncRequestArgs; } @@ -1159,6 +1662,7 @@ declare namespace ts.server.protocol { * Synchronous request for syntactic diagnostics of one file. */ export interface SyntacticDiagnosticsSyncRequest extends FileRequest { + command: CommandTypes.SyntacticDiagnosticsSync; arguments: SyntacticDiagnosticsSyncRequestArgs; } @@ -1195,6 +1699,7 @@ declare namespace ts.server.protocol { * it request for every file in this project. */ export interface GeterrForProjectRequest extends Request { + command: CommandTypes.GeterrForProject; arguments: GeterrForProjectRequestArgs; } @@ -1226,6 +1731,7 @@ declare namespace ts.server.protocol { * file that is currently visible, in most-recently-used order. */ export interface GeterrRequest extends Request { + command: CommandTypes.Geterr; arguments: GeterrRequestArgs; } @@ -1247,6 +1753,11 @@ declare namespace ts.server.protocol { * Text of diagnostic message. */ text: string; + + /** + * The error code of the diagnostic message. + */ + code?: number; } export interface DiagnosticEventBody { @@ -1313,11 +1824,12 @@ declare namespace ts.server.protocol { * The two names can be identical. */ export interface ReloadRequest extends FileRequest { + command: CommandTypes.Reload; arguments: ReloadRequestArgs; } /** - * Response to "reload" request. This is just an acknowledgement, so + * Response to "reload" request. This is just an acknowledgement, so * no body field is required. */ export interface ReloadResponse extends Response { @@ -1342,6 +1854,7 @@ declare namespace ts.server.protocol { * "saveto" request. */ export interface SavetoRequest extends FileRequest { + command: CommandTypes.Saveto; arguments: SavetoRequestArgs; } @@ -1374,6 +1887,7 @@ declare namespace ts.server.protocol { * context for the search is given by the named file. */ export interface NavtoRequest extends FileRequest { + command: CommandTypes.Navto; arguments: NavtoRequestArgs; } @@ -1457,6 +1971,7 @@ declare namespace ts.server.protocol { * Server does not currently send a response to a change request. */ export interface ChangeRequest extends FileLocationRequest { + command: CommandTypes.Change; arguments: ChangeRequestArgs; } @@ -1473,6 +1988,7 @@ declare namespace ts.server.protocol { * found in file at location line, offset. */ export interface BraceRequest extends FileLocationRequest { + command: CommandTypes.Brace; } /** @@ -1481,6 +1997,15 @@ declare namespace ts.server.protocol { * extracted from the requested file. */ export interface NavBarRequest extends FileRequest { + command: CommandTypes.NavBar; + } + + /** + * NavTree request; value of command field is "navtree". + * Return response giving the navigation tree of the requested file. + */ + export interface NavTreeRequest extends FileRequest { + command: CommandTypes.NavTree; } export interface NavigationBarItem { @@ -1515,7 +2040,20 @@ declare namespace ts.server.protocol { indent: number; } + /** protocol.NavigationTree is identical to ts.NavigationTree, except using protocol.TextSpan instead of ts.TextSpan */ + export interface NavigationTree { + text: string; + kind: string; + kindModifiers: string; + spans: TextSpan[]; + childItems?: NavigationTree[]; + } + export interface NavBarResponse extends Response { body?: NavigationBarItem[]; } + + export interface NavTreeResponse extends Response { + body?: NavigationTree; + } } diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index 410382a9ca4..68dd59d2d32 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -4,7 +4,7 @@ namespace ts.server { export class ScriptInfo { /** - * All projects that include this file + * All projects that include this file */ readonly containingProjects: Project[] = []; private formatCodeSettings: ts.FormatCodeSettings; @@ -91,7 +91,7 @@ namespace ts.server { return this.containingProjects[0]; } - setFormatOptions(formatSettings: protocol.FormatOptions): void { + setFormatOptions(formatSettings: FormatCodeSettings): void { if (formatSettings) { if (!this.formatCodeSettings) { this.formatCodeSettings = getDefaultFormatCodeSettings(this.host); diff --git a/src/server/scriptVersionCache.ts b/src/server/scriptVersionCache.ts index 1508187c13e..8d0efa081ad 100644 --- a/src/server/scriptVersionCache.ts +++ b/src/server/scriptVersionCache.ts @@ -1,6 +1,5 @@ /// /// -/// /// namespace ts.server { diff --git a/src/server/session.ts b/src/server/session.ts index d076d5deb6d..111ba53a700 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1,6 +1,6 @@ -/// +/// /// -/// +/// /// namespace ts.server { @@ -14,6 +14,17 @@ namespace ts.server { return ((1e9 * seconds) + nanoseconds) / 1000000.0; } + function shouldSkipSematicCheck(project: Project) { + if (project.getCompilerOptions().skipLibCheck !== undefined) { + return false; + } + + if ((project.projectKind === ProjectKind.Inferred || project.projectKind === ProjectKind.External) && project.isJsOnlyProject()) { + return true; + } + return false; + } + interface FileStart { file: string; start: ILineInfo; @@ -44,7 +55,8 @@ namespace ts.server { return { start: scriptInfo.positionToLineOffset(diag.start), end: scriptInfo.positionToLineOffset(diag.start + diag.length), - text: ts.flattenDiagnosticMessageText(diag.messageText, "\n") + text: ts.flattenDiagnosticMessageText(diag.messageText, "\n"), + code: diag.code }; } @@ -71,69 +83,74 @@ namespace ts.server { } export namespace CommandNames { - export const Brace = "brace"; - export const BraceFull = "brace-full"; - export const BraceCompletion = "braceCompletion"; - export const Change = "change"; - export const Close = "close"; - export const Completions = "completions"; - export const CompletionsFull = "completions-full"; - export const CompletionDetails = "completionEntryDetails"; - export const CompileOnSaveAffectedFileList = "compileOnSaveAffectedFileList"; - export const CompileOnSaveEmitFile = "compileOnSaveEmitFile"; - export const Configure = "configure"; - export const Definition = "definition"; - export const DefinitionFull = "definition-full"; - export const Exit = "exit"; - export const Format = "format"; - export const Formatonkey = "formatonkey"; - export const FormatFull = "format-full"; - export const FormatonkeyFull = "formatonkey-full"; - export const FormatRangeFull = "formatRange-full"; - export const Geterr = "geterr"; - export const GeterrForProject = "geterrForProject"; - export const Implementation = "implementation"; - export const ImplementationFull = "implementation-full"; - export const SemanticDiagnosticsSync = "semanticDiagnosticsSync"; - export const SyntacticDiagnosticsSync = "syntacticDiagnosticsSync"; - export const NavBar = "navbar"; - export const NavBarFull = "navbar-full"; - export const Navto = "navto"; - export const NavtoFull = "navto-full"; - export const Occurrences = "occurrences"; - export const DocumentHighlights = "documentHighlights"; - export const DocumentHighlightsFull = "documentHighlights-full"; - export const Open = "open"; - export const Quickinfo = "quickinfo"; - export const QuickinfoFull = "quickinfo-full"; - export const References = "references"; - export const ReferencesFull = "references-full"; - export const Reload = "reload"; - export const Rename = "rename"; - export const RenameInfoFull = "rename-full"; - export const RenameLocationsFull = "renameLocations-full"; - export const Saveto = "saveto"; - export const SignatureHelp = "signatureHelp"; - export const SignatureHelpFull = "signatureHelp-full"; - export const TypeDefinition = "typeDefinition"; - export const ProjectInfo = "projectInfo"; - export const ReloadProjects = "reloadProjects"; - export const Unknown = "unknown"; - export const OpenExternalProject = "openExternalProject"; - export const OpenExternalProjects = "openExternalProjects"; - export const CloseExternalProject = "closeExternalProject"; - export const SynchronizeProjectList = "synchronizeProjectList"; - export const ApplyChangedToOpenFiles = "applyChangedToOpenFiles"; - export const EncodedSemanticClassificationsFull = "encodedSemanticClassifications-full"; - export const Cleanup = "cleanup"; - export const OutliningSpans = "outliningSpans"; - export const TodoComments = "todoComments"; - export const Indentation = "indentation"; - export const DocCommentTemplate = "docCommentTemplate"; - export const CompilerOptionsDiagnosticsFull = "compilerOptionsDiagnostics-full"; - export const NameOrDottedNameSpan = "nameOrDottedNameSpan"; - export const BreakpointStatement = "breakpointStatement"; - export const CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects"; + export const Brace: protocol.CommandTypes.Brace = "brace"; + export const BraceFull: protocol.CommandTypes.BraceFull = "brace-full"; + export const BraceCompletion: protocol.CommandTypes.BraceCompletion = "braceCompletion"; + export const Change: protocol.CommandTypes.Change = "change"; + export const Close: protocol.CommandTypes.Close = "close"; + export const Completions: protocol.CommandTypes.Completions = "completions"; + export const CompletionsFull: protocol.CommandTypes.CompletionsFull = "completions-full"; + export const CompletionDetails: protocol.CommandTypes.CompletionDetails = "completionEntryDetails"; + export const CompileOnSaveAffectedFileList: protocol.CommandTypes.CompileOnSaveAffectedFileList = "compileOnSaveAffectedFileList"; + export const CompileOnSaveEmitFile: protocol.CommandTypes.CompileOnSaveEmitFile = "compileOnSaveEmitFile"; + export const Configure: protocol.CommandTypes.Configure = "configure"; + export const Definition: protocol.CommandTypes.Definition = "definition"; + export const DefinitionFull: protocol.CommandTypes.DefinitionFull = "definition-full"; + export const Exit: protocol.CommandTypes.Exit = "exit"; + export const Format: protocol.CommandTypes.Format = "format"; + export const Formatonkey: protocol.CommandTypes.Formatonkey = "formatonkey"; + export const FormatFull: protocol.CommandTypes.FormatFull = "format-full"; + export const FormatonkeyFull: protocol.CommandTypes.FormatonkeyFull = "formatonkey-full"; + export const FormatRangeFull: protocol.CommandTypes.FormatRangeFull = "formatRange-full"; + export const Geterr: protocol.CommandTypes.Geterr = "geterr"; + export const GeterrForProject: protocol.CommandTypes.GeterrForProject = "geterrForProject"; + export const Implementation: protocol.CommandTypes.Implementation = "implementation"; + export const ImplementationFull: protocol.CommandTypes.ImplementationFull = "implementation-full"; + export const SemanticDiagnosticsSync: protocol.CommandTypes.SemanticDiagnosticsSync = "semanticDiagnosticsSync"; + export const SyntacticDiagnosticsSync: protocol.CommandTypes.SyntacticDiagnosticsSync = "syntacticDiagnosticsSync"; + export const NavBar: protocol.CommandTypes.NavBar = "navbar"; + export const NavBarFull: protocol.CommandTypes.NavBarFull = "navbar-full"; + export const NavTree: protocol.CommandTypes.NavTree = "navtree"; + export const NavTreeFull: protocol.CommandTypes.NavTreeFull = "navtree-full"; + export const Navto: protocol.CommandTypes.Navto = "navto"; + export const NavtoFull: protocol.CommandTypes.NavtoFull = "navto-full"; + export const Occurrences: protocol.CommandTypes.Occurrences = "occurrences"; + export const DocumentHighlights: protocol.CommandTypes.DocumentHighlights = "documentHighlights"; + export const DocumentHighlightsFull: protocol.CommandTypes.DocumentHighlightsFull = "documentHighlights-full"; + export const Open: protocol.CommandTypes.Open = "open"; + export const Quickinfo: protocol.CommandTypes.Quickinfo = "quickinfo"; + export const QuickinfoFull: protocol.CommandTypes.QuickinfoFull = "quickinfo-full"; + export const References: protocol.CommandTypes.References = "references"; + export const ReferencesFull: protocol.CommandTypes.ReferencesFull = "references-full"; + export const Reload: protocol.CommandTypes.Reload = "reload"; + export const Rename: protocol.CommandTypes.Rename = "rename"; + export const RenameInfoFull: protocol.CommandTypes.RenameInfoFull = "rename-full"; + export const RenameLocationsFull: protocol.CommandTypes.RenameLocationsFull = "renameLocations-full"; + export const Saveto: protocol.CommandTypes.Saveto = "saveto"; + export const SignatureHelp: protocol.CommandTypes.SignatureHelp = "signatureHelp"; + export const SignatureHelpFull: protocol.CommandTypes.SignatureHelpFull = "signatureHelp-full"; + export const TypeDefinition: protocol.CommandTypes.TypeDefinition = "typeDefinition"; + export const ProjectInfo: protocol.CommandTypes.ProjectInfo = "projectInfo"; + export const ReloadProjects: protocol.CommandTypes.ReloadProjects = "reloadProjects"; + export const Unknown: protocol.CommandTypes.Unknown = "unknown"; + export const OpenExternalProject: protocol.CommandTypes.OpenExternalProject = "openExternalProject"; + export const OpenExternalProjects: protocol.CommandTypes.OpenExternalProjects = "openExternalProjects"; + export const CloseExternalProject: protocol.CommandTypes.CloseExternalProject = "closeExternalProject"; + export const SynchronizeProjectList: protocol.CommandTypes.SynchronizeProjectList = "synchronizeProjectList"; + export const ApplyChangedToOpenFiles: protocol.CommandTypes.ApplyChangedToOpenFiles = "applyChangedToOpenFiles"; + export const EncodedSemanticClassificationsFull: protocol.CommandTypes.EncodedSemanticClassificationsFull = "encodedSemanticClassifications-full"; + export const Cleanup: protocol.CommandTypes.Cleanup = "cleanup"; + export const OutliningSpans: protocol.CommandTypes.OutliningSpans = "outliningSpans"; + export const TodoComments: protocol.CommandTypes.TodoComments = "todoComments"; + export const Indentation: protocol.CommandTypes.Indentation = "indentation"; + export const DocCommentTemplate: protocol.CommandTypes.DocCommentTemplate = "docCommentTemplate"; + export const CompilerOptionsDiagnosticsFull: protocol.CommandTypes.CompilerOptionsDiagnosticsFull = "compilerOptionsDiagnostics-full"; + export const NameOrDottedNameSpan: protocol.CommandTypes.NameOrDottedNameSpan = "nameOrDottedNameSpan"; + export const BreakpointStatement: protocol.CommandTypes.BreakpointStatement = "breakpointStatement"; + export const CompilerOptionsForInferredProjects: protocol.CommandTypes.CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects"; + export const GetCodeFixes: protocol.CommandTypes.GetCodeFixes = "getCodeFixes"; + export const GetCodeFixesFull: protocol.CommandTypes.GetCodeFixesFull = "getCodeFixes-full"; + export const GetSupportedCodeFixes: protocol.CommandTypes.GetSupportedCodeFixes = "getSupportedCodeFixes"; } export function formatMessage(msg: T, logger: server.Logger, byteLength: (s: string, encoding: string) => number, newLine: string): string { @@ -155,6 +172,8 @@ namespace ts.server { private immediateId: any; private changeSeq = 0; + private eventHander: ProjectServiceEventHandler; + constructor( private host: ServerHost, cancellationToken: HostCancellationToken, @@ -163,17 +182,18 @@ namespace ts.server { private byteLength: (buf: string, encoding?: string) => number, private hrtime: (start?: number[]) => number[], protected logger: Logger, - protected readonly canUseEvents: boolean) { + protected readonly canUseEvents: boolean, + eventHandler?: ProjectServiceEventHandler) { - const eventHandler: ProjectServiceEventHandler = canUseEvents - ? event => this.handleEvent(event) + this.eventHander = canUseEvents + ? eventHandler || (event => this.defaultEventHandler(event)) : undefined; - this.projectService = new ProjectService(host, logger, cancellationToken, useSingleInferredProject, typingsInstaller, eventHandler); + this.projectService = new ProjectService(host, logger, cancellationToken, useSingleInferredProject, typingsInstaller, this.eventHander); this.gcTimer = new GcTimer(host, /*delay*/ 7000, logger); } - private handleEvent(event: ProjectServiceEvent) { + private defaultEventHandler(event: ProjectServiceEvent) { switch (event.eventName) { case "context": const { project, fileName } = event.data; @@ -252,12 +272,13 @@ namespace ts.server { private semanticCheck(file: NormalizedPath, project: Project) { try { - const diags = project.getLanguageService().getSemanticDiagnostics(file); - - if (diags) { - const bakedDiags = diags.map((diag) => formatDiag(file, project, diag)); - this.event({ file: file, diagnostics: bakedDiags }, "semanticDiag"); + let diags: Diagnostic[] = []; + if (!shouldSkipSematicCheck(project)) { + diags = project.getLanguageService().getSemanticDiagnostics(file); } + + const bakedDiags = diags.map((diag) => formatDiag(file, project, diag)); + this.event({ file: file, diagnostics: bakedDiags }, "semanticDiag"); } catch (err) { this.logError(err, "semantic check"); @@ -342,7 +363,7 @@ namespace ts.server { } } - private getEncodedSemanticClassifications(args: protocol.FileSpanRequestArgs) { + private getEncodedSemanticClassifications(args: protocol.EncodedSemanticClassificationsRequestArgs) { const { file, project } = this.getFileAndProject(args); return project.getLanguageService().getEncodedSemanticClassifications(file, args); } @@ -351,7 +372,7 @@ namespace ts.server { return projectFileName && this.projectService.findProject(projectFileName); } - private getCompilerOptionsDiagnostics(args: protocol.ProjectRequestArgs) { + private getCompilerOptionsDiagnostics(args: protocol.CompilerOptionsDiagnosticsRequestArgs) { const project = this.getProject(args.projectFileName); return this.convertToDiagnosticsWithLinePosition(project.getLanguageService().getCompilerOptionsDiagnostics(), /*scriptInfo*/ undefined); } @@ -370,6 +391,9 @@ namespace ts.server { private getDiagnosticsWorker(args: protocol.FileRequestArgs, selector: (project: Project, file: string) => Diagnostic[], includeLinePosition: boolean) { const { project, file } = this.getFileAndProject(args); + if (shouldSkipSematicCheck(project)) { + return []; + } const scriptInfo = project.getScriptInfoForNormalizedPath(file); const diagnostics = selector(project, file); return includeLinePosition @@ -547,7 +571,7 @@ namespace ts.server { const scriptInfo = this.projectService.getScriptInfo(args.file); projects = scriptInfo.containingProjects; } - // ts.filter handles case when 'projects' is undefined + // ts.filter handles case when 'projects' is undefined projects = filter(projects, p => p.languageServiceEnabled); if (!projects || !projects.length) { return Errors.ThrowNoProject(); @@ -734,8 +758,11 @@ namespace ts.server { */ private openClientFile(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind) { const { configFileName, configFileErrors } = this.projectService.openClientFileWithNormalizedPath(fileName, fileContent, scriptKind); - if (configFileErrors) { - this.configFileDiagnosticEvent(fileName, configFileName, configFileErrors); + if (this.eventHander) { + this.eventHander({ + eventName: "configFileDiag", + data: { fileName, configFileName, diagnostics: configFileErrors || [] } + }); } } @@ -751,7 +778,7 @@ namespace ts.server { return this.getFileAndProjectWorker(args.file, args.projectFileName, /*refreshInferredProjects*/ false, errorOnMissingProject); } - private getFileAndProjectWorker(uncheckedFileName: string, projectFileName: string, refreshInferredProjects: boolean, errorOnMissingProject: boolean) { + private getFileAndProjectWorker(uncheckedFileName: string, projectFileName: string, refreshInferredProjects: boolean, errorOnMissingProject: boolean) { const file = toNormalizedPath(uncheckedFileName); const project: Project = this.getProject(projectFileName) || this.projectService.getDefaultProjectForFile(file, refreshInferredProjects); if (!project && errorOnMissingProject) { @@ -842,13 +869,7 @@ namespace ts.server { return undefined; } - return edits.map((edit) => { - return { - start: scriptInfo.positionToLineOffset(edit.span.start), - end: scriptInfo.positionToLineOffset(ts.textSpanEnd(edit.span)), - newText: edit.newText ? edit.newText : "" - }; - }); + return edits.map(edit => this.convertTextChangeToCodeEdit(edit, scriptInfo)); } private getFormattingEditsForRangeFull(args: protocol.FormatRequestArgs) { @@ -941,15 +962,8 @@ namespace ts.server { return completions.entries.reduce((result: protocol.CompletionEntry[], entry: ts.CompletionEntry) => { if (completions.isMemberCompletion || (entry.name.toLowerCase().indexOf(prefix.toLowerCase()) === 0)) { const { name, kind, kindModifiers, sortText, replacementSpan } = entry; - - let convertedSpan: protocol.TextSpan = undefined; - if (replacementSpan) { - convertedSpan = { - start: scriptInfo.positionToLineOffset(replacementSpan.start), - end: scriptInfo.positionToLineOffset(replacementSpan.start + replacementSpan.length) - }; - } - + const convertedSpan: protocol.TextSpan = + replacementSpan ? this.decorateSpan(replacementSpan, scriptInfo) : undefined; result.push({ name, kind, kindModifiers, sortText, replacementSpan: convertedSpan }); } return result; @@ -1087,38 +1101,54 @@ namespace ts.server { this.projectService.closeClientFile(file); } - private decorateNavigationBarItem(project: Project, fileName: NormalizedPath, items: ts.NavigationBarItem[]): protocol.NavigationBarItem[] { - if (!items) { - return undefined; - } - - const scriptInfo = project.getScriptInfoForNormalizedPath(fileName); - - return items.map(item => ({ + private decorateNavigationBarItems(items: ts.NavigationBarItem[], scriptInfo: ScriptInfo): protocol.NavigationBarItem[] { + return map(items, item => ({ text: item.text, kind: item.kind, kindModifiers: item.kindModifiers, - spans: item.spans.map(span => ({ - start: scriptInfo.positionToLineOffset(span.start), - end: scriptInfo.positionToLineOffset(ts.textSpanEnd(span)) - })), - childItems: this.decorateNavigationBarItem(project, fileName, item.childItems), + spans: item.spans.map(span => this.decorateSpan(span, scriptInfo)), + childItems: this.decorateNavigationBarItems(item.childItems, scriptInfo), indent: item.indent })); } private getNavigationBarItems(args: protocol.FileRequestArgs, simplifiedResult: boolean): protocol.NavigationBarItem[] | NavigationBarItem[] { const { file, project } = this.getFileAndProject(args); - const items = project.getLanguageService().getNavigationBarItems(file); - if (!items) { - return undefined; - } - - return simplifiedResult - ? this.decorateNavigationBarItem(project, file, items) + const items = project.getLanguageService(/*ensureSynchronized*/ false).getNavigationBarItems(file); + return !items + ? undefined + : simplifiedResult + ? this.decorateNavigationBarItems(items, project.getScriptInfoForNormalizedPath(file)) : items; } + private decorateNavigationTree(tree: ts.NavigationTree, scriptInfo: ScriptInfo): protocol.NavigationTree { + return { + text: tree.text, + kind: tree.kind, + kindModifiers: tree.kindModifiers, + spans: tree.spans.map(span => this.decorateSpan(span, scriptInfo)), + childItems: map(tree.childItems, item => this.decorateNavigationTree(item, scriptInfo)) + }; + } + + private decorateSpan(span: TextSpan, scriptInfo: ScriptInfo): protocol.TextSpan { + return { + start: scriptInfo.positionToLineOffset(span.start), + end: scriptInfo.positionToLineOffset(ts.textSpanEnd(span)) + }; + } + + private getNavigationTree(args: protocol.FileRequestArgs, simplifiedResult: boolean): protocol.NavigationTree | NavigationTree { + const { file, project } = this.getFileAndProject(args); + const tree = project.getLanguageService(/*ensureSynchronized*/ false).getNavigationTree(file); + return !tree + ? undefined + : simplifiedResult + ? this.decorateNavigationTree(tree, project.getScriptInfoForNormalizedPath(file)) + : tree; + } + private getNavigateToItems(args: protocol.NavtoRequestArgs, simplifiedResult: boolean): protocol.NavtoItem[] | NavigateToItem[] { const projects = this.getProjects(args); @@ -1127,7 +1157,7 @@ namespace ts.server { return combineProjectOutput( projects, project => { - const navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isJsOnlyProject()); + const navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject()); if (!navItems) { return []; } @@ -1165,7 +1195,7 @@ namespace ts.server { else { return combineProjectOutput( projects, - project => project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isJsOnlyProject()), + project => project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject()), /*comparer*/ undefined, navigateToItemIsEqualTo); } @@ -1199,6 +1229,55 @@ namespace ts.server { } } + private getSupportedCodeFixes(): string[] { + return ts.getSupportedCodeFixes(); + } + + private getCodeFixes(args: protocol.CodeFixRequestArgs, simplifiedResult: boolean): protocol.CodeAction[] | CodeAction[] { + const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args); + + const scriptInfo = project.getScriptInfoForNormalizedPath(file); + const startPosition = getStartPosition(); + const endPosition = getEndPosition(); + + const codeActions = project.getLanguageService().getCodeFixesAtPosition(file, startPosition, endPosition, args.errorCodes); + if (!codeActions) { + return undefined; + } + if (simplifiedResult) { + return codeActions.map(codeAction => this.mapCodeAction(codeAction, scriptInfo)); + } + else { + return codeActions; + } + + function getStartPosition() { + return args.startPosition !== undefined ? args.startPosition : scriptInfo.lineOffsetToPosition(args.startLine, args.startOffset); + } + + function getEndPosition() { + return args.endPosition !== undefined ? args.endPosition : scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset); + } + } + + private mapCodeAction(codeAction: CodeAction, scriptInfo: ScriptInfo): protocol.CodeAction { + return { + description: codeAction.description, + changes: codeAction.changes.map(change => ({ + fileName: change.fileName, + textChanges: change.textChanges.map(textChange => this.convertTextChangeToCodeEdit(textChange, scriptInfo)) + })) + }; + } + + private convertTextChangeToCodeEdit(change: ts.TextChange, scriptInfo: ScriptInfo): protocol.CodeEdit { + return { + start: scriptInfo.positionToLineOffset(change.span.start), + end: scriptInfo.positionToLineOffset(change.span.start + change.span.length), + newText: change.newText ? change.newText : "" + }; + } + private getBraceMatching(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.TextSpan[] | TextSpan[] { const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args); @@ -1206,19 +1285,11 @@ namespace ts.server { const position = this.getPosition(args, scriptInfo); const spans = project.getLanguageService(/*ensureSynchronized*/ false).getBraceMatchingAtPosition(file, position); - if (!spans) { - return undefined; - } - if (simplifiedResult) { - - return spans.map(span => ({ - start: scriptInfo.positionToLineOffset(span.start), - end: scriptInfo.positionToLineOffset(span.start + span.length) - })); - } - else { - return spans; - } + return !spans + ? undefined + : simplifiedResult + ? spans.map(span => this.decorateSpan(span, scriptInfo)) + : spans; } getDiagnosticsForProject(delay: number, fileName: string) { @@ -1399,7 +1470,7 @@ namespace ts.server { [CommandNames.BraceCompletion]: (request: protocol.BraceCompletionRequest) => { return this.requiredResponse(this.isValidBraceCompletion(request.arguments)); }, - [CommandNames.DocCommentTemplate]: (request: protocol.FileLocationRequest) => { + [CommandNames.DocCommentTemplate]: (request: protocol.DocCommentTemplateRequest) => { return this.requiredResponse(this.getDocCommentTemplate(request.arguments)); }, [CommandNames.Format]: (request: protocol.FormatRequest) => { @@ -1438,10 +1509,10 @@ namespace ts.server { [CommandNames.SignatureHelpFull]: (request: protocol.SignatureHelpRequest) => { return this.requiredResponse(this.getSignatureHelpItems(request.arguments, /*simplifiedResult*/ false)); }, - [CommandNames.CompilerOptionsDiagnosticsFull]: (request: protocol.ProjectRequest) => { + [CommandNames.CompilerOptionsDiagnosticsFull]: (request: protocol.CompilerOptionsDiagnosticsRequest) => { return this.requiredResponse(this.getCompilerOptionsDiagnostics(request.arguments)); }, - [CommandNames.EncodedSemanticClassificationsFull]: (request: protocol.FileSpanRequest) => { + [CommandNames.EncodedSemanticClassificationsFull]: (request: protocol.EncodedSemanticClassificationsRequest) => { return this.requiredResponse(this.getEncodedSemanticClassifications(request.arguments)); }, [CommandNames.Cleanup]: (request: protocol.Request) => { @@ -1503,6 +1574,12 @@ namespace ts.server { [CommandNames.NavBarFull]: (request: protocol.FileRequest) => { return this.requiredResponse(this.getNavigationBarItems(request.arguments, /*simplifiedResult*/ false)); }, + [CommandNames.NavTree]: (request: protocol.FileRequest) => { + return this.requiredResponse(this.getNavigationTree(request.arguments, /*simplifiedResult*/ true)); + }, + [CommandNames.NavTreeFull]: (request: protocol.FileRequest) => { + return this.requiredResponse(this.getNavigationTree(request.arguments, /*simplifiedResult*/ false)); + }, [CommandNames.Occurrences]: (request: protocol.FileLocationRequest) => { return this.requiredResponse(this.getOccurrences(request.arguments)); }, @@ -1521,6 +1598,15 @@ namespace ts.server { [CommandNames.ReloadProjects]: (request: protocol.ReloadProjectsRequest) => { this.projectService.reloadProjects(); return this.notRequired(); + }, + [CommandNames.GetCodeFixes]: (request: protocol.CodeFixRequest) => { + return this.requiredResponse(this.getCodeFixes(request.arguments, /*simplifiedResult*/ true)); + }, + [CommandNames.GetCodeFixesFull]: (request: protocol.CodeFixRequest) => { + return this.requiredResponse(this.getCodeFixes(request.arguments, /*simplifiedResult*/ false)); + }, + [CommandNames.GetSupportedCodeFixes]: (request: protocol.Request) => { + return this.requiredResponse(this.getSupportedCodeFixes()); } }); diff --git a/src/server/tsconfig.json b/src/server/tsconfig.json index 7eb8c28f383..9f907446c03 100644 --- a/src/server/tsconfig.json +++ b/src/server/tsconfig.json @@ -22,7 +22,7 @@ "typingsCache.ts", "project.ts", "editorServices.ts", - "protocol.d.ts", + "protocol.ts", "session.ts", "server.ts" ] diff --git a/src/server/utilities.ts b/src/server/utilities.ts index 3f99da9977e..5bd3423e570 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -157,51 +157,53 @@ namespace ts.server { } }; } - function throwLanguageServiceIsDisabledError() { + function throwLanguageServiceIsDisabledError(): never { throw new Error("LanguageService is disabled"); } export const nullLanguageService: LanguageService = { - cleanupSemanticCache: (): any => throwLanguageServiceIsDisabledError(), - getSyntacticDiagnostics: (): any => throwLanguageServiceIsDisabledError(), - getSemanticDiagnostics: (): any => throwLanguageServiceIsDisabledError(), - getCompilerOptionsDiagnostics: (): any => throwLanguageServiceIsDisabledError(), - getSyntacticClassifications: (): any => throwLanguageServiceIsDisabledError(), - getEncodedSyntacticClassifications: (): any => throwLanguageServiceIsDisabledError(), - getSemanticClassifications: (): any => throwLanguageServiceIsDisabledError(), - getEncodedSemanticClassifications: (): any => throwLanguageServiceIsDisabledError(), - getCompletionsAtPosition: (): any => throwLanguageServiceIsDisabledError(), - findReferences: (): any => throwLanguageServiceIsDisabledError(), - getCompletionEntryDetails: (): any => throwLanguageServiceIsDisabledError(), - getQuickInfoAtPosition: (): any => throwLanguageServiceIsDisabledError(), - findRenameLocations: (): any => throwLanguageServiceIsDisabledError(), - getNameOrDottedNameSpan: (): any => throwLanguageServiceIsDisabledError(), - getBreakpointStatementAtPosition: (): any => throwLanguageServiceIsDisabledError(), - getBraceMatchingAtPosition: (): any => throwLanguageServiceIsDisabledError(), - getSignatureHelpItems: (): any => throwLanguageServiceIsDisabledError(), - getDefinitionAtPosition: (): any => throwLanguageServiceIsDisabledError(), - getRenameInfo: (): any => throwLanguageServiceIsDisabledError(), - getTypeDefinitionAtPosition: (): any => throwLanguageServiceIsDisabledError(), - getReferencesAtPosition: (): any => throwLanguageServiceIsDisabledError(), - getDocumentHighlights: (): any => throwLanguageServiceIsDisabledError(), - getOccurrencesAtPosition: (): any => throwLanguageServiceIsDisabledError(), - getNavigateToItems: (): any => throwLanguageServiceIsDisabledError(), - getNavigationBarItems: (): any => throwLanguageServiceIsDisabledError(), - getOutliningSpans: (): any => throwLanguageServiceIsDisabledError(), - getTodoComments: (): any => throwLanguageServiceIsDisabledError(), - getIndentationAtPosition: (): any => throwLanguageServiceIsDisabledError(), - getFormattingEditsForRange: (): any => throwLanguageServiceIsDisabledError(), - getFormattingEditsForDocument: (): any => throwLanguageServiceIsDisabledError(), - getFormattingEditsAfterKeystroke: (): any => throwLanguageServiceIsDisabledError(), - getDocCommentTemplateAtPosition: (): any => throwLanguageServiceIsDisabledError(), - isValidBraceCompletionAtPosition: (): any => throwLanguageServiceIsDisabledError(), - getEmitOutput: (): any => throwLanguageServiceIsDisabledError(), - getProgram: (): any => throwLanguageServiceIsDisabledError(), - getNonBoundSourceFile: (): any => throwLanguageServiceIsDisabledError(), - dispose: (): any => throwLanguageServiceIsDisabledError(), - getCompletionEntrySymbol: (): any => throwLanguageServiceIsDisabledError(), - getImplementationAtPosition: (): any => throwLanguageServiceIsDisabledError(), - getSourceFile: (): any => throwLanguageServiceIsDisabledError() + cleanupSemanticCache: throwLanguageServiceIsDisabledError, + getSyntacticDiagnostics: throwLanguageServiceIsDisabledError, + getSemanticDiagnostics: throwLanguageServiceIsDisabledError, + getCompilerOptionsDiagnostics: throwLanguageServiceIsDisabledError, + getSyntacticClassifications: throwLanguageServiceIsDisabledError, + getEncodedSyntacticClassifications: throwLanguageServiceIsDisabledError, + getSemanticClassifications: throwLanguageServiceIsDisabledError, + getEncodedSemanticClassifications: throwLanguageServiceIsDisabledError, + getCompletionsAtPosition: throwLanguageServiceIsDisabledError, + findReferences: throwLanguageServiceIsDisabledError, + getCompletionEntryDetails: throwLanguageServiceIsDisabledError, + getQuickInfoAtPosition: throwLanguageServiceIsDisabledError, + findRenameLocations: throwLanguageServiceIsDisabledError, + getNameOrDottedNameSpan: throwLanguageServiceIsDisabledError, + getBreakpointStatementAtPosition: throwLanguageServiceIsDisabledError, + getBraceMatchingAtPosition: throwLanguageServiceIsDisabledError, + getSignatureHelpItems: throwLanguageServiceIsDisabledError, + getDefinitionAtPosition: throwLanguageServiceIsDisabledError, + getRenameInfo: throwLanguageServiceIsDisabledError, + getTypeDefinitionAtPosition: throwLanguageServiceIsDisabledError, + getReferencesAtPosition: throwLanguageServiceIsDisabledError, + getDocumentHighlights: throwLanguageServiceIsDisabledError, + getOccurrencesAtPosition: throwLanguageServiceIsDisabledError, + getNavigateToItems: throwLanguageServiceIsDisabledError, + getNavigationBarItems: throwLanguageServiceIsDisabledError, + getNavigationTree: throwLanguageServiceIsDisabledError, + getOutliningSpans: throwLanguageServiceIsDisabledError, + getTodoComments: throwLanguageServiceIsDisabledError, + getIndentationAtPosition: throwLanguageServiceIsDisabledError, + getFormattingEditsForRange: throwLanguageServiceIsDisabledError, + getFormattingEditsForDocument: throwLanguageServiceIsDisabledError, + getFormattingEditsAfterKeystroke: throwLanguageServiceIsDisabledError, + getDocCommentTemplateAtPosition: throwLanguageServiceIsDisabledError, + isValidBraceCompletionAtPosition: throwLanguageServiceIsDisabledError, + getEmitOutput: throwLanguageServiceIsDisabledError, + getProgram: throwLanguageServiceIsDisabledError, + getNonBoundSourceFile: throwLanguageServiceIsDisabledError, + dispose: throwLanguageServiceIsDisabledError, + getCompletionEntrySymbol: throwLanguageServiceIsDisabledError, + getImplementationAtPosition: throwLanguageServiceIsDisabledError, + getSourceFile: throwLanguageServiceIsDisabledError, + getCodeFixesAtPosition: throwLanguageServiceIsDisabledError }; export interface ServerLanguageServiceHost { @@ -248,7 +250,7 @@ namespace ts.server { // another operation was already scheduled for this id - cancel it this.host.clearTimeout(this.pendingTimeouts[operationId]); } - // schedule new operation, pass arguments + // schedule new operation, pass arguments this.pendingTimeouts[operationId] = this.host.setTimeout(ThrottledOperations.run, delay, this, operationId, cb); } diff --git a/src/services/classifier.ts b/src/services/classifier.ts index 29a878224cd..c22aec6a786 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -954,8 +954,7 @@ namespace ts { return; case SyntaxKind.Parameter: if ((token.parent).name === token) { - const isThis = token.kind === SyntaxKind.Identifier && (token).originalKeywordKind === SyntaxKind.ThisKeyword; - return isThis ? ClassificationType.keyword : ClassificationType.parameterName; + return isThisIdentifier(token) ? ClassificationType.keyword : ClassificationType.parameterName; } return; } diff --git a/src/services/codefixes/codeFixProvider.ts b/src/services/codefixes/codeFixProvider.ts new file mode 100644 index 00000000000..c61cbe1b19e --- /dev/null +++ b/src/services/codefixes/codeFixProvider.ts @@ -0,0 +1,48 @@ +/* @internal */ +namespace ts { + export interface CodeFix { + errorCodes: number[]; + getCodeActions(context: CodeFixContext): CodeAction[] | undefined; + } + + export interface CodeFixContext { + errorCode: number; + sourceFile: SourceFile; + span: TextSpan; + program: Program; + newLineCharacter: string; + } + + export namespace codefix { + const codeFixes = createMap(); + + export function registerCodeFix(action: CodeFix) { + forEach(action.errorCodes, error => { + let fixes = codeFixes[error]; + if (!fixes) { + fixes = []; + codeFixes[error] = fixes; + } + fixes.push(action); + }); + } + + export function getSupportedErrorCodes() { + return Object.keys(codeFixes); + } + + export function getFixes(context: CodeFixContext): CodeAction[] { + const fixes = codeFixes[context.errorCode]; + let allActions: CodeAction[] = []; + + forEach(fixes, f => { + const actions = f.getCodeActions(context); + if (actions && actions.length > 0) { + allActions = allActions.concat(actions); + } + }); + + return allActions; + } + } +} diff --git a/src/services/codefixes/fixes.ts b/src/services/codefixes/fixes.ts new file mode 100644 index 00000000000..d64a99ca1b9 --- /dev/null +++ b/src/services/codefixes/fixes.ts @@ -0,0 +1 @@ +/// diff --git a/src/services/codefixes/superFixes.ts b/src/services/codefixes/superFixes.ts new file mode 100644 index 00000000000..f117799f3e1 --- /dev/null +++ b/src/services/codefixes/superFixes.ts @@ -0,0 +1,81 @@ +/* @internal */ +namespace ts.codefix { + function getOpenBraceEnd(constructor: ConstructorDeclaration, sourceFile: SourceFile) { + // First token is the open curly, this is where we want to put the 'super' call. + return constructor.body.getFirstToken(sourceFile).getEnd(); + } + + registerCodeFix({ + errorCodes: [Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call.code], + getCodeActions: (context: CodeFixContext) => { + const sourceFile = context.sourceFile; + const token = getTokenAtPosition(sourceFile, context.span.start); + + if (token.kind !== SyntaxKind.ConstructorKeyword) { + return undefined; + } + + const newPosition = getOpenBraceEnd(token.parent, sourceFile); + return [{ + description: getLocaleSpecificMessage(Diagnostics.Add_missing_super_call), + changes: [{ fileName: sourceFile.fileName, textChanges: [{ newText: "super();", span: { start: newPosition, length: 0 } }] }] + }]; + } + }); + + registerCodeFix({ + errorCodes: [Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class.code], + getCodeActions: (context: CodeFixContext) => { + const sourceFile = context.sourceFile; + + const token = getTokenAtPosition(sourceFile, context.span.start); + if (token.kind !== SyntaxKind.ThisKeyword) { + return undefined; + } + + const constructor = getContainingFunction(token); + const superCall = findSuperCall((constructor).body); + if (!superCall) { + return undefined; + } + + // figure out if the this access is actuall inside the supercall + // i.e. super(this.a), since in that case we won't suggest a fix + if (superCall.expression && superCall.expression.kind == SyntaxKind.CallExpression) { + const arguments = (superCall.expression).arguments; + for (let i = 0; i < arguments.length; i++) { + if ((arguments[i]).expression === token) { + return undefined; + } + } + } + + const newPosition = getOpenBraceEnd(constructor, sourceFile); + const changes = [{ + fileName: sourceFile.fileName, textChanges: [{ + newText: superCall.getText(sourceFile), + span: { start: newPosition, length: 0 } + }, + { + newText: "", + span: { start: superCall.getStart(sourceFile), length: superCall.getWidth(sourceFile) } + }] + }]; + + return [{ + description: getLocaleSpecificMessage(Diagnostics.Make_super_call_the_first_statement_in_the_constructor), + changes + }]; + + function findSuperCall(n: Node): ExpressionStatement { + if (n.kind === SyntaxKind.ExpressionStatement && isSuperCall((n).expression)) { + return n; + } + if (isFunctionLike(n)) { + return undefined; + } + return forEachChild(n, findSuperCall); + } + } + }); +} \ No newline at end of file diff --git a/src/services/completions.ts b/src/services/completions.ts index 64ea05e4f2b..c8d7c019e54 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -24,7 +24,7 @@ namespace ts.Completions { const entries: CompletionEntry[] = []; if (isSourceFileJavaScript(sourceFile)) { - const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ false); + const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true); addRange(entries, getJavaScriptCompletionEntries(sourceFile, location.pos, uniqueNames)); } else { @@ -138,7 +138,9 @@ namespace ts.Completions { return undefined; } - if (node.parent.kind === SyntaxKind.PropertyAssignment && node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression) { + if (node.parent.kind === SyntaxKind.PropertyAssignment && + node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression && + (node.parent).name === node) { // Get quoted name of properties of the object literal expression // i.e. interface ConfigFiles { // 'jspm:dev': string @@ -323,15 +325,28 @@ namespace ts.Completions { return result; } + /** + * Given a path ending at a directory, gets the completions for the path, and filters for those entries containing the basename. + */ function getCompletionEntriesForDirectoryFragment(fragment: string, scriptPath: string, extensions: string[], includeExtensions: boolean, span: TextSpan, exclude?: string, result: CompletionEntry[] = []): CompletionEntry[] { + if (fragment === undefined) { + fragment = ""; + } + + fragment = normalizeSlashes(fragment); + + /** + * Remove the basename from the path. Note that we don't use the basename to filter completions; + * the client is responsible for refining completions. + */ fragment = getDirectoryPath(fragment); - if (!fragment) { - fragment = "./"; - } - else { - fragment = ensureTrailingDirectorySeparator(fragment); + + if (fragment === "") { + fragment = "." + directorySeparator; } + fragment = ensureTrailingDirectorySeparator(fragment); + const absolutePath = normalizeAndPreserveTrailingSlash(isRootedDiskPath(fragment) ? fragment : combinePaths(scriptPath, fragment)); const baseDirectory = getDirectoryPath(absolutePath); const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames()); @@ -341,6 +356,12 @@ namespace ts.Completions { const files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/undefined, /*include*/["./*"]); if (files) { + /** + * Multiple file entries might map to the same truncated name once we remove extensions + * (happens iff includeExtensions === false)so we use a set-like data structure. Eg: + * + * both foo.ts and foo.tsx become foo + */ const foundFiles = createMap(); for (let filePath of files) { filePath = normalizePath(filePath); @@ -537,36 +558,44 @@ namespace ts.Completions { return undefined; } + const completionInfo: CompletionInfo = { + /** + * We don't want the editor to offer any other completions, such as snippets, inside a comment. + */ + isGlobalCompletion: false, + isMemberCompletion: false, + /** + * The user may type in a path that doesn't yet exist, creating a "new identifier" + * with respect to the collection of identifiers the server is aware of. + */ + isNewIdentifierLocation: true, + + entries: [] + }; + const text = sourceFile.text.substr(range.pos, position - range.pos); const match = tripleSlashDirectiveFragmentRegex.exec(text); + if (match) { const prefix = match[1]; const kind = match[2]; const toComplete = match[3]; const scriptPath = getDirectoryPath(sourceFile.path); - let entries: CompletionEntry[]; if (kind === "path") { // Give completions for a relative path const span: TextSpan = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length); - entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/true, span, sourceFile.path); + completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/true, span, sourceFile.path); } else { // Give completions based on the typings available const span: TextSpan = { start: range.pos + prefix.length, length: match[0].length - prefix.length }; - entries = getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span); + completionInfo.entries = getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span); } - - return { - isGlobalCompletion: false, - isMemberCompletion: false, - isNewIdentifierLocation: true, - entries - }; } - return undefined; + return completionInfo; } function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: CompilerOptions, scriptPath: string, span: TextSpan, result: CompletionEntry[] = []): CompletionEntry[] { @@ -1001,6 +1030,7 @@ namespace ts.Completions { if ((jsxContainer.kind === SyntaxKind.JsxSelfClosingElement) || (jsxContainer.kind === SyntaxKind.JsxOpeningElement)) { // Cursor is inside a JSX self-closing element or opening element attrsType = typeChecker.getJsxElementAttributesType(jsxContainer); + isGlobalCompletion = false; if (attrsType) { symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), (jsxContainer).attributes); @@ -1671,9 +1701,15 @@ namespace ts.Completions { * Matches a triple slash reference directive with an incomplete string literal for its path. Used * to determine if the caret is currently within the string literal and capture the literal fragment * for completions. - * For example, this matches /// parent).members, node); case SyntaxKind.ModuleDeclaration: const body = (parent).body; - return body && body.kind === SyntaxKind.Block && rangeContainsRange((body).statements, node); + return body && body.kind === SyntaxKind.ModuleBlock && rangeContainsRange((body).statements, node); case SyntaxKind.SourceFile: case SyntaxKind.Block: case SyntaxKind.ModuleBlock: diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 4fffa394fc5..84f83a9c7db 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -332,7 +332,7 @@ namespace ts.formatting { (node.parent).expression !== node) { const fullCallOrNewExpression = (node.parent).expression; - const startingExpression = getStartingExpression(fullCallOrNewExpression); + const startingExpression = getStartingExpression(fullCallOrNewExpression); if (fullCallOrNewExpression === startingExpression) { return Value.Unknown; @@ -350,15 +350,14 @@ namespace ts.formatting { return Value.Unknown; - function getStartingExpression(node: PropertyAccessExpression | CallExpression | ElementAccessExpression) { + function getStartingExpression(node: Expression) { while (true) { switch (node.kind) { case SyntaxKind.CallExpression: case SyntaxKind.NewExpression: case SyntaxKind.PropertyAccessExpression: case SyntaxKind.ElementAccessExpression: - - node = node.expression; + node = (node).expression; break; default: return node; diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 5c8c47e9666..18881ae7660 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -21,6 +21,13 @@ namespace ts.NavigationBar { return result; } + export function getNavigationTree(sourceFile: SourceFile): NavigationTree { + curSourceFile = sourceFile; + const result = convertToTree(rootNavigationBarNode(sourceFile)); + curSourceFile = undefined; + return result; + } + // Keep sourceFile handy so we don't have to search for it every time we need to call `getText`. let curSourceFile: SourceFile; function nodeText(node: Node): string { @@ -324,7 +331,7 @@ namespace ts.NavigationBar { } // More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times. - const collator: { compare(a: string, b: string): number } = typeof Intl === "undefined" ? undefined : new Intl.Collator(); + const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator() : undefined; // Intl is missing in Safari, and node 0.10 treats "a" as greater than "B". const localeCompareIsCorrect = collator && collator.compare("a", "B") < 0; const localeCompareFix: (a: string, b: string) => number = localeCompareIsCorrect ? collator.compare : function(a, b) { @@ -502,6 +509,16 @@ namespace ts.NavigationBar { // NavigationBarItem requires an array, but will not mutate it, so just give it this for performance. const emptyChildItemArray: NavigationBarItem[] = []; + function convertToTree(n: NavigationBarNode): NavigationTree { + return { + text: getItemName(n.node), + kind: getNodeKind(n.node), + kindModifiers: getNodeModifiers(n.node), + spans: getSpans(n), + childItems: map(n.children, convertToTree) + }; + } + function convertToTopLevelItem(n: NavigationBarNode): NavigationBarItem { return { text: getItemName(n.node), @@ -526,16 +543,16 @@ namespace ts.NavigationBar { grayed: false }; } + } - function getSpans(n: NavigationBarNode): TextSpan[] { - const spans = [getNodeSpan(n.node)]; - if (n.additionalNodes) { - for (const node of n.additionalNodes) { - spans.push(getNodeSpan(node)); - } + function getSpans(n: NavigationBarNode): TextSpan[] { + const spans = [getNodeSpan(n.node)]; + if (n.additionalNodes) { + for (const node of n.additionalNodes) { + spans.push(getNodeSpan(node)); } - return spans; } + return spans; } function getModuleName(moduleDeclaration: ModuleDeclaration): string { diff --git a/src/services/services.ts b/src/services/services.ts index b50e1d3313d..666644aca1b 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -24,14 +24,16 @@ /// /// /// +/// +/// namespace ts { /** The version of the language service API */ export const servicesVersion = "0.5"; - function createNode(kind: SyntaxKind, pos: number, end: number, parent?: Node): NodeObject | TokenObject | IdentifierObject { + function createNode(kind: TKind, pos: number, end: number, parent?: Node): NodeObject | TokenObject | IdentifierObject { const node = kind >= SyntaxKind.FirstNode ? new NodeObject(kind, pos, end) : - kind === SyntaxKind.Identifier ? new IdentifierObject(kind, pos, end) : + kind === SyntaxKind.Identifier ? new IdentifierObject(SyntaxKind.Identifier, pos, end) : new TokenObject(kind, pos, end); node.parent = parent; return node; @@ -210,14 +212,13 @@ namespace ts { } } - class TokenOrIdentifierObject implements Token { + class TokenOrIdentifierObject implements Node { public kind: SyntaxKind; public pos: number; public end: number; public flags: NodeFlags; public parent: Node; public jsDocComments: JSDoc[]; - public __tokenTag: any; constructor(pos: number, end: number) { // Set properties in same order as NodeObject @@ -319,16 +320,25 @@ namespace ts { } } - class TokenObject extends TokenOrIdentifierObject { - public kind: SyntaxKind; - constructor(kind: SyntaxKind, pos: number, end: number) { + class TokenObject extends TokenOrIdentifierObject implements Token { + public kind: TKind; + + constructor(kind: TKind, pos: number, end: number) { super(pos, end); this.kind = kind; } } - class IdentifierObject extends TokenOrIdentifierObject { - constructor(kind: SyntaxKind, pos: number, end: number) { + class IdentifierObject extends TokenOrIdentifierObject implements Identifier { + public kind: SyntaxKind.Identifier; + public text: string; + _primaryExpressionBrand: any; + _memberExpressionBrand: any; + _leftHandSideExpressionBrand: any; + _incrementExpressionBrand: any; + _unaryExpressionBrand: any; + _expressionBrand: any; + constructor(kind: SyntaxKind.Identifier, pos: number, end: number) { super(pos, end); } } @@ -424,6 +434,7 @@ namespace ts { } class SourceFileObject extends NodeObject implements SourceFile { + public kind: SyntaxKind.SourceFile; public _declarationBrand: any; public fileName: string; public path: Path; @@ -432,7 +443,7 @@ namespace ts { public lineMap: number[]; public statements: NodeArray; - public endOfFileToken: Node; + public endOfFileToken: Token; public amdDependencies: { name: string; path: string }[]; public moduleName: string; @@ -655,6 +666,7 @@ namespace ts { return { getNodeConstructor: () => NodeObject, getTokenConstructor: () => TokenObject, + getIdentifierConstructor: () => IdentifierObject, getSourceFileConstructor: () => SourceFileObject, getSymbolConstructor: () => SymbolObject, @@ -721,9 +733,13 @@ namespace ts { }; } - // Cache host information about script should be refreshed + export function getSupportedCodeFixes() { + return codefix.getSupportedErrorCodes(); + } + + // Cache host information about script Should be refreshed // at each language service public entry point, since we don't know when - // set of scripts handled by the host changes. + // the set of scripts handled by the host changes. class HostCache { private fileNameToEntry: FileMap; private _compilationSettings: CompilerOptions; @@ -1507,17 +1523,32 @@ namespace ts { } function getNavigationBarItems(fileName: string): NavigationBarItem[] { - const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + return NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName)); + } - return NavigationBar.getNavigationBarItems(sourceFile); + function getNavigationTree(fileName: string): NavigationTree { + return NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName)); + } + + function isTsOrTsxFile(fileName: string): boolean { + const kind = getScriptKind(fileName, host); + return kind === ScriptKind.TS || kind === ScriptKind.TSX; } function getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[] { + if (!isTsOrTsxFile(fileName)) { + // do not run semantic classification on non-ts-or-tsx files + return []; + } synchronizeHostData(); return ts.getSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span); } function getEncodedSemanticClassifications(fileName: string, span: TextSpan): Classifications { + if (!isTsOrTsxFile(fileName)) { + // do not run semantic classification on non-ts-or-tsx files + return { spans: [], endOfLineState: EndOfLineState.None }; + } synchronizeHostData(); return ts.getEncodedSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span); } @@ -1632,6 +1663,34 @@ namespace ts { return []; } + function getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[]): CodeAction[] { + synchronizeHostData(); + const sourceFile = getValidSourceFile(fileName); + const span = { start, length: end - start }; + const newLineChar = getNewLineOrDefaultFromHost(host); + + let allFixes: CodeAction[] = []; + + forEach(errorCodes, error => { + cancellationToken.throwIfCancellationRequested(); + + const context = { + errorCode: error, + sourceFile: sourceFile, + span: span, + program: program, + newLineCharacter: newLineChar + }; + + const fixes = codefix.getFixes(context); + if (fixes) { + allFixes = allFixes.concat(fixes); + } + }); + + return allFixes; + } + function getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion { return JsDoc.getDocCommentTemplateAtPosition(getNewLineOrDefaultFromHost(host), syntaxTreeCache.getCurrentSourceFile(fileName), position); } @@ -1846,6 +1905,7 @@ namespace ts { getRenameInfo, findRenameLocations, getNavigationBarItems, + getNavigationTree, getOutliningSpans, getTodoComments, getBraceMatchingAtPosition, @@ -1855,6 +1915,7 @@ namespace ts { getFormattingEditsAfterKeystroke, getDocCommentTemplateAtPosition, isValidBraceCompletionAtPosition, + getCodeFixesAtPosition, getEmitOutput, getNonBoundSourceFile, getSourceFile, diff --git a/src/services/shims.ts b/src/services/shims.ts index 56ab852606c..7ed1786640d 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -224,6 +224,9 @@ namespace ts { */ getNavigationBarItems(fileName: string): string; + /** Returns a JSON-encoded value of the type ts.NavigationTree. */ + getNavigationTree(fileName: string): string; + /** * Returns a JSON-encoded value of the type: * { textSpan: { start: number, length: number }; hintSpan: { start: number, length: number }; bannerText: string; autoCollapse: boolean } [] = []; @@ -971,6 +974,13 @@ namespace ts { ); } + public getNavigationTree(fileName: string): string { + return this.forwardJSONCall( + `getNavigationTree('${fileName}')`, + () => this.languageService.getNavigationTree(fileName) + ); + } + public getOutliningSpans(fileName: string): string { return this.forwardJSONCall( `getOutliningSpans('${fileName}')`, diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 8b4d986df53..c9141278b10 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -114,12 +114,12 @@ namespace ts.SymbolDisplay { } // try get the call/construct signature from the type if it matches - let callExpression: CallExpression; + let callExpression: CallExpression | NewExpression; if (location.kind === SyntaxKind.CallExpression || location.kind === SyntaxKind.NewExpression) { - callExpression = location; + callExpression = location; } else if (isCallExpressionTarget(location) || isNewExpressionTarget(location)) { - callExpression = location.parent; + callExpression = location.parent; } if (callExpression) { diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index c9428d9a082..03d04935068 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -79,6 +79,8 @@ "formatting/rulesMap.ts", "formatting/rulesProvider.ts", "formatting/smartIndenter.ts", - "formatting/tokenRange.ts" + "formatting/tokenRange.ts", + "codeFixes/codeFixProvider.ts", + "codeFixes/fixes.ts" ] } diff --git a/src/services/types.ts b/src/services/types.ts index f84986bb534..3d2bcf4c360 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -225,6 +225,7 @@ namespace ts { getNavigateToItems(searchValue: string, maxResultCount?: number, fileName?: string, excludeDtsFiles?: boolean): NavigateToItem[]; getNavigationBarItems(fileName: string): NavigationBarItem[]; + getNavigationTree(fileName: string): NavigationTree; getOutliningSpans(fileName: string): OutliningSpan[]; getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[]; @@ -239,6 +240,8 @@ namespace ts { isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; + getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[]): CodeAction[]; + getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput; getProgram(): Program; @@ -264,6 +267,12 @@ namespace ts { classificationType: string; // ClassificationTypeNames } + /** + * Navigation bar interface designed for visual studio's dual-column layout. + * This does not form a proper tree. + * The navbar is returned as a list of top-level items, each of which has a list of child items. + * Child items always have an empty array for their `childItems`. + */ export interface NavigationBarItem { text: string; kind: string; @@ -275,6 +284,26 @@ namespace ts { grayed: boolean; } + /** + * Node in a tree of nested declarations in a file. + * The top node is always a script or module node. + */ + export interface NavigationTree { + /** Name of the declaration, or a short description, e.g. "". */ + text: string; + /** A ScriptElementKind */ + kind: string; + /** ScriptElementKindModifier separated by commas, e.g. "public,abstract" */ + kindModifiers: string; + /** + * Spans of the nodes that generated this declaration. + * There will be more than one if this is the result of merging. + */ + spans: TextSpan[]; + /** Present if non-empty */ + childItems?: NavigationTree[]; + } + export interface TodoCommentDescriptor { text: string; priority: number; @@ -291,6 +320,18 @@ namespace ts { newText: string; } + export interface FileTextChanges { + fileName: string; + textChanges: TextChange[]; + } + + export interface CodeAction { + /** Description of the code action to display in the UI of the editor */ + description: string; + /** Text changes to apply to each file as part of the code action */ + changes: FileTextChanges[]; + } + export interface TextInsertion { newText: string; /** The position in newText the caret should point to after the insertion. */ @@ -362,11 +403,11 @@ namespace ts { export interface EditorSettings { baseIndentSize?: number; - indentSize: number; - tabSize: number; - newLineCharacter: string; - convertTabsToSpaces: boolean; - indentStyle: IndentStyle; + indentSize?: number; + tabSize?: number; + newLineCharacter?: string; + convertTabsToSpaces?: boolean; + indentStyle?: IndentStyle; } /* @deprecated - consider using FormatCodeSettings instead */ @@ -387,19 +428,19 @@ namespace ts { } export interface FormatCodeSettings extends EditorSettings { - insertSpaceAfterCommaDelimiter: boolean; - insertSpaceAfterSemicolonInForStatements: boolean; - insertSpaceBeforeAndAfterBinaryOperators: boolean; - insertSpaceAfterKeywordsInControlFlowStatements: boolean; - insertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean; - insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean; - insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean; + insertSpaceAfterCommaDelimiter?: boolean; + insertSpaceAfterSemicolonInForStatements?: boolean; + insertSpaceBeforeAndAfterBinaryOperators?: boolean; + insertSpaceAfterKeywordsInControlFlowStatements?: boolean; + insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean; + insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean; + insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean; insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces?: boolean; - insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean; - insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: boolean; + insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean; + insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean; insertSpaceAfterTypeAssertion?: boolean; - placeOpenBraceOnNewLineForFunctions: boolean; - placeOpenBraceOnNewLineForControlBlocks: boolean; + placeOpenBraceOnNewLineForFunctions?: boolean; + placeOpenBraceOnNewLineForControlBlocks?: boolean; } export interface DefinitionInfo { @@ -505,7 +546,11 @@ namespace ts { export interface CompletionInfo { isGlobalCompletion: boolean; isMemberCompletion: boolean; - isNewIdentifierLocation: boolean; // true when the current location also allows for a new identifier + + /** + * true when the current location also allows for a new identifier + */ + isNewIdentifierLocation: boolean; entries: CompletionEntry[]; } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index e61906b4f09..a255c5bc0a8 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -376,7 +376,7 @@ namespace ts { return true; case SyntaxKind.Identifier: // 'this' as a parameter - return (node as Identifier).originalKeywordKind === SyntaxKind.ThisKeyword && node.parent.kind === SyntaxKind.Parameter; + return identifierIsThisKeyword(node as Identifier) && node.parent.kind === SyntaxKind.Parameter; default: return false; } diff --git a/tests/baselines/reference/ES5SymbolProperty2.errors.txt b/tests/baselines/reference/ES5SymbolProperty2.errors.txt index 9a6526a2f86..97579a4f27a 100644 --- a/tests/baselines/reference/ES5SymbolProperty2.errors.txt +++ b/tests/baselines/reference/ES5SymbolProperty2.errors.txt @@ -4,7 +4,7 @@ tests/cases/conformance/Symbols/ES5SymbolProperty2.ts(10,11): error TS2304: Cann ==== tests/cases/conformance/Symbols/ES5SymbolProperty2.ts (2 errors) ==== module M { - var Symbol; + var Symbol: any; export class C { [Symbol.iterator]() { } diff --git a/tests/baselines/reference/ES5SymbolProperty2.js b/tests/baselines/reference/ES5SymbolProperty2.js index f04a4671d3f..0cfe717ae56 100644 --- a/tests/baselines/reference/ES5SymbolProperty2.js +++ b/tests/baselines/reference/ES5SymbolProperty2.js @@ -1,6 +1,6 @@ //// [ES5SymbolProperty2.ts] module M { - var Symbol; + var Symbol: any; export class C { [Symbol.iterator]() { } diff --git a/tests/baselines/reference/ES5SymbolProperty3.errors.txt b/tests/baselines/reference/ES5SymbolProperty3.errors.txt index 7c6cc5a9cd7..2953ed6ac6a 100644 --- a/tests/baselines/reference/ES5SymbolProperty3.errors.txt +++ b/tests/baselines/reference/ES5SymbolProperty3.errors.txt @@ -2,7 +2,7 @@ tests/cases/conformance/Symbols/ES5SymbolProperty3.ts(4,6): error TS2471: A comp ==== tests/cases/conformance/Symbols/ES5SymbolProperty3.ts (1 errors) ==== - var Symbol; + var Symbol: any; class C { [Symbol.iterator]() { } diff --git a/tests/baselines/reference/ES5SymbolProperty3.js b/tests/baselines/reference/ES5SymbolProperty3.js index 6589858625c..084f79bd077 100644 --- a/tests/baselines/reference/ES5SymbolProperty3.js +++ b/tests/baselines/reference/ES5SymbolProperty3.js @@ -1,5 +1,5 @@ //// [ES5SymbolProperty3.ts] -var Symbol; +var Symbol: any; class C { [Symbol.iterator]() { } diff --git a/tests/baselines/reference/TypeArgumentList1.errors.txt b/tests/baselines/reference/TypeArgumentList1.errors.txt index 4138f3f8cc5..851dd0b59ed 100644 --- a/tests/baselines/reference/TypeArgumentList1.errors.txt +++ b/tests/baselines/reference/TypeArgumentList1.errors.txt @@ -1,10 +1,31 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,1): error TS2304: Cannot find name 'Foo'. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,1): error TS2695: Left side of comma operator is unused and has no side effects. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,1): error TS2695: Left side of comma operator is unused and has no side effects. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,5): error TS2304: Cannot find name 'A'. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,7): error TS2304: Cannot find name 'B'. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,9): error TS1127: Invalid character. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,11): error TS2304: Cannot find name 'C'. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,14): error TS2695: Left side of comma operator is unused and has no side effects. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,14): error TS2695: Left side of comma operator is unused and has no side effects. -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts (9 errors) ==== Foo(4, 5, 6); ~~~ !!! error TS2304: Cannot find name 'Foo'. + ~~~~~ +!!! error TS2695: Left side of comma operator is unused and has no side effects. + ~~~~~~~ +!!! error TS2695: Left side of comma operator is unused and has no side effects. + ~ +!!! error TS2304: Cannot find name 'A'. + ~ +!!! error TS2304: Cannot find name 'B'. -!!! error TS1127: Invalid character. \ No newline at end of file +!!! error TS1127: Invalid character. + ~ +!!! error TS2304: Cannot find name 'C'. + ~ +!!! error TS2695: Left side of comma operator is unused and has no side effects. + ~~~~ +!!! error TS2695: Left side of comma operator is unused and has no side effects. \ No newline at end of file diff --git a/tests/baselines/reference/TypeArgumentList1.js b/tests/baselines/reference/TypeArgumentList1.js index b87b310a9af..f6f5412ce16 100644 --- a/tests/baselines/reference/TypeArgumentList1.js +++ b/tests/baselines/reference/TypeArgumentList1.js @@ -2,4 +2,5 @@ Foo(4, 5, 6); //// [TypeArgumentList1.js] -Foo(4, 5, 6); +Foo < A, B, ; +C > (4, 5, 6); diff --git a/tests/baselines/reference/anyPlusAny1.js b/tests/baselines/reference/anyPlusAny1.js index 457688933d7..4b28a1d22e2 100644 --- a/tests/baselines/reference/anyPlusAny1.js +++ b/tests/baselines/reference/anyPlusAny1.js @@ -1,5 +1,5 @@ //// [anyPlusAny1.ts] -var x; +var x: any; x.name = "hello"; var z = x + x; diff --git a/tests/baselines/reference/anyPlusAny1.symbols b/tests/baselines/reference/anyPlusAny1.symbols index e0552e4541f..3b33a11987e 100644 --- a/tests/baselines/reference/anyPlusAny1.symbols +++ b/tests/baselines/reference/anyPlusAny1.symbols @@ -1,5 +1,5 @@ === tests/cases/compiler/anyPlusAny1.ts === -var x; +var x: any; >x : Symbol(x, Decl(anyPlusAny1.ts, 0, 3)) x.name = "hello"; diff --git a/tests/baselines/reference/anyPlusAny1.types b/tests/baselines/reference/anyPlusAny1.types index f6ca9c4996e..67323a10fd6 100644 --- a/tests/baselines/reference/anyPlusAny1.types +++ b/tests/baselines/reference/anyPlusAny1.types @@ -1,5 +1,5 @@ === tests/cases/compiler/anyPlusAny1.ts === -var x; +var x: any; >x : any x.name = "hello"; diff --git a/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.types b/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.types index 7492a698e3a..c2d9213ca60 100644 --- a/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.types +++ b/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.types @@ -10,10 +10,10 @@ var Foo; >Foo : any type ->type : any +>type : undefined Foo = string; ->Foo = string : any +>Foo = string : undefined >Foo : any ->string : any +>string : undefined diff --git a/tests/baselines/reference/assignEveryTypeToAny.types b/tests/baselines/reference/assignEveryTypeToAny.types index cfc24e1da65..fd1dccefae0 100644 --- a/tests/baselines/reference/assignEveryTypeToAny.types +++ b/tests/baselines/reference/assignEveryTypeToAny.types @@ -59,9 +59,9 @@ var e = undefined; >undefined : undefined x = e; ->x = e : any +>x = e : undefined >x : any ->e : any +>e : undefined var e2: typeof undefined; >e2 : any diff --git a/tests/baselines/reference/assignmentLHSIsReference.js b/tests/baselines/reference/assignmentLHSIsReference.js index f0af56ebc3b..85d2aab2c46 100644 --- a/tests/baselines/reference/assignmentLHSIsReference.js +++ b/tests/baselines/reference/assignmentLHSIsReference.js @@ -1,5 +1,5 @@ //// [assignmentLHSIsReference.ts] -var value; +var value: any; // identifiers: variable and parameter var x1: number; diff --git a/tests/baselines/reference/assignmentLHSIsReference.symbols b/tests/baselines/reference/assignmentLHSIsReference.symbols index b551557708f..417ba3c07ea 100644 --- a/tests/baselines/reference/assignmentLHSIsReference.symbols +++ b/tests/baselines/reference/assignmentLHSIsReference.symbols @@ -1,5 +1,5 @@ === tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsReference.ts === -var value; +var value: any; >value : Symbol(value, Decl(assignmentLHSIsReference.ts, 0, 3)) // identifiers: variable and parameter diff --git a/tests/baselines/reference/assignmentLHSIsReference.types b/tests/baselines/reference/assignmentLHSIsReference.types index dfb3b236c0a..2a7fa2982aa 100644 --- a/tests/baselines/reference/assignmentLHSIsReference.types +++ b/tests/baselines/reference/assignmentLHSIsReference.types @@ -1,5 +1,5 @@ === tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsReference.ts === -var value; +var value: any; >value : any // identifiers: variable and parameter diff --git a/tests/baselines/reference/assignmentLHSIsValue.errors.txt b/tests/baselines/reference/assignmentLHSIsValue.errors.txt index bf253df5e70..f97ae2bcfa5 100644 --- a/tests/baselines/reference/assignmentLHSIsValue.errors.txt +++ b/tests/baselines/reference/assignmentLHSIsValue.errors.txt @@ -41,7 +41,7 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(7 ==== tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts (39 errors) ==== // expected error for all the LHS of assignments - var value; + var value: any; // this class C { diff --git a/tests/baselines/reference/assignmentLHSIsValue.js b/tests/baselines/reference/assignmentLHSIsValue.js index ab3f80eff21..155fa26fa81 100644 --- a/tests/baselines/reference/assignmentLHSIsValue.js +++ b/tests/baselines/reference/assignmentLHSIsValue.js @@ -1,6 +1,6 @@ //// [assignmentLHSIsValue.ts] // expected error for all the LHS of assignments -var value; +var value: any; // this class C { diff --git a/tests/baselines/reference/asyncAwaitIsolatedModules_es5.js b/tests/baselines/reference/asyncAwaitIsolatedModules_es5.js index 7eb2157c026..fe99be204fc 100644 --- a/tests/baselines/reference/asyncAwaitIsolatedModules_es5.js +++ b/tests/baselines/reference/asyncAwaitIsolatedModules_es5.js @@ -44,7 +44,7 @@ module M { 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()); }); diff --git a/tests/baselines/reference/asyncAwaitIsolatedModules_es6.js b/tests/baselines/reference/asyncAwaitIsolatedModules_es6.js index 4022fde7f54..98d11d72bfb 100644 --- a/tests/baselines/reference/asyncAwaitIsolatedModules_es6.js +++ b/tests/baselines/reference/asyncAwaitIsolatedModules_es6.js @@ -43,7 +43,7 @@ module M { 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()); }); diff --git a/tests/baselines/reference/asyncAwait_es5.js b/tests/baselines/reference/asyncAwait_es5.js index 67f7d000351..043e68abeab 100644 --- a/tests/baselines/reference/asyncAwait_es5.js +++ b/tests/baselines/reference/asyncAwait_es5.js @@ -43,7 +43,7 @@ module M { 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()); }); diff --git a/tests/baselines/reference/asyncAwait_es6.js b/tests/baselines/reference/asyncAwait_es6.js index be2eb90e3e4..4ba9e096e10 100644 --- a/tests/baselines/reference/asyncAwait_es6.js +++ b/tests/baselines/reference/asyncAwait_es6.js @@ -43,7 +43,7 @@ module M { 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()); }); diff --git a/tests/baselines/reference/asyncFunctionNoReturnType.js b/tests/baselines/reference/asyncFunctionNoReturnType.js index fc7b0b52f1c..fd39fc74d0e 100644 --- a/tests/baselines/reference/asyncFunctionNoReturnType.js +++ b/tests/baselines/reference/asyncFunctionNoReturnType.js @@ -9,7 +9,7 @@ async () => { 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()); }); diff --git a/tests/baselines/reference/asyncFunctionReturnType.js b/tests/baselines/reference/asyncFunctionReturnType.js index 12cb44fbcf0..76f9952ab9f 100644 --- a/tests/baselines/reference/asyncFunctionReturnType.js +++ b/tests/baselines/reference/asyncFunctionReturnType.js @@ -14,7 +14,7 @@ async function fAsyncExplicit(): Promise<[number, boolean]> { 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()); }); diff --git a/tests/baselines/reference/asyncFunctionsAcrossFiles.js b/tests/baselines/reference/asyncFunctionsAcrossFiles.js index 94ccff2358c..e9b5710dc07 100644 --- a/tests/baselines/reference/asyncFunctionsAcrossFiles.js +++ b/tests/baselines/reference/asyncFunctionsAcrossFiles.js @@ -19,7 +19,7 @@ export const b = { 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()); }); @@ -34,7 +34,7 @@ export const b = { 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()); }); diff --git a/tests/baselines/reference/asyncFunctionsAndStrictNullChecks.js b/tests/baselines/reference/asyncFunctionsAndStrictNullChecks.js index 3e351c37046..ac9a558a53f 100644 --- a/tests/baselines/reference/asyncFunctionsAndStrictNullChecks.js +++ b/tests/baselines/reference/asyncFunctionsAndStrictNullChecks.js @@ -30,7 +30,7 @@ async function sample2(x?: number) { 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()); }); diff --git a/tests/baselines/reference/asyncImportedPromise_es5.js b/tests/baselines/reference/asyncImportedPromise_es5.js index 76ffbc833aa..e5c28eb2dc1 100644 --- a/tests/baselines/reference/asyncImportedPromise_es5.js +++ b/tests/baselines/reference/asyncImportedPromise_es5.js @@ -29,7 +29,7 @@ exports.Task = Task; 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()); }); diff --git a/tests/baselines/reference/asyncImportedPromise_es6.js b/tests/baselines/reference/asyncImportedPromise_es6.js index 56a41b0283f..17c9de51ee6 100644 --- a/tests/baselines/reference/asyncImportedPromise_es6.js +++ b/tests/baselines/reference/asyncImportedPromise_es6.js @@ -19,7 +19,7 @@ exports.Task = Task; 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()); }); diff --git a/tests/baselines/reference/asyncMultiFile_es5.js b/tests/baselines/reference/asyncMultiFile_es5.js index cfc3cb235b0..6b44f5393fc 100644 --- a/tests/baselines/reference/asyncMultiFile_es5.js +++ b/tests/baselines/reference/asyncMultiFile_es5.js @@ -9,7 +9,7 @@ function g() { } 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()); }); diff --git a/tests/baselines/reference/asyncMultiFile_es6.js b/tests/baselines/reference/asyncMultiFile_es6.js index 08d63521fb5..0c45aa6c8a3 100644 --- a/tests/baselines/reference/asyncMultiFile_es6.js +++ b/tests/baselines/reference/asyncMultiFile_es6.js @@ -9,7 +9,7 @@ function g() { } 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()); }); diff --git a/tests/baselines/reference/await_unaryExpression_es6.js b/tests/baselines/reference/await_unaryExpression_es6.js index 46065bdada9..6609cc6f3f4 100644 --- a/tests/baselines/reference/await_unaryExpression_es6.js +++ b/tests/baselines/reference/await_unaryExpression_es6.js @@ -20,7 +20,7 @@ async function bar4() { 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()); }); diff --git a/tests/baselines/reference/await_unaryExpression_es6_1.js b/tests/baselines/reference/await_unaryExpression_es6_1.js index c6f5f1142c0..48f50d76f4a 100644 --- a/tests/baselines/reference/await_unaryExpression_es6_1.js +++ b/tests/baselines/reference/await_unaryExpression_es6_1.js @@ -24,7 +24,7 @@ async function bar4() { 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()); }); diff --git a/tests/baselines/reference/await_unaryExpression_es6_2.js b/tests/baselines/reference/await_unaryExpression_es6_2.js index 3c341018ed1..5e9d63a21d2 100644 --- a/tests/baselines/reference/await_unaryExpression_es6_2.js +++ b/tests/baselines/reference/await_unaryExpression_es6_2.js @@ -16,7 +16,7 @@ async function bar3() { 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()); }); diff --git a/tests/baselines/reference/await_unaryExpression_es6_3.js b/tests/baselines/reference/await_unaryExpression_es6_3.js index 077e264c450..469c8ea3ee9 100644 --- a/tests/baselines/reference/await_unaryExpression_es6_3.js +++ b/tests/baselines/reference/await_unaryExpression_es6_3.js @@ -22,7 +22,7 @@ async function bar4() { 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()); }); diff --git a/tests/baselines/reference/capturedLetConstInLoop9.types b/tests/baselines/reference/capturedLetConstInLoop9.types index 486697b8d84..453176a40c9 100644 --- a/tests/baselines/reference/capturedLetConstInLoop9.types +++ b/tests/baselines/reference/capturedLetConstInLoop9.types @@ -39,7 +39,7 @@ for (let x = 0; x < 1; ++x) { } switch (x) { ->x : any +>x : undefined case 1: >1 : 1 diff --git a/tests/baselines/reference/capturedLetConstInLoop9_ES6.types b/tests/baselines/reference/capturedLetConstInLoop9_ES6.types index be4457315ee..df118279f30 100644 --- a/tests/baselines/reference/capturedLetConstInLoop9_ES6.types +++ b/tests/baselines/reference/capturedLetConstInLoop9_ES6.types @@ -40,7 +40,7 @@ for (let x = 0; x < 1; ++x) { } switch (x) { ->x : any +>x : undefined case 1: >1 : 1 diff --git a/tests/baselines/reference/castOfAwait.js b/tests/baselines/reference/castOfAwait.js index 26e9812bf43..1f66d49e0f3 100644 --- a/tests/baselines/reference/castOfAwait.js +++ b/tests/baselines/reference/castOfAwait.js @@ -12,7 +12,7 @@ async function f() { 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()); }); diff --git a/tests/baselines/reference/commentsArgumentsOfCallExpression2.types b/tests/baselines/reference/commentsArgumentsOfCallExpression2.types index 7ec29aa9124..bc6bf5baa90 100644 --- a/tests/baselines/reference/commentsArgumentsOfCallExpression2.types +++ b/tests/baselines/reference/commentsArgumentsOfCallExpression2.types @@ -17,7 +17,7 @@ foo(/*c2*/ 1, /*d2*/ 1 + 2, /*e1*/ a + b); >1 : 1 >2 : 2 >a + b : any ->a : any +>a : undefined >b : any foo(/*c3*/ function () { }, /*d2*/() => { }, /*e2*/ a + /*e3*/ b); @@ -26,7 +26,7 @@ foo(/*c3*/ function () { }, /*d2*/() => { }, /*e2*/ a + /*e3*/ b); >function () { } : () => void >() => { } : () => void >a + /*e3*/ b : any ->a : any +>a : undefined >b : any foo(/*c3*/ function () { }, /*d3*/() => { }, /*e3*/(a + b)); @@ -36,7 +36,7 @@ foo(/*c3*/ function () { }, /*d3*/() => { }, /*e3*/(a + b)); >() => { } : () => void >(a + b) : any >a + b : any ->a : any +>a : undefined >b : any foo( diff --git a/tests/baselines/reference/compoundAssignmentLHSIsReference.types b/tests/baselines/reference/compoundAssignmentLHSIsReference.types index 4816307f508..a82eb17426d 100644 --- a/tests/baselines/reference/compoundAssignmentLHSIsReference.types +++ b/tests/baselines/reference/compoundAssignmentLHSIsReference.types @@ -9,12 +9,12 @@ var x1: number; x1 *= value; >x1 *= value : number >x1 : number ->value : any +>value : undefined x1 += value; ->x1 += value : any +>x1 += value : number >x1 : number ->value : any +>value : undefined function fn1(x2: number) { >fn1 : (x2: number) => void @@ -41,41 +41,41 @@ x3.a *= value; >x3.a : number >x3 : { a: number; } >a : number ->value : any +>value : undefined x3.a += value; ->x3.a += value : any +>x3.a += value : number >x3.a : number >x3 : { a: number; } >a : number ->value : any +>value : undefined x3['a'] *= value; >x3['a'] *= value : number >x3['a'] : number >x3 : { a: number; } >'a' : "a" ->value : any +>value : undefined x3['a'] += value; ->x3['a'] += value : any +>x3['a'] += value : number >x3['a'] : number >x3 : { a: number; } >'a' : "a" ->value : any +>value : undefined // parentheses, the contained expression is reference (x1) *= value; >(x1) *= value : number >(x1) : number >x1 : number ->value : any +>value : undefined (x1) += value; ->(x1) += value : any +>(x1) += value : number >(x1) : number >x1 : number ->value : any +>value : undefined function fn2(x4: number) { >fn2 : (x4: number) => void @@ -100,15 +100,15 @@ function fn2(x4: number) { >x3.a : number >x3 : { a: number; } >a : number ->value : any +>value : undefined (x3.a) += value; ->(x3.a) += value : any +>(x3.a) += value : number >(x3.a) : number >x3.a : number >x3 : { a: number; } >a : number ->value : any +>value : undefined (x3['a']) *= value; >(x3['a']) *= value : number @@ -116,13 +116,13 @@ function fn2(x4: number) { >x3['a'] : number >x3 : { a: number; } >'a' : "a" ->value : any +>value : undefined (x3['a']) += value; ->(x3['a']) += value : any +>(x3['a']) += value : number >(x3['a']) : number >x3['a'] : number >x3 : { a: number; } >'a' : "a" ->value : any +>value : undefined diff --git a/tests/baselines/reference/compoundAssignmentLHSIsValue.errors.txt b/tests/baselines/reference/compoundAssignmentLHSIsValue.errors.txt index 392e1781dd5..61f893ba88f 100644 --- a/tests/baselines/reference/compoundAssignmentLHSIsValue.errors.txt +++ b/tests/baselines/reference/compoundAssignmentLHSIsValue.errors.txt @@ -77,7 +77,7 @@ tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsVa ==== tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts (74 errors) ==== // expected error for all the LHS of compound assignments (arithmetic and addition) - var value; + var value: any; // this class C { diff --git a/tests/baselines/reference/compoundAssignmentLHSIsValue.js b/tests/baselines/reference/compoundAssignmentLHSIsValue.js index bfea11911bf..df3015731c7 100644 --- a/tests/baselines/reference/compoundAssignmentLHSIsValue.js +++ b/tests/baselines/reference/compoundAssignmentLHSIsValue.js @@ -1,7 +1,7 @@ //// [compoundAssignmentLHSIsValue.ts] // expected error for all the LHS of compound assignments (arithmetic and addition) -var value; +var value: any; // this class C { diff --git a/tests/baselines/reference/compoundExponentiationAssignmentLHSIsReference.js b/tests/baselines/reference/compoundExponentiationAssignmentLHSIsReference.js index dfee41fad81..d5104f1dbdc 100644 --- a/tests/baselines/reference/compoundExponentiationAssignmentLHSIsReference.js +++ b/tests/baselines/reference/compoundExponentiationAssignmentLHSIsReference.js @@ -1,5 +1,5 @@ //// [compoundExponentiationAssignmentLHSIsReference.ts] -var value; +var value: any; // identifiers: variable and parameter var x1: number; diff --git a/tests/baselines/reference/compoundExponentiationAssignmentLHSIsReference.symbols b/tests/baselines/reference/compoundExponentiationAssignmentLHSIsReference.symbols index 775d43b0c58..b69c1afdb9b 100644 --- a/tests/baselines/reference/compoundExponentiationAssignmentLHSIsReference.symbols +++ b/tests/baselines/reference/compoundExponentiationAssignmentLHSIsReference.symbols @@ -1,5 +1,5 @@ === tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsReference.ts === -var value; +var value: any; >value : Symbol(value, Decl(compoundExponentiationAssignmentLHSIsReference.ts, 0, 3)) // identifiers: variable and parameter diff --git a/tests/baselines/reference/compoundExponentiationAssignmentLHSIsReference.types b/tests/baselines/reference/compoundExponentiationAssignmentLHSIsReference.types index 55b90382d7b..32230f7f8ef 100644 --- a/tests/baselines/reference/compoundExponentiationAssignmentLHSIsReference.types +++ b/tests/baselines/reference/compoundExponentiationAssignmentLHSIsReference.types @@ -1,5 +1,5 @@ === tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsReference.ts === -var value; +var value: any; >value : any // identifiers: variable and parameter diff --git a/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.errors.txt b/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.errors.txt index 23720468bb7..0d9bab910ef 100644 --- a/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.errors.txt +++ b/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.errors.txt @@ -40,7 +40,7 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm ==== tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts (38 errors) ==== // expected error for all the LHS of compound assignments (arithmetic and addition) - var value; + var value: any; // this class C { diff --git a/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.js b/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.js index c8fb8c6a222..d188a592588 100644 --- a/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.js +++ b/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.js @@ -1,6 +1,6 @@ //// [compoundExponentiationAssignmentLHSIsValue.ts] // expected error for all the LHS of compound assignments (arithmetic and addition) -var value; +var value: any; // this class C { diff --git a/tests/baselines/reference/constraintSatisfactionWithAny.types b/tests/baselines/reference/constraintSatisfactionWithAny.types index f3363fe1a90..2f9c7553288 100644 --- a/tests/baselines/reference/constraintSatisfactionWithAny.types +++ b/tests/baselines/reference/constraintSatisfactionWithAny.types @@ -35,20 +35,20 @@ var a; >a : any foo(a); ->foo(a) : any +>foo(a) : undefined >foo : (x: T) => T ->a : any +>a : undefined foo2(a); ->foo2(a) : any +>foo2(a) : undefined >foo2 : (x: T) => T ->a : any +>a : undefined //foo3(a); foo4(a); ->foo4(a) : any +>foo4(a) : undefined >foo4 : (x: T) => void>(x: T) => T ->a : any +>a : undefined var b: number; >b : number @@ -84,10 +84,10 @@ class C { } var c1 = new C(a); ->c1 : C ->new C(a) : C +>c1 : C +>new C(a) : C >C : typeof C ->a : any +>a : undefined var c2 = new C(b); >c2 : C @@ -106,10 +106,10 @@ class C2 { } var c3 = new C2(a); ->c3 : C2 ->new C2(a) : C2 +>c3 : C2 +>new C2(a) : C2 >C2 : typeof C2 ->a : any +>a : undefined var c4 = new C2(b); >c4 : C2 @@ -138,10 +138,10 @@ class C4(x:T) => T> { } var c7 = new C4(a); ->c7 : C4 ->new C4(a) : C4 +>c7 : C4 +>new C4(a) : C4 >C4 : typeof C4 ->a : any +>a : undefined var c8 = new C4(b); >c8 : C4 diff --git a/tests/baselines/reference/controlFlowCaching.errors.txt b/tests/baselines/reference/controlFlowCaching.errors.txt new file mode 100644 index 00000000000..1086695313e --- /dev/null +++ b/tests/baselines/reference/controlFlowCaching.errors.txt @@ -0,0 +1,128 @@ +tests/cases/compiler/controlFlowCaching.ts(38,17): error TS2532: Object is possibly 'undefined'. +tests/cases/compiler/controlFlowCaching.ts(38,29): error TS2339: Property 'y' does not exist on type 'never'. +tests/cases/compiler/controlFlowCaching.ts(40,17): error TS2532: Object is possibly 'undefined'. +tests/cases/compiler/controlFlowCaching.ts(40,29): error TS2339: Property 'x' does not exist on type 'never'. +tests/cases/compiler/controlFlowCaching.ts(42,17): error TS2532: Object is possibly 'undefined'. +tests/cases/compiler/controlFlowCaching.ts(42,29): error TS2339: Property 'y' does not exist on type 'never'. +tests/cases/compiler/controlFlowCaching.ts(44,17): error TS2532: Object is possibly 'undefined'. +tests/cases/compiler/controlFlowCaching.ts(44,29): error TS2339: Property 'y' does not exist on type 'never'. +tests/cases/compiler/controlFlowCaching.ts(46,17): error TS2532: Object is possibly 'undefined'. +tests/cases/compiler/controlFlowCaching.ts(46,29): error TS2339: Property 'y' does not exist on type 'never'. +tests/cases/compiler/controlFlowCaching.ts(48,17): error TS2532: Object is possibly 'undefined'. +tests/cases/compiler/controlFlowCaching.ts(48,29): error TS2339: Property 'y' does not exist on type 'never'. +tests/cases/compiler/controlFlowCaching.ts(53,5): error TS2532: Object is possibly 'undefined'. +tests/cases/compiler/controlFlowCaching.ts(53,14): error TS2339: Property 'y' does not exist on type 'never'. +tests/cases/compiler/controlFlowCaching.ts(55,14): error TS2678: Type '"start"' is not comparable to type 'undefined'. +tests/cases/compiler/controlFlowCaching.ts(58,14): error TS2678: Type '"end"' is not comparable to type 'undefined'. +tests/cases/compiler/controlFlowCaching.ts(61,14): error TS2678: Type '"middle"' is not comparable to type 'undefined'. +tests/cases/compiler/controlFlowCaching.ts(62,13): error TS2532: Object is possibly 'undefined'. +tests/cases/compiler/controlFlowCaching.ts(62,25): error TS2339: Property 'y' does not exist on type 'never'. + + +==== tests/cases/compiler/controlFlowCaching.ts (19 errors) ==== + + // Repro for #8401 + + function f(dim, offsets, arr, acommon, centerAnchorLimit, g, has, lin) { + var isRtl = this._isRtl(); // chart mirroring + // prepare variable + var o = this.opt, ta = this.chart.theme.axis, position = o.position, + leftBottom = position !== "rightOrTop", rotation = o.rotation % 360, + start, stop, titlePos, titleRotation = 0, titleOffset, axisVector, tickVector, anchorOffset, labelOffset, labelAlign, + labelGap = this.chart.theme.axis.tick.labelGap, + taFont = o.font || (ta.majorTick && ta.majorTick.font) || (ta.tick && ta.tick.font), + taTitleFont = o.titleFont || (ta.title && ta.title.font), + taFontColor = o.fontColor || (ta.majorTick && ta.majorTick.fontColor) || (ta.tick && ta.tick.fontColor) || "black", + taTitleFontColor = o.titleFontColor || (ta.title && ta.title.fontColor) || "black", + taTitleGap = (o.titleGap == 0) ? 0 : o.titleGap || (ta.title && ta.title.gap) || 15, + taTitleOrientation = o.titleOrientation || (ta.title && ta.title.orientation) || "axis", + taMajorTick = this.chart.theme.getTick("major", o), + taMinorTick = this.chart.theme.getTick("minor", o), + taMicroTick = this.chart.theme.getTick("micro", o), + + taStroke = "stroke" in o ? o.stroke : ta.stroke, + size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0, + cosr = Math.abs(Math.cos(rotation * Math.PI / 180)), + sinr = Math.abs(Math.sin(rotation * Math.PI / 180)), + tsize = taTitleFont ? g.normalizedLength(g.splitFontString(taTitleFont).size) : 0; + if (rotation < 0) { + rotation += 360; + } + var cachedLabelW = this._getMaxLabelSize(); + cachedLabelW = cachedLabelW && cachedLabelW.majLabelW; + titleOffset = size * cosr + (cachedLabelW || 0) * sinr + labelGap + Math.max(taMajorTick.length > 0 ? taMajorTick.length : 0, + taMinorTick.length > 0 ? taMinorTick.length : 0) + + tsize + taTitleGap; + axisVector = { x: isRtl ? -1 : 1, y: 0 }; // chart mirroring + switch (rotation) { + default: + if (rotation < (90 - centerAnchorLimit)) { + labelOffset.y = leftBottom ? size : 0; + ~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~ +!!! error TS2339: Property 'y' does not exist on type 'never'. + } else if (rotation < (90 + centerAnchorLimit)) { + labelOffset.x = -size * 0.4; + ~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~ +!!! error TS2339: Property 'x' does not exist on type 'never'. + } else if (rotation < 180) { + labelOffset.y = leftBottom ? 0 : -size; + ~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~ +!!! error TS2339: Property 'y' does not exist on type 'never'. + } else if (rotation < (270 - centerAnchorLimit)) { + labelOffset.y = leftBottom ? 0 : -size; + ~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~ +!!! error TS2339: Property 'y' does not exist on type 'never'. + } else if (rotation < (270 + centerAnchorLimit)) { + labelOffset.y = leftBottom ? size * 0.4 : 0; + ~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~ +!!! error TS2339: Property 'y' does not exist on type 'never'. + } else { + labelOffset.y = leftBottom ? size : 0; + ~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~ +!!! error TS2339: Property 'y' does not exist on type 'never'. + } + } + + titleRotation = (taTitleOrientation && taTitleOrientation == "away") ? 180 : 0; + titlePos.y = offsets.t - titleOffset + (titleRotation ? 0 : tsize); + ~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~ +!!! error TS2339: Property 'y' does not exist on type 'never'. + switch (labelAlign) { + case "start": + ~~~~~~~ +!!! error TS2678: Type '"start"' is not comparable to type 'undefined'. + labelAlign = "end"; + break; + case "end": + ~~~~~ +!!! error TS2678: Type '"end"' is not comparable to type 'undefined'. + labelAlign = "start"; + break; + case "middle": + ~~~~~~~~ +!!! error TS2678: Type '"middle"' is not comparable to type 'undefined'. + labelOffset.y -= size; + ~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~ +!!! error TS2339: Property 'y' does not exist on type 'never'. + break; + } + + let _ = rotation; + } + \ No newline at end of file diff --git a/tests/baselines/reference/controlFlowIIFE.types b/tests/baselines/reference/controlFlowIIFE.types index 6173e79dbbb..7cf4337b53b 100644 --- a/tests/baselines/reference/controlFlowIIFE.types +++ b/tests/baselines/reference/controlFlowIIFE.types @@ -118,7 +118,7 @@ maybeNumber++; if (maybeNumber !== undefined) { >maybeNumber !== undefined : boolean ->maybeNumber : number | undefined +>maybeNumber : number >undefined : undefined maybeNumber++; diff --git a/tests/baselines/reference/controlFlowLetVar.js b/tests/baselines/reference/controlFlowLetVar.js new file mode 100644 index 00000000000..24ad95259b1 --- /dev/null +++ b/tests/baselines/reference/controlFlowLetVar.js @@ -0,0 +1,247 @@ +//// [controlFlowLetVar.ts] + +declare let cond: boolean; + +// CFA for 'let' with no type annotation and initializer +function f1() { + let x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined +} + +// CFA for 'let' with no type annotation and 'undefined' initializer +function f2() { + let x = undefined; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined +} + +// CFA for 'let' with no type annotation and 'null' initializer +function f3() { + let x = null; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | null +} + +// No CFA for 'let' with with type annotation +function f4() { + let x: any; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // any +} + +// CFA for 'var' with no type annotation and initializer +function f5() { + var x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined +} + +// CFA for 'var' with no type annotation and 'undefined' initializer +function f6() { + var x = undefined; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined +} + +// CFA for 'var' with no type annotation and 'null' initializer +function f7() { + var x = null; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | null +} + +// No CFA for 'var' with with type annotation +function f8() { + var x: any; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // any +} + +// No CFA for captured outer variables +function f9() { + let x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined + function f() { + const z = x; // any + } +} + +// No CFA for captured outer variables +function f10() { + let x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined + const f = () => { + const z = x; // any + }; +} + +//// [controlFlowLetVar.js] +// CFA for 'let' with no type annotation and initializer +function f1() { + var x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // string | number | undefined +} +// CFA for 'let' with no type annotation and 'undefined' initializer +function f2() { + var x = undefined; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // string | number | undefined +} +// CFA for 'let' with no type annotation and 'null' initializer +function f3() { + var x = null; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // string | number | null +} +// No CFA for 'let' with with type annotation +function f4() { + var x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // any +} +// CFA for 'var' with no type annotation and initializer +function f5() { + var x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // string | number | undefined +} +// CFA for 'var' with no type annotation and 'undefined' initializer +function f6() { + var x = undefined; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // string | number | undefined +} +// CFA for 'var' with no type annotation and 'null' initializer +function f7() { + var x = null; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // string | number | null +} +// No CFA for 'var' with with type annotation +function f8() { + var x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // any +} +// No CFA for captured outer variables +function f9() { + var x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // string | number | undefined + function f() { + var z = x; // any + } +} +// No CFA for captured outer variables +function f10() { + var x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // string | number | undefined + var f = function () { + var z = x; // any + }; +} diff --git a/tests/baselines/reference/controlFlowLetVar.symbols b/tests/baselines/reference/controlFlowLetVar.symbols new file mode 100644 index 00000000000..f58edd781b7 --- /dev/null +++ b/tests/baselines/reference/controlFlowLetVar.symbols @@ -0,0 +1,263 @@ +=== tests/cases/compiler/controlFlowLetVar.ts === + +declare let cond: boolean; +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + +// CFA for 'let' with no type annotation and initializer +function f1() { +>f1 : Symbol(f1, Decl(controlFlowLetVar.ts, 1, 26)) + + let x; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 5, 7)) + + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = 1; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 5, 7)) + } + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = "hello"; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 5, 7)) + } + const y = x; // string | number | undefined +>y : Symbol(y, Decl(controlFlowLetVar.ts, 12, 9)) +>x : Symbol(x, Decl(controlFlowLetVar.ts, 5, 7)) +} + +// CFA for 'let' with no type annotation and 'undefined' initializer +function f2() { +>f2 : Symbol(f2, Decl(controlFlowLetVar.ts, 13, 1)) + + let x = undefined; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 17, 7)) +>undefined : Symbol(undefined) + + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = 1; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 17, 7)) + } + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = "hello"; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 17, 7)) + } + const y = x; // string | number | undefined +>y : Symbol(y, Decl(controlFlowLetVar.ts, 24, 9)) +>x : Symbol(x, Decl(controlFlowLetVar.ts, 17, 7)) +} + +// CFA for 'let' with no type annotation and 'null' initializer +function f3() { +>f3 : Symbol(f3, Decl(controlFlowLetVar.ts, 25, 1)) + + let x = null; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 29, 7)) + + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = 1; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 29, 7)) + } + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = "hello"; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 29, 7)) + } + const y = x; // string | number | null +>y : Symbol(y, Decl(controlFlowLetVar.ts, 36, 9)) +>x : Symbol(x, Decl(controlFlowLetVar.ts, 29, 7)) +} + +// No CFA for 'let' with with type annotation +function f4() { +>f4 : Symbol(f4, Decl(controlFlowLetVar.ts, 37, 1)) + + let x: any; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 41, 7)) + + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = 1; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 41, 7)) + } + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = "hello"; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 41, 7)) + } + const y = x; // any +>y : Symbol(y, Decl(controlFlowLetVar.ts, 48, 9)) +>x : Symbol(x, Decl(controlFlowLetVar.ts, 41, 7)) +} + +// CFA for 'var' with no type annotation and initializer +function f5() { +>f5 : Symbol(f5, Decl(controlFlowLetVar.ts, 49, 1)) + + var x; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 53, 7)) + + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = 1; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 53, 7)) + } + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = "hello"; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 53, 7)) + } + const y = x; // string | number | undefined +>y : Symbol(y, Decl(controlFlowLetVar.ts, 60, 9)) +>x : Symbol(x, Decl(controlFlowLetVar.ts, 53, 7)) +} + +// CFA for 'var' with no type annotation and 'undefined' initializer +function f6() { +>f6 : Symbol(f6, Decl(controlFlowLetVar.ts, 61, 1)) + + var x = undefined; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 65, 7)) +>undefined : Symbol(undefined) + + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = 1; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 65, 7)) + } + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = "hello"; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 65, 7)) + } + const y = x; // string | number | undefined +>y : Symbol(y, Decl(controlFlowLetVar.ts, 72, 9)) +>x : Symbol(x, Decl(controlFlowLetVar.ts, 65, 7)) +} + +// CFA for 'var' with no type annotation and 'null' initializer +function f7() { +>f7 : Symbol(f7, Decl(controlFlowLetVar.ts, 73, 1)) + + var x = null; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 77, 7)) + + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = 1; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 77, 7)) + } + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = "hello"; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 77, 7)) + } + const y = x; // string | number | null +>y : Symbol(y, Decl(controlFlowLetVar.ts, 84, 9)) +>x : Symbol(x, Decl(controlFlowLetVar.ts, 77, 7)) +} + +// No CFA for 'var' with with type annotation +function f8() { +>f8 : Symbol(f8, Decl(controlFlowLetVar.ts, 85, 1)) + + var x: any; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 89, 7)) + + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = 1; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 89, 7)) + } + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = "hello"; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 89, 7)) + } + const y = x; // any +>y : Symbol(y, Decl(controlFlowLetVar.ts, 96, 9)) +>x : Symbol(x, Decl(controlFlowLetVar.ts, 89, 7)) +} + +// No CFA for captured outer variables +function f9() { +>f9 : Symbol(f9, Decl(controlFlowLetVar.ts, 97, 1)) + + let x; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 101, 7)) + + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = 1; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 101, 7)) + } + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = "hello"; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 101, 7)) + } + const y = x; // string | number | undefined +>y : Symbol(y, Decl(controlFlowLetVar.ts, 108, 9)) +>x : Symbol(x, Decl(controlFlowLetVar.ts, 101, 7)) + + function f() { +>f : Symbol(f, Decl(controlFlowLetVar.ts, 108, 16)) + + const z = x; // any +>z : Symbol(z, Decl(controlFlowLetVar.ts, 110, 13)) +>x : Symbol(x, Decl(controlFlowLetVar.ts, 101, 7)) + } +} + +// No CFA for captured outer variables +function f10() { +>f10 : Symbol(f10, Decl(controlFlowLetVar.ts, 112, 1)) + + let x; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 116, 7)) + + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = 1; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 116, 7)) + } + if (cond) { +>cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) + + x = "hello"; +>x : Symbol(x, Decl(controlFlowLetVar.ts, 116, 7)) + } + const y = x; // string | number | undefined +>y : Symbol(y, Decl(controlFlowLetVar.ts, 123, 9)) +>x : Symbol(x, Decl(controlFlowLetVar.ts, 116, 7)) + + const f = () => { +>f : Symbol(f, Decl(controlFlowLetVar.ts, 124, 9)) + + const z = x; // any +>z : Symbol(z, Decl(controlFlowLetVar.ts, 125, 13)) +>x : Symbol(x, Decl(controlFlowLetVar.ts, 116, 7)) + + }; +} diff --git a/tests/baselines/reference/controlFlowLetVar.types b/tests/baselines/reference/controlFlowLetVar.types new file mode 100644 index 00000000000..09f0ea83488 --- /dev/null +++ b/tests/baselines/reference/controlFlowLetVar.types @@ -0,0 +1,306 @@ +=== tests/cases/compiler/controlFlowLetVar.ts === + +declare let cond: boolean; +>cond : boolean + +// CFA for 'let' with no type annotation and initializer +function f1() { +>f1 : () => void + + let x; +>x : any + + if (cond) { +>cond : boolean + + x = 1; +>x = 1 : 1 +>x : any +>1 : 1 + } + if (cond) { +>cond : boolean + + x = "hello"; +>x = "hello" : "hello" +>x : any +>"hello" : "hello" + } + const y = x; // string | number | undefined +>y : string | number | undefined +>x : string | number | undefined +} + +// CFA for 'let' with no type annotation and 'undefined' initializer +function f2() { +>f2 : () => void + + let x = undefined; +>x : any +>undefined : undefined + + if (cond) { +>cond : boolean + + x = 1; +>x = 1 : 1 +>x : any +>1 : 1 + } + if (cond) { +>cond : boolean + + x = "hello"; +>x = "hello" : "hello" +>x : any +>"hello" : "hello" + } + const y = x; // string | number | undefined +>y : string | number | undefined +>x : string | number | undefined +} + +// CFA for 'let' with no type annotation and 'null' initializer +function f3() { +>f3 : () => void + + let x = null; +>x : any +>null : null + + if (cond) { +>cond : boolean + + x = 1; +>x = 1 : 1 +>x : any +>1 : 1 + } + if (cond) { +>cond : boolean + + x = "hello"; +>x = "hello" : "hello" +>x : any +>"hello" : "hello" + } + const y = x; // string | number | null +>y : string | number | null +>x : string | number | null +} + +// No CFA for 'let' with with type annotation +function f4() { +>f4 : () => void + + let x: any; +>x : any + + if (cond) { +>cond : boolean + + x = 1; +>x = 1 : 1 +>x : any +>1 : 1 + } + if (cond) { +>cond : boolean + + x = "hello"; +>x = "hello" : "hello" +>x : any +>"hello" : "hello" + } + const y = x; // any +>y : any +>x : any +} + +// CFA for 'var' with no type annotation and initializer +function f5() { +>f5 : () => void + + var x; +>x : any + + if (cond) { +>cond : boolean + + x = 1; +>x = 1 : 1 +>x : any +>1 : 1 + } + if (cond) { +>cond : boolean + + x = "hello"; +>x = "hello" : "hello" +>x : any +>"hello" : "hello" + } + const y = x; // string | number | undefined +>y : string | number | undefined +>x : string | number | undefined +} + +// CFA for 'var' with no type annotation and 'undefined' initializer +function f6() { +>f6 : () => void + + var x = undefined; +>x : any +>undefined : undefined + + if (cond) { +>cond : boolean + + x = 1; +>x = 1 : 1 +>x : any +>1 : 1 + } + if (cond) { +>cond : boolean + + x = "hello"; +>x = "hello" : "hello" +>x : any +>"hello" : "hello" + } + const y = x; // string | number | undefined +>y : string | number | undefined +>x : string | number | undefined +} + +// CFA for 'var' with no type annotation and 'null' initializer +function f7() { +>f7 : () => void + + var x = null; +>x : any +>null : null + + if (cond) { +>cond : boolean + + x = 1; +>x = 1 : 1 +>x : any +>1 : 1 + } + if (cond) { +>cond : boolean + + x = "hello"; +>x = "hello" : "hello" +>x : any +>"hello" : "hello" + } + const y = x; // string | number | null +>y : string | number | null +>x : string | number | null +} + +// No CFA for 'var' with with type annotation +function f8() { +>f8 : () => void + + var x: any; +>x : any + + if (cond) { +>cond : boolean + + x = 1; +>x = 1 : 1 +>x : any +>1 : 1 + } + if (cond) { +>cond : boolean + + x = "hello"; +>x = "hello" : "hello" +>x : any +>"hello" : "hello" + } + const y = x; // any +>y : any +>x : any +} + +// No CFA for captured outer variables +function f9() { +>f9 : () => void + + let x; +>x : any + + if (cond) { +>cond : boolean + + x = 1; +>x = 1 : 1 +>x : any +>1 : 1 + } + if (cond) { +>cond : boolean + + x = "hello"; +>x = "hello" : "hello" +>x : any +>"hello" : "hello" + } + const y = x; // string | number | undefined +>y : string | number | undefined +>x : string | number | undefined + + function f() { +>f : () => void + + const z = x; // any +>z : any +>x : any + } +} + +// No CFA for captured outer variables +function f10() { +>f10 : () => void + + let x; +>x : any + + if (cond) { +>cond : boolean + + x = 1; +>x = 1 : 1 +>x : any +>1 : 1 + } + if (cond) { +>cond : boolean + + x = "hello"; +>x = "hello" : "hello" +>x : any +>"hello" : "hello" + } + const y = x; // string | number | undefined +>y : string | number | undefined +>x : string | number | undefined + + const f = () => { +>f : () => void +>() => { const z = x; // any } : () => void + + const z = x; // any +>z : any +>x : any + + }; +} diff --git a/tests/baselines/reference/controlFlowNoImplicitAny.errors.txt b/tests/baselines/reference/controlFlowNoImplicitAny.errors.txt new file mode 100644 index 00000000000..d081f29d511 --- /dev/null +++ b/tests/baselines/reference/controlFlowNoImplicitAny.errors.txt @@ -0,0 +1,143 @@ +tests/cases/compiler/controlFlowNoImplicitAny.ts(102,9): error TS7034: Variable 'x' implicitly has type 'any' in some locations where its type cannot be determined. +tests/cases/compiler/controlFlowNoImplicitAny.ts(111,19): error TS7005: Variable 'x' implicitly has an 'any' type. +tests/cases/compiler/controlFlowNoImplicitAny.ts(117,9): error TS7034: Variable 'x' implicitly has type 'any' in some locations where its type cannot be determined. +tests/cases/compiler/controlFlowNoImplicitAny.ts(126,19): error TS7005: Variable 'x' implicitly has an 'any' type. + + +==== tests/cases/compiler/controlFlowNoImplicitAny.ts (4 errors) ==== + + declare let cond: boolean; + + // CFA for 'let' with no type annotation and initializer + function f1() { + let x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined + } + + // CFA for 'let' with no type annotation and 'undefined' initializer + function f2() { + let x = undefined; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined + } + + // CFA for 'let' with no type annotation and 'null' initializer + function f3() { + let x = null; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | null + } + + // No CFA for 'let' with with type annotation + function f4() { + let x: any; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // any + } + + // CFA for 'var' with no type annotation and initializer + function f5() { + var x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined + } + + // CFA for 'var' with no type annotation and 'undefined' initializer + function f6() { + var x = undefined; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined + } + + // CFA for 'var' with no type annotation and 'null' initializer + function f7() { + var x = null; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | null + } + + // No CFA for 'var' with with type annotation + function f8() { + var x: any; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // any + } + + // No CFA for captured outer variables + function f9() { + let x; + ~ +!!! error TS7034: Variable 'x' implicitly has type 'any' in some locations where its type cannot be determined. + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined + function f() { + const z = x; // any + ~ +!!! error TS7005: Variable 'x' implicitly has an 'any' type. + } + } + + // No CFA for captured outer variables + function f10() { + let x; + ~ +!!! error TS7034: Variable 'x' implicitly has type 'any' in some locations where its type cannot be determined. + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined + const f = () => { + const z = x; // any + ~ +!!! error TS7005: Variable 'x' implicitly has an 'any' type. + }; + } \ No newline at end of file diff --git a/tests/baselines/reference/controlFlowNoImplicitAny.js b/tests/baselines/reference/controlFlowNoImplicitAny.js new file mode 100644 index 00000000000..9a5f302d87a --- /dev/null +++ b/tests/baselines/reference/controlFlowNoImplicitAny.js @@ -0,0 +1,247 @@ +//// [controlFlowNoImplicitAny.ts] + +declare let cond: boolean; + +// CFA for 'let' with no type annotation and initializer +function f1() { + let x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined +} + +// CFA for 'let' with no type annotation and 'undefined' initializer +function f2() { + let x = undefined; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined +} + +// CFA for 'let' with no type annotation and 'null' initializer +function f3() { + let x = null; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | null +} + +// No CFA for 'let' with with type annotation +function f4() { + let x: any; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // any +} + +// CFA for 'var' with no type annotation and initializer +function f5() { + var x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined +} + +// CFA for 'var' with no type annotation and 'undefined' initializer +function f6() { + var x = undefined; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined +} + +// CFA for 'var' with no type annotation and 'null' initializer +function f7() { + var x = null; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | null +} + +// No CFA for 'var' with with type annotation +function f8() { + var x: any; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // any +} + +// No CFA for captured outer variables +function f9() { + let x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined + function f() { + const z = x; // any + } +} + +// No CFA for captured outer variables +function f10() { + let x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined + const f = () => { + const z = x; // any + }; +} + +//// [controlFlowNoImplicitAny.js] +// CFA for 'let' with no type annotation and initializer +function f1() { + var x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // string | number | undefined +} +// CFA for 'let' with no type annotation and 'undefined' initializer +function f2() { + var x = undefined; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // string | number | undefined +} +// CFA for 'let' with no type annotation and 'null' initializer +function f3() { + var x = null; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // string | number | null +} +// No CFA for 'let' with with type annotation +function f4() { + var x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // any +} +// CFA for 'var' with no type annotation and initializer +function f5() { + var x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // string | number | undefined +} +// CFA for 'var' with no type annotation and 'undefined' initializer +function f6() { + var x = undefined; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // string | number | undefined +} +// CFA for 'var' with no type annotation and 'null' initializer +function f7() { + var x = null; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // string | number | null +} +// No CFA for 'var' with with type annotation +function f8() { + var x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // any +} +// No CFA for captured outer variables +function f9() { + var x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // string | number | undefined + function f() { + var z = x; // any + } +} +// No CFA for captured outer variables +function f10() { + var x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + var y = x; // string | number | undefined + var f = function () { + var z = x; // any + }; +} diff --git a/tests/baselines/reference/declarationEmitPromise.js b/tests/baselines/reference/declarationEmitPromise.js index a4bbdd74dde..e6f3f922b46 100644 --- a/tests/baselines/reference/declarationEmitPromise.js +++ b/tests/baselines/reference/declarationEmitPromise.js @@ -27,7 +27,7 @@ export async function runSampleBreaks( 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()); }); diff --git a/tests/baselines/reference/declarationEmitTypeAliasWithTypeParameters1.js b/tests/baselines/reference/declarationEmitTypeAliasWithTypeParameters1.js new file mode 100644 index 00000000000..c41c4690391 --- /dev/null +++ b/tests/baselines/reference/declarationEmitTypeAliasWithTypeParameters1.js @@ -0,0 +1,15 @@ +//// [declarationEmitTypeAliasWithTypeParameters1.ts] + +export type Bar = () => [X, Y]; +export type Foo = Bar; +export const y = (x: Foo) => 1 + +//// [declarationEmitTypeAliasWithTypeParameters1.js] +"use strict"; +exports.y = function (x) { return 1; }; + + +//// [declarationEmitTypeAliasWithTypeParameters1.d.ts] +export declare type Bar = () => [X, Y]; +export declare type Foo = Bar; +export declare const y: (x: () => [any, string]) => number; diff --git a/tests/baselines/reference/declarationEmitTypeAliasWithTypeParameters1.symbols b/tests/baselines/reference/declarationEmitTypeAliasWithTypeParameters1.symbols new file mode 100644 index 00000000000..fa63e711f9a --- /dev/null +++ b/tests/baselines/reference/declarationEmitTypeAliasWithTypeParameters1.symbols @@ -0,0 +1,20 @@ +=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters1.ts === + +export type Bar = () => [X, Y]; +>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters1.ts, 0, 0)) +>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters1.ts, 1, 16)) +>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters1.ts, 1, 18)) +>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters1.ts, 1, 16)) +>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters1.ts, 1, 18)) + +export type Foo = Bar; +>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters1.ts, 1, 37)) +>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters1.ts, 2, 16)) +>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters1.ts, 0, 0)) +>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters1.ts, 2, 16)) + +export const y = (x: Foo) => 1 +>y : Symbol(y, Decl(declarationEmitTypeAliasWithTypeParameters1.ts, 3, 12)) +>x : Symbol(x, Decl(declarationEmitTypeAliasWithTypeParameters1.ts, 3, 18)) +>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters1.ts, 1, 37)) + diff --git a/tests/baselines/reference/declarationEmitTypeAliasWithTypeParameters1.types b/tests/baselines/reference/declarationEmitTypeAliasWithTypeParameters1.types new file mode 100644 index 00000000000..3ff9f9bde1d --- /dev/null +++ b/tests/baselines/reference/declarationEmitTypeAliasWithTypeParameters1.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters1.ts === + +export type Bar = () => [X, Y]; +>Bar : Bar +>X : X +>Y : Y +>X : X +>Y : Y + +export type Foo = Bar; +>Foo : () => [any, Y] +>Y : Y +>Bar : Bar +>Y : Y + +export const y = (x: Foo) => 1 +>y : (x: () => [any, string]) => number +>(x: Foo) => 1 : (x: () => [any, string]) => number +>x : () => [any, string] +>Foo : () => [any, Y] +>1 : 1 + diff --git a/tests/baselines/reference/decoratorMetadataPromise.js b/tests/baselines/reference/decoratorMetadataPromise.js index 56a66216dea..52449f91755 100644 --- a/tests/baselines/reference/decoratorMetadataPromise.js +++ b/tests/baselines/reference/decoratorMetadataPromise.js @@ -25,7 +25,7 @@ var __metadata = (this && this.__metadata) || function (k, v) { 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()); }); diff --git a/tests/baselines/reference/decrementOperatorWithAnyOtherType.js b/tests/baselines/reference/decrementOperatorWithAnyOtherType.js index 51015cf44ed..f3ff58b80ca 100644 --- a/tests/baselines/reference/decrementOperatorWithAnyOtherType.js +++ b/tests/baselines/reference/decrementOperatorWithAnyOtherType.js @@ -2,7 +2,7 @@ // -- operator on any type var ANY: any; -var ANY1; +var ANY1: any; var ANY2: any[] = ["", ""]; var obj = {x:1,y:null}; class A { diff --git a/tests/baselines/reference/decrementOperatorWithAnyOtherType.symbols b/tests/baselines/reference/decrementOperatorWithAnyOtherType.symbols index cbef7442578..8d1b023c97a 100644 --- a/tests/baselines/reference/decrementOperatorWithAnyOtherType.symbols +++ b/tests/baselines/reference/decrementOperatorWithAnyOtherType.symbols @@ -4,7 +4,7 @@ var ANY: any; >ANY : Symbol(ANY, Decl(decrementOperatorWithAnyOtherType.ts, 2, 3)) -var ANY1; +var ANY1: any; >ANY1 : Symbol(ANY1, Decl(decrementOperatorWithAnyOtherType.ts, 3, 3)) var ANY2: any[] = ["", ""]; diff --git a/tests/baselines/reference/decrementOperatorWithAnyOtherType.types b/tests/baselines/reference/decrementOperatorWithAnyOtherType.types index c8b8852e4d2..74fbd0012d1 100644 --- a/tests/baselines/reference/decrementOperatorWithAnyOtherType.types +++ b/tests/baselines/reference/decrementOperatorWithAnyOtherType.types @@ -4,7 +4,7 @@ var ANY: any; >ANY : any -var ANY1; +var ANY1: any; >ANY1 : any var ANY2: any[] = ["", ""]; diff --git a/tests/baselines/reference/decrementOperatorWithAnyOtherTypeInvalidOperations.errors.txt b/tests/baselines/reference/decrementOperatorWithAnyOtherTypeInvalidOperations.errors.txt index 46e5515633a..2e1d594164d 100644 --- a/tests/baselines/reference/decrementOperatorWithAnyOtherTypeInvalidOperations.errors.txt +++ b/tests/baselines/reference/decrementOperatorWithAnyOtherTypeInvalidOperations.errors.txt @@ -52,7 +52,7 @@ tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOp ==== tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts (50 errors) ==== // -- operator on any type - var ANY1; + var ANY1: any; var ANY2: any[] = ["", ""]; var obj: () => {} @@ -63,7 +63,7 @@ tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOp } class A { public a: any; - static foo() { + static foo(): any { var a; return a; } diff --git a/tests/baselines/reference/decrementOperatorWithAnyOtherTypeInvalidOperations.js b/tests/baselines/reference/decrementOperatorWithAnyOtherTypeInvalidOperations.js index 94f5c942bfc..88d045ab378 100644 --- a/tests/baselines/reference/decrementOperatorWithAnyOtherTypeInvalidOperations.js +++ b/tests/baselines/reference/decrementOperatorWithAnyOtherTypeInvalidOperations.js @@ -1,6 +1,6 @@ //// [decrementOperatorWithAnyOtherTypeInvalidOperations.ts] // -- operator on any type -var ANY1; +var ANY1: any; var ANY2: any[] = ["", ""]; var obj: () => {} @@ -11,7 +11,7 @@ function foo(): any { } class A { public a: any; - static foo() { + static foo(): any { var a; return a; } diff --git a/tests/baselines/reference/defaultExportInAwaitExpression01.js b/tests/baselines/reference/defaultExportInAwaitExpression01.js index b57b6237d7a..a16e2f07f5f 100644 --- a/tests/baselines/reference/defaultExportInAwaitExpression01.js +++ b/tests/baselines/reference/defaultExportInAwaitExpression01.js @@ -30,7 +30,7 @@ import x from './a'; 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()); }); diff --git a/tests/baselines/reference/defaultExportInAwaitExpression02.js b/tests/baselines/reference/defaultExportInAwaitExpression02.js index db2150c66f1..db05d62a2ad 100644 --- a/tests/baselines/reference/defaultExportInAwaitExpression02.js +++ b/tests/baselines/reference/defaultExportInAwaitExpression02.js @@ -22,7 +22,7 @@ exports.default = x; 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()); }); diff --git a/tests/baselines/reference/downlevelLetConst14.types b/tests/baselines/reference/downlevelLetConst14.types index 29c87e76cce..493c17b97cd 100644 --- a/tests/baselines/reference/downlevelLetConst14.types +++ b/tests/baselines/reference/downlevelLetConst14.types @@ -77,22 +77,22 @@ use(x); use(z0); >use(z0) : any >use : (a: any) => any ->z0 : any +>z0 : undefined use(z1); >use(z1) : any >use : (a: any) => any ->z1 : any +>z1 : undefined use(z2); >use(z2) : any >use : (a: any) => any ->z2 : any +>z2 : undefined use(z3); >use(z3) : any >use : (a: any) => any ->z3 : any +>z3 : undefined var z6; >z6 : any @@ -149,7 +149,7 @@ use(y); use(z6); >use(z6) : any >use : (a: any) => any ->z6 : any +>z6 : undefined var z = false; >z : boolean diff --git a/tests/baselines/reference/downlevelLetConst15.types b/tests/baselines/reference/downlevelLetConst15.types index 9e58c648821..6d224b6310d 100644 --- a/tests/baselines/reference/downlevelLetConst15.types +++ b/tests/baselines/reference/downlevelLetConst15.types @@ -83,22 +83,22 @@ use(x); use(z0); >use(z0) : any >use : (a: any) => any ->z0 : any +>z0 : undefined use(z1); >use(z1) : any >use : (a: any) => any ->z1 : any +>z1 : undefined use(z2); >use(z2) : any >use : (a: any) => any ->z2 : any +>z2 : undefined use(z3); >use(z3) : any >use : (a: any) => any ->z3 : any +>z3 : undefined var z6; >z6 : any @@ -155,7 +155,7 @@ use(y); use(z6); >use(z6) : any >use : (a: any) => any ->z6 : any +>z6 : undefined var z = false; >z : boolean diff --git a/tests/baselines/reference/es5-asyncFunction.js b/tests/baselines/reference/es5-asyncFunction.js index d6cd770e454..5123566dc8c 100644 --- a/tests/baselines/reference/es5-asyncFunction.js +++ b/tests/baselines/reference/es5-asyncFunction.js @@ -12,7 +12,7 @@ async function singleAwait() { 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()); }); diff --git a/tests/baselines/reference/es5-asyncFunctionTryStatements.js b/tests/baselines/reference/es5-asyncFunctionTryStatements.js index c9c5507afa7..513420dd6f4 100644 --- a/tests/baselines/reference/es5-asyncFunctionTryStatements.js +++ b/tests/baselines/reference/es5-asyncFunctionTryStatements.js @@ -1,8 +1,8 @@ //// [es5-asyncFunctionTryStatements.ts] -declare var x, y, z, a, b, c; +declare var x: any, y: any, z: any, a: any, b: any, c: any; async function tryCatch0() { - var x, y; + var x: any, y: any; try { x; } @@ -12,7 +12,7 @@ async function tryCatch0() { } async function tryCatch1() { - var x, y; + var x: any, y: any; try { await x; } @@ -22,7 +22,7 @@ async function tryCatch1() { } async function tryCatch2() { - var x, y; + var x: any, y: any; try { x; } @@ -32,7 +32,7 @@ async function tryCatch2() { } async function tryCatch3(): Promise { - var x, y; + var x: any, y: any; try { await x; } @@ -41,7 +41,7 @@ async function tryCatch3(): Promise { } } async function tryFinally0() { - var x, y; + var x: any, y: any; try { x; } @@ -51,7 +51,7 @@ async function tryFinally0() { } async function tryFinally1() { - var x, y; + var x: any, y: any; try { await x; } @@ -61,7 +61,7 @@ async function tryFinally1() { } async function tryFinally2() { - var x, y; + var x: any, y: any; try { x; } @@ -71,7 +71,7 @@ async function tryFinally2() { } async function tryCatchFinally0() { - var x, y, z; + var x: any, y: any, z: any; try { x; } @@ -84,7 +84,7 @@ async function tryCatchFinally0() { } async function tryCatchFinally1() { - var x, y, z; + var x: any, y: any, z: any; try { await x; } @@ -97,7 +97,7 @@ async function tryCatchFinally1() { } async function tryCatchFinally2() { - var x, y, z; + var x: any, y: any, z: any; try { x; } @@ -110,7 +110,7 @@ async function tryCatchFinally2() { } async function tryCatchFinally3() { - var x, y, z; + var x: any, y: any, z: any; try { x; } diff --git a/tests/baselines/reference/es5-asyncFunctionTryStatements.symbols b/tests/baselines/reference/es5-asyncFunctionTryStatements.symbols index ecf8fbc505b..52a4ec8df76 100644 --- a/tests/baselines/reference/es5-asyncFunctionTryStatements.symbols +++ b/tests/baselines/reference/es5-asyncFunctionTryStatements.symbols @@ -1,18 +1,18 @@ === tests/cases/compiler/es5-asyncFunctionTryStatements.ts === -declare var x, y, z, a, b, c; +declare var x: any, y: any, z: any, a: any, b: any, c: any; >x : Symbol(x, Decl(es5-asyncFunctionTryStatements.ts, 0, 11)) ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 0, 14)) ->z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 0, 17)) ->a : Symbol(a, Decl(es5-asyncFunctionTryStatements.ts, 0, 20)) ->b : Symbol(b, Decl(es5-asyncFunctionTryStatements.ts, 0, 23)) ->c : Symbol(c, Decl(es5-asyncFunctionTryStatements.ts, 0, 26)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 0, 19)) +>z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 0, 27)) +>a : Symbol(a, Decl(es5-asyncFunctionTryStatements.ts, 0, 35)) +>b : Symbol(b, Decl(es5-asyncFunctionTryStatements.ts, 0, 43)) +>c : Symbol(c, Decl(es5-asyncFunctionTryStatements.ts, 0, 51)) async function tryCatch0() { ->tryCatch0 : Symbol(tryCatch0, Decl(es5-asyncFunctionTryStatements.ts, 0, 29)) +>tryCatch0 : Symbol(tryCatch0, Decl(es5-asyncFunctionTryStatements.ts, 0, 59)) - var x, y; + var x: any, y: any; >x : Symbol(x, Decl(es5-asyncFunctionTryStatements.ts, 3, 7)) ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 3, 10)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 3, 15)) try { x; @@ -22,16 +22,16 @@ async function tryCatch0() { >e : Symbol(e, Decl(es5-asyncFunctionTryStatements.ts, 7, 11)) y; ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 3, 10)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 3, 15)) } } async function tryCatch1() { >tryCatch1 : Symbol(tryCatch1, Decl(es5-asyncFunctionTryStatements.ts, 10, 1)) - var x, y; + var x: any, y: any; >x : Symbol(x, Decl(es5-asyncFunctionTryStatements.ts, 13, 7)) ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 13, 10)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 13, 15)) try { await x; @@ -41,16 +41,16 @@ async function tryCatch1() { >e : Symbol(e, Decl(es5-asyncFunctionTryStatements.ts, 17, 11)) y; ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 13, 10)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 13, 15)) } } async function tryCatch2() { >tryCatch2 : Symbol(tryCatch2, Decl(es5-asyncFunctionTryStatements.ts, 20, 1)) - var x, y; + var x: any, y: any; >x : Symbol(x, Decl(es5-asyncFunctionTryStatements.ts, 23, 7)) ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 23, 10)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 23, 15)) try { x; @@ -60,7 +60,7 @@ async function tryCatch2() { >e : Symbol(e, Decl(es5-asyncFunctionTryStatements.ts, 27, 11)) await y; ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 23, 10)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 23, 15)) } } @@ -69,9 +69,9 @@ async function tryCatch3(): Promise { >Promise : Symbol(Promise, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) - var x, y; + var x: any, y: any; >x : Symbol(x, Decl(es5-asyncFunctionTryStatements.ts, 33, 7)) ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 33, 10)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 33, 15)) try { await x; @@ -87,9 +87,9 @@ async function tryCatch3(): Promise { async function tryFinally0() { >tryFinally0 : Symbol(tryFinally0, Decl(es5-asyncFunctionTryStatements.ts, 40, 1)) - var x, y; + var x: any, y: any; >x : Symbol(x, Decl(es5-asyncFunctionTryStatements.ts, 42, 7)) ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 42, 10)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 42, 15)) try { x; @@ -97,16 +97,16 @@ async function tryFinally0() { } finally { y; ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 42, 10)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 42, 15)) } } async function tryFinally1() { >tryFinally1 : Symbol(tryFinally1, Decl(es5-asyncFunctionTryStatements.ts, 49, 1)) - var x, y; + var x: any, y: any; >x : Symbol(x, Decl(es5-asyncFunctionTryStatements.ts, 52, 7)) ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 52, 10)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 52, 15)) try { await x; @@ -114,16 +114,16 @@ async function tryFinally1() { } finally { y; ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 52, 10)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 52, 15)) } } async function tryFinally2() { >tryFinally2 : Symbol(tryFinally2, Decl(es5-asyncFunctionTryStatements.ts, 59, 1)) - var x, y; + var x: any, y: any; >x : Symbol(x, Decl(es5-asyncFunctionTryStatements.ts, 62, 7)) ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 62, 10)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 62, 15)) try { x; @@ -131,17 +131,17 @@ async function tryFinally2() { } finally { await y; ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 62, 10)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 62, 15)) } } async function tryCatchFinally0() { >tryCatchFinally0 : Symbol(tryCatchFinally0, Decl(es5-asyncFunctionTryStatements.ts, 69, 1)) - var x, y, z; + var x: any, y: any, z: any; >x : Symbol(x, Decl(es5-asyncFunctionTryStatements.ts, 72, 7)) ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 72, 10)) ->z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 72, 13)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 72, 15)) +>z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 72, 23)) try { x; @@ -151,21 +151,21 @@ async function tryCatchFinally0() { >e : Symbol(e, Decl(es5-asyncFunctionTryStatements.ts, 76, 11)) y; ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 72, 10)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 72, 15)) } finally { z; ->z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 72, 13)) +>z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 72, 23)) } } async function tryCatchFinally1() { >tryCatchFinally1 : Symbol(tryCatchFinally1, Decl(es5-asyncFunctionTryStatements.ts, 82, 1)) - var x, y, z; + var x: any, y: any, z: any; >x : Symbol(x, Decl(es5-asyncFunctionTryStatements.ts, 85, 7)) ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 85, 10)) ->z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 85, 13)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 85, 15)) +>z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 85, 23)) try { await x; @@ -175,21 +175,21 @@ async function tryCatchFinally1() { >e : Symbol(e, Decl(es5-asyncFunctionTryStatements.ts, 89, 11)) y; ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 85, 10)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 85, 15)) } finally { z; ->z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 85, 13)) +>z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 85, 23)) } } async function tryCatchFinally2() { >tryCatchFinally2 : Symbol(tryCatchFinally2, Decl(es5-asyncFunctionTryStatements.ts, 95, 1)) - var x, y, z; + var x: any, y: any, z: any; >x : Symbol(x, Decl(es5-asyncFunctionTryStatements.ts, 98, 7)) ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 98, 10)) ->z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 98, 13)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 98, 15)) +>z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 98, 23)) try { x; @@ -199,21 +199,21 @@ async function tryCatchFinally2() { >e : Symbol(e, Decl(es5-asyncFunctionTryStatements.ts, 102, 11)) await y; ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 98, 10)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 98, 15)) } finally { z; ->z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 98, 13)) +>z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 98, 23)) } } async function tryCatchFinally3() { >tryCatchFinally3 : Symbol(tryCatchFinally3, Decl(es5-asyncFunctionTryStatements.ts, 108, 1)) - var x, y, z; + var x: any, y: any, z: any; >x : Symbol(x, Decl(es5-asyncFunctionTryStatements.ts, 111, 7)) ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 111, 10)) ->z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 111, 13)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 111, 15)) +>z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 111, 23)) try { x; @@ -223,10 +223,10 @@ async function tryCatchFinally3() { >e : Symbol(e, Decl(es5-asyncFunctionTryStatements.ts, 115, 11)) y; ->y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 111, 10)) +>y : Symbol(y, Decl(es5-asyncFunctionTryStatements.ts, 111, 15)) } finally { await z; ->z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 111, 13)) +>z : Symbol(z, Decl(es5-asyncFunctionTryStatements.ts, 111, 23)) } } diff --git a/tests/baselines/reference/es5-asyncFunctionTryStatements.types b/tests/baselines/reference/es5-asyncFunctionTryStatements.types index ab1cd845616..f4c4536c6fc 100644 --- a/tests/baselines/reference/es5-asyncFunctionTryStatements.types +++ b/tests/baselines/reference/es5-asyncFunctionTryStatements.types @@ -1,5 +1,5 @@ === tests/cases/compiler/es5-asyncFunctionTryStatements.ts === -declare var x, y, z, a, b, c; +declare var x: any, y: any, z: any, a: any, b: any, c: any; >x : any >y : any >z : any @@ -10,7 +10,7 @@ declare var x, y, z, a, b, c; async function tryCatch0() { >tryCatch0 : () => Promise - var x, y; + var x: any, y: any; >x : any >y : any @@ -29,7 +29,7 @@ async function tryCatch0() { async function tryCatch1() { >tryCatch1 : () => Promise - var x, y; + var x: any, y: any; >x : any >y : any @@ -49,7 +49,7 @@ async function tryCatch1() { async function tryCatch2() { >tryCatch2 : () => Promise - var x, y; + var x: any, y: any; >x : any >y : any @@ -71,7 +71,7 @@ async function tryCatch3(): Promise { >Promise : Promise >Function : Function - var x, y; + var x: any, y: any; >x : any >y : any @@ -91,7 +91,7 @@ async function tryCatch3(): Promise { async function tryFinally0() { >tryFinally0 : () => Promise - var x, y; + var x: any, y: any; >x : any >y : any @@ -108,7 +108,7 @@ async function tryFinally0() { async function tryFinally1() { >tryFinally1 : () => Promise - var x, y; + var x: any, y: any; >x : any >y : any @@ -126,7 +126,7 @@ async function tryFinally1() { async function tryFinally2() { >tryFinally2 : () => Promise - var x, y; + var x: any, y: any; >x : any >y : any @@ -144,7 +144,7 @@ async function tryFinally2() { async function tryCatchFinally0() { >tryCatchFinally0 : () => Promise - var x, y, z; + var x: any, y: any, z: any; >x : any >y : any >z : any @@ -168,7 +168,7 @@ async function tryCatchFinally0() { async function tryCatchFinally1() { >tryCatchFinally1 : () => Promise - var x, y, z; + var x: any, y: any, z: any; >x : any >y : any >z : any @@ -193,7 +193,7 @@ async function tryCatchFinally1() { async function tryCatchFinally2() { >tryCatchFinally2 : () => Promise - var x, y, z; + var x: any, y: any, z: any; >x : any >y : any >z : any @@ -218,7 +218,7 @@ async function tryCatchFinally2() { async function tryCatchFinally3() { >tryCatchFinally3 : () => Promise - var x, y, z; + var x: any, y: any, z: any; >x : any >y : any >z : any diff --git a/tests/baselines/reference/es5-importHelpersAsyncFunctions.js b/tests/baselines/reference/es5-importHelpersAsyncFunctions.js index 6c9a16b546f..0fd308cee3b 100644 --- a/tests/baselines/reference/es5-importHelpersAsyncFunctions.js +++ b/tests/baselines/reference/es5-importHelpersAsyncFunctions.js @@ -32,7 +32,7 @@ exports.foo = foo; 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()); }); diff --git a/tests/baselines/reference/exponentiationOperatorSyntaxError2.errors.txt b/tests/baselines/reference/exponentiationOperatorSyntaxError2.errors.txt index af17a7ddf7a..134a883540e 100644 --- a/tests/baselines/reference/exponentiationOperatorSyntaxError2.errors.txt +++ b/tests/baselines/reference/exponentiationOperatorSyntaxError2.errors.txt @@ -84,7 +84,7 @@ tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxE ==== tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts (81 errors) ==== // Error: early syntax error using ES7 SimpleUnaryExpression on left-hand side without () - var temp; + var temp: any; delete --temp ** 3; ~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/exponentiationOperatorSyntaxError2.js b/tests/baselines/reference/exponentiationOperatorSyntaxError2.js index 9e07273522f..e443b756575 100644 --- a/tests/baselines/reference/exponentiationOperatorSyntaxError2.js +++ b/tests/baselines/reference/exponentiationOperatorSyntaxError2.js @@ -1,7 +1,7 @@ //// [exponentiationOperatorSyntaxError2.ts] // Error: early syntax error using ES7 SimpleUnaryExpression on left-hand side without () -var temp; +var temp: any; delete --temp ** 3; delete ++temp ** 3; diff --git a/tests/baselines/reference/exportDefaultAsyncFunction.js b/tests/baselines/reference/exportDefaultAsyncFunction.js index a06b41b5e73..22f686b6ec8 100644 --- a/tests/baselines/reference/exportDefaultAsyncFunction.js +++ b/tests/baselines/reference/exportDefaultAsyncFunction.js @@ -7,7 +7,7 @@ foo(); 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()); }); diff --git a/tests/baselines/reference/exportDefaultAsyncFunction2.js b/tests/baselines/reference/exportDefaultAsyncFunction2.js index ff242eec6a1..aed6eb6c879 100644 --- a/tests/baselines/reference/exportDefaultAsyncFunction2.js +++ b/tests/baselines/reference/exportDefaultAsyncFunction2.js @@ -38,7 +38,7 @@ export default async(() => await(Promise.resolve(1))); 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()); }); diff --git a/tests/baselines/reference/expr.errors.txt b/tests/baselines/reference/expr.errors.txt index 17e39cc80be..23215cac6ba 100644 --- a/tests/baselines/reference/expr.errors.txt +++ b/tests/baselines/reference/expr.errors.txt @@ -78,7 +78,7 @@ tests/cases/compiler/expr.ts(242,7): error TS2363: The right-hand side of an ari } function f() { - var a; + var a: any; var n=3; var s=""; var b=false; diff --git a/tests/baselines/reference/expr.js b/tests/baselines/reference/expr.js index 9baf55084c1..689ff1e27dc 100644 --- a/tests/baselines/reference/expr.js +++ b/tests/baselines/reference/expr.js @@ -7,7 +7,7 @@ enum E { } function f() { - var a; + var a: any; var n=3; var s=""; var b=false; diff --git a/tests/baselines/reference/for-inStatements.errors.txt b/tests/baselines/reference/for-inStatements.errors.txt index 7e20b8ca316..f0e6c950ebb 100644 --- a/tests/baselines/reference/for-inStatements.errors.txt +++ b/tests/baselines/reference/for-inStatements.errors.txt @@ -18,7 +18,7 @@ tests/cases/conformance/statements/for-inStatements/for-inStatements.ts(79,15): for (var x in /[a-z]/) { } for (var x in new Date()) { } - var c, d, e; + var c: any, d: any, e: any; for (var x in c || d) { } for (var x in e ? c : d) { } diff --git a/tests/baselines/reference/for-inStatements.js b/tests/baselines/reference/for-inStatements.js index 4f52b5e1456..15d771bf587 100644 --- a/tests/baselines/reference/for-inStatements.js +++ b/tests/baselines/reference/for-inStatements.js @@ -15,7 +15,7 @@ for (var x in fn()) { } for (var x in /[a-z]/) { } for (var x in new Date()) { } -var c, d, e; +var c: any, d: any, e: any; for (var x in c || d) { } for (var x in e ? c : d) { } diff --git a/tests/baselines/reference/for-of3.errors.txt b/tests/baselines/reference/for-of3.errors.txt index ba8e3e4a5c6..99ed3098a63 100644 --- a/tests/baselines/reference/for-of3.errors.txt +++ b/tests/baselines/reference/for-of3.errors.txt @@ -2,7 +2,7 @@ tests/cases/conformance/es6/for-ofStatements/for-of3.ts(2,6): error TS2487: Inva ==== tests/cases/conformance/es6/for-ofStatements/for-of3.ts (1 errors) ==== - var v; + var v: any; for (v++ of []) { } ~~~ !!! error TS2487: Invalid left-hand side in 'for...of' statement. \ No newline at end of file diff --git a/tests/baselines/reference/for-of3.js b/tests/baselines/reference/for-of3.js index 7ef27187702..15918223e6b 100644 --- a/tests/baselines/reference/for-of3.js +++ b/tests/baselines/reference/for-of3.js @@ -1,5 +1,5 @@ //// [for-of3.ts] -var v; +var v: any; for (v++ of []) { } //// [for-of3.js] diff --git a/tests/baselines/reference/forIn.errors.txt b/tests/baselines/reference/forIn.errors.txt index ccc1423f1aa..a7dd629698a 100644 --- a/tests/baselines/reference/forIn.errors.txt +++ b/tests/baselines/reference/forIn.errors.txt @@ -1,17 +1,24 @@ tests/cases/compiler/forIn.ts(2,10): error TS2404: The left-hand side of a 'for...in' statement cannot use a type annotation. +tests/cases/compiler/forIn.ts(2,22): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter. +tests/cases/compiler/forIn.ts(7,15): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter. +tests/cases/compiler/forIn.ts(18,15): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter. tests/cases/compiler/forIn.ts(20,4): error TS2304: Cannot find name 'k'. -==== tests/cases/compiler/forIn.ts (2 errors) ==== +==== tests/cases/compiler/forIn.ts (5 errors) ==== var arr = null; for (var i:number in arr) { // error ~ !!! error TS2404: The left-hand side of a 'for...in' statement cannot use a type annotation. + ~~~ +!!! error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter. var x1 = arr[i]; var y1 = arr[i]; } for (var j in arr) { // ok + ~~~ +!!! error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter. var x2 = arr[j]; var y2 = arr[j]; } @@ -23,6 +30,8 @@ tests/cases/compiler/forIn.ts(20,4): error TS2304: Cannot find name 'k'. } for (var l in arr) { + ~~~ +!!! error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter. // error in the body k[l] = 1; ~ diff --git a/tests/baselines/reference/implicitAnyDeclareVariablesWithoutTypeAndInit.errors.txt b/tests/baselines/reference/implicitAnyDeclareVariablesWithoutTypeAndInit.errors.txt index 3acb6e47e10..36993750ccf 100644 --- a/tests/baselines/reference/implicitAnyDeclareVariablesWithoutTypeAndInit.errors.txt +++ b/tests/baselines/reference/implicitAnyDeclareVariablesWithoutTypeAndInit.errors.txt @@ -1,19 +1,23 @@ -tests/cases/compiler/implicitAnyDeclareVariablesWithoutTypeAndInit.ts(2,5): error TS7005: Variable 'x' implicitly has an 'any' type. -tests/cases/compiler/implicitAnyDeclareVariablesWithoutTypeAndInit.ts(3,13): error TS7005: Variable 'foo' implicitly has an 'any' type. -tests/cases/compiler/implicitAnyDeclareVariablesWithoutTypeAndInit.ts(4,15): error TS7006: Parameter 'k' implicitly has an 'any' type. +tests/cases/compiler/implicitAnyDeclareVariablesWithoutTypeAndInit.ts(3,5): error TS7034: Variable 'y' implicitly has type 'any' in some locations where its type cannot be determined. +tests/cases/compiler/implicitAnyDeclareVariablesWithoutTypeAndInit.ts(4,13): error TS7005: Variable 'foo' implicitly has an 'any' type. +tests/cases/compiler/implicitAnyDeclareVariablesWithoutTypeAndInit.ts(5,15): error TS7006: Parameter 'k' implicitly has an 'any' type. +tests/cases/compiler/implicitAnyDeclareVariablesWithoutTypeAndInit.ts(5,20): error TS7005: Variable 'y' implicitly has an 'any' type. -==== tests/cases/compiler/implicitAnyDeclareVariablesWithoutTypeAndInit.ts (3 errors) ==== +==== tests/cases/compiler/implicitAnyDeclareVariablesWithoutTypeAndInit.ts (4 errors) ==== // this should be an error - var x; // error at "x" + var x; // no error, control flow typed + var y; // error because captured ~ -!!! error TS7005: Variable 'x' implicitly has an 'any' type. - declare var foo; // error at "foo" +!!! error TS7034: Variable 'y' implicitly has type 'any' in some locations where its type cannot be determined. + declare var foo; // error at "foo" ~~~ !!! error TS7005: Variable 'foo' implicitly has an 'any' type. - function func(k) { }; //error at "k" + function func(k) { y }; // error at "k" ~ !!! error TS7006: Parameter 'k' implicitly has an 'any' type. + ~ +!!! error TS7005: Variable 'y' implicitly has an 'any' type. func(x); // this shouldn't be an error diff --git a/tests/baselines/reference/implicitAnyDeclareVariablesWithoutTypeAndInit.js b/tests/baselines/reference/implicitAnyDeclareVariablesWithoutTypeAndInit.js index e3c44e9b783..5770050d449 100644 --- a/tests/baselines/reference/implicitAnyDeclareVariablesWithoutTypeAndInit.js +++ b/tests/baselines/reference/implicitAnyDeclareVariablesWithoutTypeAndInit.js @@ -1,8 +1,9 @@ //// [implicitAnyDeclareVariablesWithoutTypeAndInit.ts] // this should be an error -var x; // error at "x" -declare var foo; // error at "foo" -function func(k) { }; //error at "k" +var x; // no error, control flow typed +var y; // error because captured +declare var foo; // error at "foo" +function func(k) { y }; // error at "k" func(x); // this shouldn't be an error @@ -13,9 +14,10 @@ var x1: any; var y1 = new x1; //// [implicitAnyDeclareVariablesWithoutTypeAndInit.js] // this should be an error -var x; // error at "x" -function func(k) { } -; //error at "k" +var x; // no error, control flow typed +var y; // error because captured +function func(k) { y; } +; // error at "k" func(x); // this shouldn't be an error var bar = 3; diff --git a/tests/baselines/reference/implicitAnyFunctionInvocationWithAnyArguements.errors.txt b/tests/baselines/reference/implicitAnyFunctionInvocationWithAnyArguements.errors.txt index b15fb779b51..55108bb803e 100644 --- a/tests/baselines/reference/implicitAnyFunctionInvocationWithAnyArguements.errors.txt +++ b/tests/baselines/reference/implicitAnyFunctionInvocationWithAnyArguements.errors.txt @@ -1,4 +1,3 @@ -tests/cases/compiler/implicitAnyFunctionInvocationWithAnyArguements.ts(2,5): error TS7005: Variable 'arg0' implicitly has an 'any' type. tests/cases/compiler/implicitAnyFunctionInvocationWithAnyArguements.ts(3,5): error TS7005: Variable 'anyArray' implicitly has an 'any[]' type. tests/cases/compiler/implicitAnyFunctionInvocationWithAnyArguements.ts(4,13): error TS7008: Member 'v' implicitly has an 'any' type. tests/cases/compiler/implicitAnyFunctionInvocationWithAnyArguements.ts(4,16): error TS7008: Member 'w' implicitly has an 'any' type. @@ -7,11 +6,9 @@ tests/cases/compiler/implicitAnyFunctionInvocationWithAnyArguements.ts(6,16): er tests/cases/compiler/implicitAnyFunctionInvocationWithAnyArguements.ts(10,36): error TS7006: Parameter 'y2' implicitly has an 'any' type. -==== tests/cases/compiler/implicitAnyFunctionInvocationWithAnyArguements.ts (7 errors) ==== +==== tests/cases/compiler/implicitAnyFunctionInvocationWithAnyArguements.ts (6 errors) ==== // this should be errors var arg0 = null; // error at "arg0" - ~~~~ -!!! error TS7005: Variable 'arg0' implicitly has an 'any' type. var anyArray = [null, undefined]; // error at array literal ~~~~~~~~ !!! error TS7005: Variable 'anyArray' implicitly has an 'any[]' type. diff --git a/tests/baselines/reference/implicitAnyWidenToAny.errors.txt b/tests/baselines/reference/implicitAnyWidenToAny.errors.txt index 3b86c52c2ea..95739a450a8 100644 --- a/tests/baselines/reference/implicitAnyWidenToAny.errors.txt +++ b/tests/baselines/reference/implicitAnyWidenToAny.errors.txt @@ -1,17 +1,11 @@ -tests/cases/compiler/implicitAnyWidenToAny.ts(2,5): error TS7005: Variable 'x' implicitly has an 'any' type. -tests/cases/compiler/implicitAnyWidenToAny.ts(3,5): error TS7005: Variable 'x1' implicitly has an 'any' type. tests/cases/compiler/implicitAnyWidenToAny.ts(4,5): error TS7005: Variable 'widenArray' implicitly has an 'any[]' type. tests/cases/compiler/implicitAnyWidenToAny.ts(5,5): error TS7005: Variable 'emptyArray' implicitly has an 'any[]' type. -==== tests/cases/compiler/implicitAnyWidenToAny.ts (4 errors) ==== +==== tests/cases/compiler/implicitAnyWidenToAny.ts (2 errors) ==== // these should be errors var x = null; // error at "x" - ~ -!!! error TS7005: Variable 'x' implicitly has an 'any' type. var x1 = undefined; // error at "x1" - ~~ -!!! error TS7005: Variable 'x1' implicitly has an 'any' type. var widenArray = [null, undefined]; // error at "widenArray" ~~~~~~~~~~ !!! error TS7005: Variable 'widenArray' implicitly has an 'any[]' type. diff --git a/tests/baselines/reference/incrementOperatorWithAnyOtherType.js b/tests/baselines/reference/incrementOperatorWithAnyOtherType.js index e99340a53e2..989d4d900d3 100644 --- a/tests/baselines/reference/incrementOperatorWithAnyOtherType.js +++ b/tests/baselines/reference/incrementOperatorWithAnyOtherType.js @@ -2,7 +2,7 @@ // ++ operator on any type var ANY: any; -var ANY1; +var ANY1: any; var ANY2: any[] = ["", ""]; var obj = {x:1,y:null}; class A { diff --git a/tests/baselines/reference/incrementOperatorWithAnyOtherType.symbols b/tests/baselines/reference/incrementOperatorWithAnyOtherType.symbols index 338ab905064..2eceb1a2431 100644 --- a/tests/baselines/reference/incrementOperatorWithAnyOtherType.symbols +++ b/tests/baselines/reference/incrementOperatorWithAnyOtherType.symbols @@ -4,7 +4,7 @@ var ANY: any; >ANY : Symbol(ANY, Decl(incrementOperatorWithAnyOtherType.ts, 2, 3)) -var ANY1; +var ANY1: any; >ANY1 : Symbol(ANY1, Decl(incrementOperatorWithAnyOtherType.ts, 3, 3)) var ANY2: any[] = ["", ""]; diff --git a/tests/baselines/reference/incrementOperatorWithAnyOtherType.types b/tests/baselines/reference/incrementOperatorWithAnyOtherType.types index 715de620bff..13a39410df7 100644 --- a/tests/baselines/reference/incrementOperatorWithAnyOtherType.types +++ b/tests/baselines/reference/incrementOperatorWithAnyOtherType.types @@ -4,7 +4,7 @@ var ANY: any; >ANY : any -var ANY1; +var ANY1: any; >ANY1 : any var ANY2: any[] = ["", ""]; diff --git a/tests/baselines/reference/incrementOperatorWithAnyOtherTypeInvalidOperations.errors.txt b/tests/baselines/reference/incrementOperatorWithAnyOtherTypeInvalidOperations.errors.txt index 92e639df21e..4aae7f5b51e 100644 --- a/tests/baselines/reference/incrementOperatorWithAnyOtherTypeInvalidOperations.errors.txt +++ b/tests/baselines/reference/incrementOperatorWithAnyOtherTypeInvalidOperations.errors.txt @@ -47,7 +47,7 @@ tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOp ==== tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts (45 errors) ==== // ++ operator on any type - var ANY1; + var ANY1: any; var ANY2: any[] = [1, 2]; var obj: () => {} @@ -58,7 +58,7 @@ tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOp } class A { public a: any; - static foo() { + static foo(): any { var a; return a; } diff --git a/tests/baselines/reference/incrementOperatorWithAnyOtherTypeInvalidOperations.js b/tests/baselines/reference/incrementOperatorWithAnyOtherTypeInvalidOperations.js index 636ca74ba08..be2726f083b 100644 --- a/tests/baselines/reference/incrementOperatorWithAnyOtherTypeInvalidOperations.js +++ b/tests/baselines/reference/incrementOperatorWithAnyOtherTypeInvalidOperations.js @@ -1,6 +1,6 @@ //// [incrementOperatorWithAnyOtherTypeInvalidOperations.ts] // ++ operator on any type -var ANY1; +var ANY1: any; var ANY2: any[] = [1, 2]; var obj: () => {} @@ -11,7 +11,7 @@ function foo(): any { } class A { public a: any; - static foo() { + static foo(): any { var a; return a; } diff --git a/tests/baselines/reference/inferenceLimit.js b/tests/baselines/reference/inferenceLimit.js index a3fa5226830..b9423ebd655 100644 --- a/tests/baselines/reference/inferenceLimit.js +++ b/tests/baselines/reference/inferenceLimit.js @@ -47,7 +47,7 @@ export interface MyModel { 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()); }); diff --git a/tests/baselines/reference/initializePropertiesWithRenamedLet.types b/tests/baselines/reference/initializePropertiesWithRenamedLet.types index 65ea68059a7..d6937da8983 100644 --- a/tests/baselines/reference/initializePropertiesWithRenamedLet.types +++ b/tests/baselines/reference/initializePropertiesWithRenamedLet.types @@ -10,15 +10,15 @@ if (true) { >x0 : any var obj1 = { x0: x0 }; ->obj1 : { x0: any; } ->{ x0: x0 } : { x0: any; } ->x0 : any ->x0 : any +>obj1 : { x0: undefined; } +>{ x0: x0 } : { x0: undefined; } +>x0 : undefined +>x0 : undefined var obj2 = { x0 }; ->obj2 : { x0: any; } ->{ x0 } : { x0: any; } ->x0 : any +>obj2 : { x0: undefined; } +>{ x0 } : { x0: undefined; } +>x0 : undefined } var x, y, z; diff --git a/tests/baselines/reference/jsFileCompilationBindMultipleDefaultExports.errors.txt b/tests/baselines/reference/jsFileCompilationBindMultipleDefaultExports.errors.txt index 4c1d237aa47..05fecf03d30 100644 --- a/tests/baselines/reference/jsFileCompilationBindMultipleDefaultExports.errors.txt +++ b/tests/baselines/reference/jsFileCompilationBindMultipleDefaultExports.errors.txt @@ -1,9 +1,15 @@ +tests/cases/compiler/a.js(1,22): error TS2528: A module cannot have multiple default exports. +tests/cases/compiler/a.js(3,1): error TS2528: A module cannot have multiple default exports. tests/cases/compiler/a.js(3,16): error TS1109: Expression expected. -==== tests/cases/compiler/a.js (1 errors) ==== +==== tests/cases/compiler/a.js (3 errors) ==== export default class a { + ~ +!!! error TS2528: A module cannot have multiple default exports. } export default var a = 10; + ~~~~~~~~~~~~~~ +!!! error TS2528: A module cannot have multiple default exports. ~~~ !!! error TS1109: Expression expected. \ No newline at end of file diff --git a/tests/baselines/reference/json.stringify.types b/tests/baselines/reference/json.stringify.types index b063b06d8d0..8ff84885d9c 100644 --- a/tests/baselines/reference/json.stringify.types +++ b/tests/baselines/reference/json.stringify.types @@ -1,7 +1,7 @@ === tests/cases/compiler/json.stringify.ts === var value = null; ->value : null +>value : any >null : null JSON.stringify(value, undefined, 2); diff --git a/tests/baselines/reference/metadataOfStringLiteral.js b/tests/baselines/reference/metadataOfStringLiteral.js new file mode 100644 index 00000000000..676914681cb --- /dev/null +++ b/tests/baselines/reference/metadataOfStringLiteral.js @@ -0,0 +1,28 @@ +//// [metadataOfStringLiteral.ts] +function PropDeco(target: Object, propKey: string | symbol) { } + +class Foo { + @PropDeco + public foo: "foo" | "bar"; +} + +//// [metadataOfStringLiteral.js] +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +function PropDeco(target, propKey) { } +var Foo = (function () { + function Foo() { + } + return Foo; +}()); +__decorate([ + PropDeco, + __metadata("design:type", String) +], Foo.prototype, "foo"); diff --git a/tests/baselines/reference/metadataOfStringLiteral.symbols b/tests/baselines/reference/metadataOfStringLiteral.symbols new file mode 100644 index 00000000000..959a3403e14 --- /dev/null +++ b/tests/baselines/reference/metadataOfStringLiteral.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/metadataOfStringLiteral.ts === +function PropDeco(target: Object, propKey: string | symbol) { } +>PropDeco : Symbol(PropDeco, Decl(metadataOfStringLiteral.ts, 0, 0)) +>target : Symbol(target, Decl(metadataOfStringLiteral.ts, 0, 18)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>propKey : Symbol(propKey, Decl(metadataOfStringLiteral.ts, 0, 33)) + +class Foo { +>Foo : Symbol(Foo, Decl(metadataOfStringLiteral.ts, 0, 63)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfStringLiteral.ts, 0, 0)) + + public foo: "foo" | "bar"; +>foo : Symbol(Foo.foo, Decl(metadataOfStringLiteral.ts, 2, 11)) +} diff --git a/tests/baselines/reference/metadataOfStringLiteral.types b/tests/baselines/reference/metadataOfStringLiteral.types new file mode 100644 index 00000000000..666cdf38e45 --- /dev/null +++ b/tests/baselines/reference/metadataOfStringLiteral.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/metadataOfStringLiteral.ts === +function PropDeco(target: Object, propKey: string | symbol) { } +>PropDeco : (target: Object, propKey: string | symbol) => void +>target : Object +>Object : Object +>propKey : string | symbol + +class Foo { +>Foo : Foo + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + public foo: "foo" | "bar"; +>foo : "foo" | "bar" +} diff --git a/tests/baselines/reference/metadataOfUnion.js b/tests/baselines/reference/metadataOfUnion.js new file mode 100644 index 00000000000..9a88481c80a --- /dev/null +++ b/tests/baselines/reference/metadataOfUnion.js @@ -0,0 +1,99 @@ +//// [metadataOfUnion.ts] +function PropDeco(target: Object, propKey: string | symbol) { } + +class A { +} + +class B { + @PropDeco + x: "foo" | A; + + @PropDeco + y: true | boolean; + + @PropDeco + z: "foo" | boolean; +} + +enum E { + A, + B, + C, + D +} + +class D { + @PropDeco + a: E.A; + + @PropDeco + b: E.B | E.C; + + @PropDeco + c: E; + + @PropDeco + d: E | number; +} + +//// [metadataOfUnion.js] +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +function PropDeco(target, propKey) { } +var A = (function () { + function A() { + } + return A; +}()); +var B = (function () { + function B() { + } + return B; +}()); +__decorate([ + PropDeco, + __metadata("design:type", Object) +], B.prototype, "x"); +__decorate([ + PropDeco, + __metadata("design:type", Boolean) +], B.prototype, "y"); +__decorate([ + PropDeco, + __metadata("design:type", Object) +], B.prototype, "z"); +var E; +(function (E) { + E[E["A"] = 0] = "A"; + E[E["B"] = 1] = "B"; + E[E["C"] = 2] = "C"; + E[E["D"] = 3] = "D"; +})(E || (E = {})); +var D = (function () { + function D() { + } + return D; +}()); +__decorate([ + PropDeco, + __metadata("design:type", Number) +], D.prototype, "a"); +__decorate([ + PropDeco, + __metadata("design:type", Number) +], D.prototype, "b"); +__decorate([ + PropDeco, + __metadata("design:type", Number) +], D.prototype, "c"); +__decorate([ + PropDeco, + __metadata("design:type", Number) +], D.prototype, "d"); diff --git a/tests/baselines/reference/metadataOfUnion.symbols b/tests/baselines/reference/metadataOfUnion.symbols new file mode 100644 index 00000000000..22c0cc37602 --- /dev/null +++ b/tests/baselines/reference/metadataOfUnion.symbols @@ -0,0 +1,85 @@ +=== tests/cases/compiler/metadataOfUnion.ts === +function PropDeco(target: Object, propKey: string | symbol) { } +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0)) +>target : Symbol(target, Decl(metadataOfUnion.ts, 0, 18)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>propKey : Symbol(propKey, Decl(metadataOfUnion.ts, 0, 33)) + +class A { +>A : Symbol(A, Decl(metadataOfUnion.ts, 0, 63)) +} + +class B { +>B : Symbol(B, Decl(metadataOfUnion.ts, 3, 1)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0)) + + x: "foo" | A; +>x : Symbol(B.x, Decl(metadataOfUnion.ts, 5, 9)) +>A : Symbol(A, Decl(metadataOfUnion.ts, 0, 63)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0)) + + y: true | boolean; +>y : Symbol(B.y, Decl(metadataOfUnion.ts, 7, 17)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0)) + + z: "foo" | boolean; +>z : Symbol(B.z, Decl(metadataOfUnion.ts, 10, 22)) +} + +enum E { +>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1)) + + A, +>A : Symbol(E.A, Decl(metadataOfUnion.ts, 16, 8)) + + B, +>B : Symbol(E.B, Decl(metadataOfUnion.ts, 17, 6)) + + C, +>C : Symbol(E.C, Decl(metadataOfUnion.ts, 18, 6)) + + D +>D : Symbol(E.D, Decl(metadataOfUnion.ts, 19, 6)) +} + +class D { +>D : Symbol(D, Decl(metadataOfUnion.ts, 21, 1)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0)) + + a: E.A; +>a : Symbol(D.a, Decl(metadataOfUnion.ts, 23, 9)) +>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1)) +>A : Symbol(E.A, Decl(metadataOfUnion.ts, 16, 8)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0)) + + b: E.B | E.C; +>b : Symbol(D.b, Decl(metadataOfUnion.ts, 25, 11)) +>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1)) +>B : Symbol(E.B, Decl(metadataOfUnion.ts, 17, 6)) +>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1)) +>C : Symbol(E.C, Decl(metadataOfUnion.ts, 18, 6)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0)) + + c: E; +>c : Symbol(D.c, Decl(metadataOfUnion.ts, 28, 17)) +>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0)) + + d: E | number; +>d : Symbol(D.d, Decl(metadataOfUnion.ts, 31, 9)) +>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1)) +} diff --git a/tests/baselines/reference/metadataOfUnion.types b/tests/baselines/reference/metadataOfUnion.types new file mode 100644 index 00000000000..08afc4e81bb --- /dev/null +++ b/tests/baselines/reference/metadataOfUnion.types @@ -0,0 +1,86 @@ +=== tests/cases/compiler/metadataOfUnion.ts === +function PropDeco(target: Object, propKey: string | symbol) { } +>PropDeco : (target: Object, propKey: string | symbol) => void +>target : Object +>Object : Object +>propKey : string | symbol + +class A { +>A : A +} + +class B { +>B : B + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + x: "foo" | A; +>x : A | "foo" +>A : A + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + y: true | boolean; +>y : boolean +>true : true + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + z: "foo" | boolean; +>z : boolean | "foo" +} + +enum E { +>E : E + + A, +>A : E.A + + B, +>B : E.B + + C, +>C : E.C + + D +>D : E.D +} + +class D { +>D : D + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + a: E.A; +>a : E.A +>E : any +>A : E.A + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + b: E.B | E.C; +>b : E.B | E.C +>E : any +>B : E.B +>E : any +>C : E.C + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + c: E; +>c : E +>E : E + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + d: E | number; +>d : number | E +>E : E +} diff --git a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.js b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.js index 9a5ed619b2d..180b53028ff 100644 --- a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.js +++ b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.js @@ -85,7 +85,7 @@ const o1 = { 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()); }); diff --git a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.js b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.js index c4c2d6853af..cf69f260223 100644 --- a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.js +++ b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.js @@ -85,7 +85,7 @@ const o1 = { 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()); }); diff --git a/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.js b/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.js index 8736c51cd16..350113ec6a0 100644 --- a/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.js +++ b/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.js @@ -85,7 +85,7 @@ const o1 = { 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()); }); diff --git a/tests/baselines/reference/multipleDefaultExports01.errors.txt b/tests/baselines/reference/multipleDefaultExports01.errors.txt index b3e7d757289..16aa3b2f7b1 100644 --- a/tests/baselines/reference/multipleDefaultExports01.errors.txt +++ b/tests/baselines/reference/multipleDefaultExports01.errors.txt @@ -1,16 +1,13 @@ -tests/cases/conformance/es6/modules/m1.ts(2,22): error TS2323: Cannot redeclare exported variable 'default'. tests/cases/conformance/es6/modules/m1.ts(2,22): error TS2528: A module cannot have multiple default exports. tests/cases/conformance/es6/modules/m1.ts(6,25): error TS2528: A module cannot have multiple default exports. -tests/cases/conformance/es6/modules/m1.ts(11,1): error TS2323: Cannot redeclare exported variable 'default'. +tests/cases/conformance/es6/modules/m1.ts(11,1): error TS2528: A module cannot have multiple default exports. tests/cases/conformance/es6/modules/m2.ts(3,1): error TS2348: Value of type 'typeof foo' is not callable. Did you mean to include 'new'? -==== tests/cases/conformance/es6/modules/m1.ts (4 errors) ==== +==== tests/cases/conformance/es6/modules/m1.ts (3 errors) ==== export default class foo { ~~~ -!!! error TS2323: Cannot redeclare exported variable 'default'. - ~~~ !!! error TS2528: A module cannot have multiple default exports. } @@ -24,7 +21,7 @@ tests/cases/conformance/es6/modules/m2.ts(3,1): error TS2348: Value of type 'typ var x = 10; export default x; ~~~~~~~~~~~~~~~~~ -!!! error TS2323: Cannot redeclare exported variable 'default'. +!!! error TS2528: A module cannot have multiple default exports. ==== tests/cases/conformance/es6/modules/m2.ts (1 errors) ==== import Entity from "./m1" diff --git a/tests/baselines/reference/multipleExportDefault1.errors.txt b/tests/baselines/reference/multipleExportDefault1.errors.txt new file mode 100644 index 00000000000..3da6afc41e0 --- /dev/null +++ b/tests/baselines/reference/multipleExportDefault1.errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/externalModules/multipleExportDefault1.ts(1,25): error TS2528: A module cannot have multiple default exports. +tests/cases/conformance/externalModules/multipleExportDefault1.ts(5,1): error TS2528: A module cannot have multiple default exports. + + +==== tests/cases/conformance/externalModules/multipleExportDefault1.ts (2 errors) ==== + export default function Foo (){ + ~~~ +!!! error TS2528: A module cannot have multiple default exports. + + } + + export default { + ~~~~~~~~~~~~~~~~ + uhoh: "another default", + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + }; + ~~ +!!! error TS2528: A module cannot have multiple default exports. + \ No newline at end of file diff --git a/tests/baselines/reference/multipleExportDefault1.js b/tests/baselines/reference/multipleExportDefault1.js new file mode 100644 index 00000000000..bec4fb48969 --- /dev/null +++ b/tests/baselines/reference/multipleExportDefault1.js @@ -0,0 +1,20 @@ +//// [multipleExportDefault1.ts] +export default function Foo (){ + +} + +export default { + uhoh: "another default", +}; + + +//// [multipleExportDefault1.js] +"use strict"; +function Foo() { +} +exports.__esModule = true; +exports["default"] = Foo; +exports.__esModule = true; +exports["default"] = { + uhoh: "another default" +}; diff --git a/tests/baselines/reference/multipleExportDefault2.errors.txt b/tests/baselines/reference/multipleExportDefault2.errors.txt new file mode 100644 index 00000000000..0543e25a163 --- /dev/null +++ b/tests/baselines/reference/multipleExportDefault2.errors.txt @@ -0,0 +1,18 @@ +tests/cases/conformance/externalModules/multipleExportDefault2.ts(1,1): error TS2528: A module cannot have multiple default exports. +tests/cases/conformance/externalModules/multipleExportDefault2.ts(5,25): error TS2528: A module cannot have multiple default exports. + + +==== tests/cases/conformance/externalModules/multipleExportDefault2.ts (2 errors) ==== + export default { + ~~~~~~~~~~~~~~~~ + uhoh: "another default", + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + }; + ~~ +!!! error TS2528: A module cannot have multiple default exports. + + export default function Foo() { } + ~~~ +!!! error TS2528: A module cannot have multiple default exports. + + \ No newline at end of file diff --git a/tests/baselines/reference/multipleExportDefault2.js b/tests/baselines/reference/multipleExportDefault2.js new file mode 100644 index 00000000000..dc82500a1d9 --- /dev/null +++ b/tests/baselines/reference/multipleExportDefault2.js @@ -0,0 +1,18 @@ +//// [multipleExportDefault2.ts] +export default { + uhoh: "another default", +}; + +export default function Foo() { } + + + +//// [multipleExportDefault2.js] +"use strict"; +exports.__esModule = true; +exports["default"] = { + uhoh: "another default" +}; +function Foo() { } +exports.__esModule = true; +exports["default"] = Foo; diff --git a/tests/baselines/reference/multipleExportDefault3.errors.txt b/tests/baselines/reference/multipleExportDefault3.errors.txt new file mode 100644 index 00000000000..f1e55da9112 --- /dev/null +++ b/tests/baselines/reference/multipleExportDefault3.errors.txt @@ -0,0 +1,18 @@ +tests/cases/conformance/externalModules/multipleExportDefault3.ts(1,1): error TS2528: A module cannot have multiple default exports. +tests/cases/conformance/externalModules/multipleExportDefault3.ts(5,22): error TS2528: A module cannot have multiple default exports. + + +==== tests/cases/conformance/externalModules/multipleExportDefault3.ts (2 errors) ==== + export default { + ~~~~~~~~~~~~~~~~ + uhoh: "another default", + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + }; + ~~ +!!! error TS2528: A module cannot have multiple default exports. + + export default class C { } + ~ +!!! error TS2528: A module cannot have multiple default exports. + + \ No newline at end of file diff --git a/tests/baselines/reference/multipleExportDefault3.js b/tests/baselines/reference/multipleExportDefault3.js new file mode 100644 index 00000000000..5d7ad48e0ca --- /dev/null +++ b/tests/baselines/reference/multipleExportDefault3.js @@ -0,0 +1,22 @@ +//// [multipleExportDefault3.ts] +export default { + uhoh: "another default", +}; + +export default class C { } + + + +//// [multipleExportDefault3.js] +"use strict"; +exports.__esModule = true; +exports["default"] = { + uhoh: "another default" +}; +var C = (function () { + function C() { + } + return C; +}()); +exports.__esModule = true; +exports["default"] = C; diff --git a/tests/baselines/reference/multipleExportDefault4.errors.txt b/tests/baselines/reference/multipleExportDefault4.errors.txt new file mode 100644 index 00000000000..bba15527d00 --- /dev/null +++ b/tests/baselines/reference/multipleExportDefault4.errors.txt @@ -0,0 +1,16 @@ +tests/cases/conformance/externalModules/multipleExportDefault4.ts(1,22): error TS2528: A module cannot have multiple default exports. +tests/cases/conformance/externalModules/multipleExportDefault4.ts(3,1): error TS2528: A module cannot have multiple default exports. + + +==== tests/cases/conformance/externalModules/multipleExportDefault4.ts (2 errors) ==== + export default class C { } + ~ +!!! error TS2528: A module cannot have multiple default exports. + + export default { + ~~~~~~~~~~~~~~~~ + uhoh: "another default", + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + }; + ~~ +!!! error TS2528: A module cannot have multiple default exports. \ No newline at end of file diff --git a/tests/baselines/reference/multipleExportDefault4.js b/tests/baselines/reference/multipleExportDefault4.js new file mode 100644 index 00000000000..1199fa91c9c --- /dev/null +++ b/tests/baselines/reference/multipleExportDefault4.js @@ -0,0 +1,20 @@ +//// [multipleExportDefault4.ts] +export default class C { } + +export default { + uhoh: "another default", +}; + +//// [multipleExportDefault4.js] +"use strict"; +var C = (function () { + function C() { + } + return C; +}()); +exports.__esModule = true; +exports["default"] = C; +exports.__esModule = true; +exports["default"] = { + uhoh: "another default" +}; diff --git a/tests/baselines/reference/multipleExportDefault5.errors.txt b/tests/baselines/reference/multipleExportDefault5.errors.txt new file mode 100644 index 00000000000..30c87339ff2 --- /dev/null +++ b/tests/baselines/reference/multipleExportDefault5.errors.txt @@ -0,0 +1,11 @@ +tests/cases/conformance/externalModules/multipleExportDefault5.ts(1,25): error TS2528: A module cannot have multiple default exports. +tests/cases/conformance/externalModules/multipleExportDefault5.ts(2,22): error TS2528: A module cannot have multiple default exports. + + +==== tests/cases/conformance/externalModules/multipleExportDefault5.ts (2 errors) ==== + export default function bar() { } + ~~~ +!!! error TS2528: A module cannot have multiple default exports. + export default class C {} + ~ +!!! error TS2528: A module cannot have multiple default exports. \ No newline at end of file diff --git a/tests/baselines/reference/multipleExportDefault5.js b/tests/baselines/reference/multipleExportDefault5.js new file mode 100644 index 00000000000..7ae33aee9f4 --- /dev/null +++ b/tests/baselines/reference/multipleExportDefault5.js @@ -0,0 +1,16 @@ +//// [multipleExportDefault5.ts] +export default function bar() { } +export default class C {} + +//// [multipleExportDefault5.js] +"use strict"; +function bar() { } +exports.__esModule = true; +exports["default"] = bar; +var C = (function () { + function C() { + } + return C; +}()); +exports.__esModule = true; +exports["default"] = C; diff --git a/tests/baselines/reference/multipleExportDefault6.errors.txt b/tests/baselines/reference/multipleExportDefault6.errors.txt new file mode 100644 index 00000000000..a8bf80e8df0 --- /dev/null +++ b/tests/baselines/reference/multipleExportDefault6.errors.txt @@ -0,0 +1,20 @@ +tests/cases/conformance/externalModules/multipleExportDefault6.ts(1,1): error TS2528: A module cannot have multiple default exports. +tests/cases/conformance/externalModules/multipleExportDefault6.ts(5,1): error TS2528: A module cannot have multiple default exports. + + +==== tests/cases/conformance/externalModules/multipleExportDefault6.ts (2 errors) ==== + export default { + ~~~~~~~~~~~~~~~~ + lol: 1 + ~~~~~~~~~~ + } + ~ +!!! error TS2528: A module cannot have multiple default exports. + + export default { + ~~~~~~~~~~~~~~~~ + lol: 2 + ~~~~~~~~~~ + } + ~ +!!! error TS2528: A module cannot have multiple default exports. \ No newline at end of file diff --git a/tests/baselines/reference/multipleExportDefault6.js b/tests/baselines/reference/multipleExportDefault6.js new file mode 100644 index 00000000000..a8b93459e4e --- /dev/null +++ b/tests/baselines/reference/multipleExportDefault6.js @@ -0,0 +1,19 @@ +//// [multipleExportDefault6.ts] +export default { + lol: 1 +} + +export default { + lol: 2 +} + +//// [multipleExportDefault6.js] +"use strict"; +exports.__esModule = true; +exports["default"] = { + lol: 1 +}; +exports.__esModule = true; +exports["default"] = { + lol: 2 +}; diff --git a/tests/baselines/reference/negateOperatorWithAnyOtherType.errors.txt b/tests/baselines/reference/negateOperatorWithAnyOtherType.errors.txt index f008b4698ed..03e596aca41 100644 --- a/tests/baselines/reference/negateOperatorWithAnyOtherType.errors.txt +++ b/tests/baselines/reference/negateOperatorWithAnyOtherType.errors.txt @@ -5,7 +5,7 @@ tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperator // - operator on any type var ANY: any; - var ANY1; + var ANY1: any; var ANY2: any[] = ["", ""]; var obj: () => {} var obj1 = { x: "", y: () => { }}; @@ -16,7 +16,7 @@ tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperator } class A { public a: any; - static foo() { + static foo(): any { var a; return a; } diff --git a/tests/baselines/reference/negateOperatorWithAnyOtherType.js b/tests/baselines/reference/negateOperatorWithAnyOtherType.js index 6a2fe74c7ba..eb5f70d8c9c 100644 --- a/tests/baselines/reference/negateOperatorWithAnyOtherType.js +++ b/tests/baselines/reference/negateOperatorWithAnyOtherType.js @@ -2,7 +2,7 @@ // - operator on any type var ANY: any; -var ANY1; +var ANY1: any; var ANY2: any[] = ["", ""]; var obj: () => {} var obj1 = { x: "", y: () => { }}; @@ -13,7 +13,7 @@ function foo(): any { } class A { public a: any; - static foo() { + static foo(): any { var a; return a; } diff --git a/tests/baselines/reference/nestedBlockScopedBindings3.types b/tests/baselines/reference/nestedBlockScopedBindings3.types index 0de8123861d..ca13759bac4 100644 --- a/tests/baselines/reference/nestedBlockScopedBindings3.types +++ b/tests/baselines/reference/nestedBlockScopedBindings3.types @@ -31,7 +31,7 @@ function a1() { for (let x; x < 1;) { >x : any >x < 1 : boolean ->x : any +>x : undefined >1 : 1 () => x; @@ -53,24 +53,24 @@ function a2() { for (let x; x < 1;) { >x : any >x < 1 : boolean ->x : any +>x : number >1 : 1 x = x + 1; ->x = x + 1 : any ->x : any ->x + 1 : any +>x = x + 1 : number >x : any +>x + 1 : number +>x : number >1 : 1 } for (let x;;) { >x : any x = x + 2; ->x = x + 2 : any ->x : any ->x + 2 : any +>x = x + 2 : number >x : any +>x + 2 : number +>x : number >2 : 2 } } @@ -82,14 +82,14 @@ function a3() { for (let x; x < 1;) { >x : any >x < 1 : boolean ->x : any +>x : number >1 : 1 x = x + 1; ->x = x + 1 : any ->x : any ->x + 1 : any +>x = x + 1 : number >x : any +>x + 1 : number +>x : number >1 : 1 } switch (1) { @@ -111,14 +111,14 @@ function a4() { for (let x; x < 1;) { >x : any >x < 1 : boolean ->x : any +>x : number >1 : 1 x = x + 1; ->x = x + 1 : any ->x : any ->x + 1 : any +>x = x + 1 : number >x : any +>x + 1 : number +>x : number >1 : 1 () => x; @@ -145,14 +145,14 @@ function a5() { for (let x; x < 1;) { >x : any >x < 1 : boolean ->x : any +>x : number >1 : 1 x = x + 1; ->x = x + 1 : any ->x : any ->x + 1 : any +>x = x + 1 : number >x : any +>x + 1 : number +>x : number >1 : 1 () => x; diff --git a/tests/baselines/reference/nestedBlockScopedBindings4.types b/tests/baselines/reference/nestedBlockScopedBindings4.types index 65b5d73db9d..9e0147f25f7 100644 --- a/tests/baselines/reference/nestedBlockScopedBindings4.types +++ b/tests/baselines/reference/nestedBlockScopedBindings4.types @@ -5,24 +5,24 @@ function a0() { for (let x; x < 1;) { >x : any >x < 1 : boolean ->x : any +>x : number >1 : 1 x = x + 1; ->x = x + 1 : any ->x : any ->x + 1 : any +>x = x + 1 : number >x : any +>x + 1 : number +>x : number >1 : 1 } for (let x;;) { >x : any x = x + 2; ->x = x + 2 : any ->x : any ->x + 2 : any +>x = x + 2 : number >x : any +>x + 2 : number +>x : number >2 : 2 } } @@ -33,14 +33,14 @@ function a1() { for (let x; x < 1;) { >x : any >x < 1 : boolean ->x : any +>x : number >1 : 1 x = x + 1; ->x = x + 1 : any ->x : any ->x + 1 : any +>x = x + 1 : number >x : any +>x + 1 : number +>x : number >1 : 1 () => x; @@ -51,10 +51,10 @@ function a1() { >x : any x = x + 2; ->x = x + 2 : any ->x : any ->x + 2 : any +>x = x + 2 : number >x : any +>x + 2 : number +>x : number >2 : 2 } } @@ -65,24 +65,24 @@ function a2() { for (let x; x < 1;) { >x : any >x < 1 : boolean ->x : any +>x : number >1 : 1 x = x + 1; ->x = x + 1 : any ->x : any ->x + 1 : any +>x = x + 1 : number >x : any +>x + 1 : number +>x : number >1 : 1 } for (let x;;) { >x : any x = x + 2; ->x = x + 2 : any ->x : any ->x + 2 : any +>x = x + 2 : number >x : any +>x + 2 : number +>x : number >2 : 2 () => x; @@ -98,14 +98,14 @@ function a3() { for (let x; x < 1;) { >x : any >x < 1 : boolean ->x : any +>x : number >1 : 1 x = x + 1; ->x = x + 1 : any ->x : any ->x + 1 : any +>x = x + 1 : number >x : any +>x + 1 : number +>x : number >1 : 1 () => x; @@ -116,10 +116,10 @@ function a3() { >x : any x = x + 2; ->x = x + 2 : any ->x : any ->x + 2 : any +>x = x + 2 : number >x : any +>x + 2 : number +>x : number >2 : 2 () => x; diff --git a/tests/baselines/reference/nestedBlockScopedBindings6.types b/tests/baselines/reference/nestedBlockScopedBindings6.types index 865dea31e37..bf38f46d508 100644 --- a/tests/baselines/reference/nestedBlockScopedBindings6.types +++ b/tests/baselines/reference/nestedBlockScopedBindings6.types @@ -18,10 +18,10 @@ function a0() { >x : any x = x + 2; ->x = x + 2 : any ->x : any ->x + 2 : any +>x = x + 2 : number >x : any +>x + 2 : number +>x : number >2 : 2 } } @@ -49,10 +49,10 @@ function a1() { >x : any x = x + 2; ->x = x + 2 : any ->x : any ->x + 2 : any +>x = x + 2 : number >x : any +>x + 2 : number +>x : number >2 : 2 } } @@ -76,10 +76,10 @@ function a2() { >x : any x = x + 2; ->x = x + 2 : any ->x : any ->x + 2 : any +>x = x + 2 : number >x : any +>x + 2 : number +>x : number >2 : 2 () => x; @@ -111,10 +111,10 @@ function a3() { >x : any x = x + 2; ->x = x + 2 : any ->x : any ->x + 2 : any +>x = x + 2 : number >x : any +>x + 2 : number +>x : number >2 : 2 () => x; diff --git a/tests/baselines/reference/noImplicitAnyDestructuringVarDeclaration.errors.txt b/tests/baselines/reference/noImplicitAnyDestructuringVarDeclaration.errors.txt index f7e6475b971..cedbbc8ed3d 100644 --- a/tests/baselines/reference/noImplicitAnyDestructuringVarDeclaration.errors.txt +++ b/tests/baselines/reference/noImplicitAnyDestructuringVarDeclaration.errors.txt @@ -2,14 +2,10 @@ tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(1,5): error TS1 tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(1,6): error TS7031: Binding element 'a' implicitly has an 'any' type. tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(1,10): error TS1182: A destructuring declaration must have an initializer. tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(1,11): error TS7031: Binding element 'b' implicitly has an 'any' type. -tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(1,15): error TS7005: Variable 'c' implicitly has an 'any' type. -tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(1,18): error TS7005: Variable 'd' implicitly has an 'any' type. tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(3,5): error TS1182: A destructuring declaration must have an initializer. tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(3,6): error TS7031: Binding element 'a1' implicitly has an 'any' type. tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(3,23): error TS1182: A destructuring declaration must have an initializer. tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(3,24): error TS7031: Binding element 'b1' implicitly has an 'any' type. -tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(3,36): error TS7005: Variable 'c1' implicitly has an 'any' type. -tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(3,52): error TS7005: Variable 'd1' implicitly has an 'any' type. tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(5,5): error TS1182: A destructuring declaration must have an initializer. tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(5,18): error TS1182: A destructuring declaration must have an initializer. tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(7,5): error TS1182: A destructuring declaration must have an initializer. @@ -17,12 +13,10 @@ tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(7,13): error TS tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(7,25): error TS7008: Member 'b3' implicitly has an 'any' type. tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(9,6): error TS7031: Binding element 'a4' implicitly has an 'any' type. tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(9,26): error TS7031: Binding element 'b4' implicitly has an 'any' type. -tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(9,46): error TS7005: Variable 'c4' implicitly has an 'any' type. -tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(9,62): error TS7005: Variable 'd4' implicitly has an 'any' type. tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(11,6): error TS7031: Binding element 'a5' implicitly has an 'any' type. -==== tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts (22 errors) ==== +==== tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts (16 errors) ==== var [a], {b}, c, d; // error ~~~ !!! error TS1182: A destructuring declaration must have an initializer. @@ -32,10 +26,6 @@ tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(11,6): error TS !!! error TS1182: A destructuring declaration must have an initializer. ~ !!! error TS7031: Binding element 'b' implicitly has an 'any' type. - ~ -!!! error TS7005: Variable 'c' implicitly has an 'any' type. - ~ -!!! error TS7005: Variable 'd' implicitly has an 'any' type. var [a1 = undefined], {b1 = null}, c1 = undefined, d1 = null; // error ~~~~~~~~~~~~~~~~ @@ -46,10 +36,6 @@ tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(11,6): error TS !!! error TS1182: A destructuring declaration must have an initializer. ~~ !!! error TS7031: Binding element 'b1' implicitly has an 'any' type. - ~~ -!!! error TS7005: Variable 'c1' implicitly has an 'any' type. - ~~ -!!! error TS7005: Variable 'd1' implicitly has an 'any' type. var [a2]: [any], {b2}: { b2: any }, c2: any, d2: any; ~~~~ @@ -70,10 +56,6 @@ tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(11,6): error TS !!! error TS7031: Binding element 'a4' implicitly has an 'any' type. ~~ !!! error TS7031: Binding element 'b4' implicitly has an 'any' type. - ~~ -!!! error TS7005: Variable 'c4' implicitly has an 'any' type. - ~~ -!!! error TS7005: Variable 'd4' implicitly has an 'any' type. var [a5 = undefined] = []; // error ~~ diff --git a/tests/baselines/reference/noImplicitAnyForIn.errors.txt b/tests/baselines/reference/noImplicitAnyForIn.errors.txt index 2fb8e5a4103..69b5cd34906 100644 --- a/tests/baselines/reference/noImplicitAnyForIn.errors.txt +++ b/tests/baselines/reference/noImplicitAnyForIn.errors.txt @@ -1,11 +1,10 @@ tests/cases/compiler/noImplicitAnyForIn.ts(8,18): error TS7017: Index signature of object type implicitly has an 'any' type. tests/cases/compiler/noImplicitAnyForIn.ts(15,18): error TS7017: Index signature of object type implicitly has an 'any' type. -tests/cases/compiler/noImplicitAnyForIn.ts(21,9): error TS7005: Variable 'b' implicitly has an 'any' type. tests/cases/compiler/noImplicitAnyForIn.ts(29,5): error TS7005: Variable 'n' implicitly has an 'any[][]' type. tests/cases/compiler/noImplicitAnyForIn.ts(31,6): error TS2405: The left-hand side of a 'for...in' statement must be of type 'string' or 'any'. -==== tests/cases/compiler/noImplicitAnyForIn.ts (5 errors) ==== +==== tests/cases/compiler/noImplicitAnyForIn.ts (4 errors) ==== var x: {}[] = [[1, 2, 3], ["hello"]]; @@ -31,8 +30,6 @@ tests/cases/compiler/noImplicitAnyForIn.ts(31,6): error TS2405: The left-hand si for (var a in x) { // Should yield an implicit 'any' error. var b; - ~ -!!! error TS7005: Variable 'b' implicitly has an 'any' type. var c = a || b; } diff --git a/tests/baselines/reference/noImplicitReturnsInAsync1.js b/tests/baselines/reference/noImplicitReturnsInAsync1.js index 6192e9e7f24..5274264a6b1 100644 --- a/tests/baselines/reference/noImplicitReturnsInAsync1.js +++ b/tests/baselines/reference/noImplicitReturnsInAsync1.js @@ -11,7 +11,7 @@ async function test(isError: boolean = false) { 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()); }); diff --git a/tests/baselines/reference/noImplicitReturnsInAsync2.js b/tests/baselines/reference/noImplicitReturnsInAsync2.js index 5e034237fef..93f8c97d1fb 100644 --- a/tests/baselines/reference/noImplicitReturnsInAsync2.js +++ b/tests/baselines/reference/noImplicitReturnsInAsync2.js @@ -40,7 +40,7 @@ async function test7(isError: boolean = true) { 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()); }); diff --git a/tests/baselines/reference/null.types b/tests/baselines/reference/null.types index 35c084c3cbf..ab5ae728dea 100644 --- a/tests/baselines/reference/null.types +++ b/tests/baselines/reference/null.types @@ -5,10 +5,10 @@ var x=null; >null : null var y=3+x; ->y : any ->3+x : any +>y : number +>3+x : number >3 : 3 ->x : any +>x : null var z=3+null; >z : number diff --git a/tests/baselines/reference/objectLiteralShorthandProperties.types b/tests/baselines/reference/objectLiteralShorthandProperties.types index 4f4482906aa..168fcc07af7 100644 --- a/tests/baselines/reference/objectLiteralShorthandProperties.types +++ b/tests/baselines/reference/objectLiteralShorthandProperties.types @@ -5,35 +5,35 @@ var a, b, c; >c : any var x1 = { ->x1 : { a: any; } ->{ a} : { a: any; } +>x1 : { a: undefined; } +>{ a} : { a: undefined; } a ->a : any +>a : undefined }; var x2 = { ->x2 : { a: any; } ->{ a,} : { a: any; } +>x2 : { a: undefined; } +>{ a,} : { a: undefined; } a, ->a : any +>a : undefined } var x3 = { >x3 : any ->{ a: 0, b, c, d() { }, x3, parent: x3} : { a: number; b: any; c: any; d(): void; x3: any; parent: any; } +>{ a: 0, b, c, d() { }, x3, parent: x3} : { a: number; b: undefined; c: undefined; d(): void; x3: any; parent: any; } a: 0, >a : number >0 : 0 b, ->b : any +>b : undefined c, ->c : any +>c : undefined d() { }, >d : () => void diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesES6.types b/tests/baselines/reference/objectLiteralShorthandPropertiesES6.types index 1565be04625..80cbe304040 100644 --- a/tests/baselines/reference/objectLiteralShorthandPropertiesES6.types +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesES6.types @@ -5,35 +5,35 @@ var a, b, c; >c : any var x1 = { ->x1 : { a: any; } ->{ a} : { a: any; } +>x1 : { a: undefined; } +>{ a} : { a: undefined; } a ->a : any +>a : undefined }; var x2 = { ->x2 : { a: any; } ->{ a,} : { a: any; } +>x2 : { a: undefined; } +>{ a,} : { a: undefined; } a, ->a : any +>a : undefined } var x3 = { >x3 : any ->{ a: 0, b, c, d() { }, x3, parent: x3} : { a: number; b: any; c: any; d(): void; x3: any; parent: any; } +>{ a: 0, b, c, d() { }, x3, parent: x3} : { a: number; b: undefined; c: undefined; d(): void; x3: any; parent: any; } a: 0, >a : number >0 : 0 b, ->b : any +>b : undefined c, ->c : any +>c : undefined d() { }, >d : () => void diff --git a/tests/baselines/reference/parserAmbiguityWithBinaryOperator1.types b/tests/baselines/reference/parserAmbiguityWithBinaryOperator1.types index 234375fb46d..ca7d65c9c34 100644 --- a/tests/baselines/reference/parserAmbiguityWithBinaryOperator1.types +++ b/tests/baselines/reference/parserAmbiguityWithBinaryOperator1.types @@ -10,12 +10,12 @@ function f1() { if (a < b || b > (c + 1)) { } >a < b || b > (c + 1) : boolean >a < b : boolean ->a : any ->b : any +>a : undefined +>b : undefined >b > (c + 1) : boolean ->b : any ->(c + 1) : any ->c + 1 : any ->c : any +>b : undefined +>(c + 1) : number +>c + 1 : number +>c : undefined >1 : 1 } diff --git a/tests/baselines/reference/parserAmbiguityWithBinaryOperator2.types b/tests/baselines/reference/parserAmbiguityWithBinaryOperator2.types index ed3b4b903bb..f4c1c2ac690 100644 --- a/tests/baselines/reference/parserAmbiguityWithBinaryOperator2.types +++ b/tests/baselines/reference/parserAmbiguityWithBinaryOperator2.types @@ -10,12 +10,12 @@ function f() { if (a < b && b > (c + 1)) { } >a < b && b > (c + 1) : boolean >a < b : boolean ->a : any ->b : any +>a : undefined +>b : undefined >b > (c + 1) : boolean ->b : any ->(c + 1) : any ->c + 1 : any ->c : any +>b : undefined +>(c + 1) : number +>c + 1 : number +>c : undefined >1 : 1 } diff --git a/tests/baselines/reference/parserAmbiguityWithBinaryOperator3.types b/tests/baselines/reference/parserAmbiguityWithBinaryOperator3.types index 61601d8bdf6..b1129656342 100644 --- a/tests/baselines/reference/parserAmbiguityWithBinaryOperator3.types +++ b/tests/baselines/reference/parserAmbiguityWithBinaryOperator3.types @@ -10,13 +10,13 @@ function f() { if (a < b && b < (c + 1)) { } >a < b && b < (c + 1) : boolean >a < b : boolean ->a : any ->b : any +>a : undefined +>b : undefined >b < (c + 1) : boolean ->b : any ->(c + 1) : any ->c + 1 : any ->c : any +>b : undefined +>(c + 1) : number +>c + 1 : number +>c : undefined >1 : 1 } diff --git a/tests/baselines/reference/parserSkippedTokens20.errors.txt b/tests/baselines/reference/parserSkippedTokens20.errors.txt index 4e66b51f48d..774443d4d9a 100644 --- a/tests/baselines/reference/parserSkippedTokens20.errors.txt +++ b/tests/baselines/reference/parserSkippedTokens20.errors.txt @@ -1,13 +1,10 @@ tests/cases/conformance/parser/ecmascript5/SkippedTokens/parserSkippedTokens20.ts(1,8): error TS2304: Cannot find name 'X'. tests/cases/conformance/parser/ecmascript5/SkippedTokens/parserSkippedTokens20.ts(1,12): error TS1127: Invalid character. -tests/cases/conformance/parser/ecmascript5/SkippedTokens/parserSkippedTokens20.ts(1,13): error TS1005: '>' expected. -==== tests/cases/conformance/parser/ecmascript5/SkippedTokens/parserSkippedTokens20.ts (3 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/SkippedTokens/parserSkippedTokens20.ts (2 errors) ==== var v: X' expected. \ No newline at end of file +!!! error TS1127: Invalid character. \ No newline at end of file diff --git a/tests/baselines/reference/parserX_TypeArgumentList1.errors.txt b/tests/baselines/reference/parserX_TypeArgumentList1.errors.txt index 13956c86e7d..b881942dfd5 100644 --- a/tests/baselines/reference/parserX_TypeArgumentList1.errors.txt +++ b/tests/baselines/reference/parserX_TypeArgumentList1.errors.txt @@ -1,10 +1,31 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts(1,1): error TS2304: Cannot find name 'Foo'. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts(1,1): error TS2695: Left side of comma operator is unused and has no side effects. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts(1,1): error TS2695: Left side of comma operator is unused and has no side effects. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts(1,5): error TS2304: Cannot find name 'A'. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts(1,7): error TS2304: Cannot find name 'B'. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts(1,9): error TS1127: Invalid character. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts(1,11): error TS2304: Cannot find name 'C'. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts(1,14): error TS2695: Left side of comma operator is unused and has no side effects. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts(1,14): error TS2695: Left side of comma operator is unused and has no side effects. -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts (9 errors) ==== Foo(4, 5, 6); ~~~ !!! error TS2304: Cannot find name 'Foo'. + ~~~~~ +!!! error TS2695: Left side of comma operator is unused and has no side effects. + ~~~~~~~ +!!! error TS2695: Left side of comma operator is unused and has no side effects. + ~ +!!! error TS2304: Cannot find name 'A'. + ~ +!!! error TS2304: Cannot find name 'B'. -!!! error TS1127: Invalid character. \ No newline at end of file +!!! error TS1127: Invalid character. + ~ +!!! error TS2304: Cannot find name 'C'. + ~ +!!! error TS2695: Left side of comma operator is unused and has no side effects. + ~~~~ +!!! error TS2695: Left side of comma operator is unused and has no side effects. \ No newline at end of file diff --git a/tests/baselines/reference/parserX_TypeArgumentList1.js b/tests/baselines/reference/parserX_TypeArgumentList1.js index f1bd7f595ee..c83223ee3fb 100644 --- a/tests/baselines/reference/parserX_TypeArgumentList1.js +++ b/tests/baselines/reference/parserX_TypeArgumentList1.js @@ -2,4 +2,5 @@ Foo(4, 5, 6); //// [parserX_TypeArgumentList1.js] -Foo(4, 5, 6); +Foo < A, B, ; +C > (4, 5, 6); diff --git a/tests/baselines/reference/parserharness.errors.txt b/tests/baselines/reference/parserharness.errors.txt index d3d0c4056a1..90ac8e0e760 100644 --- a/tests/baselines/reference/parserharness.errors.txt +++ b/tests/baselines/reference/parserharness.errors.txt @@ -25,6 +25,9 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(776,42): e tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(781,23): error TS2503: Cannot find namespace 'TypeScript'. tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(794,49): error TS2304: Cannot find name 'TypeScript'. tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(795,49): error TS2304: Cannot find name 'TypeScript'. +tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(820,31): error TS2339: Property 'length' does not exist on type 'null'. +tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(976,28): error TS2339: Property 'length' does not exist on type 'null'. +tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(977,82): error TS2339: Property 'join' does not exist on type 'null'. tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(987,53): error TS2304: Cannot find name 'TypeScript'. tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(987,89): error TS2304: Cannot find name 'TypeScript'. tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(987,115): error TS2503: Cannot find namespace 'TypeScript'. @@ -110,7 +113,7 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(1787,68): tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(2030,32): error TS2304: Cannot find name 'Diff'. -==== tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts (110 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts (113 errors) ==== // // Copyright (c) Microsoft Corporation. All rights reserved. // @@ -985,6 +988,8 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(2030,32): }) return errors.length === 0; + ~~~~~~ +!!! error TS2339: Property 'length' does not exist on type 'null'. } public isSubtypeOf(other: Type) { @@ -1141,7 +1146,11 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(2030,32): }) if (errors.length > 0) + ~~~~~~ +!!! error TS2339: Property 'length' does not exist on type 'null'. throw new Error("Type definition contains errors: " + errors.join(",")); + ~~~~ +!!! error TS2339: Property 'join' does not exist on type 'null'. var matchingIdentifiers: Type[] = []; diff --git a/tests/baselines/reference/promiseType.js b/tests/baselines/reference/promiseType.js index fc49dda9db4..9fbdb2ab2b6 100644 --- a/tests/baselines/reference/promiseType.js +++ b/tests/baselines/reference/promiseType.js @@ -159,7 +159,7 @@ const p85 = p.then(() => Promise.reject(1), () => Promise.reject(1)); 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()); }); diff --git a/tests/baselines/reference/promiseTypeStrictNull.js b/tests/baselines/reference/promiseTypeStrictNull.js index cba4f7735ce..8c5cef4c7c4 100644 --- a/tests/baselines/reference/promiseTypeStrictNull.js +++ b/tests/baselines/reference/promiseTypeStrictNull.js @@ -159,7 +159,7 @@ const p85 = p.then(() => Promise.reject(1), () => Promise.reject(1)); 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()); }); diff --git a/tests/baselines/reference/protoAsIndexInIndexExpression.types b/tests/baselines/reference/protoAsIndexInIndexExpression.types index b761aa2c7a7..6d1374d1f78 100644 --- a/tests/baselines/reference/protoAsIndexInIndexExpression.types +++ b/tests/baselines/reference/protoAsIndexInIndexExpression.types @@ -14,11 +14,11 @@ var WorkspacePrototype = { } }; WorkspacePrototype['__proto__'] = EntityPrototype; ->WorkspacePrototype['__proto__'] = EntityPrototype : any +>WorkspacePrototype['__proto__'] = EntityPrototype : undefined >WorkspacePrototype['__proto__'] : any >WorkspacePrototype : { serialize: () => any; } >'__proto__' : "___proto__" ->EntityPrototype : any +>EntityPrototype : undefined var o = { >o : { "__proto__": number; } diff --git a/tests/baselines/reference/reachabilityChecks7.js b/tests/baselines/reference/reachabilityChecks7.js index 0a6b5b0dac7..b8334f4276b 100644 --- a/tests/baselines/reference/reachabilityChecks7.js +++ b/tests/baselines/reference/reachabilityChecks7.js @@ -34,7 +34,7 @@ let x1 = () => { use("Test"); } 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()); }); diff --git a/tests/baselines/reference/selfReference.js b/tests/baselines/reference/selfReference.js new file mode 100644 index 00000000000..2bb8ce9d9d0 --- /dev/null +++ b/tests/baselines/reference/selfReference.js @@ -0,0 +1,6 @@ +//// [selfReference.ts] +declare function asFunction(value: T): () => T; +asFunction(() => { return 1; }); + +//// [selfReference.js] +asFunction(function () { return 1; }); diff --git a/tests/baselines/reference/selfReference.symbols b/tests/baselines/reference/selfReference.symbols new file mode 100644 index 00000000000..dc618eaae17 --- /dev/null +++ b/tests/baselines/reference/selfReference.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/selfReference.ts === +declare function asFunction(value: T): () => T; +>asFunction : Symbol(asFunction, Decl(selfReference.ts, 0, 0)) +>T : Symbol(T, Decl(selfReference.ts, 0, 28)) +>value : Symbol(value, Decl(selfReference.ts, 0, 31)) +>T : Symbol(T, Decl(selfReference.ts, 0, 28)) +>T : Symbol(T, Decl(selfReference.ts, 0, 28)) + +asFunction(() => { return 1; }); +>asFunction : Symbol(asFunction, Decl(selfReference.ts, 0, 0)) + diff --git a/tests/baselines/reference/selfReference.types b/tests/baselines/reference/selfReference.types new file mode 100644 index 00000000000..eed1da72387 --- /dev/null +++ b/tests/baselines/reference/selfReference.types @@ -0,0 +1,14 @@ +=== tests/cases/compiler/selfReference.ts === +declare function asFunction(value: T): () => T; +>asFunction : (value: T) => () => T +>T : T +>value : T +>T : T +>T : T + +asFunction(() => { return 1; }); +>asFunction(() => { return 1; }) : () => () => 1 +>asFunction : (value: T) => () => T +>() => { return 1; } : () => 1 +>1 : 1 + diff --git a/tests/baselines/reference/strictNullChecksNoWidening.types b/tests/baselines/reference/strictNullChecksNoWidening.types index a544f9cef94..375977ae375 100644 --- a/tests/baselines/reference/strictNullChecksNoWidening.types +++ b/tests/baselines/reference/strictNullChecksNoWidening.types @@ -1,11 +1,11 @@ === tests/cases/conformance/types/typeRelationships/widenedTypes/strictNullChecksNoWidening.ts === var a1 = null; ->a1 : null +>a1 : any >null : null var a2 = undefined; ->a2 : undefined +>a2 : any >undefined : undefined var a3 = void 0; diff --git a/tests/baselines/reference/transformNestedGeneratorsWithTry.js b/tests/baselines/reference/transformNestedGeneratorsWithTry.js index 4ad1b2b7e88..69273e62633 100644 --- a/tests/baselines/reference/transformNestedGeneratorsWithTry.js +++ b/tests/baselines/reference/transformNestedGeneratorsWithTry.js @@ -27,7 +27,7 @@ declare module "bluebird" { 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()); }); diff --git a/tests/baselines/reference/tsxCorrectlyParseLessThanComparison1.js b/tests/baselines/reference/tsxCorrectlyParseLessThanComparison1.js new file mode 100644 index 00000000000..f5d35ccaf77 --- /dev/null +++ b/tests/baselines/reference/tsxCorrectlyParseLessThanComparison1.js @@ -0,0 +1,41 @@ +//// [tsxCorrectlyParseLessThanComparison1.tsx] +declare module JSX { + interface Element { + div: string; + } +} +declare namespace React { + class Component { + constructor(props?: P, context?: any); + props: P; + } +} + +export class ShortDetails extends React.Component<{ id: number }, {}> { + public render(): JSX.Element { + if (this.props.id < 1) { + return (
); + } + } +} + +//// [tsxCorrectlyParseLessThanComparison1.js] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var ShortDetails = (function (_super) { + __extends(ShortDetails, _super); + function ShortDetails() { + return _super.apply(this, arguments) || this; + } + ShortDetails.prototype.render = function () { + if (this.props.id < 1) { + return (React.createElement("div", null)); + } + }; + return ShortDetails; +}(React.Component)); +exports.ShortDetails = ShortDetails; diff --git a/tests/baselines/reference/tsxCorrectlyParseLessThanComparison1.symbols b/tests/baselines/reference/tsxCorrectlyParseLessThanComparison1.symbols new file mode 100644 index 00000000000..d00b4ca115f --- /dev/null +++ b/tests/baselines/reference/tsxCorrectlyParseLessThanComparison1.symbols @@ -0,0 +1,55 @@ +=== tests/cases/conformance/jsx/tsxCorrectlyParseLessThanComparison1.tsx === +declare module JSX { +>JSX : Symbol(JSX, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 0, 0)) + + interface Element { +>Element : Symbol(Element, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 0, 20)) + + div: string; +>div : Symbol(Element.div, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 1, 23)) + } +} +declare namespace React { +>React : Symbol(React, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 4, 1)) + + class Component { +>Component : Symbol(Component, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 5, 25)) +>P : Symbol(P, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 6, 20)) +>S : Symbol(S, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 6, 22)) + + constructor(props?: P, context?: any); +>props : Symbol(props, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 7, 20)) +>P : Symbol(P, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 6, 20)) +>context : Symbol(context, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 7, 30)) + + props: P; +>props : Symbol(Component.props, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 7, 46)) +>P : Symbol(P, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 6, 20)) + } +} + +export class ShortDetails extends React.Component<{ id: number }, {}> { +>ShortDetails : Symbol(ShortDetails, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 10, 1)) +>React.Component : Symbol(React.Component, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 5, 25)) +>React : Symbol(React, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 4, 1)) +>Component : Symbol(React.Component, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 5, 25)) +>id : Symbol(id, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 12, 51)) + + public render(): JSX.Element { +>render : Symbol(ShortDetails.render, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 12, 71)) +>JSX : Symbol(JSX, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 0, 0)) +>Element : Symbol(JSX.Element, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 0, 20)) + + if (this.props.id < 1) { +>this.props.id : Symbol(id, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 12, 51)) +>this.props : Symbol(React.Component.props, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 7, 46)) +>this : Symbol(ShortDetails, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 10, 1)) +>props : Symbol(React.Component.props, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 7, 46)) +>id : Symbol(id, Decl(tsxCorrectlyParseLessThanComparison1.tsx, 12, 51)) + + return (
); +>div : Symbol(unknown) +>div : Symbol(unknown) + } + } +} diff --git a/tests/baselines/reference/tsxCorrectlyParseLessThanComparison1.types b/tests/baselines/reference/tsxCorrectlyParseLessThanComparison1.types new file mode 100644 index 00000000000..0d97ed87784 --- /dev/null +++ b/tests/baselines/reference/tsxCorrectlyParseLessThanComparison1.types @@ -0,0 +1,59 @@ +=== tests/cases/conformance/jsx/tsxCorrectlyParseLessThanComparison1.tsx === +declare module JSX { +>JSX : any + + interface Element { +>Element : Element + + div: string; +>div : string + } +} +declare namespace React { +>React : typeof React + + class Component { +>Component : Component +>P : P +>S : S + + constructor(props?: P, context?: any); +>props : P +>P : P +>context : any + + props: P; +>props : P +>P : P + } +} + +export class ShortDetails extends React.Component<{ id: number }, {}> { +>ShortDetails : ShortDetails +>React.Component : React.Component<{ id: number; }, {}> +>React : typeof React +>Component : typeof React.Component +>id : number + + public render(): JSX.Element { +>render : () => JSX.Element +>JSX : any +>Element : JSX.Element + + if (this.props.id < 1) { +>this.props.id < 1 : boolean +>this.props.id : number +>this.props : { id: number; } +>this : this +>props : { id: number; } +>id : number +>1 : 1 + + return (
); +>(
) : any +>
: any +>div : any +>div : any + } + } +} diff --git a/tests/baselines/reference/tsxEmit1.types b/tests/baselines/reference/tsxEmit1.types index 84f00b4758a..c3ca7a2b1b0 100644 --- a/tests/baselines/reference/tsxEmit1.types +++ b/tests/baselines/reference/tsxEmit1.types @@ -61,7 +61,7 @@ var selfClosed7 =
; >
: JSX.Element >div : any >x : any ->p : any +>p : undefined >y : any var openClosed1 =
; @@ -82,7 +82,7 @@ var openClosed3 =
{p}
; >
{p}
: JSX.Element >div : any >n : any ->p : any +>p : undefined >div : any var openClosed4 =
{p < p}
; @@ -91,8 +91,8 @@ var openClosed4 =
{p < p}
; >div : any >n : any >p < p : boolean ->p : any ->p : any +>p : undefined +>p : undefined >div : any var openClosed5 =
{p > p}
; @@ -101,8 +101,8 @@ var openClosed5 =
{p > p}
; >div : any >n : any >p > p : boolean ->p : any ->p : any +>p : undefined +>p : undefined >div : any class SomeClass { @@ -180,7 +180,7 @@ var whitespace2 =
{p}
; >whitespace2 : JSX.Element >
{p}
: JSX.Element >div : any ->p : any +>p : undefined >div : any var whitespace3 =
@@ -189,7 +189,7 @@ var whitespace3 =
>div : any {p} ->p : any +>p : undefined
; >div : any diff --git a/tests/baselines/reference/tsxEmit2.types b/tests/baselines/reference/tsxEmit2.types index 5b267d8b802..d306dc9ffe0 100644 --- a/tests/baselines/reference/tsxEmit2.types +++ b/tests/baselines/reference/tsxEmit2.types @@ -22,16 +22,16 @@ var spreads1 =
{p2}
; >spreads1 : JSX.Element >
{p2}
: JSX.Element >div : any ->p1 : any ->p2 : any +>p1 : undefined +>p2 : undefined >div : any var spreads2 =
{p2}
; >spreads2 : JSX.Element >
{p2}
: JSX.Element >div : any ->p1 : any ->p2 : any +>p1 : undefined +>p2 : undefined >div : any var spreads3 =
{p2}
; @@ -39,19 +39,19 @@ var spreads3 =
{p2}
; >
{p2}
: JSX.Element >div : any >x : any ->p3 : any ->p1 : any ->p2 : any +>p3 : undefined +>p1 : undefined +>p2 : undefined >div : any var spreads4 =
{p2}
; >spreads4 : JSX.Element >
{p2}
: JSX.Element >div : any ->p1 : any +>p1 : undefined >x : any ->p3 : any ->p2 : any +>p3 : undefined +>p2 : undefined >div : any var spreads5 =
{p2}
; @@ -59,10 +59,10 @@ var spreads5 =
{p2}
; >
{p2}
: JSX.Element >div : any >x : any ->p2 : any ->p1 : any +>p2 : undefined +>p1 : undefined >y : any ->p3 : any ->p2 : any +>p3 : undefined +>p2 : undefined >div : any diff --git a/tests/baselines/reference/tsxGenericArrowFunctionParsing.js b/tests/baselines/reference/tsxGenericArrowFunctionParsing.js index e77e832cb0a..7dbb2477db5 100644 --- a/tests/baselines/reference/tsxGenericArrowFunctionParsing.js +++ b/tests/baselines/reference/tsxGenericArrowFunctionParsing.js @@ -3,7 +3,7 @@ declare module JSX { interface Element { isElement; } } -var T, T1, T2; +var T: any, T1: any, T2: any; // This is an element var x1 = () => {}; diff --git a/tests/baselines/reference/tsxGenericArrowFunctionParsing.symbols b/tests/baselines/reference/tsxGenericArrowFunctionParsing.symbols index 6d90c583a66..2d3c1f18d48 100644 --- a/tests/baselines/reference/tsxGenericArrowFunctionParsing.symbols +++ b/tests/baselines/reference/tsxGenericArrowFunctionParsing.symbols @@ -7,10 +7,10 @@ declare module JSX { >isElement : Symbol(Element.isElement, Decl(file.tsx, 1, 20)) } -var T, T1, T2; +var T: any, T1: any, T2: any; >T : Symbol(T, Decl(file.tsx, 4, 3)) ->T1 : Symbol(T1, Decl(file.tsx, 4, 6)) ->T2 : Symbol(T2, Decl(file.tsx, 4, 10)) +>T1 : Symbol(T1, Decl(file.tsx, 4, 11)) +>T2 : Symbol(T2, Decl(file.tsx, 4, 20)) // This is an element var x1 = () => {}; diff --git a/tests/baselines/reference/tsxGenericArrowFunctionParsing.types b/tests/baselines/reference/tsxGenericArrowFunctionParsing.types index 693f920195d..0f746a07136 100644 --- a/tests/baselines/reference/tsxGenericArrowFunctionParsing.types +++ b/tests/baselines/reference/tsxGenericArrowFunctionParsing.types @@ -7,7 +7,7 @@ declare module JSX { >isElement : any } -var T, T1, T2; +var T: any, T1: any, T2: any; >T : any >T1 : any >T2 : any diff --git a/tests/baselines/reference/tsxReactEmit1.types b/tests/baselines/reference/tsxReactEmit1.types index 8eb14e91963..b2cb2f73eba 100644 --- a/tests/baselines/reference/tsxReactEmit1.types +++ b/tests/baselines/reference/tsxReactEmit1.types @@ -63,7 +63,7 @@ var selfClosed7 =
; >
: JSX.Element >div : any >x : any ->p : any +>p : undefined >y : any >b : any @@ -85,7 +85,7 @@ var openClosed3 =
{p}
; >
{p}
: JSX.Element >div : any >n : any ->p : any +>p : undefined >div : any var openClosed4 =
{p < p}
; @@ -94,8 +94,8 @@ var openClosed4 =
{p < p}
; >div : any >n : any >p < p : boolean ->p : any ->p : any +>p : undefined +>p : undefined >div : any var openClosed5 =
{p > p}
; @@ -105,8 +105,8 @@ var openClosed5 =
{p > p}
; >n : any >b : any >p > p : boolean ->p : any ->p : any +>p : undefined +>p : undefined >div : any class SomeClass { @@ -184,7 +184,7 @@ var whitespace2 =
{p}
; >whitespace2 : JSX.Element >
{p}
: JSX.Element >div : any ->p : any +>p : undefined >div : any var whitespace3 =
@@ -193,7 +193,7 @@ var whitespace3 =
>div : any {p} ->p : any +>p : undefined
; >div : any diff --git a/tests/baselines/reference/tsxReactEmit2.types b/tests/baselines/reference/tsxReactEmit2.types index 928eeecadfa..b05764e996f 100644 --- a/tests/baselines/reference/tsxReactEmit2.types +++ b/tests/baselines/reference/tsxReactEmit2.types @@ -24,16 +24,16 @@ var spreads1 =
{p2}
; >spreads1 : JSX.Element >
{p2}
: JSX.Element >div : any ->p1 : any ->p2 : any +>p1 : undefined +>p2 : undefined >div : any var spreads2 =
{p2}
; >spreads2 : JSX.Element >
{p2}
: JSX.Element >div : any ->p1 : any ->p2 : any +>p1 : undefined +>p2 : undefined >div : any var spreads3 =
{p2}
; @@ -41,19 +41,19 @@ var spreads3 =
{p2}
; >
{p2}
: JSX.Element >div : any >x : any ->p3 : any ->p1 : any ->p2 : any +>p3 : undefined +>p1 : undefined +>p2 : undefined >div : any var spreads4 =
{p2}
; >spreads4 : JSX.Element >
{p2}
: JSX.Element >div : any ->p1 : any +>p1 : undefined >x : any ->p3 : any ->p2 : any +>p3 : undefined +>p2 : undefined >div : any var spreads5 =
{p2}
; @@ -61,10 +61,10 @@ var spreads5 =
{p2}
; >
{p2}
: JSX.Element >div : any >x : any ->p2 : any ->p1 : any +>p2 : undefined +>p1 : undefined >y : any ->p3 : any ->p2 : any +>p3 : undefined +>p2 : undefined >div : any diff --git a/tests/baselines/reference/tsxReactEmit5.types b/tests/baselines/reference/tsxReactEmit5.types index fb1c6594f30..73e7e6ff391 100644 --- a/tests/baselines/reference/tsxReactEmit5.types +++ b/tests/baselines/reference/tsxReactEmit5.types @@ -32,6 +32,6 @@ var spread1 =
; >
: JSX.Element >div : any >x : any ->foo : any +>foo : undefined >y : any diff --git a/tests/baselines/reference/tsxReactEmit6.types b/tests/baselines/reference/tsxReactEmit6.types index b8a307eb9d7..ae56de052cc 100644 --- a/tests/baselines/reference/tsxReactEmit6.types +++ b/tests/baselines/reference/tsxReactEmit6.types @@ -35,7 +35,7 @@ namespace M { >
: JSX.Element >div : any >x : any ->foo : any +>foo : undefined >y : any // Quotes diff --git a/tests/baselines/reference/typeCheckObjectCreationExpressionWithUndefinedCallResolutionData.errors.txt b/tests/baselines/reference/typeCheckObjectCreationExpressionWithUndefinedCallResolutionData.errors.txt new file mode 100644 index 00000000000..3f8cdf56c3d --- /dev/null +++ b/tests/baselines/reference/typeCheckObjectCreationExpressionWithUndefinedCallResolutionData.errors.txt @@ -0,0 +1,15 @@ +tests/cases/compiler/file1.ts(3,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + + +==== tests/cases/compiler/file2.ts (0 errors) ==== + import f = require('./file1'); + f.foo(); + +==== tests/cases/compiler/file1.ts (1 errors) ==== + export function foo() { + var classes = undefined; + return new classes(null); + ~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + } + \ No newline at end of file diff --git a/tests/baselines/reference/typingsLookupAmd.js b/tests/baselines/reference/typingsLookupAmd.js new file mode 100644 index 00000000000..1e99644d489 --- /dev/null +++ b/tests/baselines/reference/typingsLookupAmd.js @@ -0,0 +1,18 @@ +//// [tests/cases/conformance/typings/typingsLookupAmd.ts] //// + +//// [index.d.ts] + +export declare class A {} + +//// [index.d.ts] +import {A} from "a"; +export declare class B extends A {} + +//// [foo.ts] +import {B} from "b"; + + +//// [foo.js] +define(["require", "exports"], function (require, exports) { + "use strict"; +}); diff --git a/tests/baselines/reference/typingsLookupAmd.symbols b/tests/baselines/reference/typingsLookupAmd.symbols new file mode 100644 index 00000000000..8235467daf8 --- /dev/null +++ b/tests/baselines/reference/typingsLookupAmd.symbols @@ -0,0 +1,17 @@ +=== /x/y/foo.ts === +import {B} from "b"; +>B : Symbol(B, Decl(foo.ts, 0, 8)) + +=== /node_modules/@types/a/index.d.ts === + +export declare class A {} +>A : Symbol(A, Decl(index.d.ts, 0, 0)) + +=== /x/node_modules/@types/b/index.d.ts === +import {A} from "a"; +>A : Symbol(A, Decl(index.d.ts, 0, 8)) + +export declare class B extends A {} +>B : Symbol(B, Decl(index.d.ts, 0, 20)) +>A : Symbol(A, Decl(index.d.ts, 0, 8)) + diff --git a/tests/baselines/reference/typingsLookupAmd.trace.json b/tests/baselines/reference/typingsLookupAmd.trace.json new file mode 100644 index 00000000000..5c83757454c --- /dev/null +++ b/tests/baselines/reference/typingsLookupAmd.trace.json @@ -0,0 +1,59 @@ +[ + "======== Resolving module 'b' from '/x/y/foo.ts'. ========", + "Module resolution kind is not specified, using 'Classic'.", + "File '/x/y/b.ts' does not exist.", + "File '/x/y/b.d.ts' does not exist.", + "File '/x/b.ts' does not exist.", + "File '/x/b.d.ts' does not exist.", + "File '/b.ts' does not exist.", + "File '/b.d.ts' does not exist.", + "File '/x/y/node_modules/@types/b.ts' does not exist.", + "File '/x/y/node_modules/@types/b.d.ts' does not exist.", + "File '/x/y/node_modules/@types/b/package.json' does not exist.", + "File '/x/y/node_modules/@types/b/index.ts' does not exist.", + "File '/x/y/node_modules/@types/b/index.d.ts' does not exist.", + "File '/x/node_modules/@types/b.ts' does not exist.", + "File '/x/node_modules/@types/b.d.ts' does not exist.", + "File '/x/node_modules/@types/b/package.json' does not exist.", + "File '/x/node_modules/@types/b/index.ts' does not exist.", + "File '/x/node_modules/@types/b/index.d.ts' exist - use it as a name resolution result.", + "======== Module name 'b' was successfully resolved to '/x/node_modules/@types/b/index.d.ts'. ========", + "======== Resolving module 'a' from '/x/node_modules/@types/b/index.d.ts'. ========", + "Module resolution kind is not specified, using 'Classic'.", + "File '/x/node_modules/@types/b/a.ts' does not exist.", + "File '/x/node_modules/@types/b/a.d.ts' does not exist.", + "File '/x/node_modules/@types/a.ts' does not exist.", + "File '/x/node_modules/@types/a.d.ts' does not exist.", + "File '/x/node_modules/a.ts' does not exist.", + "File '/x/node_modules/a.d.ts' does not exist.", + "File '/x/a.ts' does not exist.", + "File '/x/a.d.ts' does not exist.", + "File '/a.ts' does not exist.", + "File '/a.d.ts' does not exist.", + "File '/x/node_modules/@types/b/node_modules/@types/a.ts' does not exist.", + "File '/x/node_modules/@types/b/node_modules/@types/a.d.ts' does not exist.", + "File '/x/node_modules/@types/b/node_modules/@types/a/package.json' does not exist.", + "File '/x/node_modules/@types/b/node_modules/@types/a/index.ts' does not exist.", + "File '/x/node_modules/@types/b/node_modules/@types/a/index.d.ts' does not exist.", + "File '/x/node_modules/@types/node_modules/@types/a.ts' does not exist.", + "File '/x/node_modules/@types/node_modules/@types/a.d.ts' does not exist.", + "File '/x/node_modules/@types/node_modules/@types/a/package.json' does not exist.", + "File '/x/node_modules/@types/node_modules/@types/a/index.ts' does not exist.", + "File '/x/node_modules/@types/node_modules/@types/a/index.d.ts' does not exist.", + "File '/x/node_modules/@types/a.ts' does not exist.", + "File '/x/node_modules/@types/a.d.ts' does not exist.", + "File '/x/node_modules/@types/a/package.json' does not exist.", + "File '/x/node_modules/@types/a/index.ts' does not exist.", + "File '/x/node_modules/@types/a/index.d.ts' does not exist.", + "File '/node_modules/@types/a.ts' does not exist.", + "File '/node_modules/@types/a.d.ts' does not exist.", + "File '/node_modules/@types/a/package.json' does not exist.", + "File '/node_modules/@types/a/index.ts' does not exist.", + "File '/node_modules/@types/a/index.d.ts' exist - use it as a name resolution result.", + "======== Module name 'a' was successfully resolved to '/node_modules/@types/a/index.d.ts'. ========", + "======== Resolving type reference directive 'a', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========", + "Resolving with primary search path '/node_modules/@types'", + "File '/node_modules/@types/a/package.json' does not exist.", + "File '/node_modules/@types/a/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'a' was successfully resolved to '/node_modules/@types/a/index.d.ts', primary: true. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/typingsLookupAmd.types b/tests/baselines/reference/typingsLookupAmd.types new file mode 100644 index 00000000000..44273c03f80 --- /dev/null +++ b/tests/baselines/reference/typingsLookupAmd.types @@ -0,0 +1,17 @@ +=== /x/y/foo.ts === +import {B} from "b"; +>B : typeof B + +=== /node_modules/@types/a/index.d.ts === + +export declare class A {} +>A : A + +=== /x/node_modules/@types/b/index.d.ts === +import {A} from "a"; +>A : typeof A + +export declare class B extends A {} +>B : B +>A : A + diff --git a/tests/baselines/reference/umd5.errors.txt b/tests/baselines/reference/umd5.errors.txt index 9628ad738db..5595de8de29 100644 --- a/tests/baselines/reference/umd5.errors.txt +++ b/tests/baselines/reference/umd5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/externalModules/a.ts(6,9): error TS2686: Identifier 'Foo' must be imported from a module +tests/cases/conformance/externalModules/a.ts(6,9): error TS2686: 'Foo' refers to a UMD global, but the current file is a module. Consider adding an import instead. ==== tests/cases/conformance/externalModules/a.ts (1 errors) ==== @@ -9,7 +9,7 @@ tests/cases/conformance/externalModules/a.ts(6,9): error TS2686: Identifier 'Foo // should error let z = Foo; ~~~ -!!! error TS2686: Identifier 'Foo' must be imported from a module +!!! error TS2686: 'Foo' refers to a UMD global, but the current file is a module. Consider adding an import instead. ==== tests/cases/conformance/externalModules/foo.d.ts (0 errors) ==== diff --git a/tests/baselines/reference/umd8.errors.txt b/tests/baselines/reference/umd8.errors.txt index 9396c8c5450..26c8adef561 100644 --- a/tests/baselines/reference/umd8.errors.txt +++ b/tests/baselines/reference/umd8.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/externalModules/a.ts(7,14): error TS2686: Identifier 'Foo' must be imported from a module +tests/cases/conformance/externalModules/a.ts(7,14): error TS2686: 'Foo' refers to a UMD global, but the current file is a module. Consider adding an import instead. ==== tests/cases/conformance/externalModules/a.ts (1 errors) ==== @@ -10,7 +10,7 @@ tests/cases/conformance/externalModules/a.ts(7,14): error TS2686: Identifier 'Fo let z: Foo.SubThing; // OK in ns position let x: any = Foo; // Not OK in value position ~~~ -!!! error TS2686: Identifier 'Foo' must be imported from a module +!!! error TS2686: 'Foo' refers to a UMD global, but the current file is a module. Consider adding an import instead. ==== tests/cases/conformance/externalModules/foo.d.ts (0 errors) ==== diff --git a/tests/baselines/reference/unusedSwitchStatment.errors.txt b/tests/baselines/reference/unusedSwitchStatment.errors.txt index a22c252f60d..591e9deca7a 100644 --- a/tests/baselines/reference/unusedSwitchStatment.errors.txt +++ b/tests/baselines/reference/unusedSwitchStatment.errors.txt @@ -4,9 +4,10 @@ tests/cases/compiler/unusedSwitchStatment.ts(7,15): error TS6133: 'c' is declare tests/cases/compiler/unusedSwitchStatment.ts(10,13): error TS6133: 'z' is declared but never used. tests/cases/compiler/unusedSwitchStatment.ts(15,10): error TS2678: Type '0' is not comparable to type '2'. tests/cases/compiler/unusedSwitchStatment.ts(17,10): error TS2678: Type '1' is not comparable to type '2'. +tests/cases/compiler/unusedSwitchStatment.ts(18,9): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. -==== tests/cases/compiler/unusedSwitchStatment.ts (6 errors) ==== +==== tests/cases/compiler/unusedSwitchStatment.ts (7 errors) ==== switch (1) { case 0: @@ -37,4 +38,6 @@ tests/cases/compiler/unusedSwitchStatment.ts(17,10): error TS2678: Type '1' is n ~ !!! error TS2678: Type '1' is not comparable to type '2'. x++; + ~ +!!! error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. } \ No newline at end of file diff --git a/tests/cases/compiler/anyPlusAny1.ts b/tests/cases/compiler/anyPlusAny1.ts index 084dcc02be3..c1bee9b97b0 100644 --- a/tests/cases/compiler/anyPlusAny1.ts +++ b/tests/cases/compiler/anyPlusAny1.ts @@ -1,3 +1,3 @@ -var x; +var x: any; x.name = "hello"; var z = x + x; \ No newline at end of file diff --git a/tests/cases/compiler/controlFlowLetVar.ts b/tests/cases/compiler/controlFlowLetVar.ts new file mode 100644 index 00000000000..a56a3382642 --- /dev/null +++ b/tests/cases/compiler/controlFlowLetVar.ts @@ -0,0 +1,129 @@ +// @strictNullChecks: true + +declare let cond: boolean; + +// CFA for 'let' with no type annotation and initializer +function f1() { + let x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined +} + +// CFA for 'let' with no type annotation and 'undefined' initializer +function f2() { + let x = undefined; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined +} + +// CFA for 'let' with no type annotation and 'null' initializer +function f3() { + let x = null; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | null +} + +// No CFA for 'let' with with type annotation +function f4() { + let x: any; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // any +} + +// CFA for 'var' with no type annotation and initializer +function f5() { + var x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined +} + +// CFA for 'var' with no type annotation and 'undefined' initializer +function f6() { + var x = undefined; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined +} + +// CFA for 'var' with no type annotation and 'null' initializer +function f7() { + var x = null; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | null +} + +// No CFA for 'var' with with type annotation +function f8() { + var x: any; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // any +} + +// No CFA for captured outer variables +function f9() { + let x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined + function f() { + const z = x; // any + } +} + +// No CFA for captured outer variables +function f10() { + let x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined + const f = () => { + const z = x; // any + }; +} \ No newline at end of file diff --git a/tests/cases/compiler/controlFlowNoImplicitAny.ts b/tests/cases/compiler/controlFlowNoImplicitAny.ts new file mode 100644 index 00000000000..a388a495f08 --- /dev/null +++ b/tests/cases/compiler/controlFlowNoImplicitAny.ts @@ -0,0 +1,130 @@ +// @strictNullChecks: true +// @noImplicitAny: true + +declare let cond: boolean; + +// CFA for 'let' with no type annotation and initializer +function f1() { + let x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined +} + +// CFA for 'let' with no type annotation and 'undefined' initializer +function f2() { + let x = undefined; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined +} + +// CFA for 'let' with no type annotation and 'null' initializer +function f3() { + let x = null; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | null +} + +// No CFA for 'let' with with type annotation +function f4() { + let x: any; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // any +} + +// CFA for 'var' with no type annotation and initializer +function f5() { + var x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined +} + +// CFA for 'var' with no type annotation and 'undefined' initializer +function f6() { + var x = undefined; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined +} + +// CFA for 'var' with no type annotation and 'null' initializer +function f7() { + var x = null; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | null +} + +// No CFA for 'var' with with type annotation +function f8() { + var x: any; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // any +} + +// No CFA for captured outer variables +function f9() { + let x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined + function f() { + const z = x; // any + } +} + +// No CFA for captured outer variables +function f10() { + let x; + if (cond) { + x = 1; + } + if (cond) { + x = "hello"; + } + const y = x; // string | number | undefined + const f = () => { + const z = x; // any + }; +} \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters1.ts b/tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters1.ts new file mode 100644 index 00000000000..ff9042af699 --- /dev/null +++ b/tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters1.ts @@ -0,0 +1,5 @@ +// @declaration: true + +export type Bar = () => [X, Y]; +export type Foo = Bar; +export const y = (x: Foo) => 1 \ No newline at end of file diff --git a/tests/cases/compiler/es5-asyncFunctionTryStatements.ts b/tests/cases/compiler/es5-asyncFunctionTryStatements.ts index 11459295f47..0d14b5f4242 100644 --- a/tests/cases/compiler/es5-asyncFunctionTryStatements.ts +++ b/tests/cases/compiler/es5-asyncFunctionTryStatements.ts @@ -1,10 +1,10 @@ // @lib: es5,es2015.promise // @noEmitHelpers: true // @target: ES5 -declare var x, y, z, a, b, c; +declare var x: any, y: any, z: any, a: any, b: any, c: any; async function tryCatch0() { - var x, y; + var x: any, y: any; try { x; } @@ -14,7 +14,7 @@ async function tryCatch0() { } async function tryCatch1() { - var x, y; + var x: any, y: any; try { await x; } @@ -24,7 +24,7 @@ async function tryCatch1() { } async function tryCatch2() { - var x, y; + var x: any, y: any; try { x; } @@ -34,7 +34,7 @@ async function tryCatch2() { } async function tryCatch3(): Promise { - var x, y; + var x: any, y: any; try { await x; } @@ -43,7 +43,7 @@ async function tryCatch3(): Promise { } } async function tryFinally0() { - var x, y; + var x: any, y: any; try { x; } @@ -53,7 +53,7 @@ async function tryFinally0() { } async function tryFinally1() { - var x, y; + var x: any, y: any; try { await x; } @@ -63,7 +63,7 @@ async function tryFinally1() { } async function tryFinally2() { - var x, y; + var x: any, y: any; try { x; } @@ -73,7 +73,7 @@ async function tryFinally2() { } async function tryCatchFinally0() { - var x, y, z; + var x: any, y: any, z: any; try { x; } @@ -86,7 +86,7 @@ async function tryCatchFinally0() { } async function tryCatchFinally1() { - var x, y, z; + var x: any, y: any, z: any; try { await x; } @@ -99,7 +99,7 @@ async function tryCatchFinally1() { } async function tryCatchFinally2() { - var x, y, z; + var x: any, y: any, z: any; try { x; } @@ -112,7 +112,7 @@ async function tryCatchFinally2() { } async function tryCatchFinally3() { - var x, y, z; + var x: any, y: any, z: any; try { x; } diff --git a/tests/cases/compiler/expr.ts b/tests/cases/compiler/expr.ts index b76aba88103..8d6f7beed7e 100644 --- a/tests/cases/compiler/expr.ts +++ b/tests/cases/compiler/expr.ts @@ -6,7 +6,7 @@ enum E { } function f() { - var a; + var a: any; var n=3; var s=""; var b=false; diff --git a/tests/cases/compiler/implicitAnyDeclareVariablesWithoutTypeAndInit.ts b/tests/cases/compiler/implicitAnyDeclareVariablesWithoutTypeAndInit.ts index 88812001c9e..a84ab03f4b3 100644 --- a/tests/cases/compiler/implicitAnyDeclareVariablesWithoutTypeAndInit.ts +++ b/tests/cases/compiler/implicitAnyDeclareVariablesWithoutTypeAndInit.ts @@ -1,8 +1,9 @@ // @noimplicitany: true // this should be an error -var x; // error at "x" -declare var foo; // error at "foo" -function func(k) { }; //error at "k" +var x; // no error, control flow typed +var y; // error because captured +declare var foo; // error at "foo" +function func(k) { y }; // error at "k" func(x); // this shouldn't be an error diff --git a/tests/cases/compiler/metadataOfStringLiteral.ts b/tests/cases/compiler/metadataOfStringLiteral.ts new file mode 100644 index 00000000000..d5ff9bcf22b --- /dev/null +++ b/tests/cases/compiler/metadataOfStringLiteral.ts @@ -0,0 +1,8 @@ +// @experimentalDecorators: true +// @emitDecoratorMetadata: true +function PropDeco(target: Object, propKey: string | symbol) { } + +class Foo { + @PropDeco + public foo: "foo" | "bar"; +} \ No newline at end of file diff --git a/tests/cases/compiler/metadataOfUnion.ts b/tests/cases/compiler/metadataOfUnion.ts new file mode 100644 index 00000000000..2093357cb31 --- /dev/null +++ b/tests/cases/compiler/metadataOfUnion.ts @@ -0,0 +1,38 @@ +// @experimentalDecorators: true +// @emitDecoratorMetadata: true +function PropDeco(target: Object, propKey: string | symbol) { } + +class A { +} + +class B { + @PropDeco + x: "foo" | A; + + @PropDeco + y: true | boolean; + + @PropDeco + z: "foo" | boolean; +} + +enum E { + A, + B, + C, + D +} + +class D { + @PropDeco + a: E.A; + + @PropDeco + b: E.B | E.C; + + @PropDeco + c: E; + + @PropDeco + d: E | number; +} \ No newline at end of file diff --git a/tests/cases/compiler/selfReference.ts b/tests/cases/compiler/selfReference.ts new file mode 100644 index 00000000000..708acc42e02 --- /dev/null +++ b/tests/cases/compiler/selfReference.ts @@ -0,0 +1,3 @@ +// @noImplicitAny: true +declare function asFunction(value: T): () => T; +asFunction(() => { return 1; }); \ No newline at end of file diff --git a/tests/cases/conformance/Symbols/ES5SymbolProperty2.ts b/tests/cases/conformance/Symbols/ES5SymbolProperty2.ts index 07c95eb27d9..6bfce5fc58d 100644 --- a/tests/cases/conformance/Symbols/ES5SymbolProperty2.ts +++ b/tests/cases/conformance/Symbols/ES5SymbolProperty2.ts @@ -1,6 +1,6 @@ //@target: ES5 module M { - var Symbol; + var Symbol: any; export class C { [Symbol.iterator]() { } diff --git a/tests/cases/conformance/Symbols/ES5SymbolProperty3.ts b/tests/cases/conformance/Symbols/ES5SymbolProperty3.ts index 262e47557f8..a6eecc72124 100644 --- a/tests/cases/conformance/Symbols/ES5SymbolProperty3.ts +++ b/tests/cases/conformance/Symbols/ES5SymbolProperty3.ts @@ -1,5 +1,5 @@ //@target: ES5 -var Symbol; +var Symbol: any; class C { [Symbol.iterator]() { } diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of3.ts b/tests/cases/conformance/es6/for-ofStatements/for-of3.ts index 7eb1e1fd220..850daee8368 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of3.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of3.ts @@ -1,3 +1,3 @@ //@target: ES6 -var v; +var v: any; for (v++ of []) { } \ No newline at end of file diff --git a/tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsReference.ts b/tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsReference.ts index 02e6acfa685..7339704fc65 100644 --- a/tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsReference.ts +++ b/tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsReference.ts @@ -1,4 +1,4 @@ -var value; +var value: any; // identifiers: variable and parameter var x1: number; diff --git a/tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts b/tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts index 0eac581bfe4..176c2043344 100644 --- a/tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts +++ b/tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts @@ -1,5 +1,5 @@ // expected error for all the LHS of compound assignments (arithmetic and addition) -var value; +var value: any; // this class C { diff --git a/tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts b/tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts index e5118d18551..13f5ce14e7d 100644 --- a/tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts +++ b/tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts @@ -1,7 +1,7 @@ // @target: es5 // Error: early syntax error using ES7 SimpleUnaryExpression on left-hand side without () -var temp; +var temp: any; delete --temp ** 3; delete ++temp ** 3; diff --git a/tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsReference.ts b/tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsReference.ts index de5dbf6d747..91db91a3a9b 100644 --- a/tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsReference.ts +++ b/tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsReference.ts @@ -1,4 +1,4 @@ -var value; +var value: any; // identifiers: variable and parameter var x1: number; diff --git a/tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts b/tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts index 467a750b418..30b8df4268a 100644 --- a/tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts +++ b/tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts @@ -1,5 +1,5 @@ // expected error for all the LHS of assignments -var value; +var value: any; // this class C { diff --git a/tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts b/tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts index 62311ee75c9..8eb50d2f64a 100644 --- a/tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts +++ b/tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts @@ -1,7 +1,7 @@ // @allowUnusedLabels: true // expected error for all the LHS of compound assignments (arithmetic and addition) -var value; +var value: any; // this class C { diff --git a/tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherType.ts b/tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherType.ts index 4ca37129f60..f8efeb81ecb 100644 --- a/tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherType.ts +++ b/tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherType.ts @@ -1,7 +1,7 @@ // -- operator on any type var ANY: any; -var ANY1; +var ANY1: any; var ANY2: any[] = ["", ""]; var obj = {x:1,y:null}; class A { diff --git a/tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts b/tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts index 10dc05a4a33..d5dd62de442 100644 --- a/tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts +++ b/tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts @@ -1,5 +1,5 @@ // -- operator on any type -var ANY1; +var ANY1: any; var ANY2: any[] = ["", ""]; var obj: () => {} @@ -10,7 +10,7 @@ function foo(): any { } class A { public a: any; - static foo() { + static foo(): any { var a; return a; } diff --git a/tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherType.ts b/tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherType.ts index f1fa058745f..09f272442e1 100644 --- a/tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherType.ts +++ b/tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherType.ts @@ -1,7 +1,7 @@ // ++ operator on any type var ANY: any; -var ANY1; +var ANY1: any; var ANY2: any[] = ["", ""]; var obj = {x:1,y:null}; class A { diff --git a/tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts b/tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts index 2e6b14d7727..397024d45d6 100644 --- a/tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts +++ b/tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts @@ -1,5 +1,5 @@ // ++ operator on any type -var ANY1; +var ANY1: any; var ANY2: any[] = [1, 2]; var obj: () => {} @@ -10,7 +10,7 @@ function foo(): any { } class A { public a: any; - static foo() { + static foo(): any { var a; return a; } diff --git a/tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorWithAnyOtherType.ts b/tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorWithAnyOtherType.ts index 189f1f000d8..d29b1a845eb 100644 --- a/tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorWithAnyOtherType.ts +++ b/tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorWithAnyOtherType.ts @@ -1,7 +1,7 @@ // - operator on any type var ANY: any; -var ANY1; +var ANY1: any; var ANY2: any[] = ["", ""]; var obj: () => {} var obj1 = { x: "", y: () => { }}; @@ -12,7 +12,7 @@ function foo(): any { } class A { public a: any; - static foo() { + static foo(): any { var a; return a; } diff --git a/tests/cases/conformance/externalModules/multipleExportDefault1.ts b/tests/cases/conformance/externalModules/multipleExportDefault1.ts new file mode 100644 index 00000000000..623cc2acc20 --- /dev/null +++ b/tests/cases/conformance/externalModules/multipleExportDefault1.ts @@ -0,0 +1,7 @@ +export default function Foo (){ + +} + +export default { + uhoh: "another default", +}; diff --git a/tests/cases/conformance/externalModules/multipleExportDefault2.ts b/tests/cases/conformance/externalModules/multipleExportDefault2.ts new file mode 100644 index 00000000000..0e14b570aa1 --- /dev/null +++ b/tests/cases/conformance/externalModules/multipleExportDefault2.ts @@ -0,0 +1,6 @@ +export default { + uhoh: "another default", +}; + +export default function Foo() { } + diff --git a/tests/cases/conformance/externalModules/multipleExportDefault3.ts b/tests/cases/conformance/externalModules/multipleExportDefault3.ts new file mode 100644 index 00000000000..3b5460e8141 --- /dev/null +++ b/tests/cases/conformance/externalModules/multipleExportDefault3.ts @@ -0,0 +1,6 @@ +export default { + uhoh: "another default", +}; + +export default class C { } + diff --git a/tests/cases/conformance/externalModules/multipleExportDefault4.ts b/tests/cases/conformance/externalModules/multipleExportDefault4.ts new file mode 100644 index 00000000000..6181c360798 --- /dev/null +++ b/tests/cases/conformance/externalModules/multipleExportDefault4.ts @@ -0,0 +1,5 @@ +export default class C { } + +export default { + uhoh: "another default", +}; \ No newline at end of file diff --git a/tests/cases/conformance/externalModules/multipleExportDefault5.ts b/tests/cases/conformance/externalModules/multipleExportDefault5.ts new file mode 100644 index 00000000000..d2b67fce46f --- /dev/null +++ b/tests/cases/conformance/externalModules/multipleExportDefault5.ts @@ -0,0 +1,2 @@ +export default function bar() { } +export default class C {} \ No newline at end of file diff --git a/tests/cases/conformance/externalModules/multipleExportDefault6.ts b/tests/cases/conformance/externalModules/multipleExportDefault6.ts new file mode 100644 index 00000000000..889ae64376b --- /dev/null +++ b/tests/cases/conformance/externalModules/multipleExportDefault6.ts @@ -0,0 +1,7 @@ +export default { + lol: 1 +} + +export default { + lol: 2 +} \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxCorrectlyParseLessThanComparison1.tsx b/tests/cases/conformance/jsx/tsxCorrectlyParseLessThanComparison1.tsx new file mode 100644 index 00000000000..87a3d2d12aa --- /dev/null +++ b/tests/cases/conformance/jsx/tsxCorrectlyParseLessThanComparison1.tsx @@ -0,0 +1,20 @@ +// @jsx: react +declare module JSX { + interface Element { + div: string; + } +} +declare namespace React { + class Component { + constructor(props?: P, context?: any); + props: P; + } +} + +export class ShortDetails extends React.Component<{ id: number }, {}> { + public render(): JSX.Element { + if (this.props.id < 1) { + return (
); + } + } +} \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxGenericArrowFunctionParsing.tsx b/tests/cases/conformance/jsx/tsxGenericArrowFunctionParsing.tsx index b3d3d34020a..deb7ba57b5d 100644 --- a/tests/cases/conformance/jsx/tsxGenericArrowFunctionParsing.tsx +++ b/tests/cases/conformance/jsx/tsxGenericArrowFunctionParsing.tsx @@ -4,7 +4,7 @@ declare module JSX { interface Element { isElement; } } -var T, T1, T2; +var T: any, T1: any, T2: any; // This is an element var x1 = () => {}; diff --git a/tests/cases/conformance/parser/ecmascript5/RegressionTests/parser537152.ts b/tests/cases/conformance/parser/ecmascript5/RegressionTests/parser537152.ts deleted file mode 100644 index d418f92b7ec..00000000000 --- a/tests/cases/conformance/parser/ecmascript5/RegressionTests/parser537152.ts +++ /dev/null @@ -1,2 +0,0 @@ -var t; -var y = t.e1; diff --git a/tests/cases/conformance/statements/for-inStatements/for-inStatements.ts b/tests/cases/conformance/statements/for-inStatements/for-inStatements.ts index 1ff19b3e412..89cc0314d36 100644 --- a/tests/cases/conformance/statements/for-inStatements/for-inStatements.ts +++ b/tests/cases/conformance/statements/for-inStatements/for-inStatements.ts @@ -14,7 +14,7 @@ for (var x in fn()) { } for (var x in /[a-z]/) { } for (var x in new Date()) { } -var c, d, e; +var c: any, d: any, e: any; for (var x in c || d) { } for (var x in e ? c : d) { } diff --git a/tests/cases/conformance/typings/typingsLookupAmd.ts b/tests/cases/conformance/typings/typingsLookupAmd.ts new file mode 100644 index 00000000000..e452894e9b4 --- /dev/null +++ b/tests/cases/conformance/typings/typingsLookupAmd.ts @@ -0,0 +1,14 @@ +// @traceResolution: true +// @noImplicitReferences: true +// @currentDirectory: / +// @module: amd + +// @filename: /node_modules/@types/a/index.d.ts +export declare class A {} + +// @filename: /x/node_modules/@types/b/index.d.ts +import {A} from "a"; +export declare class B extends A {} + +// @filename: /x/y/foo.ts +import {B} from "b"; diff --git a/tests/cases/fourslash/completionForStringLiteralRelativeImport1.ts b/tests/cases/fourslash/completionForStringLiteralRelativeImport1.ts deleted file mode 100644 index 3ba82fb0acf..00000000000 --- a/tests/cases/fourslash/completionForStringLiteralRelativeImport1.ts +++ /dev/null @@ -1,70 +0,0 @@ -/// - -// Should give completions for ts files when allowJs is false - -// @Filename: test0.ts -//// import * as foo1 from "./*import_as0*/ -//// import * as foo2 from ".//*import_as1*/ -//// import * as foo4 from "./folder//*import_as2*/ - -//// import foo6 = require("./*import_equals0*/ -//// import foo7 = require(".//*import_equals1*/ -//// import foo9 = require("./folder//*import_equals2*/ - -//// var foo11 = require("./*require0*/ -//// var foo12 = require(".//*require1*/ -//// var foo14 = require("./folder//*require2*/ - -// @Filename: parentTest/sub/test5.ts -//// import * as foo16 from "../g/*import_as3*/ -//// import foo17 = require("../g/*import_equals3*/ -//// var foo18 = require("../g/*require3*/ - - -// @Filename: f1.ts -//// /*f1*/ -// @Filename: f1.js -//// /*f1j*/ -// @Filename: f1.d.ts -//// /*f1d*/ -// @Filename: f2.tsx -//// /f2*/ -// @Filename: f3.js -//// /*f3*/ -// @Filename: f4.jsx -//// /*f4*/ -// @Filename: e1.ts -//// /*e1*/ -// @Filename: folder/f3.ts -//// /*subf1*/ -// @Filename: folder/h1.ts -//// /*subh1*/ -// @Filename: parentTest/f4.ts -//// /*parentf1*/ -// @Filename: parentTest/g1.ts -//// /*parentg1*/ -const kinds = ["import_as", "import_equals", "require"]; - -for (const kind of kinds) { - goTo.marker(kind + "0"); - verify.completionListIsEmpty(); - - goTo.marker(kind + "1"); - verify.completionListContains("f1"); - verify.completionListContains("f2"); - verify.completionListContains("e1"); - verify.completionListContains("folder"); - verify.completionListContains("parentTest"); - verify.not.completionListItemsCountIsGreaterThan(5); - - goTo.marker(kind + "2"); - verify.completionListContains("f3"); - verify.completionListContains("h1"); - verify.not.completionListItemsCountIsGreaterThan(2); - - goTo.marker(kind + "3"); - verify.completionListContains("f4"); - verify.completionListContains("g1"); - verify.completionListContains("sub"); - verify.not.completionListItemsCountIsGreaterThan(3); -} \ No newline at end of file diff --git a/tests/cases/fourslash/completionForStringLiteralRelativeImportAllowJSFalse.ts b/tests/cases/fourslash/completionForStringLiteralRelativeImportAllowJSFalse.ts new file mode 100644 index 00000000000..f343ce8699b --- /dev/null +++ b/tests/cases/fourslash/completionForStringLiteralRelativeImportAllowJSFalse.ts @@ -0,0 +1,72 @@ +/// + +// Should give completions for ts files only when allowJs is false. + +// @Filename: test0.ts +//// import * as foo1 from "./*import_as0*/ +//// import * as foo2 from ".//*import_as1*/ +//// import * as foo4 from "./d1//*import_as2*/ + +//// import foo6 = require("./*import_equals0*/ +//// import foo7 = require(".//*import_equals1*/ +//// import foo9 = require("./d1//*import_equals2*/ + +//// var foo11 = require("./*require0*/ +//// var foo12 = require(".//*require1*/ +//// var foo14 = require("./d1//*require2*/ + +// @Filename: d2/d3/test1.ts +//// import * as foo16 from "..//*import_as3*/ +//// import foo17 = require("..//*import_equals3*/ +//// var foo18 = require("..//*require3*/ + + +// @Filename: f1.ts +//// /*f1*/ +// @Filename: f2.js +//// /*f2*/ +// @Filename: f3.d.ts +//// /*f3*/ +// @Filename: f4.tsx +//// /f4*/ +// @Filename: f5.js +//// /*f5*/ +// @Filename: f6.jsx +//// /*f6*/ +// @Filename: f7.ts +//// /*f7*/ +// @Filename: d1/f8.ts +//// /*d1f1*/ +// @Filename: d1/f9.ts +//// /*d1f9*/ +// @Filename: d2/f10.ts +//// /*d2f1*/ +// @Filename: d2/f11.ts +//// /*d2f11*/ + +const kinds = ["import_as", "import_equals", "require"]; + +for (const kind of kinds) { + goTo.marker(kind + "0"); + verify.completionListIsEmpty(); + + goTo.marker(kind + "1"); + verify.completionListContains("f1"); + verify.completionListContains("f3"); + verify.completionListContains("f4"); + verify.completionListContains("f7"); + verify.completionListContains("d1"); + verify.completionListContains("d2"); + verify.not.completionListItemsCountIsGreaterThan(6); + + goTo.marker(kind + "2"); + verify.completionListContains("f8"); + verify.completionListContains("f9"); + verify.not.completionListItemsCountIsGreaterThan(2); + + goTo.marker(kind + "3"); + verify.completionListContains("f10"); + verify.completionListContains("f11"); + verify.completionListContains("d3"); + verify.not.completionListItemsCountIsGreaterThan(3); +} \ No newline at end of file diff --git a/tests/cases/fourslash/completionForStringLiteralRelativeImport2.ts b/tests/cases/fourslash/completionForStringLiteralRelativeImportAllowJSTrue.ts similarity index 51% rename from tests/cases/fourslash/completionForStringLiteralRelativeImport2.ts rename to tests/cases/fourslash/completionForStringLiteralRelativeImportAllowJSTrue.ts index 18a80ab3481..6eab9aaeca2 100644 --- a/tests/cases/fourslash/completionForStringLiteralRelativeImport2.ts +++ b/tests/cases/fourslash/completionForStringLiteralRelativeImportAllowJSTrue.ts @@ -1,6 +1,6 @@ /// -// Should give completions for ts and js files when allowJs is true +// Should give completions for ts and js files when allowJs is true. // @allowJs: true @@ -16,38 +16,33 @@ // @Filename: f1.ts //// /f1*/ -// @Filename: f1.js -//// /*f1j*/ -// @Filename: f1.d.ts -//// /*f1d*/ -// @Filename: f2.tsx +// @Filename: f2.js //// /*f2*/ -// @Filename: f3.js +// @Filename: f3.d.ts //// /*f3*/ -// @Filename: f4.jsx +// @Filename: f4.tsx //// /*f4*/ -// @Filename: e1.ts -//// /*e1*/ -// @Filename: e2.js -//// /*e2*/ +// @Filename: f5.js +//// /*f5*/ +// @Filename: f6.jsx +//// /*f6*/ +// @Filename: g1.ts +//// /*g1*/ +// @Filename: g2.js +//// /*g2*/ const kinds = ["import_as", "import_equals", "require"]; for (const kind of kinds) { - goTo.marker(kind + "0"); + for(let i = 0; i < 2; ++i) { + goTo.marker(kind + i); verify.completionListContains("f1"); verify.completionListContains("f2"); verify.completionListContains("f3"); verify.completionListContains("f4"); - verify.completionListContains("e1"); - verify.completionListContains("e2"); - verify.not.completionListItemsCountIsGreaterThan(6); - - goTo.marker(kind + "1"); - verify.completionListContains("f1"); - verify.completionListContains("f2"); - verify.completionListContains("f3"); - verify.completionListContains("f4"); - verify.completionListContains("e1"); - verify.completionListContains("e2"); - verify.not.completionListItemsCountIsGreaterThan(6); + verify.completionListContains("f5"); + verify.completionListContains("f6"); + verify.completionListContains("g1"); + verify.completionListContains("g2"); + verify.not.completionListItemsCountIsGreaterThan(8); + } } \ No newline at end of file diff --git a/tests/cases/fourslash/completionForTripleSlashReference1.ts b/tests/cases/fourslash/completionForTripleSlashReference1.ts deleted file mode 100644 index 2ce4de2e72e..00000000000 --- a/tests/cases/fourslash/completionForTripleSlashReference1.ts +++ /dev/null @@ -1,51 +0,0 @@ -/// - -// Should give completions for relative references to ts files when allowJs is false - -// @Filename: test0.ts -//// /// -//// /// + +// @Filename: foo.d.ts +//// declare class Foo { +//// static prop1(x: number): number; +//// static prop1(x: string): string; +//// static prop2(x: boolean): boolean; +//// } +//// export = Foo; /*2*/ + +// @Filename: app.ts +////import {/*1*/} from './foo'; + +goTo.marker('1'); +verify.completionListContains('prop1'); +verify.completionListContains('prop2'); +verify.not.completionListContains('Foo'); +verify.numberOfErrorsInCurrentFile(0); +goTo.marker('2'); +verify.numberOfErrorsInCurrentFile(0); diff --git a/tests/cases/fourslash/completionListInObjectLiteralPropertyAssignment.ts b/tests/cases/fourslash/completionListInObjectLiteralPropertyAssignment.ts new file mode 100644 index 00000000000..14ccd985577 --- /dev/null +++ b/tests/cases/fourslash/completionListInObjectLiteralPropertyAssignment.ts @@ -0,0 +1,15 @@ +/// + +////var foo; +////interface I { +//// metadata: string; +//// wat: string; +////} +////var x: I = { +//// metadata: "/*1*/ +////} + +goTo.marker('1'); + +verify.not.completionListContains("metadata"); +verify.not.completionListContains("wat"); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListInvalidMemberNames3.ts b/tests/cases/fourslash/completionListInvalidMemberNames3.ts new file mode 100644 index 00000000000..cf1141b4094 --- /dev/null +++ b/tests/cases/fourslash/completionListInvalidMemberNames3.ts @@ -0,0 +1,71 @@ +/// + +// @allowjs: true + +// @Filename: test.js +////interface Symbol { +//// /** Returns a string representation of an object. */ +//// toString(): string; + +//// /** Returns the primitive value of the specified object. */ +//// valueOf(): Object; +////} + +////interface SymbolConstructor { +//// /** +//// * A reference to the prototype. +//// */ +//// readonly prototype: Symbol; + +//// /** +//// * Returns a new unique Symbol value. +//// * @param description Description of the new Symbol object. +//// */ +//// (description?: string | number): symbol; + +//// /** +//// * Returns a Symbol object from the global symbol registry matching the given key if found. +//// * Otherwise, returns a new symbol with this key. +//// * @param key key to search for. +//// */ +//// for(key: string): symbol; + +//// /** +//// * Returns a key from the global symbol registry matching the given Symbol if found. +//// * Otherwise, returns a undefined. +//// * @param sym Symbol to find the key for. +//// */ +//// keyFor(sym: symbol): string | undefined; +////} + +////declare var Symbol: SymbolConstructor;/// + +////interface SymbolConstructor { +//// /** +//// * A method that determines if a constructor object recognizes an object as one of the +//// * constructor’s instances. Called by the semantics of the instanceof operator. +//// */ +//// readonly hasInstance: symbol; +////} + +////interface Function { +//// /** +//// * Determines whether the given value inherits from this function if this function was used +//// * as a constructor function. +//// * +//// * A constructor function can control which objects are recognized as its instances by +//// * 'instanceof' by overriding this method. +//// */ +//// [Symbol.hasInstance](value: any): boolean; +////} + +////interface SomeInterface { +//// (value: number): any; +////} + +////var _ : SomeInterface; +////_./**/ + +goTo.marker(); + +verify.not.completionListContains("[Symbol.hasInstance]"); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListIsGlobalCompletion.ts b/tests/cases/fourslash/completionListIsGlobalCompletion.ts index 3a7adb465a1..73cb6bb2176 100644 --- a/tests/cases/fourslash/completionListIsGlobalCompletion.ts +++ b/tests/cases/fourslash/completionListIsGlobalCompletion.ts @@ -1,5 +1,6 @@ /// +//@Filename: file.tsx /////// // no globals in reference paths ////import { /*2*/ } from "./file.ts"; // no globals in imports ////var test = "/*3*/"; // no globals in strings @@ -20,6 +21,7 @@ //// /*9*/ // insert globals ////} /////*10*/ // insert globals +////const y =
; goTo.marker("1"); verify.completionListIsGlobal(false); goTo.marker("2"); @@ -40,3 +42,5 @@ goTo.marker("9"); verify.completionListIsGlobal(true); goTo.marker("10"); verify.completionListIsGlobal(true); +goTo.marker("11"); +verify.completionListIsGlobal(false); diff --git a/tests/cases/fourslash/deleteClassWithEnumPresent.ts b/tests/cases/fourslash/deleteClassWithEnumPresent.ts index eb40a27bcd7..8914e0020a0 100644 --- a/tests/cases/fourslash/deleteClassWithEnumPresent.ts +++ b/tests/cases/fourslash/deleteClassWithEnumPresent.ts @@ -5,6 +5,32 @@ goTo.marker(); edit.deleteAtCaret('class Bar { }'.length); + +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "Foo", + "kind": "enum", + "childItems": [ + { + "text": "a", + "kind": "const" + }, + { + "text": "b", + "kind": "const" + }, + { + "text": "c", + "kind": "const" + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 5f86cbbafa4..0a72d295295 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -136,6 +136,7 @@ declare namespace FourSlashInterface { typeDefinitionCountIs(expectedCount: number): void; implementationListIsEmpty(): void; isValidBraceCompletionAtPosition(openingBrace?: string): void; + codeFixAvailable(): void; } class verify extends verifyNegatable { assertHasRanges(ranges: Range[]): void; @@ -208,8 +209,10 @@ declare namespace FourSlashInterface { noMatchingBracePositionInCurrentFile(bracePosition: number): void; DocCommentTemplate(expectedText: string, expectedOffset: number, empty?: boolean): void; noDocCommentTemplate(): void; + codeFixAtPosition(expectedText: string, errorCode?: number): void; navigationBar(json: any): void; + navigationTree(json: any): void; navigationItemsListCount(count: number, searchValue: string, matchKind?: string, fileName?: string): void; navigationItemsListContains(name: string, kind: string, searchValue: string, matchKind: string, fileName?: string, parentName?: string): void; occurrencesAtPositionContains(range: Range, isWriteAccess?: boolean): void; diff --git a/tests/cases/fourslash/getMatchingBraces.ts b/tests/cases/fourslash/getMatchingBraces.ts index fc8a71197db..cea9c8c84eb 100644 --- a/tests/cases/fourslash/getMatchingBraces.ts +++ b/tests/cases/fourslash/getMatchingBraces.ts @@ -36,6 +36,7 @@ //// return [||] a; //// } ////} +////const x: Array[|<() => void>|] = []; test.ranges().forEach((range) => { verify.matchingBracePositionInCurrentFile(range.start, range.end - 1); diff --git a/tests/cases/fourslash/getNavigationBarItems.ts b/tests/cases/fourslash/getNavigationBarItems.ts index 8041ba3b464..4bcfc3e18aa 100644 --- a/tests/cases/fourslash/getNavigationBarItems.ts +++ b/tests/cases/fourslash/getNavigationBarItems.ts @@ -5,6 +5,27 @@ //// ["bar"]: string; ////} +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "C", + "kind": "class", + "childItems": [ + { + "text": "[\"bar\"]", + "kind": "property" + }, + { + "text": "foo", + "kind": "property" + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", @@ -31,4 +52,4 @@ verify.navigationBar([ ], "indent": 1 } -]) +]); diff --git a/tests/cases/fourslash/goToDefinitionJsModuleName.ts b/tests/cases/fourslash/goToDefinitionJsModuleName.ts new file mode 100644 index 00000000000..cdd322158f7 --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionJsModuleName.ts @@ -0,0 +1,10 @@ +/// + +// @allowJs: true +// @Filename: foo.js +/////*2*/module.exports = {}; + +// @Filename: bar.js +////var x = require(/*1*/"./foo"); + +verify.goToDefinition("1", "2"); diff --git a/tests/cases/fourslash/jsDocForTypeAlias.ts b/tests/cases/fourslash/jsDocForTypeAlias.ts new file mode 100644 index 00000000000..dbda7ccbc13 --- /dev/null +++ b/tests/cases/fourslash/jsDocForTypeAlias.ts @@ -0,0 +1,7 @@ +/// + +/////** DOC */ +////type /**/T = number + +goTo.marker(); +verify.quickInfoIs("type T = number", "DOC "); diff --git a/tests/cases/fourslash/navbar_const.ts b/tests/cases/fourslash/navbar_const.ts index faaedb54482..2d3e3b919d0 100644 --- a/tests/cases/fourslash/navbar_const.ts +++ b/tests/cases/fourslash/navbar_const.ts @@ -2,6 +2,17 @@ //// const c = 0; +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "c", + "kind": "const" + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navbar_contains-no-duplicates.ts b/tests/cases/fourslash/navbar_contains-no-duplicates.ts index ba48c4a93dd..f4b52bb09a1 100644 --- a/tests/cases/fourslash/navbar_contains-no-duplicates.ts +++ b/tests/cases/fourslash/navbar_contains-no-duplicates.ts @@ -27,6 +27,83 @@ //// export var x = 3; //// } +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "ABC", + "kind": "class", + "childItems": [ + { + "text": "foo", + "kind": "method", + "kindModifiers": "public" + } + ] + }, + { + "text": "ABC", + "kind": "module", + "childItems": [ + { + "text": "x", + "kind": "var", + "kindModifiers": "export" + } + ] + }, + { + "text": "Windows", + "kind": "module", + "kindModifiers": "declare", + "childItems": [ + { + "text": "Foundation", + "kind": "module", + "kindModifiers": "export,declare", + "childItems": [ + { + "text": "A", + "kind": "var", + "kindModifiers": "export,declare" + }, + { + "text": "B", + "kind": "var", + "kindModifiers": "export,declare" + }, + { + "text": "Test", + "kind": "class", + "kindModifiers": "export,declare", + "childItems": [ + { + "text": "wow", + "kind": "method", + "kindModifiers": "public,declare" + } + ] + }, + { + "text": "Test", + "kind": "module", + "kindModifiers": "export,declare", + "childItems": [ + { + "text": "Boom", + "kind": "function", + "kindModifiers": "export,declare" + } + ] + } + ] + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navbar_exportDefault.ts b/tests/cases/fourslash/navbar_exportDefault.ts index e547c9129a6..84f50610e6b 100644 --- a/tests/cases/fourslash/navbar_exportDefault.ts +++ b/tests/cases/fourslash/navbar_exportDefault.ts @@ -13,6 +13,17 @@ ////export default function Func { } goTo.file("a.ts"); +verify.navigationTree({ + "text": "\"a\"", + "kind": "module", + "childItems": [ + { + "text": "default", + "kind": "class", + "kindModifiers": "export" + } + ] +}); verify.navigationBar([ { "text": "\"a\"", @@ -34,6 +45,17 @@ verify.navigationBar([ ]); goTo.file("b.ts"); +verify.navigationTree({ + "text": "\"b\"", + "kind": "module", + "childItems": [ + { + "text": "C", + "kind": "class", + "kindModifiers": "export" + } + ] +}); verify.navigationBar([ { "text": "\"b\"", @@ -55,6 +77,17 @@ verify.navigationBar([ ]); goTo.file("c.ts"); +verify.navigationTree({ + "text": "\"c\"", + "kind": "module", + "childItems": [ + { + "text": "default", + "kind": "function", + "kindModifiers": "export" + } + ] +}); verify.navigationBar([ { "text": "\"c\"", @@ -76,6 +109,17 @@ verify.navigationBar([ ]); goTo.file("d.ts"); +verify.navigationTree({ + "text": "\"d\"", + "kind": "module", + "childItems": [ + { + "text": "Func", + "kind": "function", + "kindModifiers": "export" + } + ] +}); verify.navigationBar([ { "text": "\"d\"", diff --git a/tests/cases/fourslash/navbar_let.ts b/tests/cases/fourslash/navbar_let.ts index bd0e702bbf9..77e00ad7300 100644 --- a/tests/cases/fourslash/navbar_let.ts +++ b/tests/cases/fourslash/navbar_let.ts @@ -2,6 +2,17 @@ ////let c = 0; +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "c", + "kind": "let" + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarAnonymousClassAndFunctionExpressions.ts b/tests/cases/fourslash/navigationBarAnonymousClassAndFunctionExpressions.ts index 30e96739ab0..69fa697f7bc 100644 --- a/tests/cases/fourslash/navigationBarAnonymousClassAndFunctionExpressions.ts +++ b/tests/cases/fourslash/navigationBarAnonymousClassAndFunctionExpressions.ts @@ -26,6 +26,85 @@ //// (class { }); ////}) +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "", + "kind": "function", + "childItems": [ + { + "text": "nest", + "kind": "function", + "childItems": [ + { + "text": "moreNest", + "kind": "function" + } + ] + }, + { + "text": "x", + "kind": "function", + "childItems": [ + { + "text": "xx", + "kind": "function" + } + ] + }, + { + "text": "y", + "kind": "const", + "childItems": [ + { + "text": "foo", + "kind": "function" + } + ] + } + ] + }, + { + "text": "", + "kind": "function", + "childItems": [ + { + "text": "", + "kind": "function" + }, + { + "text": "z", + "kind": "function" + } + ] + }, + { + "text": "classes", + "kind": "function", + "childItems": [ + { + "text": "", + "kind": "class" + }, + { + "text": "cls2", + "kind": "class" + }, + { + "text": "cls3", + "kind": "class" + } + ] + }, + { + "text": "global.cls", + "kind": "class" + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarAnonymousClassAndFunctionExpressions2.ts b/tests/cases/fourslash/navigationBarAnonymousClassAndFunctionExpressions2.ts index 36b1e07cd8a..f6ce02e0dd0 100644 --- a/tests/cases/fourslash/navigationBarAnonymousClassAndFunctionExpressions2.ts +++ b/tests/cases/fourslash/navigationBarAnonymousClassAndFunctionExpressions2.ts @@ -3,6 +3,39 @@ ////console.log(console.log(class Y {}, class X {}), console.log(class B {}, class A {})); ////console.log(class Cls { meth() {} }); +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "A", + "kind": "class" + }, + { + "text": "B", + "kind": "class" + }, + { + "text": "Cls", + "kind": "class", + "childItems": [ + { + "text": "meth", + "kind": "method" + } + ] + }, + { + "text": "X", + "kind": "class" + }, + { + "text": "Y", + "kind": "class" + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarFunctionIndirectlyInVariableDeclaration.ts b/tests/cases/fourslash/navigationBarFunctionIndirectlyInVariableDeclaration.ts index f14419a121a..a0ed5174f56 100644 --- a/tests/cases/fourslash/navigationBarFunctionIndirectlyInVariableDeclaration.ts +++ b/tests/cases/fourslash/navigationBarFunctionIndirectlyInVariableDeclaration.ts @@ -8,39 +8,64 @@ //// propB: function() {} ////}; -verify.navigationBar([ - { +verify.navigationTree({ "text": "", "kind": "script", "childItems": [ - { - "text": "a", - "kind": "var" - }, - { - "text": "b", - "kind": "var" - }, - { - "text": "propB", - "kind": "function" - } + { + "text": "a", + "kind": "var", + "childItems": [ + { + "text": "propA", + "kind": "function" + } + ] + }, + { + "text": "b", + "kind": "var" + }, + { + "text": "propB", + "kind": "function" + } ] - }, - { - "text": "a", - "kind": "var", - "childItems": [ - { - "text": "propA", - "kind": "function" - } - ], - "indent": 1 - }, - { - "text": "propB", - "kind": "function", - "indent": 1 - } +}); + +verify.navigationBar([ + { + "text": "", + "kind": "script", + "childItems": [ + { + "text": "a", + "kind": "var" + }, + { + "text": "b", + "kind": "var" + }, + { + "text": "propB", + "kind": "function" + } + ] + }, + { + "text": "a", + "kind": "var", + "childItems": [ + { + "text": "propA", + "kind": "function" + } + ], + "indent": 1 + }, + { + "text": "propB", + "kind": "function", + "indent": 1 + } ]); diff --git a/tests/cases/fourslash/navigationBarGetterAndSetter.ts b/tests/cases/fourslash/navigationBarGetterAndSetter.ts index 3ae2e0f60ac..ccf9e7c472e 100644 --- a/tests/cases/fourslash/navigationBarGetterAndSetter.ts +++ b/tests/cases/fourslash/navigationBarGetterAndSetter.ts @@ -8,6 +8,33 @@ //// } ////} +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "X", + "kind": "class", + "childItems": [ + { + "text": "x", + "kind": "getter" + }, + { + "text": "x", + "kind": "setter", + "childItems": [ + { + "text": "f", + "kind": "function" + } + ] + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarImports.ts b/tests/cases/fourslash/navigationBarImports.ts index 43cb99c556a..44f0d46b401 100644 --- a/tests/cases/fourslash/navigationBarImports.ts +++ b/tests/cases/fourslash/navigationBarImports.ts @@ -4,6 +4,29 @@ ////import c = require("m"); ////import * as d from "m"; +verify.navigationTree({ + "text": "\"navigationBarImports\"", + "kind": "module", + "childItems": [ + { + "text": "a", + "kind": "alias" + }, + { + "text": "b", + "kind": "alias" + }, + { + "text": "c", + "kind": "alias" + }, + { + "text": "d", + "kind": "alias" + } + ] +}); + verify.navigationBar([ { "text": "\"navigationBarImports\"", diff --git a/tests/cases/fourslash/navigationBarItemsBindingPatterns.ts b/tests/cases/fourslash/navigationBarItemsBindingPatterns.ts index ff1de04c07e..d2b8b24bcbf 100644 --- a/tests/cases/fourslash/navigationBarItemsBindingPatterns.ts +++ b/tests/cases/fourslash/navigationBarItemsBindingPatterns.ts @@ -6,6 +6,57 @@ ////const bar1, [c, d] ////var {e, x: [f, g]} = {a:1, x:[]}; +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "a", + "kind": "let" + }, + { + "text": "b", + "kind": "let" + }, + { + "text": "bar", + "kind": "var" + }, + { + "text": "bar1", + "kind": "const" + }, + { + "text": "c", + "kind": "const" + }, + { + "text": "d", + "kind": "const" + }, + { + "text": "e", + "kind": "var" + }, + { + "text": "f", + "kind": "var" + }, + { + "text": "foo", + "kind": "var" + }, + { + "text": "foo1", + "kind": "let" + }, + { + "text": "g", + "kind": "var" + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarItemsBindingPatternsInConstructor.ts b/tests/cases/fourslash/navigationBarItemsBindingPatternsInConstructor.ts index 61e34d0f30e..f1250d530d3 100644 --- a/tests/cases/fourslash/navigationBarItemsBindingPatternsInConstructor.ts +++ b/tests/cases/fourslash/navigationBarItemsBindingPatternsInConstructor.ts @@ -11,6 +11,41 @@ //// } ////} +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "A", + "kind": "class", + "childItems": [ + { + "text": "constructor", + "kind": "constructor" + }, + { + "text": "x", + "kind": "property" + } + ] + }, + { + "text": "B", + "kind": "class", + "childItems": [ + { + "text": "constructor", + "kind": "constructor" + }, + { + "text": "x", + "kind": "property" + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarItemsEmptyConstructors.ts b/tests/cases/fourslash/navigationBarItemsEmptyConstructors.ts index 2e37f69b456..c300a1207d5 100644 --- a/tests/cases/fourslash/navigationBarItemsEmptyConstructors.ts +++ b/tests/cases/fourslash/navigationBarItemsEmptyConstructors.ts @@ -5,6 +5,23 @@ //// } ////} +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "Test", + "kind": "class", + "childItems": [ + { + "text": "constructor", + "kind": "constructor" + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarItemsExports.ts b/tests/cases/fourslash/navigationBarItemsExports.ts index 3ec9b0a7138..1f29ae5af5b 100644 --- a/tests/cases/fourslash/navigationBarItemsExports.ts +++ b/tests/cases/fourslash/navigationBarItemsExports.ts @@ -9,6 +9,26 @@ //// ////export * from "a"; // no bindings here +verify.navigationTree({ + "text": "\"navigationBarItemsExports\"", + "kind": "module", + "childItems": [ + { + "text": "a", + "kind": "alias" + }, + { + "text": "B", + "kind": "alias" + }, + { + "text": "e", + "kind": "alias", + "kindModifiers": "export" + } + ] +}); + verify.navigationBar([ { "text": "\"navigationBarItemsExports\"", diff --git a/tests/cases/fourslash/navigationBarItemsFunctions.ts b/tests/cases/fourslash/navigationBarItemsFunctions.ts index b85e898065c..f43cd3effaf 100644 --- a/tests/cases/fourslash/navigationBarItemsFunctions.ts +++ b/tests/cases/fourslash/navigationBarItemsFunctions.ts @@ -14,6 +14,53 @@ //// var v = 10; ////} +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "baz", + "kind": "function", + "childItems": [ + { + "text": "v", + "kind": "var" + } + ] + }, + { + "text": "foo", + "kind": "function", + "childItems": [ + { + "text": "bar", + "kind": "function", + "childItems": [ + { + "text": "biz", + "kind": "function", + "childItems": [ + { + "text": "z", + "kind": "var" + } + ] + }, + { + "text": "y", + "kind": "var" + } + ] + }, + { + "text": "x", + "kind": "var" + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarItemsFunctionsBroken.ts b/tests/cases/fourslash/navigationBarItemsFunctionsBroken.ts index b0238a1ef06..49ca40841d7 100644 --- a/tests/cases/fourslash/navigationBarItemsFunctionsBroken.ts +++ b/tests/cases/fourslash/navigationBarItemsFunctionsBroken.ts @@ -4,6 +4,23 @@ //// function; ////} +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "f", + "kind": "function", + "childItems": [ + { + "text": "", + "kind": "function" + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarItemsFunctionsBroken2.ts b/tests/cases/fourslash/navigationBarItemsFunctionsBroken2.ts index 4f279446100..8ebfab8519b 100644 --- a/tests/cases/fourslash/navigationBarItemsFunctionsBroken2.ts +++ b/tests/cases/fourslash/navigationBarItemsFunctionsBroken2.ts @@ -5,6 +5,27 @@ //// function; ////} +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "", + "kind": "function" + }, + { + "text": "f", + "kind": "function", + "childItems": [ + { + "text": "", + "kind": "function" + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarItemsImports.ts b/tests/cases/fourslash/navigationBarItemsImports.ts index ed398ec7f1d..b0ce515a56c 100644 --- a/tests/cases/fourslash/navigationBarItemsImports.ts +++ b/tests/cases/fourslash/navigationBarItemsImports.ts @@ -13,6 +13,44 @@ //// ////import * as ns from "a"; +verify.navigationTree({ + "text": "\"navigationBarItemsImports\"", + "kind": "module", + "childItems": [ + { + "text": "a", + "kind": "alias" + }, + { + "text": "B", + "kind": "alias" + }, + { + "text": "c", + "kind": "alias" + }, + { + "text": "D", + "kind": "alias" + }, + { + "text": "d1", + "kind": "alias" + }, + { + "text": "d2", + "kind": "alias" + }, + { + "text": "e", + "kind": "alias" + }, + { + "text": "ns", + "kind": "alias" + } + ] +}); verify.navigationBar([ { diff --git a/tests/cases/fourslash/navigationBarItemsInsideMethodsAndConstructors.ts b/tests/cases/fourslash/navigationBarItemsInsideMethodsAndConstructors.ts index a49f32d960e..35dff3af14c 100644 --- a/tests/cases/fourslash/navigationBarItemsInsideMethodsAndConstructors.ts +++ b/tests/cases/fourslash/navigationBarItemsInsideMethodsAndConstructors.ts @@ -18,6 +18,77 @@ //// emptyMethod() { } // Non child functions method should not be duplicated ////} +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "Class", + "kind": "class", + "childItems": [ + { + "text": "constructor", + "kind": "constructor", + "childItems": [ + { + "text": "LocalEnumInConstructor", + "kind": "enum", + "childItems": [ + { + "text": "LocalEnumMemberInConstructor", + "kind": "const" + } + ] + }, + { + "text": "LocalFunctionInConstructor", + "kind": "function" + }, + { + "text": "LocalInterfaceInConstrcutor", + "kind": "interface" + } + ] + }, + { + "text": "emptyMethod", + "kind": "method" + }, + { + "text": "method", + "kind": "method", + "childItems": [ + { + "text": "LocalEnumInMethod", + "kind": "enum", + "childItems": [ + { + "text": "LocalEnumMemberInMethod", + "kind": "const" + } + ] + }, + { + "text": "LocalFunctionInMethod", + "kind": "function", + "childItems": [ + { + "text": "LocalFunctionInLocalFunctionInMethod", + "kind": "function" + } + ] + }, + { + "text": "LocalInterfaceInMethod", + "kind": "interface" + } + ] + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarItemsItems.ts b/tests/cases/fourslash/navigationBarItemsItems.ts index e3d8f0e633c..69422dd0cc2 100644 --- a/tests/cases/fourslash/navigationBarItemsItems.ts +++ b/tests/cases/fourslash/navigationBarItemsItems.ts @@ -39,6 +39,114 @@ ////var p: IPoint = new Shapes.Point(3, 4); ////var dist = p.getDist(); +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "dist", + "kind": "var" + }, + { + "text": "IPoint", + "kind": "interface", + "childItems": [ + { + "text": "()", + "kind": "call" + }, + { + "text": "new()", + "kind": "construct" + }, + { + "text": "[]", + "kind": "index" + }, + { + "text": "getDist", + "kind": "method" + }, + { + "text": "prop", + "kind": "property" + } + ] + }, + { + "text": "p", + "kind": "var" + }, + { + "text": "Shapes", + "kind": "module", + "childItems": [ + { + "text": "Point", + "kind": "class", + "kindModifiers": "export", + "childItems": [ + { + "text": "constructor", + "kind": "constructor" + }, + { + "text": "getDist", + "kind": "method" + }, + { + "text": "getOrigin", + "kind": "method", + "kindModifiers": "private,static" + }, + { + "text": "origin", + "kind": "property", + "kindModifiers": "static" + }, + { + "text": "value", + "kind": "getter" + }, + { + "text": "value", + "kind": "setter" + }, + { + "text": "x", + "kind": "property", + "kindModifiers": "public" + }, + { + "text": "y", + "kind": "property", + "kindModifiers": "public" + } + ] + }, + { + "text": "Values", + "kind": "enum", + "childItems": [ + { + "text": "value1", + "kind": "const" + }, + { + "text": "value2", + "kind": "const" + }, + { + "text": "value3", + "kind": "const" + } + ] + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarItemsItems2.ts b/tests/cases/fourslash/navigationBarItemsItems2.ts index 6ab0827e8f9..fa5a5b09fac 100644 --- a/tests/cases/fourslash/navigationBarItemsItems2.ts +++ b/tests/cases/fourslash/navigationBarItemsItems2.ts @@ -6,6 +6,22 @@ goTo.marker(); edit.insertLine("module A"); edit.insert("export class "); +verify.navigationTree({ + "text": "\"navigationBarItemsItems2\"", + "kind": "module", + "childItems": [ + { + "text": "", + "kind": "class", + "kindModifiers": "export" + }, + { + "text": "A", + "kind": "module" + } + ] +}); + // should not crash verify.navigationBar([ { diff --git a/tests/cases/fourslash/navigationBarItemsItemsExternalModules.ts b/tests/cases/fourslash/navigationBarItemsItemsExternalModules.ts index 04091185dd0..705dc2227b3 100644 --- a/tests/cases/fourslash/navigationBarItemsItemsExternalModules.ts +++ b/tests/cases/fourslash/navigationBarItemsItemsExternalModules.ts @@ -4,6 +4,25 @@ //// public s: string; ////} +verify.navigationTree({ + "text": "\"navigationBarItemsItemsExternalModules\"", + "kind": "module", + "childItems": [ + { + "text": "Bar", + "kind": "class", + "kindModifiers": "export", + "childItems": [ + { + "text": "s", + "kind": "property", + "kindModifiers": "public" + } + ] + } + ] +}); + verify.navigationBar([ { "text": "\"navigationBarItemsItemsExternalModules\"", diff --git a/tests/cases/fourslash/navigationBarItemsItemsExternalModules2.ts b/tests/cases/fourslash/navigationBarItemsItemsExternalModules2.ts index 4939091d944..c271050bc52 100644 --- a/tests/cases/fourslash/navigationBarItemsItemsExternalModules2.ts +++ b/tests/cases/fourslash/navigationBarItemsItemsExternalModules2.ts @@ -6,6 +6,30 @@ ////} ////export var x: number; +verify.navigationTree({ + "text": "\"file\"", + "kind": "module", + "childItems": [ + { + "text": "Bar", + "kind": "class", + "kindModifiers": "export", + "childItems": [ + { + "text": "s", + "kind": "property", + "kindModifiers": "public" + } + ] + }, + { + "text": "x", + "kind": "var", + "kindModifiers": "export" + } + ] +}); + verify.navigationBar([ { "text": "\"file\"", diff --git a/tests/cases/fourslash/navigationBarItemsItemsExternalModules3.ts b/tests/cases/fourslash/navigationBarItemsItemsExternalModules3.ts index 5ee760fabc6..91ac533d75c 100644 --- a/tests/cases/fourslash/navigationBarItemsItemsExternalModules3.ts +++ b/tests/cases/fourslash/navigationBarItemsItemsExternalModules3.ts @@ -6,6 +6,30 @@ ////} ////export var x: number; +verify.navigationTree({ + "text": "\"my fil\\\"e\"", + "kind": "module", + "childItems": [ + { + "text": "Bar", + "kind": "class", + "kindModifiers": "export", + "childItems": [ + { + "text": "s", + "kind": "property", + "kindModifiers": "public" + } + ] + }, + { + "text": "x", + "kind": "var", + "kindModifiers": "export" + } + ] +}); + verify.navigationBar([ { "text": "\"my fil\\\"e\"", diff --git a/tests/cases/fourslash/navigationBarItemsItemsModuleVariables.ts b/tests/cases/fourslash/navigationBarItemsItemsModuleVariables.ts index 9b8a65d0430..1beeffddb21 100644 --- a/tests/cases/fourslash/navigationBarItemsItemsModuleVariables.ts +++ b/tests/cases/fourslash/navigationBarItemsItemsModuleVariables.ts @@ -20,6 +20,23 @@ ////} goTo.marker("file1"); // nothing else should show up +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "Module1", + "kind": "module", + "childItems": [ + { + "text": "x", + "kind": "var", + "kindModifiers": "export" + } + ] + } + ] +}); verify.navigationBar([ { "text": "", @@ -46,6 +63,23 @@ verify.navigationBar([ ]); goTo.marker("file2"); +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "Module1.SubModule", + "kind": "module", + "childItems": [ + { + "text": "y", + "kind": "var", + "kindModifiers": "export" + } + ] + } + ] +}); verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarItemsMissingName1.ts b/tests/cases/fourslash/navigationBarItemsMissingName1.ts index 2a445a5e1ed..60123d92e71 100644 --- a/tests/cases/fourslash/navigationBarItemsMissingName1.ts +++ b/tests/cases/fourslash/navigationBarItemsMissingName1.ts @@ -3,6 +3,28 @@ //// foo() {} ////} +verify.navigationTree({ + "text": "\"navigationBarItemsMissingName1\"", + "kind": "module", + "childItems": [ + { + "text": "", + "kind": "function", + "kindModifiers": "export" + }, + { + "text": "C", + "kind": "class", + "childItems": [ + { + "text": "foo", + "kind": "method" + } + ] + } + ] +}); + verify.navigationBar([ { "text": "\"navigationBarItemsMissingName1\"", diff --git a/tests/cases/fourslash/navigationBarItemsMissingName2.ts b/tests/cases/fourslash/navigationBarItemsMissingName2.ts index 9faeb6de902..ce92128c825 100644 --- a/tests/cases/fourslash/navigationBarItemsMissingName2.ts +++ b/tests/cases/fourslash/navigationBarItemsMissingName2.ts @@ -6,6 +6,23 @@ ////} // Anonymous classes are still included. +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "", + "kind": "class", + "childItems": [ + { + "text": "foo", + "kind": "method" + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarItemsModules.ts b/tests/cases/fourslash/navigationBarItemsModules.ts index a41c75de550..fd5907e2bc7 100644 --- a/tests/cases/fourslash/navigationBarItemsModules.ts +++ b/tests/cases/fourslash/navigationBarItemsModules.ts @@ -27,6 +27,73 @@ //We have 8 module keywords, and 4 var keywords. //The declarations of A.B.C.x do not get merged, so the 4 vars are independent. //The two 'A' modules, however, do get merged, so in reality we have 7 modules. +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "'X2.Y2.Z2'", + "kind": "module", + "kindModifiers": "declare" + }, + { + "text": "\"X.Y.Z\"", + "kind": "module", + "kindModifiers": "declare" + }, + { + "text": "A", + "kind": "module", + "childItems": [ + { + "text": "B", + "kind": "module", + "childItems": [ + { + "text": "C", + "kind": "module", + "childItems": [ + { + "text": "x", + "kind": "var", + "kindModifiers": "declare" + } + ] + } + ] + }, + { + "text": "z", + "kind": "var", + "kindModifiers": "export" + } + ] + }, + { + "text": "A.B", + "kind": "module", + "childItems": [ + { + "text": "y", + "kind": "var", + "kindModifiers": "export" + } + ] + }, + { + "text": "A.B.C", + "kind": "module", + "childItems": [ + { + "text": "x", + "kind": "var", + "kindModifiers": "export" + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarItemsMultilineStringIdentifiers.ts b/tests/cases/fourslash/navigationBarItemsMultilineStringIdentifiers.ts index dcf8894bb61..793844ac970 100644 --- a/tests/cases/fourslash/navigationBarItemsMultilineStringIdentifiers.ts +++ b/tests/cases/fourslash/navigationBarItemsMultilineStringIdentifiers.ts @@ -24,6 +24,56 @@ //// } ////} +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "\"Multiline\\\nMadness\"", + "kind": "module", + "kindModifiers": "declare" + }, + { + "text": "\"Multiline\\r\\nMadness\"", + "kind": "module", + "kindModifiers": "declare" + }, + { + "text": "\"MultilineMadness\"", + "kind": "module", + "kindModifiers": "declare" + }, + { + "text": "Bar", + "kind": "class", + "childItems": [ + { + "text": "'a1\\\\\\r\\nb'", + "kind": "property" + }, + { + "text": "'a2\\\n \\\n b'", + "kind": "method" + } + ] + }, + { + "text": "Foo", + "kind": "interface", + "childItems": [ + { + "text": "\"a1\\\\\\r\\nb\"", + "kind": "property" + }, + { + "text": "\"a2\\\n \\\n b\"", + "kind": "method" + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarItemsPropertiesDefinedInConstructors.ts b/tests/cases/fourslash/navigationBarItemsPropertiesDefinedInConstructors.ts index b741084dab5..6e8e0ea350c 100644 --- a/tests/cases/fourslash/navigationBarItemsPropertiesDefinedInConstructors.ts +++ b/tests/cases/fourslash/navigationBarItemsPropertiesDefinedInConstructors.ts @@ -6,6 +6,43 @@ //// } ////} +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "List", + "kind": "class", + "childItems": [ + { + "text": "constructor", + "kind": "constructor", + "childItems": [ + { + "text": "local", + "kind": "var" + } + ] + }, + { + "text": "a", + "kind": "property", + "kindModifiers": "public" + }, + { + "text": "b", + "kind": "property", + "kindModifiers": "private" + }, + { + "text": "c", + "kind": "property" + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarItemsSymbols1.ts b/tests/cases/fourslash/navigationBarItemsSymbols1.ts index ba57916028b..4326d7b4deb 100644 --- a/tests/cases/fourslash/navigationBarItemsSymbols1.ts +++ b/tests/cases/fourslash/navigationBarItemsSymbols1.ts @@ -6,6 +6,31 @@ //// get [Symbol.isConcatSpreadable]() { } ////} +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "C", + "kind": "class", + "childItems": [ + { + "text": "[Symbol.isConcatSpreadable]", + "kind": "getter" + }, + { + "text": "[Symbol.isRegExp]", + "kind": "property" + }, + { + "text": "[Symbol.iterator]", + "kind": "method" + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarItemsSymbols2.ts b/tests/cases/fourslash/navigationBarItemsSymbols2.ts index 6812c88c150..64b076aaf0c 100644 --- a/tests/cases/fourslash/navigationBarItemsSymbols2.ts +++ b/tests/cases/fourslash/navigationBarItemsSymbols2.ts @@ -5,6 +5,27 @@ //// [Symbol.iterator](): string; ////} +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "I", + "kind": "interface", + "childItems": [ + { + "text": "[Symbol.isRegExp]", + "kind": "property" + }, + { + "text": "[Symbol.iterator]", + "kind": "method" + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarItemsSymbols3.ts b/tests/cases/fourslash/navigationBarItemsSymbols3.ts index 661005b86d9..be001c75e0b 100644 --- a/tests/cases/fourslash/navigationBarItemsSymbols3.ts +++ b/tests/cases/fourslash/navigationBarItemsSymbols3.ts @@ -5,6 +5,17 @@ //// [Symbol.isRegExp] = 0 ////} +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "E", + "kind": "enum" + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarItemsTypeAlias.ts b/tests/cases/fourslash/navigationBarItemsTypeAlias.ts index cba3fb8789c..387a9925d82 100644 --- a/tests/cases/fourslash/navigationBarItemsTypeAlias.ts +++ b/tests/cases/fourslash/navigationBarItemsTypeAlias.ts @@ -2,6 +2,17 @@ ////type T = number | string; +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "T", + "kind": "type" + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarJsDoc.ts b/tests/cases/fourslash/navigationBarJsDoc.ts index 89049e6011a..8efce74d111 100644 --- a/tests/cases/fourslash/navigationBarJsDoc.ts +++ b/tests/cases/fourslash/navigationBarJsDoc.ts @@ -5,6 +5,25 @@ /////** @typedef {(string|number)} */ ////const x = 0; +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "NumberLike", + "kind": "type" + }, + { + "text": "x", + "kind": "const" + }, + { + "text": "x", + "kind": "type" + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarJsDocCommentWithNoTags.ts b/tests/cases/fourslash/navigationBarJsDocCommentWithNoTags.ts index 8746f135e4d..561bdf4a056 100644 --- a/tests/cases/fourslash/navigationBarJsDocCommentWithNoTags.ts +++ b/tests/cases/fourslash/navigationBarJsDocCommentWithNoTags.ts @@ -3,6 +3,18 @@ /////** Test */ ////export const Test = {} +verify.navigationTree({ + "text": "\"navigationBarJsDocCommentWithNoTags\"", + "kind": "module", + "childItems": [ + { + "text": "Test", + "kind": "const", + "kindModifiers": "export" + } + ] +}); + verify.navigationBar([ { "text": "\"navigationBarJsDocCommentWithNoTags\"", diff --git a/tests/cases/fourslash/navigationBarMerging.ts b/tests/cases/fourslash/navigationBarMerging.ts index 2798d186c96..ebf02c94466 100644 --- a/tests/cases/fourslash/navigationBarMerging.ts +++ b/tests/cases/fourslash/navigationBarMerging.ts @@ -11,6 +11,37 @@ //// function bar() {} ////} +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "a", + "kind": "module", + "childItems": [ + { + "text": "bar", + "kind": "function" + }, + { + "text": "foo", + "kind": "function" + } + ] + }, + { + "text": "b", + "kind": "module", + "childItems": [ + { + "text": "foo", + "kind": "function" + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", @@ -60,6 +91,22 @@ verify.navigationBar([ ////function a() {} goTo.file("file2.ts"); + +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "a", + "kind": "function" + }, + { + "text": "a", + "kind": "module" + } + ] +}); + verify.navigationBar([ { "text": "", @@ -101,6 +148,34 @@ verify.navigationBar([ ////} goTo.file("file3.ts"); + +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "a", + "kind": "module", + "childItems": [ + { + "text": "A", + "kind": "interface", + "childItems": [ + { + "text": "bar", + "kind": "property" + }, + { + "text": "foo", + "kind": "property" + } + ] + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", @@ -147,6 +222,36 @@ verify.navigationBar([ ////module A.B { export var y; } goTo.file("file4.ts"); + +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "A", + "kind": "module", + "childItems": [ + { + "text": "x", + "kind": "var", + "kindModifiers": "export" + } + ] + }, + { + "text": "A.B", + "kind": "module", + "childItems": [ + { + "text": "y", + "kind": "var", + "kindModifiers": "export" + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/navigationBarNamespaceImportWithNoName.ts b/tests/cases/fourslash/navigationBarNamespaceImportWithNoName.ts index 732e2deb1dd..4c441728fdf 100644 --- a/tests/cases/fourslash/navigationBarNamespaceImportWithNoName.ts +++ b/tests/cases/fourslash/navigationBarNamespaceImportWithNoName.ts @@ -1,4 +1,16 @@ ////import *{} from 'foo'; + +verify.navigationTree({ + "text": "\"navigationBarNamespaceImportWithNoName\"", + "kind": "module", + "childItems": [ + { + "text": "", + "kind": "alias" + } + ] +}); + verify.navigationBar([ { "text": "\"navigationBarNamespaceImportWithNoName\"", diff --git a/tests/cases/fourslash/navigationBarVariables.ts b/tests/cases/fourslash/navigationBarVariables.ts index 93093df1306..98d5e816e8e 100644 --- a/tests/cases/fourslash/navigationBarVariables.ts +++ b/tests/cases/fourslash/navigationBarVariables.ts @@ -4,6 +4,25 @@ ////let y = 1; ////const z = 2; +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "x", + "kind": "var" + }, + { + "text": "y", + "kind": "let" + }, + { + "text": "z", + "kind": "const" + } + ] +}); + verify.navigationBar([ { "text": "", @@ -31,6 +50,26 @@ verify.navigationBar([ ////const [c] = 0; goTo.file("file2.ts"); + +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "a", + "kind": "var" + }, + { + "text": "b", + "kind": "let" + }, + { + "text": "c", + "kind": "const" + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/semanticClassificationJs.ts b/tests/cases/fourslash/semanticClassificationJs.ts new file mode 100644 index 00000000000..8105202a23f --- /dev/null +++ b/tests/cases/fourslash/semanticClassificationJs.ts @@ -0,0 +1,9 @@ +/// + +// @Filename: app.js +//// function foo() { +//// } +//// let x = 1; + +// no semantic classification in js file +verify.semanticClassificationsAre(); \ No newline at end of file diff --git a/tests/cases/fourslash/server/codefix.ts b/tests/cases/fourslash/server/codefix.ts new file mode 100644 index 00000000000..7fbe2cb4fd7 --- /dev/null +++ b/tests/cases/fourslash/server/codefix.ts @@ -0,0 +1,10 @@ +/// + +////class Base{ +////} +////class C extends Base{ +//// constructor() {[| |] +//// } +////} + +verify.codeFixAtPosition('super();'); diff --git a/tests/cases/fourslash/server/jsdocTypedefTagNavigateTo.ts b/tests/cases/fourslash/server/jsdocTypedefTagNavigateTo.ts index 978db18ab3b..212394159a8 100644 --- a/tests/cases/fourslash/server/jsdocTypedefTagNavigateTo.ts +++ b/tests/cases/fourslash/server/jsdocTypedefTagNavigateTo.ts @@ -10,6 +10,29 @@ //// /** @type {/*1*/NumberLike} */ //// var numberLike; +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "numberLike", + "kind": "var" + }, + { + "text": "NumberLike", + "kind": "type" + }, + { + "text": "NumberLike2", + "kind": "var" + }, + { + "text": "NumberLike2", + "kind": "type" + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/server/navbar01.ts b/tests/cases/fourslash/server/navbar01.ts index a5b22ee1fa9..4a4f59bcf78 100644 --- a/tests/cases/fourslash/server/navbar01.ts +++ b/tests/cases/fourslash/server/navbar01.ts @@ -38,6 +38,114 @@ ////var p: IPoint = new Shapes.Point(3, 4); ////var dist = p.getDist(); +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "dist", + "kind": "var" + }, + { + "text": "IPoint", + "kind": "interface", + "childItems": [ + { + "text": "()", + "kind": "call" + }, + { + "text": "new()", + "kind": "construct" + }, + { + "text": "[]", + "kind": "index" + }, + { + "text": "getDist", + "kind": "method" + }, + { + "text": "prop", + "kind": "property" + } + ] + }, + { + "text": "p", + "kind": "var" + }, + { + "text": "Shapes", + "kind": "module", + "childItems": [ + { + "text": "Point", + "kind": "class", + "kindModifiers": "export", + "childItems": [ + { + "text": "constructor", + "kind": "constructor" + }, + { + "text": "getDist", + "kind": "method" + }, + { + "text": "getOrigin", + "kind": "method", + "kindModifiers": "private,static" + }, + { + "text": "origin", + "kind": "property", + "kindModifiers": "static" + }, + { + "text": "value", + "kind": "getter" + }, + { + "text": "value", + "kind": "setter" + }, + { + "text": "x", + "kind": "property", + "kindModifiers": "public" + }, + { + "text": "y", + "kind": "property", + "kindModifiers": "public" + } + ] + }, + { + "text": "Values", + "kind": "enum", + "childItems": [ + { + "text": "value1", + "kind": "const" + }, + { + "text": "value2", + "kind": "const" + }, + { + "text": "value3", + "kind": "const" + } + ] + } + ] + } + ] +}); + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/shims-pp/getNavigationBarItems.ts b/tests/cases/fourslash/shims-pp/getNavigationBarItems.ts index fba24bdcf77..627d4dac178 100644 --- a/tests/cases/fourslash/shims-pp/getNavigationBarItems.ts +++ b/tests/cases/fourslash/shims-pp/getNavigationBarItems.ts @@ -2,6 +2,17 @@ //// {| "itemName": "c", "kind": "const", "parentName": "" |}const c = 0; +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "c", + "kind": "const" + } + ] +}) + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/shims/getNavigationBarItems.ts b/tests/cases/fourslash/shims/getNavigationBarItems.ts index fba24bdcf77..627d4dac178 100644 --- a/tests/cases/fourslash/shims/getNavigationBarItems.ts +++ b/tests/cases/fourslash/shims/getNavigationBarItems.ts @@ -2,6 +2,17 @@ //// {| "itemName": "c", "kind": "const", "parentName": "" |}const c = 0; +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "c", + "kind": "const" + } + ] +}) + verify.navigationBar([ { "text": "", diff --git a/tests/cases/fourslash/superFix1.ts b/tests/cases/fourslash/superFix1.ts new file mode 100644 index 00000000000..7fbe2cb4fd7 --- /dev/null +++ b/tests/cases/fourslash/superFix1.ts @@ -0,0 +1,10 @@ +/// + +////class Base{ +////} +////class C extends Base{ +//// constructor() {[| |] +//// } +////} + +verify.codeFixAtPosition('super();'); diff --git a/tests/cases/fourslash/superFix2.ts b/tests/cases/fourslash/superFix2.ts new file mode 100644 index 00000000000..880b5d43167 --- /dev/null +++ b/tests/cases/fourslash/superFix2.ts @@ -0,0 +1,13 @@ +/// + +////class Base{ +////} +////class C extends Base{ +//// private a:number; +//// constructor() {[| +//// this.a = 12; +//// super();|] +//// } +////} + +verify.codeFixAtPosition("super(); this.a = 12;"); \ No newline at end of file diff --git a/tests/cases/fourslash/superFix3.ts b/tests/cases/fourslash/superFix3.ts new file mode 100644 index 00000000000..9b443b7df62 --- /dev/null +++ b/tests/cases/fourslash/superFix3.ts @@ -0,0 +1,12 @@ +/// + +////class Base{ +//// constructor(id: number) { } +////} +////class C extends Base{ +//// constructor(private a:number) { +//// super(this.a); +//// } +////} + +verify.not.codeFixAvailable(); \ No newline at end of file diff --git a/tests/cases/fourslash/completionForTripleSlashReference3.ts b/tests/cases/fourslash/tripleSlashRefPathCompletionAbsolutePaths.ts similarity index 95% rename from tests/cases/fourslash/completionForTripleSlashReference3.ts rename to tests/cases/fourslash/tripleSlashRefPathCompletionAbsolutePaths.ts index 798e556be58..99fffd7a7d6 100644 --- a/tests/cases/fourslash/completionForTripleSlashReference3.ts +++ b/tests/cases/fourslash/tripleSlashRefPathCompletionAbsolutePaths.ts @@ -1,6 +1,6 @@ /// -// Should give completions for absolute paths +// Exercises completions for absolute paths. // @Filename: tests/test0.ts //// /// + +// Exercises whether completions are supplied, conditional on the caret position in the ref comment. + +// @Filename: f.ts +//// /*f*/ + +// @Filename: test.ts +//// /// /*7*/ + +for(let m = 0; m < 8; ++m) { + goTo.marker("" + m); + verify.not.completionListItemsCountIsGreaterThan(0); +} + +for(let m of ["8", "9"]) { + goTo.marker(m); + verify.completionListContains("f.ts"); + verify.not.completionListItemsCountIsGreaterThan(1); +} \ No newline at end of file diff --git a/tests/cases/fourslash/tripleSlashRefPathCompletionExtensionsAllowJSFalse.ts b/tests/cases/fourslash/tripleSlashRefPathCompletionExtensionsAllowJSFalse.ts new file mode 100644 index 00000000000..95a4cd01b60 --- /dev/null +++ b/tests/cases/fourslash/tripleSlashRefPathCompletionExtensionsAllowJSFalse.ts @@ -0,0 +1,31 @@ +/// + +// Should give completions for relative references to ts files only when allowJs is false. + +// @Filename: test0.ts +//// /// -// Should give completions for relative references to js and ts files when allowJs is true +// Should give completions for relative references to ts and js files when allowJs is true. // @allowJs: true // @Filename: test0.ts //// /// +//// /// + +// Exercises completions for hidden files (ie: those beginning with '.') + +// @Filename: f.ts +//// /*f*/ +// @Filename: .hidden.ts +//// /*hidden*/ + +// @Filename: test.ts +//// /// + +// Exercises how changes in the basename change the completions offered. +// They should have no effect, as filtering completions is the responsibility of the editor. + +// @Filename: f1.ts +//// /*f1*/ +// @Filename: f2.ts +//// /*f2*/ +// @Filename: d/g.ts +//// /*g*/ + +// @Filename: test.ts +//// /// + +// Exercises relative path completions going up and down 2 directories +// and the use of forward- and back-slashes and combinations thereof. + +// @Filename: f.ts +//// /*f1*/ +// @Filename: d1/g.ts +//// /*g1*/ +// @Filename: d1/d2/h.ts +//// /*h1*/ +// @Filename: d1/d2/d3/i.ts +//// /*i1*/ +// @Filename: d1/d2/d3/d4/j.ts +//// /*j1*/ + +// @Filename: d1/d2/test.ts +//// ///