diff --git a/issue_template.md b/issue_template.md index b5872a0f9fa..e812fe7b74c 100644 --- a/issue_template.md +++ b/issue_template.md @@ -8,7 +8,7 @@ ```ts // A *self-contained* demonstration of the problem follows... - +// Test this by running `tsc` on the command-line, rather than through another build tool such as Gulp, Webpack, etc. ``` **Expected behavior:** diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index e7b759ff64f..803c9f60709 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1395,14 +1395,12 @@ namespace ts { case SyntaxKind.ObjectLiteralExpression: case SyntaxKind.TypeLiteral: case SyntaxKind.JSDocTypeLiteral: - case SyntaxKind.JSDocRecordType: case SyntaxKind.JsxAttributes: return ContainerFlags.IsContainer; case SyntaxKind.InterfaceDeclaration: return ContainerFlags.IsContainer | ContainerFlags.IsInterface; - case SyntaxKind.JSDocFunctionType: case SyntaxKind.ModuleDeclaration: case SyntaxKind.TypeAliasDeclaration: case SyntaxKind.MappedType: @@ -1422,9 +1420,10 @@ namespace ts { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: case SyntaxKind.CallSignature: + case SyntaxKind.JSDocFunctionType: + case SyntaxKind.FunctionType: case SyntaxKind.ConstructSignature: case SyntaxKind.IndexSignature: - case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike; @@ -1502,7 +1501,6 @@ namespace ts { case SyntaxKind.TypeLiteral: case SyntaxKind.ObjectLiteralExpression: case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.JSDocRecordType: case SyntaxKind.JSDocTypeLiteral: case SyntaxKind.JsxAttributes: // Interface/Object-types always have their children added to the 'members' of @@ -2095,6 +2093,7 @@ namespace ts { case SyntaxKind.SetAccessor: return bindPropertyOrMethodOrAccessor(node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes); case SyntaxKind.FunctionType: + case SyntaxKind.JSDocFunctionType: case SyntaxKind.ConstructorType: return bindFunctionOrConstructorType(node); case SyntaxKind.TypeLiteral: @@ -2157,18 +2156,13 @@ namespace ts { case SyntaxKind.ModuleBlock: return updateStrictModeStatementList((node).statements); - case SyntaxKind.JSDocRecordMember: - return bindPropertyWorker(node as JSDocRecordMember); case SyntaxKind.JSDocPropertyTag: return declareSymbolAndAddToSymbolTable(node as JSDocPropertyTag, (node as JSDocPropertyTag).isBracketed || ((node as JSDocPropertyTag).typeExpression && (node as JSDocPropertyTag).typeExpression.type.kind === SyntaxKind.JSDocOptionalType) ? SymbolFlags.Property | SymbolFlags.Optional : SymbolFlags.Property, SymbolFlags.PropertyExcludes); - case SyntaxKind.JSDocFunctionType: - return bindFunctionOrConstructorType(node); case SyntaxKind.JSDocTypeLiteral: - case SyntaxKind.JSDocRecordType: - return bindAnonymousTypeWorker(node as JSDocTypeLiteral | JSDocRecordType); + return bindAnonymousTypeWorker(node as JSDocTypeLiteral); case SyntaxKind.JSDocTypedefTag: { const { fullName } = node as JSDocTypedefTag; if (!fullName || fullName.kind === SyntaxKind.Identifier) { @@ -2183,7 +2177,7 @@ namespace ts { return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property | (node.questionToken ? SymbolFlags.Optional : SymbolFlags.None), SymbolFlags.PropertyExcludes); } - function bindAnonymousTypeWorker(node: TypeLiteralNode | MappedTypeNode | JSDocTypeLiteral | JSDocRecordType) { + function bindAnonymousTypeWorker(node: TypeLiteralNode | MappedTypeNode | JSDocTypeLiteral) { return bindAnonymousDeclaration(node, SymbolFlags.TypeLiteral, InternalSymbolName.Type); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6c5fcc36e4d..dafa75372e1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6798,8 +6798,6 @@ namespace ts { switch (node.kind) { case SyntaxKind.TypeReference: return (node).typeName; - case SyntaxKind.JSDocTypeReference: - return (node).name; case SyntaxKind.ExpressionWithTypeArguments: // We only support expressions that are simple qualified names. For other // expressions this produces undefined. @@ -6807,7 +6805,6 @@ namespace ts { if (isEntityNameExpression(expr)) { return expr; } - // fall through; } @@ -6833,8 +6830,8 @@ namespace ts { return type; } - if (symbol.flags & SymbolFlags.Value && node.kind === SyntaxKind.JSDocTypeReference) { - // A JSDocTypeReference may have resolved to a value (as opposed to a type). If + if (symbol.flags & SymbolFlags.Value && isJSDocTypeReference(node)) { + // A jsdoc TypeReference may have resolved to a value (as opposed to a type). If // the symbol is a constructor function, return the inferred class type; otherwise, // the type of this reference is just the type of the value we resolved to. const valueType = getTypeOfSymbol(symbol); @@ -6862,14 +6859,20 @@ namespace ts { return getTypeFromTypeAliasReference(node, symbol, typeArguments); } - if (symbol.flags & SymbolFlags.Function && node.kind === SyntaxKind.JSDocTypeReference && (symbol.members || getJSDocClassTag(symbol.valueDeclaration))) { + if (symbol.flags & SymbolFlags.Function && + isJSDocTypeReference(node) && + (symbol.members || getJSDocClassTag(symbol.valueDeclaration))) { return getInferredClassType(symbol); } } - function getPrimitiveTypeFromJSDocTypeReference(node: JSDocTypeReference): Type { - if (isIdentifier(node.name)) { - switch (node.name.text) { + function isJSDocTypeReference(node: TypeReferenceType): node is TypeReferenceNode { + return node.flags & NodeFlags.JSDoc && node.kind === SyntaxKind.TypeReference; + } + + function getPrimitiveTypeFromJSDocTypeReference(node: TypeReferenceNode): Type { + if (isIdentifier(node.typeName)) { + switch (node.typeName.text) { case "String": return stringType; case "Number": @@ -6883,14 +6886,13 @@ namespace ts { case "Null": return nullType; case "Object": - case "object": return anyType; case "Function": case "function": return globalFunctionType; case "Array": case "array": - return !node.typeArguments || !node.typeArguments.length ? createArrayType(anyType) : undefined; + return !node.typeArguments || !node.typeArguments.length ? anyArrayType : undefined; case "Promise": case "promise": return !node.typeArguments || !node.typeArguments.length ? createPromiseType(anyType) : undefined; @@ -6909,7 +6911,7 @@ namespace ts { let symbol: Symbol; let type: Type; let meaning = SymbolFlags.Type; - if (node.kind === SyntaxKind.JSDocTypeReference) { + if (isJSDocTypeReference(node)) { type = getPrimitiveTypeFromJSDocTypeReference(node); meaning |= SymbolFlags.Value; } @@ -7799,15 +7801,6 @@ namespace ts { return links.resolvedType; } - function getTypeFromJSDocTupleType(node: JSDocTupleType): Type { - const links = getNodeLinks(node); - if (!links.resolvedType) { - const types = map(node.types, getTypeFromTypeNode); - links.resolvedType = createTupleType(types); - } - return links.resolvedType; - } - function getThisType(node: Node): Type { const container = getThisContainer(node, /*includeArrowFunctions*/ false); const parent = container && container.parent; @@ -7852,16 +7845,13 @@ namespace ts { case SyntaxKind.NeverKeyword: return neverType; case SyntaxKind.ObjectKeyword: - return nonPrimitiveType; + return node.flags & NodeFlags.JavaScriptFile ? anyType : nonPrimitiveType; case SyntaxKind.ThisType: case SyntaxKind.ThisKeyword: return getTypeFromThisTypeNode(node); case SyntaxKind.LiteralType: return getTypeFromLiteralTypeNode(node); - case SyntaxKind.JSDocLiteralType: - return getTypeFromLiteralTypeNode((node).literal); case SyntaxKind.TypeReference: - case SyntaxKind.JSDocTypeReference: return getTypeFromTypeReference(node); case SyntaxKind.TypePredicate: return booleanType; @@ -7870,12 +7860,10 @@ namespace ts { case SyntaxKind.TypeQuery: return getTypeFromTypeQueryNode(node); case SyntaxKind.ArrayType: - case SyntaxKind.JSDocArrayType: return getTypeFromArrayTypeNode(node); case SyntaxKind.TupleType: return getTypeFromTupleTypeNode(node); case SyntaxKind.UnionType: - case SyntaxKind.JSDocUnionType: return getTypeFromUnionTypeNode(node); case SyntaxKind.IntersectionType: return getTypeFromIntersectionTypeNode(node); @@ -7883,12 +7871,8 @@ namespace ts { return getTypeFromJSDocNullableTypeNode(node); case SyntaxKind.ParenthesizedType: case SyntaxKind.JSDocNonNullableType: - case SyntaxKind.JSDocConstructorType: - case SyntaxKind.JSDocThisType: case SyntaxKind.JSDocOptionalType: return getTypeFromTypeNode((node).type); - case SyntaxKind.JSDocRecordType: - return getTypeFromTypeNode((node as JSDocRecordType).literal); case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: case SyntaxKind.TypeLiteral: @@ -7907,8 +7891,6 @@ namespace ts { case SyntaxKind.QualifiedName: const symbol = getSymbolAtLocation(node); return symbol && getDeclaredTypeOfSymbol(symbol); - case SyntaxKind.JSDocTupleType: - return getTypeFromJSDocTupleType(node); case SyntaxKind.JSDocVariadicType: return getTypeFromJSDocVariadicType(node); default: @@ -12381,7 +12363,9 @@ namespace ts { const jsdocType = getJSDocType(node); if (jsdocType && jsdocType.kind === SyntaxKind.JSDocFunctionType) { const jsDocFunctionType = jsdocType; - if (jsDocFunctionType.parameters.length > 0 && jsDocFunctionType.parameters[0].type.kind === SyntaxKind.JSDocThisType) { + if (jsDocFunctionType.parameters.length > 0 && + jsDocFunctionType.parameters[0].name && + (jsDocFunctionType.parameters[0].name as Identifier).text === "this") { return getTypeFromTypeNode(jsDocFunctionType.parameters[0].type); } } @@ -17883,9 +17867,9 @@ namespace ts { if (node.questionToken && isBindingPattern(node.name) && (func as FunctionLikeDeclaration).body) { error(node, Diagnostics.A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature); } - if ((node.name).text === "this") { + if (node.name && ((node.name as Identifier).text === "this" || (node.name as Identifier).text === "new")) { if (indexOf(func.parameters, node) !== 0) { - error(node, Diagnostics.A_this_parameter_must_be_the_first_parameter); + error(node, Diagnostics.A_0_parameter_must_be_the_first_parameter, (node.name as Identifier).text as string); } if (func.kind === SyntaxKind.Constructor || func.kind === SyntaxKind.ConstructSignature || func.kind === SyntaxKind.ConstructorType) { error(node, Diagnostics.A_constructor_cannot_have_a_this_parameter); @@ -18474,6 +18458,10 @@ namespace ts { function checkTypeReferenceNode(node: TypeReferenceNode | ExpressionWithTypeArguments) { checkGrammarTypeArguments(node, node.typeArguments); + if (node.kind === SyntaxKind.TypeReference && node.typeName.jsdocDotPos !== undefined && !isInJavaScriptFile(node) && !isInJSDoc(node)) { + grammarErrorAtPos(getSourceFileOfNode(node), node.typeName.jsdocDotPos, 1, Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments); + + } const type = getTypeFromTypeReference(node); if (type !== unknownType) { if (node.typeArguments) { @@ -19372,7 +19360,23 @@ namespace ts { } } + function checkJSDoc(node: FunctionDeclaration | MethodDeclaration) { + if (!isInJavaScriptFile(node)) { + return; + } + forEach(node.jsDoc, checkSourceElement); + } + + function checkJSDocComment(node: JSDoc) { + if ((node as JSDoc).tags) { + for (const tag of (node as JSDoc).tags) { + checkSourceElement(tag); + } + } + } + function checkFunctionOrMethodDeclaration(node: FunctionDeclaration | MethodDeclaration): void { + checkJSDoc(node); checkDecorators(node); checkSignatureDeclaration(node); const functionFlags = getFunctionFlags(node); @@ -19916,6 +19920,11 @@ namespace ts { function checkVariableLikeDeclaration(node: VariableLikeDeclaration) { checkDecorators(node); checkSourceElement(node.type); + + // JSDoc `function(string, string): string` syntax results in parameters with no name + if (!node.name) { + return; + } // For a computed property, just check the initializer and exit // Do not use hasDynamicName here, because that returns false for well known symbols. // We want to perform checkComputedPropertyName for all computed properties, including @@ -22030,6 +22039,24 @@ namespace ts { case SyntaxKind.ParenthesizedType: case SyntaxKind.TypeOperator: return checkSourceElement((node).type); + case SyntaxKind.JSDocComment: + return checkJSDocComment(node as JSDoc); + case SyntaxKind.JSDocParameterTag: + return checkSourceElement((node as JSDocParameterTag).typeExpression); + case SyntaxKind.JSDocFunctionType: + checkSignatureDeclaration(node as JSDocFunctionType); + // falls through + case SyntaxKind.JSDocVariadicType: + case SyntaxKind.JSDocNonNullableType: + case SyntaxKind.JSDocNullableType: + case SyntaxKind.JSDocAllType: + case SyntaxKind.JSDocUnknownType: + if (!isInJavaScriptFile(node) && !isInJSDoc(node)) { + grammarErrorOnNode(node, Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments); + } + return; + case SyntaxKind.JSDocTypeExpression: + return checkSourceElement((node as JSDocTypeExpression).type); case SyntaxKind.IndexedAccessType: return checkIndexedAccessType(node); case SyntaxKind.MappedType: @@ -22386,7 +22413,7 @@ namespace ts { node = node.parent; } - return node.parent && (node.parent.kind === SyntaxKind.TypeReference || node.parent.kind === SyntaxKind.JSDocTypeReference) ; + return node.parent && node.parent.kind === SyntaxKind.TypeReference ; } function isHeritageClauseElementIdentifier(entityName: Node): boolean { @@ -22540,7 +22567,7 @@ namespace ts { } } else if (isTypeReferenceIdentifier(entityName)) { - const meaning = (entityName.parent.kind === SyntaxKind.TypeReference || entityName.parent.kind === SyntaxKind.JSDocTypeReference) ? SymbolFlags.Type : SymbolFlags.Namespace; + const meaning = entityName.parent.kind === SyntaxKind.TypeReference ? SymbolFlags.Type : SymbolFlags.Namespace; return resolveEntityName(entityName, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true); } else if (entityName.parent.kind === SyntaxKind.JsxAttribute) { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 3b3127f8a41..209562f842d 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -752,7 +752,7 @@ namespace ts { } } - export function parseCommandLine(commandLine: string[], readFile?: (path: string) => string): ParsedCommandLine { + export function parseCommandLine(commandLine: string[], readFile?: (path: string) => string | undefined): ParsedCommandLine { const options: CompilerOptions = {}; const fileNames: string[] = []; const errors: Diagnostic[] = []; @@ -878,15 +878,9 @@ namespace ts { * Read tsconfig.json file * @param fileName The path to the config file */ - export function readConfigFile(fileName: string, readFile: (path: string) => string): { config?: any; error?: Diagnostic } { - let text = ""; - try { - text = readFile(fileName); - } - catch (e) { - return { config: {}, error: createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message) }; - } - return parseConfigFileTextToJson(fileName, text); + export function readConfigFile(fileName: string, readFile: (path: string) => string | undefined): { config?: any; error?: Diagnostic } { + const textOrDiagnostic = tryReadFile(fileName, readFile); + return typeof textOrDiagnostic === "string" ? parseConfigFileTextToJson(fileName, textOrDiagnostic) : { config: {}, error: textOrDiagnostic }; } /** @@ -906,15 +900,20 @@ namespace ts { * Read tsconfig.json file * @param fileName The path to the config file */ - export function readJsonConfigFile(fileName: string, readFile: (path: string) => string): JsonSourceFile { - let text = ""; + export function readJsonConfigFile(fileName: string, readFile: (path: string) => string | undefined): JsonSourceFile { + const textOrDiagnostic = tryReadFile(fileName, readFile); + return typeof textOrDiagnostic === "string" ? parseJsonText(fileName, textOrDiagnostic) : { parseDiagnostics: [textOrDiagnostic] }; + } + + function tryReadFile(fileName: string, readFile: (path: string) => string | undefined): string | Diagnostic { + let text: string | undefined; try { text = readFile(fileName); } catch (e) { - return { parseDiagnostics: [createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message)] }; + return createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message); } - return parseJsonText(fileName, text); + return text === undefined ? createCompilerDiagnostic(Diagnostics.The_specified_path_does_not_exist_Colon_0, fileName) : text; } function commandLineOptionsToMap(options: CommandLineOption[]) { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index b4ea5943eec..902dd9179d2 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -787,7 +787,7 @@ namespace ts { /** * Stable sort of an array. Elements equal to each other maintain their relative position in the array. */ - export function stableSort(array: ReadonlyArray, comparer: (x: T, y: T) => Comparison = compareValues) { + export function stableSort(array: ReadonlyArray, comparer: Comparer = compareValues) { return array .map((_, i) => i) // create array of indices .sort((x, y) => comparer(array[x], array[y]) || compareValues(x, y)) // sort indices by value then position @@ -859,6 +859,8 @@ namespace ts { return result; } + export type Comparer = (a: T, b: T) => Comparison; + /** * Performs a binary search, finding the index at which 'value' occurs in 'array'. * If no such index is found, returns the 2's-complement of first index at which @@ -866,7 +868,7 @@ namespace ts { * @param array A sorted array whose first element must be no larger than number * @param number The value to be searched for in the array. */ - export function binarySearch(array: ReadonlyArray, value: T, comparer?: (v1: T, v2: T) => number, offset?: number): number { + export function binarySearch(array: ReadonlyArray, value: T, comparer?: Comparer, offset?: number): number { if (!array || array.length === 0) { return -1; } @@ -1587,10 +1589,21 @@ namespace ts { return path && !isRootedDiskPath(path) && path.indexOf("://") !== -1; } + /* @internal */ + export function pathIsRelative(path: string): boolean { + return /^\.\.?($|[\\/])/.test(path); + } + export function isExternalModuleNameRelative(moduleName: string): boolean { // TypeScript 1.0 spec (April 2014): 11.2.1 // An external module name is "relative" if the first term is "." or "..". - return /^\.\.?($|[\\/])/.test(moduleName); + // Update: We also consider a path like `C:\foo.ts` "relative" because we do not search for it in `node_modules` or treat it as an ambient module. + return pathIsRelative(moduleName) || isRootedDiskPath(moduleName); + } + + /** @deprecated Use `!isExternalModuleNameRelative(moduleName)` instead. */ + export function moduleHasNonRelativeName(moduleName: string): boolean { + return !isExternalModuleNameRelative(moduleName); } export function getEmitScriptTarget(compilerOptions: CompilerOptions) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index d5ac603bf1b..b2e2b882692 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2064,7 +2064,7 @@ "category": "Error", "code": 2679 }, - "A 'this' parameter must be the first parameter.": { + "A '{0}' parameter must be the first parameter.": { "category": "Error", "code": 2680 }, @@ -3459,6 +3459,22 @@ "category": "Error", "code": 8016 }, + "Octal literal types must use ES2015 syntax. Use the syntax '{0}'.": { + "category": "Error", + "code": 8017 + }, + "Octal literals are not allowed in enums members initializer. Use the syntax '{0}'.": { + "category": "Error", + "code": 8018 + }, + "Report errors in .js files.": { + "category": "Message", + "code": 8019 + }, + "JSDoc types can only be used inside documentation comments.": { + "category": "Error", + "code": 8020 + }, "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause.": { "category": "Error", "code": 9002 @@ -3641,18 +3657,5 @@ "Convert function '{0}' to class": { "category": "Message", "code": 95002 - }, - - "Octal literal types must use ES2015 syntax. Use the syntax '{0}'.": { - "category": "Error", - "code": 8017 - }, - "Octal literals are not allowed in enums members initializer. Use the syntax '{0}'.": { - "category": "Error", - "code": 8018 - }, - "Report errors in .js files.": { - "category": "Message", - "code": 8019 } } diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 2a32dc11f7b..59afd8daff0 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -54,10 +54,6 @@ namespace ts { }; } - export function moduleHasNonRelativeName(moduleName: string): boolean { - return !(isRootedDiskPath(moduleName) || isExternalModuleNameRelative(moduleName)); - } - interface ModuleResolutionState { host: ModuleResolutionHost; compilerOptions: CompilerOptions; @@ -318,7 +314,7 @@ namespace ts { } function getOrCreateCacheForModuleName(nonRelativeModuleName: string) { - if (!moduleHasNonRelativeName(nonRelativeModuleName)) { + if (isExternalModuleNameRelative(nonRelativeModuleName)) { return undefined; } let perModuleNameCache = moduleNameToDirectoryMap.get(nonRelativeModuleName); @@ -535,7 +531,7 @@ namespace ts { function tryLoadModuleUsingOptionalResolutionSettings(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader, failedLookupLocations: Push, state: ModuleResolutionState): Resolved | undefined { - if (moduleHasNonRelativeName(moduleName)) { + if (!isExternalModuleNameRelative(moduleName)) { return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, failedLookupLocations, state); } else { @@ -711,7 +707,7 @@ namespace ts { return toSearchResult({ resolved, isExternalLibraryImport: false }); } - if (moduleHasNonRelativeName(moduleName)) { + if (!isExternalModuleNameRelative(moduleName)) { if (traceEnabled) { trace(host, Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]); } @@ -1024,7 +1020,7 @@ namespace ts { } const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName); - if (moduleHasNonRelativeName(moduleName)) { + if (!isExternalModuleNameRelative(moduleName)) { // Climb up parent directories looking for a module. const resolved = forEachAncestorDirectory(containingDirectory, directory => { const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, traceEnabled, host); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 089bff53a05..20c9559a8f4 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -9,6 +9,7 @@ namespace ts { Type = 1 << 2, RequireCompleteParameterList = 1 << 3, IgnoreMissingOpenBrace = 1 << 4, + JSDoc = 1 << 5, } let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; @@ -392,21 +393,10 @@ namespace ts { case SyntaxKind.JSDocTypeExpression: return visitNode(cbNode, (node).type); - case SyntaxKind.JSDocUnionType: - return visitNodes(cbNode, cbNodes, (node).types); - case SyntaxKind.JSDocTupleType: - return visitNodes(cbNode, cbNodes, (node).types); - case SyntaxKind.JSDocArrayType: - return visitNode(cbNode, (node).elementType); case SyntaxKind.JSDocNonNullableType: return visitNode(cbNode, (node).type); case SyntaxKind.JSDocNullableType: return visitNode(cbNode, (node).type); - case SyntaxKind.JSDocRecordType: - return visitNode(cbNode, (node).literal); - case SyntaxKind.JSDocTypeReference: - return visitNode(cbNode, (node).name) || - visitNodes(cbNode, cbNodes, (node).typeArguments); case SyntaxKind.JSDocOptionalType: return visitNode(cbNode, (node).type); case SyntaxKind.JSDocFunctionType: @@ -414,13 +404,6 @@ namespace ts { visitNode(cbNode, (node).type); case SyntaxKind.JSDocVariadicType: return visitNode(cbNode, (node).type); - case SyntaxKind.JSDocConstructorType: - return visitNode(cbNode, (node).type); - case SyntaxKind.JSDocThisType: - return visitNode(cbNode, (node).type); - case SyntaxKind.JSDocRecordMember: - return visitNode(cbNode, (node).name) || - visitNode(cbNode, (node).type); case SyntaxKind.JSDocComment: return visitNodes(cbNode, cbNodes, (node).tags); case SyntaxKind.JSDocParameterTag: @@ -447,8 +430,6 @@ namespace ts { visitNode(cbNode, (node).name); case SyntaxKind.PartiallyEmittedExpression: return visitNode(cbNode, (node).expression); - case SyntaxKind.JSDocLiteralType: - return visitNode(cbNode, (node).literal); } } @@ -1239,14 +1220,6 @@ namespace ts { return parsePropertyNameWorker(/*allowComputedPropertyNames*/ true); } - function parseSimplePropertyName(): Identifier | LiteralExpression { - return parsePropertyNameWorker(/*allowComputedPropertyNames*/ false); - } - - function isSimplePropertyName() { - return token() === SyntaxKind.StringLiteral || token() === SyntaxKind.NumericLiteral || tokenIsIdentifierOrKeyword(token()); - } - function parseComputedPropertyName(): ComputedPropertyName { // PropertyName [Yield]: // LiteralPropertyName @@ -1394,12 +1367,6 @@ namespace ts { return tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.OpenBraceToken; case ParsingContext.JsxChildren: return true; - case ParsingContext.JSDocFunctionParameters: - case ParsingContext.JSDocTypeArguments: - case ParsingContext.JSDocTupleTypes: - return JSDocParser.isJSDocType(); - case ParsingContext.JSDocRecordMembers: - return isSimplePropertyName(); } Debug.fail("Non-exhaustive case in 'isListElement'."); @@ -1494,14 +1461,6 @@ namespace ts { return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.SlashToken; case ParsingContext.JsxChildren: return token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsSlash); - case ParsingContext.JSDocFunctionParameters: - return token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.ColonToken || token() === SyntaxKind.CloseBraceToken; - case ParsingContext.JSDocTypeArguments: - return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.CloseBraceToken; - case ParsingContext.JSDocTupleTypes: - return token() === SyntaxKind.CloseBracketToken || token() === SyntaxKind.CloseBraceToken; - case ParsingContext.JSDocRecordMembers: - return token() === SyntaxKind.CloseBraceToken; } } @@ -1887,10 +1846,6 @@ namespace ts { case ParsingContext.ImportOrExportSpecifiers: return Diagnostics.Identifier_expected; case ParsingContext.JsxAttributes: return Diagnostics.Identifier_expected; case ParsingContext.JsxChildren: return Diagnostics.Identifier_expected; - case ParsingContext.JSDocFunctionParameters: return Diagnostics.Parameter_declaration_expected; - case ParsingContext.JSDocTypeArguments: return Diagnostics.Type_argument_expected; - case ParsingContext.JSDocTupleTypes: return Diagnostics.Type_expected; - case ParsingContext.JSDocRecordMembers: return Diagnostics.Property_assignment_expected; } } @@ -1967,11 +1922,17 @@ namespace ts { return createMissingList(); } - // The allowReservedWords parameter controls whether reserved words are permitted after the first dot function parseEntityName(allowReservedWords: boolean, diagnosticMessage?: DiagnosticMessage): EntityName { - let entity: EntityName = parseIdentifier(diagnosticMessage); + let entity: EntityName = allowReservedWords ? parseIdentifierName() : parseIdentifier(diagnosticMessage); + let dotPos = scanner.getStartPos(); while (parseOptional(SyntaxKind.DotToken)) { - const node: QualifiedName = createNode(SyntaxKind.QualifiedName, entity.pos); // !!! + if (token() === SyntaxKind.LessThanToken) { + // the entity is part of a JSDoc-style generic, so record the trailing dot for later error reporting + entity.jsdocDotPos = dotPos; + break; + } + dotPos = scanner.getStartPos(); + const node: QualifiedName = createNode(SyntaxKind.QualifiedName, entity.pos); node.left = entity; node.right = parseRightSideOfDot(allowReservedWords); entity = finishNode(node); @@ -2098,7 +2059,7 @@ namespace ts { function parseTypeReference(): TypeReferenceNode { const node = createNode(SyntaxKind.TypeReference); - node.typeName = parseEntityName(/*allowReservedWords*/ false, Diagnostics.Type_expected); + node.typeName = parseEntityName(/*allowReservedWords*/ !!(contextFlags & NodeFlags.JSDoc), Diagnostics.Type_expected); if (!scanner.hasPrecedingLineBreak() && token() === SyntaxKind.LessThanToken) { node.typeArguments = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken); } @@ -2119,6 +2080,73 @@ namespace ts { return finishNode(node); } + function parseJSDocAllType(): JSDocAllType { + const result = createNode(SyntaxKind.JSDocAllType); + nextToken(); + return finishNode(result); + } + + function parseJSDocUnknownOrNullableType(): JSDocUnknownType | JSDocNullableType { + const pos = scanner.getStartPos(); + // skip the ? + nextToken(); + + // Need to lookahead to decide if this is a nullable or unknown type. + + // Here are cases where we'll pick the unknown type: + // + // Foo(?, + // { a: ? } + // Foo(?) + // Foo + // Foo(?= + // (?| + if (token() === SyntaxKind.CommaToken || + token() === SyntaxKind.CloseBraceToken || + token() === SyntaxKind.CloseParenToken || + token() === SyntaxKind.GreaterThanToken || + token() === SyntaxKind.EqualsToken || + token() === SyntaxKind.BarToken) { + + const result = createNode(SyntaxKind.JSDocUnknownType, pos); + return finishNode(result); + } + else { + const result = createNode(SyntaxKind.JSDocNullableType, pos); + result.type = parseType(); + return finishNode(result); + } + } + + function parseJSDocFunctionType(): JSDocFunctionType | TypeReferenceNode { + if (lookAhead(nextTokenIsOpenParen)) { + const result = createNode(SyntaxKind.JSDocFunctionType); + nextToken(); + fillSignature(SyntaxKind.ColonToken, SignatureFlags.Type | SignatureFlags.JSDoc, result); + return finishNode(result); + } + const node = createNode(SyntaxKind.TypeReference); + node.typeName = parseIdentifierName(); + return finishNode(node); + } + + function parseJSDocParameter(): ParameterDeclaration { + const parameter = createNode(SyntaxKind.Parameter) as ParameterDeclaration; + if (token() === SyntaxKind.ThisKeyword || token() === SyntaxKind.NewKeyword) { + parameter.name = parseIdentifierName(); + parseExpected(SyntaxKind.ColonToken); + } + parameter.type = parseType(); + return finishNode(parameter); + } + + function parseJSDocNodeWithType(kind: SyntaxKind.JSDocVariadicType | SyntaxKind.JSDocNonNullableType): TypeNode { + const result = createNode(kind) as JSDocVariadicType | JSDocNonNullableType; + nextToken(); + result.type = parseType(); + return finishNode(result); + } + function parseTypeQuery(): TypeQueryNode { const node = createNode(SyntaxKind.TypeQuery); parseExpected(SyntaxKind.TypeOfKeyword); @@ -2171,7 +2199,11 @@ namespace ts { } function isStartOfParameter(): boolean { - return token() === SyntaxKind.DotDotDotToken || isIdentifierOrPattern() || isModifierKind(token()) || token() === SyntaxKind.AtToken || token() === SyntaxKind.ThisKeyword; + return token() === SyntaxKind.DotDotDotToken || + isIdentifierOrPattern() || + isModifierKind(token()) || + token() === SyntaxKind.AtToken || token() === SyntaxKind.ThisKeyword || token() === SyntaxKind.NewKeyword || + token() === SyntaxKind.StringLiteral || token() === SyntaxKind.NumericLiteral; } function parseParameter(): ParameterDeclaration { @@ -2229,7 +2261,9 @@ namespace ts { returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, flags: SignatureFlags, signature: SignatureDeclaration): void { - signature.typeParameters = parseTypeParameters(); + if (!(flags & SignatureFlags.JSDoc)) { + signature.typeParameters = parseTypeParameters(); + } signature.parameters = parseParameterList(flags); const returnTokenRequired = returnToken === SyntaxKind.EqualsGreaterThanToken; @@ -2273,7 +2307,7 @@ namespace ts { setYieldContext(!!(flags & SignatureFlags.Yield)); setAwaitContext(!!(flags & SignatureFlags.Await)); - const result = parseDelimitedList(ParsingContext.Parameters, parseParameter); + const result = parseDelimitedList(ParsingContext.Parameters, flags & SignatureFlags.JSDoc ? parseJSDocParameter : parseParameter); setYieldContext(savedYieldContext); setAwaitContext(savedAwaitContext); @@ -2574,8 +2608,17 @@ namespace ts { case SyntaxKind.NeverKeyword: case SyntaxKind.ObjectKeyword: // If these are followed by a dot, then parse these out as a dotted type reference instead. - const node = tryParse(parseKeywordAndNoDot); - return node || parseTypeReference(); + return tryParse(parseKeywordAndNoDot) || parseTypeReference(); + case SyntaxKind.AsteriskToken: + return parseJSDocAllType(); + case SyntaxKind.QuestionToken: + return parseJSDocUnknownOrNullableType(); + case SyntaxKind.FunctionKeyword: + return parseJSDocFunctionType(); + case SyntaxKind.DotDotDotToken: + return parseJSDocNodeWithType(SyntaxKind.JSDocVariadicType); + case SyntaxKind.ExclamationToken: + return parseJSDocNodeWithType(SyntaxKind.JSDocNonNullableType); case SyntaxKind.StringLiteral: case SyntaxKind.NumericLiteral: case SyntaxKind.TrueKeyword: @@ -2649,8 +2692,31 @@ namespace ts { return token() === SyntaxKind.CloseParenToken || isStartOfParameter() || isStartOfType(); } + function parseJSDocPostfixTypeOrHigher(): TypeNode { + const type = parseNonArrayType(); + const kind = getKind(token()); + if (!kind) return type; + nextToken(); + + const postfix = createNode(kind, type.pos) as JSDocOptionalType | JSDocNonNullableType | JSDocNullableType; + postfix.type = type; + return finishNode(postfix); + + function getKind(tokenKind: SyntaxKind): SyntaxKind | undefined { + switch (tokenKind) { + case SyntaxKind.EqualsToken: + // only parse postfix = inside jsdoc, because it's ambiguous elsewhere + return contextFlags & NodeFlags.JSDoc ? SyntaxKind.JSDocOptionalType : undefined; + case SyntaxKind.ExclamationToken: + return SyntaxKind.JSDocNonNullableType; + case SyntaxKind.QuestionToken: + return SyntaxKind.JSDocNullableType; + } + } + } + function parseArrayTypeOrHigher(): TypeNode { - let type = parseNonArrayType(); + let type = parseJSDocPostfixTypeOrHigher(); while (!scanner.hasPrecedingLineBreak() && parseOptional(SyntaxKind.OpenBracketToken)) { if (isStartOfType()) { const node = createNode(SyntaxKind.IndexedAccessType, type.pos); @@ -6015,10 +6081,6 @@ namespace ts { TupleElementTypes, // Element types in tuple element type list HeritageClauses, // Heritage clauses for a class or interface declaration. ImportOrExportSpecifiers, // Named import clause's import specifier list - JSDocFunctionParameters, - JSDocTypeArguments, - JSDocRecordMembers, - JSDocTupleTypes, Count // Number of parsing contexts } @@ -6029,24 +6091,6 @@ namespace ts { } export namespace JSDocParser { - export function isJSDocType() { - switch (token()) { - case SyntaxKind.AsteriskToken: - case SyntaxKind.QuestionToken: - case SyntaxKind.OpenParenToken: - case SyntaxKind.OpenBracketToken: - case SyntaxKind.ExclamationToken: - case SyntaxKind.OpenBraceToken: - case SyntaxKind.FunctionKeyword: - case SyntaxKind.DotDotDotToken: - case SyntaxKind.NewKeyword: - case SyntaxKind.ThisKeyword: - return true; - } - - return tokenIsIdentifierOrKeyword(token()); - } - export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number) { initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS); @@ -6065,308 +6109,13 @@ namespace ts { const result = createNode(SyntaxKind.JSDocTypeExpression, scanner.getTokenPos()); parseExpected(SyntaxKind.OpenBraceToken); - result.type = parseJSDocTopLevelType(); + result.type = doInsideOfContext(NodeFlags.JSDoc, parseType); parseExpected(SyntaxKind.CloseBraceToken); fixupParentReferences(result); return finishNode(result); } - function parseJSDocTopLevelType(): JSDocType { - let type = parseJSDocType(); - if (token() === SyntaxKind.BarToken) { - const unionType = createNode(SyntaxKind.JSDocUnionType, type.pos); - unionType.types = parseJSDocTypeList(type); - type = finishNode(unionType); - } - - if (token() === SyntaxKind.EqualsToken) { - const optionalType = createNode(SyntaxKind.JSDocOptionalType, type.pos); - nextToken(); - optionalType.type = type; - type = finishNode(optionalType); - } - - return type; - } - - function parseJSDocType(): JSDocType { - let type = parseBasicTypeExpression(); - - while (true) { - if (token() === SyntaxKind.OpenBracketToken) { - const arrayType = createNode(SyntaxKind.JSDocArrayType, type.pos); - arrayType.elementType = type; - - nextToken(); - parseExpected(SyntaxKind.CloseBracketToken); - - type = finishNode(arrayType); - } - else if (token() === SyntaxKind.QuestionToken) { - const nullableType = createNode(SyntaxKind.JSDocNullableType, type.pos); - nullableType.type = type; - - nextToken(); - type = finishNode(nullableType); - } - else if (token() === SyntaxKind.ExclamationToken) { - const nonNullableType = createNode(SyntaxKind.JSDocNonNullableType, type.pos); - nonNullableType.type = type; - - nextToken(); - type = finishNode(nonNullableType); - } - else { - break; - } - } - - return type; - } - - function parseBasicTypeExpression(): JSDocType { - switch (token()) { - case SyntaxKind.AsteriskToken: - return parseJSDocAllType(); - case SyntaxKind.QuestionToken: - return parseJSDocUnknownOrNullableType(); - case SyntaxKind.OpenParenToken: - return parseJSDocUnionType(); - case SyntaxKind.OpenBracketToken: - return parseJSDocTupleType(); - case SyntaxKind.ExclamationToken: - return parseJSDocNonNullableType(); - case SyntaxKind.OpenBraceToken: - return parseJSDocRecordType(); - case SyntaxKind.FunctionKeyword: - if (lookAhead(nextTokenIsOpenParen)) { - return parseJSDocFunctionType(); - } - break; - case SyntaxKind.DotDotDotToken: - return parseJSDocVariadicType(); - case SyntaxKind.NewKeyword: - return parseJSDocConstructorType(); - case SyntaxKind.ThisKeyword: - return parseJSDocThisType(); - case SyntaxKind.AnyKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.NullKeyword: - case SyntaxKind.UndefinedKeyword: - case SyntaxKind.NeverKeyword: - return parseTokenNode(); - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - return parseJSDocLiteralType(); - } - - return parseJSDocTypeReference(); - } - - function parseJSDocThisType(): JSDocThisType { - const result = createNode(SyntaxKind.JSDocThisType); - nextToken(); - parseExpected(SyntaxKind.ColonToken); - result.type = parseJSDocType(); - return finishNode(result); - } - - function parseJSDocConstructorType(): JSDocConstructorType { - const result = createNode(SyntaxKind.JSDocConstructorType); - nextToken(); - parseExpected(SyntaxKind.ColonToken); - result.type = parseJSDocType(); - return finishNode(result); - } - - function parseJSDocVariadicType(): JSDocVariadicType { - const result = createNode(SyntaxKind.JSDocVariadicType); - nextToken(); - result.type = parseJSDocType(); - return finishNode(result); - } - - function parseJSDocFunctionType(): JSDocFunctionType { - const result = createNode(SyntaxKind.JSDocFunctionType); - nextToken(); - - parseExpected(SyntaxKind.OpenParenToken); - result.parameters = parseDelimitedList(ParsingContext.JSDocFunctionParameters, parseJSDocParameter); - checkForTrailingComma(result.parameters); - parseExpected(SyntaxKind.CloseParenToken); - - if (token() === SyntaxKind.ColonToken) { - nextToken(); - result.type = parseJSDocType(); - } - - return finishNode(result); - } - - function parseJSDocParameter(): ParameterDeclaration { - const parameter = createNode(SyntaxKind.Parameter); - parameter.type = parseJSDocType(); - if (parseOptional(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(); - - if (token() === SyntaxKind.LessThanToken) { - result.typeArguments = parseTypeArguments(); - } - else { - while (parseOptional(SyntaxKind.DotToken)) { - if (token() === SyntaxKind.LessThanToken) { - result.typeArguments = parseTypeArguments(); - break; - } - else { - result.name = parseQualifiedName(result.name); - } - } - } - - - return finishNode(result); - } - - function parseTypeArguments() { - // Move past the < - nextToken(); - const typeArguments = parseDelimitedList(ParsingContext.JSDocTypeArguments, parseJSDocType); - checkForTrailingComma(typeArguments); - checkForEmptyTypeArgumentList(typeArguments); - parseExpected(SyntaxKind.GreaterThanToken); - - return typeArguments; - } - - function checkForEmptyTypeArgumentList(typeArguments: NodeArray) { - if (parseDiagnostics.length === 0 && typeArguments && typeArguments.length === 0) { - const start = typeArguments.pos - "<".length; - const end = skipTrivia(sourceText, typeArguments.end) + ">".length; - return parseErrorAtPosition(start, end - start, Diagnostics.Type_argument_list_cannot_be_empty); - } - } - - function parseQualifiedName(left: EntityName): QualifiedName { - const result = createNode(SyntaxKind.QualifiedName, left.pos); - result.left = left; - result.right = parseIdentifierName(); - - return finishNode(result); - } - - function parseJSDocRecordType(): JSDocRecordType { - const result = createNode(SyntaxKind.JSDocRecordType); - result.literal = parseTypeLiteral(); - return finishNode(result); - } - - function parseJSDocNonNullableType(): JSDocNonNullableType { - const result = createNode(SyntaxKind.JSDocNonNullableType); - nextToken(); - result.type = parseJSDocType(); - return finishNode(result); - } - - function parseJSDocTupleType(): JSDocTupleType { - const result = createNode(SyntaxKind.JSDocTupleType); - nextToken(); - result.types = parseDelimitedList(ParsingContext.JSDocTupleTypes, parseJSDocType); - checkForTrailingComma(result.types); - parseExpected(SyntaxKind.CloseBracketToken); - - return finishNode(result); - } - - function checkForTrailingComma(list: NodeArray) { - if (parseDiagnostics.length === 0 && list.hasTrailingComma) { - const start = list.end - ",".length; - parseErrorAtPosition(start, ",".length, Diagnostics.Trailing_comma_not_allowed); - } - } - - function parseJSDocUnionType(): JSDocUnionType { - const result = createNode(SyntaxKind.JSDocUnionType); - nextToken(); - result.types = parseJSDocTypeList(parseJSDocType()); - - parseExpected(SyntaxKind.CloseParenToken); - - return finishNode(result); - } - - function parseJSDocTypeList(firstType: JSDocType) { - Debug.assert(!!firstType); - - const types = createNodeArray([firstType], firstType.pos); - - while (parseOptional(SyntaxKind.BarToken)) { - types.push(parseJSDocType()); - } - - types.end = scanner.getStartPos(); - return types; - } - - function parseJSDocAllType(): JSDocAllType { - const result = createNode(SyntaxKind.JSDocAllType); - nextToken(); - return finishNode(result); - } - - function parseJSDocLiteralType(): JSDocLiteralType { - const result = createNode(SyntaxKind.JSDocLiteralType); - result.literal = parseLiteralTypeNode(); - return finishNode(result); - } - - function parseJSDocUnknownOrNullableType(): JSDocUnknownType | JSDocNullableType { - const pos = scanner.getStartPos(); - // skip the ? - nextToken(); - - // Need to lookahead to decide if this is a nullable or unknown type. - - // Here are cases where we'll pick the unknown type: - // - // Foo(?, - // { a: ? } - // Foo(?) - // Foo - // Foo(?= - // (?| - if (token() === SyntaxKind.CommaToken || - token() === SyntaxKind.CloseBraceToken || - token() === SyntaxKind.CloseParenToken || - token() === SyntaxKind.GreaterThanToken || - token() === SyntaxKind.EqualsToken || - token() === SyntaxKind.BarToken) { - - const result = createNode(SyntaxKind.JSDocUnknownType, pos); - return finishNode(result); - } - else { - const result = createNode(SyntaxKind.JSDocNullableType, pos); - result.type = parseJSDocType(); - return finishNode(result); - } - } - export function parseIsolatedJSDocComment(content: string, start: number, length: number) { initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); sourceFile = { languageVariant: LanguageVariant.Standard, text: content }; @@ -6820,14 +6569,8 @@ namespace ts { skipWhitespace(); if (typeExpression) { - if (typeExpression.type.kind === SyntaxKind.JSDocTypeReference) { - const jsDocTypeReference = typeExpression.type; - if (jsDocTypeReference.name.kind === SyntaxKind.Identifier) { - const name = jsDocTypeReference.name; - if (name.text === "Object" || name.text === "object") { - typedefTag.jsDocTypeLiteral = scanChildTags(); - } - } + if (isObjectTypeReference(typeExpression.type)) { + typedefTag.jsDocTypeLiteral = scanChildTags(); } if (!typedefTag.jsDocTypeLiteral) { typedefTag.jsDocTypeLiteral = typeExpression.type; @@ -6839,6 +6582,11 @@ namespace ts { return finishNode(typedefTag); + function isObjectTypeReference(node: TypeNode) { + return node.kind === SyntaxKind.ObjectKeyword || + isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && node.typeName.text === "Object"; + } + function scanChildTags(): JSDocTypeLiteral { const jsDocTypeLiteral = createNode(SyntaxKind.JSDocTypeLiteral, scanner.getStartPos()); let resumePos = scanner.getStartPos(); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 153e4506ea9..3d63edddac1 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -332,6 +332,7 @@ namespace ts { const categoryColor = getCategoryFormat(diagnostic.category); const category = DiagnosticCategory[diagnostic.category].toLowerCase(); output += `${ formatAndReset(category, categoryColor) } TS${ diagnostic.code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, sys.newLine) }`; + output += sys.newLine; } return output; } diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 3e3ff90c00c..62ce272e96c 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -23,7 +23,7 @@ namespace ts { newLine: string; useCaseSensitiveFileNames: boolean; write(s: string): void; - readFile(path: string, encoding?: string): string; + readFile(path: string, encoding?: string): string | undefined; getFileSize?(path: string): number; writeFile(path: string, data: string, writeByteOrderMark?: boolean): void; /** @@ -97,7 +97,7 @@ namespace ts { directoryExists(path: string): boolean; createDirectory(path: string): void; resolvePath(path: string): string; - readFile(path: string): string; + readFile(path: string): string | undefined; writeFile(path: string, contents: string): void; getDirectories(path: string): string[]; readDirectory(path: string, extensions?: ReadonlyArray, basePaths?: ReadonlyArray, excludeEx?: string, includeFileEx?: string, includeDirEx?: string): string[]; @@ -204,7 +204,7 @@ namespace ts { const platform: string = _os.platform(); const useCaseSensitiveFileNames = isFileSystemCaseSensitive(); - function readFile(fileName: string, _encoding?: string): string { + function readFile(fileName: string, _encoding?: string): string | undefined { if (!fileExists(fileName)) { return undefined; } diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 6e0aefd99a0..8cc2e5c5ef6 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -61,7 +61,7 @@ namespace ts { } function reportDiagnosticWithColorAndContext(diagnostic: Diagnostic, host: FormatDiagnosticsHost): void { - sys.write(ts.formatDiagnosticsWithColorAndContext([diagnostic], host) + sys.newLine + sys.newLine); + sys.write(ts.formatDiagnosticsWithColorAndContext([diagnostic], host) + sys.newLine); } function reportWatchDiagnostic(diagnostic: Diagnostic) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c26fa5603ea..c507d9ee043 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -347,19 +347,11 @@ namespace ts { JSDocAllType, // The ? type JSDocUnknownType, - JSDocArrayType, - JSDocUnionType, - JSDocTupleType, JSDocNullableType, JSDocNonNullableType, - JSDocRecordType, - JSDocRecordMember, - JSDocTypeReference, JSDocOptionalType, JSDocFunctionType, JSDocVariadicType, - JSDocConstructorType, - JSDocThisType, JSDocComment, JSDocTag, JSDocAugmentsTag, @@ -371,7 +363,6 @@ namespace ts { JSDocTypedefTag, JSDocPropertyTag, JSDocTypeLiteral, - JSDocLiteralType, // Synthesized list SyntaxList, @@ -413,9 +404,9 @@ namespace ts { LastBinaryOperator = CaretEqualsToken, FirstNode = QualifiedName, FirstJSDocNode = JSDocTypeExpression, - LastJSDocNode = JSDocLiteralType, + LastJSDocNode = JSDocTypeLiteral, FirstJSDocTagNode = JSDocTag, - LastJSDocTagNode = JSDocLiteralType + LastJSDocTagNode = JSDocTypeLiteral } export const enum NodeFlags { @@ -450,6 +441,7 @@ namespace ts { // we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used. /* @internal */ PossiblyContainsDynamicImport = 1 << 19, + JSDoc = 1 << 20, // If node was parsed inside jsdoc BlockScoped = Let | Const, @@ -584,6 +576,7 @@ namespace ts { /*@internal*/ autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name. isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace /*@internal*/ typeArguments?: NodeArray; // Only defined on synthesized nodes. Though not syntactically valid, used in emitting diagnostics. + /*@internal*/ jsdocDotPos?: number; // Identifier occurs in JSDoc-style generic: Id. } // Transient identifier node (marked by id === -1) @@ -603,6 +596,7 @@ namespace ts { kind: SyntaxKind.QualifiedName; left: EntityName; right: Identifier; + /*@internal*/ jsdocDotPos?: number; // QualifiedName occurs in JSDoc-style generic: Id1.Id2. } export type EntityName = Identifier | QualifiedName; @@ -694,7 +688,7 @@ namespace ts { initializer?: Expression; // Optional initializer } - export interface TSPropertySignature extends TypeElement { + export interface PropertySignature extends TypeElement { kind: SyntaxKind.PropertySignature; name: PropertyName; // Declared property name questionToken?: QuestionToken; // Present on optional property @@ -702,16 +696,6 @@ namespace ts { initializer?: Expression; // Optional initializer } - export interface JSDocPropertySignature extends TypeElement { - kind: SyntaxKind.JSDocRecordMember; - name: PropertyName; // Declared property name - questionToken?: QuestionToken; // Present on optional property - type?: TypeNode; // Optional type annotation - initializer?: Expression; // Optional initializer - } - - export type PropertySignature = TSPropertySignature | JSDocPropertySignature; - export interface PropertyDeclaration extends ClassElement { kind: SyntaxKind.PropertyDeclaration; questionToken?: QuestionToken; // Present for use with reporting a grammar error @@ -921,7 +905,7 @@ namespace ts { kind: SyntaxKind.ConstructorType; } - export type TypeReferenceType = TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference; + export type TypeReferenceType = TypeReferenceNode | ExpressionWithTypeArguments; export interface TypeReferenceNode extends TypeNode { kind: SyntaxKind.TypeReference; @@ -2042,7 +2026,7 @@ namespace ts { // represents a top level: { type } expression in a JSDoc comment. export interface JSDocTypeExpression extends Node { kind: SyntaxKind.JSDocTypeExpression; - type: JSDocType; + type: TypeNode; } export interface JSDocType extends TypeNode { @@ -2057,80 +2041,31 @@ namespace ts { kind: SyntaxKind.JSDocUnknownType; } - export interface JSDocArrayType extends JSDocType { - kind: SyntaxKind.JSDocArrayType; - elementType: JSDocType; - } - - export interface JSDocUnionType extends JSDocType { - kind: SyntaxKind.JSDocUnionType; - types: NodeArray; - } - - export interface JSDocTupleType extends JSDocType { - kind: SyntaxKind.JSDocTupleType; - types: NodeArray; - } - export interface JSDocNonNullableType extends JSDocType { kind: SyntaxKind.JSDocNonNullableType; - type: JSDocType; + type: TypeNode; } export interface JSDocNullableType extends JSDocType { kind: SyntaxKind.JSDocNullableType; - type: JSDocType; - } - - export interface JSDocRecordType extends JSDocType { - kind: SyntaxKind.JSDocRecordType; - literal: TypeLiteralNode; - } - - export interface JSDocTypeReference extends JSDocType { - kind: SyntaxKind.JSDocTypeReference; - name: EntityName; - typeArguments: NodeArray; + type: TypeNode; } export interface JSDocOptionalType extends JSDocType { kind: SyntaxKind.JSDocOptionalType; - type: JSDocType; + type: TypeNode; } export interface JSDocFunctionType extends JSDocType, SignatureDeclaration { kind: SyntaxKind.JSDocFunctionType; - parameters: NodeArray; - type: JSDocType; } export interface JSDocVariadicType extends JSDocType { kind: SyntaxKind.JSDocVariadicType; - type: JSDocType; + type: TypeNode; } - export interface JSDocConstructorType extends JSDocType { - kind: SyntaxKind.JSDocConstructorType; - type: JSDocType; - } - - 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; - - export interface JSDocRecordMember extends JSDocPropertySignature { - kind: SyntaxKind.JSDocRecordMember; - name: Identifier | StringLiteral | NumericLiteral; - type?: JSDocType; - } + export type JSDocTypeReferencingNode = JSDocVariadicType | JSDocOptionalType | JSDocNullableType | JSDocNonNullableType; export interface JSDoc extends Node { kind: SyntaxKind.JSDocComment; @@ -2414,7 +2349,7 @@ namespace ts { */ fileExists(path: string): boolean; - readFile(path: string): string; + readFile(path: string): string | undefined; } export interface WriteFileCallback { @@ -3932,7 +3867,7 @@ namespace ts { fileExists(fileName: string): boolean; // readFile function is used to read arbitrary text files on disk, i.e. when resolution procedure needs the content of 'package.json' // to determine location of bundled typings for node module - readFile(fileName: string): string; + readFile(fileName: string): string | undefined; trace?(s: string): void; directoryExists?(directoryName: string): boolean; realpath?(path: string): string; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index c8751f497a6..b7fabdda381 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1082,7 +1082,6 @@ namespace ts { export function getEntityNameFromTypeNode(node: TypeNode): EntityNameOrEntityNameExpression { switch (node.kind) { case SyntaxKind.TypeReference: - case SyntaxKind.JSDocTypeReference: return (node).typeName; case SyntaxKind.ExpressionWithTypeArguments: @@ -1293,6 +1292,10 @@ namespace ts { return node && !!(node.flags & NodeFlags.JavaScriptFile); } + export function isInJSDoc(node: Node): boolean { + return node && !!(node.flags & NodeFlags.JSDoc); + } + /** * Returns true if the node is a CallExpression to the identifier 'require' with * exactly one argument (of the form 'require("name")'). @@ -1448,8 +1451,9 @@ namespace ts { export function isJSDocConstructSignature(node: Node) { return node.kind === SyntaxKind.JSDocFunctionType && - (node).parameters.length > 0 && - (node).parameters[0].type.kind === SyntaxKind.JSDocConstructorType; + (node as JSDocFunctionType).parameters.length > 0 && + (node as JSDocFunctionType).parameters[0].name && + ((node as JSDocFunctionType).parameters[0].name as Identifier).text === "new"; } export function hasJSDocParameterTags(node: FunctionLikeDeclaration | SignatureDeclaration): boolean { @@ -1582,7 +1586,7 @@ namespace ts { return find(typeParameters, p => p.name.text === name); } - export function getJSDocType(node: Node): JSDocType { + export function getJSDocType(node: Node): TypeNode { let tag: JSDocTypeTag | JSDocParameterTag = getFirstJSDocTag(node, SyntaxKind.JSDocTypeTag) as JSDocTypeTag; if (!tag && node.kind === SyntaxKind.Parameter) { const paramTags = getJSDocParameterTags(node as ParameterDeclaration); @@ -1606,7 +1610,7 @@ namespace ts { return getFirstJSDocTag(node, SyntaxKind.JSDocReturnTag) as JSDocReturnTag; } - export function getJSDocReturnType(node: Node): JSDocType { + export function getJSDocReturnType(node: Node): TypeNode { const returnTag = getJSDocReturnTag(node); return returnTag && returnTag.typeExpression && returnTag.typeExpression.type; } @@ -3921,7 +3925,7 @@ namespace ts { */ export function validateLocaleAndSetLanguage( locale: string, - sys: { getExecutingFilePath(): string, resolvePath(path: string): string, fileExists(fileName: string): boolean, readFile(fileName: string): string }, + sys: { getExecutingFilePath(): string, resolvePath(path: string): string, fileExists(fileName: string): boolean, readFile(fileName: string): string | undefined }, errors?: Diagnostic[]) { const matchResult = /^([a-z]+)([_\-]([a-z]+))?$/.exec(locale.toLowerCase()); @@ -4664,18 +4668,6 @@ namespace ts { return node.kind === SyntaxKind.JSDocUnknownType; } - export function isJSDocArrayType(node: Node): node is JSDocArrayType { - return node.kind === SyntaxKind.JSDocArrayType; - } - - export function isJSDocUnionType(node: Node): node is JSDocUnionType { - return node.kind === SyntaxKind.JSDocUnionType; - } - - export function isJSDocTupleType(node: Node): node is JSDocTupleType { - return node.kind === SyntaxKind.JSDocTupleType; - } - export function isJSDocNullableType(node: Node): node is JSDocNullableType { return node.kind === SyntaxKind.JSDocNullableType; } @@ -4684,18 +4676,6 @@ namespace ts { return node.kind === SyntaxKind.JSDocNonNullableType; } - export function isJSDocRecordType(node: Node): node is JSDocRecordType { - return node.kind === SyntaxKind.JSDocRecordType; - } - - export function isJSDocRecordMember(node: Node): node is JSDocRecordMember { - return node.kind === SyntaxKind.JSDocRecordMember; - } - - export function isJSDocTypeReference(node: Node): node is JSDocTypeReference { - return node.kind === SyntaxKind.JSDocTypeReference; - } - export function isJSDocOptionalType(node: Node): node is JSDocOptionalType { return node.kind === SyntaxKind.JSDocOptionalType; } @@ -4708,14 +4688,6 @@ namespace ts { return node.kind === SyntaxKind.JSDocVariadicType; } - export function isJSDocConstructorType(node: Node): node is JSDocConstructorType { - return node.kind === SyntaxKind.JSDocConstructorType; - } - - export function isJSDocThisType(node: Node): node is JSDocThisType { - return node.kind === SyntaxKind.JSDocThisType; - } - export function isJSDoc(node: Node): node is JSDoc { return node.kind === SyntaxKind.JSDocComment; } @@ -4751,10 +4723,6 @@ namespace ts { export function isJSDocTypeLiteral(node: Node): node is JSDocTypeLiteral { return node.kind === SyntaxKind.JSDocTypeLiteral; } - - export function isJSDocLiteralType(node: Node): node is JSDocLiteralType { - return node.kind === SyntaxKind.JSDocLiteralType; - } } // Node tests @@ -4905,6 +4873,7 @@ namespace ts { case SyntaxKind.ConstructSignature: case SyntaxKind.IndexSignature: case SyntaxKind.FunctionType: + case SyntaxKind.JSDocFunctionType: case SyntaxKind.ConstructorType: return true; } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index d5218695f09..55a8f3ebb4d 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -479,7 +479,7 @@ namespace Harness { getCurrentDirectory(): string; useCaseSensitiveFileNames(): boolean; resolvePath(path: string): string; - readFile(path: string): string; + readFile(path: string): string | undefined; writeFile(path: string, contents: string): void; directoryName(path: string): string; getDirectories(path: string): string[]; @@ -719,7 +719,7 @@ namespace Harness { } }); - export function readFile(file: string) { + export function readFile(file: string): string | undefined { const response = Http.getFileFromServerSync(serverRoot + file); if (response.status === 200) { return response.responseText; @@ -976,7 +976,7 @@ namespace Harness { useCaseSensitiveFileNames: () => useCaseSensitiveFileNames, getNewLine: () => newLine, fileExists: fileName => fileMap.has(toPath(fileName)), - readFile: (fileName: string): string => { + readFile(fileName: string): string | undefined { const file = fileMap.get(toPath(fileName)); if (ts.endsWith(fileName, "json")) { // strip comments diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 339138ba30f..156a9e08dce 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -215,7 +215,7 @@ namespace Harness.LanguageService { depth, (p) => this.virtualFileSystem.getAccessibleFileSystemEntries(p)); } - readFile(path: string): string { + readFile(path: string): string | undefined { const snapshot = this.getScriptSnapshot(path); return snapshot.getText(0, snapshot.getLength()); } @@ -619,7 +619,7 @@ namespace Harness.LanguageService { this.writeMessage(message); } - readFile(fileName: string): string { + readFile(fileName: string): string | undefined { if (fileName.indexOf(Harness.Compiler.defaultLibFileName) >= 0) { fileName = Harness.Compiler.defaultLibFileName; } diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index 46c2b42f6a0..7344c432b97 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -289,7 +289,7 @@ class ProjectRunner extends RunnerBase { return Harness.IO.fileExists(getFileNameInTheProjectTest(fileName)); } - function readFile(fileName: string): string { + function readFile(fileName: string): string | undefined { return Harness.IO.readFile(getFileNameInTheProjectTest(fileName)); } diff --git a/src/harness/unittests/jsDocParsing.ts b/src/harness/unittests/jsDocParsing.ts index 309e49bd6b8..0e6221567a2 100644 --- a/src/harness/unittests/jsDocParsing.ts +++ b/src/harness/unittests/jsDocParsing.ts @@ -44,8 +44,8 @@ namespace ts { parsesCorrectly("functionType1", "{function()}"); parsesCorrectly("functionType2", "{function(string, boolean)}"); parsesCorrectly("functionReturnType1", "{function(string, boolean)}"); - parsesCorrectly("thisType1", "{this:a.b}"); - parsesCorrectly("newType1", "{new:a.b}"); + parsesCorrectly("thisType1", "{function(this:a.b)}"); + parsesCorrectly("newType1", "{function(new:a.b)}"); parsesCorrectly("variadicType", "{...number}"); parsesCorrectly("optionalType", "{number=}"); parsesCorrectly("optionalNullable", "{?=}"); @@ -54,7 +54,7 @@ namespace ts { parsesCorrectly("typeReference3", "{a.function}"); parsesCorrectly("arrayType1", "{a[]}"); parsesCorrectly("arrayType2", "{a[][]}"); - parsesCorrectly("arrayType3", "{a[][]=}"); + parsesCorrectly("arrayType3", "{(a[][])=}"); parsesCorrectly("keyword1", "{var}"); parsesCorrectly("keyword2", "{null}"); parsesCorrectly("keyword3", "{undefined}"); @@ -62,6 +62,12 @@ namespace ts { parsesCorrectly("tupleType1", "{[number]}"); parsesCorrectly("tupleType2", "{[number,string]}"); parsesCorrectly("tupleType3", "{[number,string,boolean]}"); + parsesCorrectly("tupleTypeWithTrailingComma", "{[number,]}"); + parsesCorrectly("typeOfType", "{typeof M}"); + parsesCorrectly("tsConstructorType", "{new () => string}"); + parsesCorrectly("tsFunctionType", "{() => string}"); + parsesCorrectly("typeArgumentsNotFollowingDot", "{a<>}"); + parsesCorrectly("functionTypeWithTrailingComma", "{function(a,)}"); }); describe("parsesIncorrectly", () => { @@ -69,21 +75,13 @@ namespace ts { parsesIncorrectly("unionTypeWithTrailingBar", "{(a|)}"); parsesIncorrectly("unionTypeWithoutTypes", "{()}"); parsesIncorrectly("nullableTypeWithoutType", "{!}"); - parsesIncorrectly("functionTypeWithTrailingComma", "{function(a,)}"); parsesIncorrectly("thisWithoutType", "{this:}"); parsesIncorrectly("newWithoutType", "{new:}"); parsesIncorrectly("variadicWithoutType", "{...}"); parsesIncorrectly("optionalWithoutType", "{=}"); parsesIncorrectly("allWithType", "{*foo}"); - parsesIncorrectly("typeArgumentsNotFollowingDot", "{a<>}"); - parsesIncorrectly("emptyTypeArguments", "{a.<>}"); - parsesIncorrectly("typeArgumentsWithTrailingComma", "{a.}"); - parsesIncorrectly("tsFunctionType", "{() => string}"); - parsesIncorrectly("tsConstructoType", "{new () => string}"); - parsesIncorrectly("typeOfType", "{typeof M}"); parsesIncorrectly("namedParameter", "{function(a: number)}"); parsesIncorrectly("tupleTypeWithComma", "{[,]}"); - parsesIncorrectly("tupleTypeWithTrailingComma", "{[number,]}"); parsesIncorrectly("tupleTypeWithLeadingComma", "{[,number]}"); }); }); diff --git a/src/harness/unittests/moduleResolution.ts b/src/harness/unittests/moduleResolution.ts index 3923e4b2755..ffae1b5f4a9 100644 --- a/src/harness/unittests/moduleResolution.ts +++ b/src/harness/unittests/moduleResolution.ts @@ -56,7 +56,7 @@ namespace ts { else { return { readFile, fileExists: path => map.has(path) }; } - function readFile(path: string): string { + function readFile(path: string): string | undefined { const file = map.get(path); return file && file.content; } diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index c6ec2042fae..862ebee4b03 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -9,7 +9,7 @@ namespace ts.server { newLine: "\n", useCaseSensitiveFileNames: true, write(s): void { lastWrittenToHost = s; }, - readFile(): string { return void 0; }, + readFile: () => undefined, writeFile: noop, resolvePath(): string { return void 0; }, fileExists: () => false, diff --git a/src/harness/virtualFileSystem.ts b/src/harness/virtualFileSystem.ts index da7784770df..8accd6f621e 100644 --- a/src/harness/virtualFileSystem.ts +++ b/src/harness/virtualFileSystem.ts @@ -209,7 +209,7 @@ namespace Utils { } } - readFile(path: string): string { + readFile(path: string): string | undefined { const value = this.traversePath(path); if (value && value.isFile()) { return value.content.content; diff --git a/src/server/builder.ts b/src/server/builder.ts index 8fd8fbf1e65..bc86780fbbe 100644 --- a/src/server/builder.ts +++ b/src/server/builder.ts @@ -203,57 +203,27 @@ namespace ts.server { } class ModuleBuilderFileInfo extends BuilderFileInfo { - references: ModuleBuilderFileInfo[] = []; - referencedBy: ModuleBuilderFileInfo[] = []; + references = createSortedArray(); + readonly referencedBy = createSortedArray(); scriptVersionForReferences: string; - static compareFileInfos(lf: ModuleBuilderFileInfo, rf: ModuleBuilderFileInfo): number { - const l = lf.scriptInfo.fileName; - const r = rf.scriptInfo.fileName; - return (l < r ? -1 : (l > r ? 1 : 0)); - } - - static addToReferenceList(array: ModuleBuilderFileInfo[], fileInfo: ModuleBuilderFileInfo) { - if (array.length === 0) { - array.push(fileInfo); - return; - } - - const insertIndex = binarySearch(array, fileInfo, ModuleBuilderFileInfo.compareFileInfos); - if (insertIndex < 0) { - array.splice(~insertIndex, 0, fileInfo); - } - } - - static removeFromReferenceList(array: ModuleBuilderFileInfo[], fileInfo: ModuleBuilderFileInfo) { - if (!array || array.length === 0) { - return; - } - - if (array[0] === fileInfo) { - array.splice(0, 1); - return; - } - - const removeIndex = binarySearch(array, fileInfo, ModuleBuilderFileInfo.compareFileInfos); - if (removeIndex >= 0) { - array.splice(removeIndex, 1); - } + static compareFileInfos(lf: ModuleBuilderFileInfo, rf: ModuleBuilderFileInfo): Comparison { + return compareStrings(lf.scriptInfo.fileName, rf.scriptInfo.fileName); } addReferencedBy(fileInfo: ModuleBuilderFileInfo): void { - ModuleBuilderFileInfo.addToReferenceList(this.referencedBy, fileInfo); + insertSorted(this.referencedBy, fileInfo, ModuleBuilderFileInfo.compareFileInfos); } removeReferencedBy(fileInfo: ModuleBuilderFileInfo): void { - ModuleBuilderFileInfo.removeFromReferenceList(this.referencedBy, fileInfo); + removeSorted(this.referencedBy, fileInfo, ModuleBuilderFileInfo.compareFileInfos); } removeFileReferences() { for (const reference of this.references) { reference.removeReferencedBy(this); } - this.references = []; + this.references = createSortedArray(); } } @@ -270,16 +240,13 @@ namespace ts.server { super.clear(); } - private getReferencedFileInfos(fileInfo: ModuleBuilderFileInfo): ModuleBuilderFileInfo[] { + private getReferencedFileInfos(fileInfo: ModuleBuilderFileInfo): SortedArray { if (!fileInfo.isExternalModuleOrHasOnlyAmbientExternalModules()) { - return []; + return createSortedArray(); } const referencedFilePaths = this.project.getReferencedFiles(fileInfo.scriptInfo.path); - if (referencedFilePaths.length > 0) { - return map(referencedFilePaths, f => this.getOrCreateFileInfo(f)).sort(ModuleBuilderFileInfo.compareFileInfos); - } - return []; + return toSortedArray(referencedFilePaths.map(f => this.getOrCreateFileInfo(f)), ModuleBuilderFileInfo.compareFileInfos); } protected ensureFileInfoIfInProject(_scriptInfo: ScriptInfo) { @@ -319,39 +286,15 @@ namespace ts.server { const newReferences = this.getReferencedFileInfos(fileInfo); const oldReferences = fileInfo.references; - - let oldIndex = 0; - let newIndex = 0; - while (oldIndex < oldReferences.length && newIndex < newReferences.length) { - const oldReference = oldReferences[oldIndex]; - const newReference = newReferences[newIndex]; - const compare = ModuleBuilderFileInfo.compareFileInfos(oldReference, newReference); - if (compare < 0) { + enumerateInsertsAndDeletes(newReferences, oldReferences, + /*inserted*/ newReference => newReference.addReferencedBy(fileInfo), + /*deleted*/ oldReference => { // New reference is greater then current reference. That means // the current reference doesn't exist anymore after parsing. So delete // references. oldReference.removeReferencedBy(fileInfo); - oldIndex++; - } - else if (compare > 0) { - // A new reference info. Add it. - newReference.addReferencedBy(fileInfo); - newIndex++; - } - else { - // Equal. Go to next - oldIndex++; - newIndex++; - } - } - // Clean old references - for (let i = oldIndex; i < oldReferences.length; i++) { - oldReferences[i].removeReferencedBy(fileInfo); - } - // Update new references - for (let i = newIndex; i < newReferences.length; i++) { - newReferences[i].addReferencedBy(fileInfo); - } + }, + /*compare*/ ModuleBuilderFileInfo.compareFileInfos); fileInfo.references = newReferences; fileInfo.scriptVersionForReferences = fileInfo.scriptInfo.getLatestVersion(); diff --git a/src/server/lsHost.ts b/src/server/lsHost.ts index 1be0f203206..fb1cd80b660 100644 --- a/src/server/lsHost.ts +++ b/src/server/lsHost.ts @@ -223,7 +223,7 @@ namespace ts.server { : undefined; const primaryResult = resolveModuleName(moduleName, containingFile, compilerOptions, host); // return result immediately only if it is .ts, .tsx or .d.ts - if (moduleHasNonRelativeName(moduleName) && !(primaryResult.resolvedModule && extensionIsTypeScript(primaryResult.resolvedModule.extension)) && globalCache !== undefined) { + if (!isExternalModuleNameRelative(moduleName) && !(primaryResult.resolvedModule && extensionIsTypeScript(primaryResult.resolvedModule.extension)) && globalCache !== undefined) { // otherwise try to load typings from @types // create different collection of failed lookup locations for second pass @@ -411,7 +411,7 @@ namespace ts.server { return !this.project.isWatchedMissingFile(path) && this.host.fileExists(file); } - readFile(fileName: string): string { + readFile(fileName: string): string | undefined { return this.host.readFile(fileName); } diff --git a/src/server/project.ts b/src/server/project.ts index d45f2e99be4..c75cadb642b 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -583,7 +583,7 @@ namespace ts.server { for (const sourceFile of this.program.getSourceFiles()) { this.extractUnresolvedImportsFromSourceFile(sourceFile, result); } - this.lastCachedUnresolvedImportsList = toSortedReadonlyArray(result); + this.lastCachedUnresolvedImportsList = toSortedArray(result); } unresolvedImports = this.lastCachedUnresolvedImportsList; @@ -823,7 +823,7 @@ namespace ts.server { // We need to use a set here since the code can contain the same import twice, // but that will only be one dependency. // To avoid invernal conversion, the key of the referencedFiles map must be of type Path - const referencedFiles = createMap(); + const referencedFiles = createMap(); if (sourceFile.imports && sourceFile.imports.length > 0) { const checker: TypeChecker = this.program.getTypeChecker(); for (const importName of sourceFile.imports) { @@ -1124,7 +1124,7 @@ namespace ts.server { } getExternalFiles(): SortedReadonlyArray { - return toSortedReadonlyArray(flatMap(this.plugins, plugin => { + return toSortedArray(flatMap(this.plugins, plugin => { if (typeof plugin.getExternalFiles !== "function") return; try { return plugin.getExternalFiles(this); diff --git a/src/server/types.ts b/src/server/types.ts index 72d6a7c6cfc..07b94fe827e 100644 --- a/src/server/types.ts +++ b/src/server/types.ts @@ -20,8 +20,12 @@ declare namespace ts.server { require?(initialPath: string, moduleName: string): RequireResult; } + export interface SortedArray extends Array { + " __sortedArrayBrand": any; + } + export interface SortedReadonlyArray extends ReadonlyArray { - " __sortedReadonlyArrayBrand": any; + " __sortedArrayBrand": any; } export interface TypingInstallerRequest { diff --git a/src/server/typingsCache.ts b/src/server/typingsCache.ts index a97b12ff7a8..3ef37685da2 100644 --- a/src/server/typingsCache.ts +++ b/src/server/typingsCache.ts @@ -110,7 +110,7 @@ namespace ts.server { this.perProjectCache.set(projectName, { compilerOptions, typeAcquisition, - typings: toSortedReadonlyArray(newTypings), + typings: toSortedArray(newTypings), unresolvedImports, poisoned: false }); diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index 730257d2ccc..b1fddfb4129 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -93,10 +93,10 @@ namespace ts.server.typingsInstaller { abstract readonly typesRegistry: Map; constructor( - readonly installTypingHost: InstallTypingHost, - readonly globalCachePath: string, - readonly safeListPath: Path, - readonly throttleLimit: number, + protected readonly installTypingHost: InstallTypingHost, + private readonly globalCachePath: string, + private readonly safeListPath: Path, + private readonly throttleLimit: number, protected readonly log = nullLog) { if (this.log.isEnabled()) { this.log.writeLine(`Global cache location '${globalCachePath}', safe file path '${safeListPath}'`); diff --git a/src/server/utilities.ts b/src/server/utilities.ts index ce49fcdb9bf..eec62606b9f 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -9,7 +9,7 @@ namespace ts.server { verbose } - export const emptyArray: ReadonlyArray = []; + export const emptyArray: SortedReadonlyArray = createSortedArray(); export interface Logger { close(): void; @@ -190,39 +190,45 @@ namespace ts.server { return `/dev/null/inferredProject${counter}*`; } - export function toSortedReadonlyArray(arr: string[]): SortedReadonlyArray { - arr.sort(); - return arr; + export function createSortedArray(): SortedArray { + return [] as SortedArray; } - export function enumerateInsertsAndDeletes(a: SortedReadonlyArray, b: SortedReadonlyArray, inserted: (item: T) => void, deleted: (item: T) => void, compare?: (a: T, b: T) => Comparison) { + export function toSortedArray(arr: string[]): SortedArray; + export function toSortedArray(arr: T[], comparer: Comparer): SortedArray; + export function toSortedArray(arr: T[], comparer?: Comparer): SortedArray { + arr.sort(comparer); + return arr as SortedArray; + } + + export function enumerateInsertsAndDeletes(newItems: SortedReadonlyArray, oldItems: SortedReadonlyArray, inserted: (newItem: T) => void, deleted: (oldItem: T) => void, compare?: Comparer) { compare = compare || compareValues; - let aIndex = 0; - let bIndex = 0; - const aLen = a.length; - const bLen = b.length; - while (aIndex < aLen && bIndex < bLen) { - const aItem = a[aIndex]; - const bItem = b[bIndex]; - const compareResult = compare(aItem, bItem); + let newIndex = 0; + let oldIndex = 0; + const newLen = newItems.length; + const oldLen = oldItems.length; + while (newIndex < newLen && oldIndex < oldLen) { + const newItem = newItems[newIndex]; + const oldItem = oldItems[oldIndex]; + const compareResult = compare(newItem, oldItem); if (compareResult === Comparison.LessThan) { - inserted(aItem); - aIndex++; + inserted(newItem); + newIndex++; } else if (compareResult === Comparison.GreaterThan) { - deleted(bItem); - bIndex++; + deleted(oldItem); + oldIndex++; } else { - aIndex++; - bIndex++; + newIndex++; + oldIndex++; } } - while (aIndex < aLen) { - inserted(a[aIndex++]); + while (newIndex < newLen) { + inserted(newItems[newIndex++]); } - while (bIndex < bLen) { - deleted(b[bIndex++]); + while (oldIndex < oldLen) { + deleted(oldItems[oldIndex++]); } } @@ -346,4 +352,32 @@ namespace ts.server { } } } + + export function insertSorted(array: SortedArray, insert: T, compare: Comparer): void { + if (array.length === 0) { + array.push(insert); + return; + } + + const insertIndex = binarySearch(array, insert, compare); + if (insertIndex < 0) { + array.splice(~insertIndex, 0, insert); + } + } + + export function removeSorted(array: SortedArray, remove: T, compare: Comparer): void { + if (!array || array.length === 0) { + return; + } + + if (array[0] === remove) { + array.splice(0, 1); + return; + } + + const removeIndex = binarySearch(array, remove, compare); + if (removeIndex >= 0) { + array.splice(removeIndex, 1); + } + } } diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index d30997aa076..2be20f35c16 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -565,7 +565,7 @@ namespace ts.codefix { function getRelativePath(path: string, directoryPath: string) { const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); - return moduleHasNonRelativeName(relativePath) ? "./" + relativePath : relativePath; + return !pathIsRelative(relativePath) ? "./" + relativePath : relativePath; } } diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index f17406b16f1..417c16909df 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -453,7 +453,7 @@ namespace ts.FindAllReferences { } } else { - const exportNode = getExportNode(parent); + const exportNode = getExportNode(parent, node); if (exportNode && hasModifier(exportNode, ModifierFlags.Export)) { if (isImportEqualsDeclaration(exportNode) && exportNode.moduleReference === node) { // We're at `Y` in `export import X = Y`. This is not the exported symbol, the left-hand-side is. So treat this as an import statement. @@ -558,10 +558,11 @@ namespace ts.FindAllReferences { // If a reference is a class expression, the exported node would be its parent. // If a reference is a variable declaration, the exported node would be the variable statement. - function getExportNode(parent: Node): Node | undefined { + function getExportNode(parent: Node, node: Node): Node | undefined { if (parent.kind === SyntaxKind.VariableDeclaration) { const p = parent as ts.VariableDeclaration; - return p.parent.kind === ts.SyntaxKind.CatchClause ? undefined : p.parent.parent.kind === SyntaxKind.VariableStatement ? p.parent.parent : undefined; + return p.name !== node ? undefined : + p.parent.kind === ts.SyntaxKind.CatchClause ? undefined : p.parent.parent.kind === SyntaxKind.VariableStatement ? p.parent.parent : undefined; } else { return parent; diff --git a/src/services/jsTyping.ts b/src/services/jsTyping.ts index f31276b6498..670633eb44b 100644 --- a/src/services/jsTyping.ts +++ b/src/services/jsTyping.ts @@ -9,10 +9,10 @@ namespace ts.JsTyping { export interface TypingResolutionHost { - directoryExists: (path: string) => boolean; - fileExists: (fileName: string) => boolean; - readFile: (path: string, encoding?: string) => string; - readDirectory: (rootDir: string, extensions: ReadonlyArray, excludes: ReadonlyArray, includes: ReadonlyArray, depth?: number) => string[]; + directoryExists(path: string): boolean; + fileExists(fileName: string): boolean; + readFile(path: string, encoding?: string): string | undefined; + readDirectory(rootDir: string, extensions: ReadonlyArray, excludes: ReadonlyArray, includes: ReadonlyArray, depth?: number): string[]; } interface PackageJson { diff --git a/src/services/refactors/convertFunctionToEs6Class.ts b/src/services/refactors/convertFunctionToEs6Class.ts index a570ef1f2b8..2fb67ea98e8 100644 --- a/src/services/refactors/convertFunctionToEs6Class.ts +++ b/src/services/refactors/convertFunctionToEs6Class.ts @@ -12,7 +12,11 @@ namespace ts.refactor { registerRefactor(convertFunctionToES6Class); - function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] { + function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined { + if (!isInJavaScriptFile(context.file)) { + return undefined; + } + const start = context.startPosition; const node = getTokenAtPosition(context.file, start, /*includeJsDocComment*/ false); const checker = context.program.getTypeChecker(); diff --git a/src/services/services.ts b/src/services/services.ts index 7cb70ed5a07..a444bd808d9 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1141,7 +1141,7 @@ namespace ts { !!hostCache.getEntryByPath(path) : (host.fileExists && host.fileExists(fileName)); }, - readFile: (fileName): string => { + readFile(fileName) { // stub missing host functionality const path = toPath(fileName, currentDirectory, getCanonicalFileName); if (hostCache.containsEntryByPath(path)) { diff --git a/src/services/shims.ts b/src/services/shims.ts index 2ee1853f18f..03965cb5d48 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -69,7 +69,7 @@ namespace ts { getTypeRootsVersion?(): number; readDirectory(rootDir: string, extension: string, basePaths?: string, excludeEx?: string, includeFileEx?: string, includeDirEx?: string, depth?: number): string; - readFile(path: string, encoding?: string): string; + readFile(path: string, encoding?: string): string | undefined; fileExists(path: string): boolean; getModuleResolutionsForFile?(fileName: string): string; @@ -95,7 +95,7 @@ namespace ts { /** * Read arbitary text files on disk, i.e. when resolution procedure needs the content of 'package.json' to determine location of bundled typings for node modules */ - readFile(fileName: string): string; + readFile(fileName: string): string | undefined; realpath?(path: string): string; trace(s: string): void; useCaseSensitiveFileNames?(): boolean; @@ -458,7 +458,7 @@ namespace ts { )); } - public readFile(path: string, encoding?: string): string { + public readFile(path: string, encoding?: string): string | undefined { return this.shimHost.readFile(path, encoding); } @@ -501,7 +501,7 @@ namespace ts { return this.shimHost.fileExists(fileName); } - public readFile(fileName: string): string { + public readFile(fileName: string): string | undefined { return this.shimHost.readFile(fileName); } @@ -1006,7 +1006,7 @@ namespace ts { class CoreServicesShimObject extends ShimBase implements CoreServicesShim { private logPerformance = false; - constructor(factory: ShimFactory, public logger: Logger, private host: CoreServicesShimHostAdapter) { + constructor(factory: ShimFactory, public readonly logger: Logger, private readonly host: CoreServicesShimHostAdapter) { super(factory); } diff --git a/src/services/types.ts b/src/services/types.ts index bfb8a80b769..19d2345d968 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -165,7 +165,7 @@ namespace ts { * Without these methods, only completions for ambient modules will be provided. */ readDirectory?(path: string, extensions?: ReadonlyArray, exclude?: ReadonlyArray, include?: ReadonlyArray, depth?: number): string[]; - readFile?(path: string, encoding?: string): string; + readFile?(path: string, encoding?: string): string | undefined; fileExists?(path: string): boolean; /* diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 7fcfffc3ee2..0e92884d502 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -176,7 +176,6 @@ namespace ts { switch (node.parent.kind) { case SyntaxKind.TypeReference: - case SyntaxKind.JSDocTypeReference: return true; case SyntaxKind.ExpressionWithTypeArguments: return !isExpressionWithTypeArgumentsInClassExtendsClause(node.parent); diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json index 13826b63d9c..370e139b512 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json @@ -54,10 +54,10 @@ "pos": 34, "end": 42, "type": { - "kind": "JSDocTypeReference", + "kind": "TypeReference", "pos": 35, "end": 41, - "name": { + "typeName": { "kind": "Identifier", "pos": 35, "end": 41, diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.allType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.allType.json index 68081a1b9e4..7fb632c7a35 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.allType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.allType.json @@ -1,5 +1,6 @@ { "kind": "JSDocAllType", "pos": 1, - "end": 2 + "end": 2, + "flags": "JSDoc" } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType1.json index cd9255d392c..b1e7fa13dc9 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType1.json @@ -1,15 +1,18 @@ { - "kind": "JSDocArrayType", + "kind": "ArrayType", "pos": 1, "end": 4, + "flags": "JSDoc", "elementType": { - "kind": "JSDocTypeReference", + "kind": "TypeReference", "pos": 1, "end": 2, - "name": { + "flags": "JSDoc", + "typeName": { "kind": "Identifier", "pos": 1, "end": 2, + "flags": "JSDoc", "text": "a" } } diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType2.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType2.json index 1fe6d184599..125c706510d 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType2.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType2.json @@ -1,19 +1,23 @@ { - "kind": "JSDocArrayType", + "kind": "ArrayType", "pos": 1, "end": 6, + "flags": "JSDoc", "elementType": { - "kind": "JSDocArrayType", + "kind": "ArrayType", "pos": 1, "end": 4, + "flags": "JSDoc", "elementType": { - "kind": "JSDocTypeReference", + "kind": "TypeReference", "pos": 1, "end": 2, - "name": { + "flags": "JSDoc", + "typeName": { "kind": "Identifier", "pos": 1, "end": 2, + "flags": "JSDoc", "text": "a" } } diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType3.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType3.json index 2fe27c67a1b..49ecaf53d4c 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType3.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType3.json @@ -1,24 +1,35 @@ { "kind": "JSDocOptionalType", "pos": 1, - "end": 7, + "end": 9, + "flags": "JSDoc", "type": { - "kind": "JSDocArrayType", + "kind": "ParenthesizedType", "pos": 1, - "end": 6, - "elementType": { - "kind": "JSDocArrayType", - "pos": 1, - "end": 4, + "end": 8, + "flags": "JSDoc", + "type": { + "kind": "ArrayType", + "pos": 2, + "end": 7, + "flags": "JSDoc", "elementType": { - "kind": "JSDocTypeReference", - "pos": 1, - "end": 2, - "name": { - "kind": "Identifier", - "pos": 1, - "end": 2, - "text": "a" + "kind": "ArrayType", + "pos": 2, + "end": 5, + "flags": "JSDoc", + "elementType": { + "kind": "TypeReference", + "pos": 2, + "end": 3, + "flags": "JSDoc", + "typeName": { + "kind": "Identifier", + "pos": 2, + "end": 3, + "flags": "JSDoc", + "text": "a" + } } } } diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.callSignatureInRecordType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.callSignatureInRecordType.json index 244c568ae05..6c00c3a8912 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.callSignatureInRecordType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.callSignatureInRecordType.json @@ -1,30 +1,28 @@ { - "kind": "JSDocRecordType", + "kind": "TypeLiteral", "pos": 1, "end": 13, - "literal": { - "kind": "TypeLiteral", - "pos": 1, - "end": 13, - "members": { - "0": { - "kind": "CallSignature", - "pos": 2, - "end": 12, - "parameters": { - "length": 0, - "pos": 3, - "end": 3 - }, - "type": { - "kind": "NumberKeyword", - "pos": 5, - "end": 12 - } - }, - "length": 1, + "flags": "JSDoc", + "members": { + "0": { + "kind": "CallSignature", "pos": 2, - "end": 12 - } + "end": 12, + "flags": "JSDoc", + "parameters": { + "length": 0, + "pos": 3, + "end": 3 + }, + "type": { + "kind": "NumberKeyword", + "pos": 5, + "end": 12, + "flags": "JSDoc" + } + }, + "length": 1, + "pos": 2, + "end": 12 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionReturnType1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionReturnType1.json index 209b9440a87..d33287fb251 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionReturnType1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionReturnType1.json @@ -2,25 +2,30 @@ "kind": "JSDocFunctionType", "pos": 1, "end": 26, + "flags": "JSDoc", "parameters": { "0": { "kind": "Parameter", "pos": 10, "end": 16, + "flags": "JSDoc", "type": { "kind": "StringKeyword", "pos": 10, - "end": 16 + "end": 16, + "flags": "JSDoc" } }, "1": { "kind": "Parameter", "pos": 17, "end": 25, + "flags": "JSDoc", "type": { "kind": "BooleanKeyword", "pos": 17, - "end": 25 + "end": 25, + "flags": "JSDoc" } }, "length": 2, diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionType1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionType1.json index d3be94a76ff..c589fd75317 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionType1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionType1.json @@ -2,6 +2,7 @@ "kind": "JSDocFunctionType", "pos": 1, "end": 11, + "flags": "JSDoc", "parameters": { "length": 0, "pos": 10, diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionType2.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionType2.json index 209b9440a87..d33287fb251 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionType2.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionType2.json @@ -2,25 +2,30 @@ "kind": "JSDocFunctionType", "pos": 1, "end": 26, + "flags": "JSDoc", "parameters": { "0": { "kind": "Parameter", "pos": 10, "end": 16, + "flags": "JSDoc", "type": { "kind": "StringKeyword", "pos": 10, - "end": 16 + "end": 16, + "flags": "JSDoc" } }, "1": { "kind": "Parameter", "pos": 17, "end": 25, + "flags": "JSDoc", "type": { "kind": "BooleanKeyword", "pos": 17, - "end": 25 + "end": 25, + "flags": "JSDoc" } }, "length": 2, diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionTypeWithTrailingComma.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionTypeWithTrailingComma.json new file mode 100644 index 00000000000..a3d7fd40267 --- /dev/null +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionTypeWithTrailingComma.json @@ -0,0 +1,31 @@ +{ + "kind": "JSDocFunctionType", + "pos": 1, + "end": 13, + "flags": "JSDoc", + "parameters": { + "0": { + "kind": "Parameter", + "pos": 10, + "end": 11, + "flags": "JSDoc", + "type": { + "kind": "TypeReference", + "pos": 10, + "end": 11, + "flags": "JSDoc", + "typeName": { + "kind": "Identifier", + "pos": 10, + "end": 11, + "flags": "JSDoc", + "text": "a" + } + } + }, + "length": 1, + "pos": 10, + "end": 12, + "hasTrailingComma": true + } +} \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword1.json index 80b1378b291..b37c372a30c 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword1.json @@ -1,11 +1,13 @@ { - "kind": "JSDocTypeReference", + "kind": "TypeReference", "pos": 1, "end": 4, - "name": { + "flags": "JSDoc", + "typeName": { "kind": "Identifier", "pos": 1, "end": 4, + "flags": "JSDoc", "originalKeywordKind": "VarKeyword", "text": "var" } diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword2.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword2.json index 4148937b278..a733da557af 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword2.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword2.json @@ -1,5 +1,6 @@ { "kind": "NullKeyword", "pos": 1, - "end": 5 + "end": 5, + "flags": "JSDoc" } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword3.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword3.json index c61912f9eb8..c991d6cecc4 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword3.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword3.json @@ -1,5 +1,6 @@ { "kind": "UndefinedKeyword", "pos": 1, - "end": 10 + "end": 10, + "flags": "JSDoc" } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.methodInRecordType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.methodInRecordType.json index fab9a581bd9..296a5b0cc31 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.methodInRecordType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.methodInRecordType.json @@ -1,36 +1,35 @@ { - "kind": "JSDocRecordType", + "kind": "TypeLiteral", "pos": 1, "end": 16, - "literal": { - "kind": "TypeLiteral", - "pos": 1, - "end": 16, - "members": { - "0": { - "kind": "MethodSignature", - "pos": 2, - "end": 15, - "name": { - "kind": "Identifier", - "pos": 2, - "end": 5, - "text": "foo" - }, - "parameters": { - "length": 0, - "pos": 6, - "end": 6 - }, - "type": { - "kind": "NumberKeyword", - "pos": 8, - "end": 15 - } - }, - "length": 1, + "flags": "JSDoc", + "members": { + "0": { + "kind": "MethodSignature", "pos": 2, - "end": 15 - } + "end": 15, + "flags": "JSDoc", + "name": { + "kind": "Identifier", + "pos": 2, + "end": 5, + "flags": "JSDoc", + "text": "foo" + }, + "parameters": { + "length": 0, + "pos": 6, + "end": 6 + }, + "type": { + "kind": "NumberKeyword", + "pos": 8, + "end": 15, + "flags": "JSDoc" + } + }, + "length": 1, + "pos": 2, + "end": 15 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.newType1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.newType1.json index 194037970c5..4458100a3c1 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.newType1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.newType1.json @@ -1,27 +1,51 @@ { - "kind": "JSDocConstructorType", + "kind": "JSDocFunctionType", "pos": 1, - "end": 8, - "type": { - "kind": "JSDocTypeReference", - "pos": 5, - "end": 8, - "name": { - "kind": "FirstNode", - "pos": 5, - "end": 8, - "left": { + "end": 18, + "flags": "JSDoc", + "parameters": { + "0": { + "kind": "Parameter", + "pos": 10, + "end": 17, + "flags": "JSDoc", + "name": { "kind": "Identifier", - "pos": 5, - "end": 6, - "text": "a" + "pos": 10, + "end": 13, + "flags": "JSDoc", + "originalKeywordKind": "NewKeyword", + "text": "new" }, - "right": { - "kind": "Identifier", - "pos": 7, - "end": 8, - "text": "b" + "type": { + "kind": "TypeReference", + "pos": 14, + "end": 17, + "flags": "JSDoc", + "typeName": { + "kind": "FirstNode", + "pos": 14, + "end": 17, + "flags": "JSDoc", + "left": { + "kind": "Identifier", + "pos": 14, + "end": 15, + "flags": "JSDoc", + "text": "a" + }, + "right": { + "kind": "Identifier", + "pos": 16, + "end": 17, + "flags": "JSDoc", + "text": "b" + } + } } - } + }, + "length": 1, + "pos": 10, + "end": 17 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nonNullableType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nonNullableType.json index e089754a0de..5096e2c5ae1 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nonNullableType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nonNullableType.json @@ -2,9 +2,11 @@ "kind": "JSDocNonNullableType", "pos": 1, "end": 8, + "flags": "JSDoc", "type": { "kind": "NumberKeyword", "pos": 2, - "end": 8 + "end": 8, + "flags": "JSDoc" } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nonNullableType2.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nonNullableType2.json index 377b19d0f70..75bed7d45b6 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nonNullableType2.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nonNullableType2.json @@ -2,9 +2,11 @@ "kind": "JSDocNonNullableType", "pos": 1, "end": 8, + "flags": "JSDoc", "type": { "kind": "NumberKeyword", "pos": 1, - "end": 7 + "end": 7, + "flags": "JSDoc" } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nullableType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nullableType.json index 9c4457fba12..3b57e9c760a 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nullableType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nullableType.json @@ -2,9 +2,11 @@ "kind": "JSDocNullableType", "pos": 1, "end": 8, + "flags": "JSDoc", "type": { "kind": "NumberKeyword", "pos": 2, - "end": 8 + "end": 8, + "flags": "JSDoc" } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nullableType2.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nullableType2.json index 03aea7be8c5..1f0adde5ee1 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nullableType2.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nullableType2.json @@ -2,9 +2,11 @@ "kind": "JSDocNullableType", "pos": 1, "end": 8, + "flags": "JSDoc", "type": { "kind": "NumberKeyword", "pos": 1, - "end": 7 + "end": 7, + "flags": "JSDoc" } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.optionalNullable.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.optionalNullable.json index f4940c28475..069de4aa09d 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.optionalNullable.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.optionalNullable.json @@ -2,9 +2,11 @@ "kind": "JSDocOptionalType", "pos": 1, "end": 3, + "flags": "JSDoc", "type": { "kind": "JSDocUnknownType", "pos": 1, - "end": 2 + "end": 2, + "flags": "JSDoc" } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.optionalType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.optionalType.json index 6069107cc6e..9faa4db0744 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.optionalType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.optionalType.json @@ -2,9 +2,11 @@ "kind": "JSDocOptionalType", "pos": 1, "end": 8, + "flags": "JSDoc", "type": { "kind": "NumberKeyword", "pos": 1, - "end": 7 + "end": 7, + "flags": "JSDoc" } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType1.json index 12be4806629..eb669992ca2 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType1.json @@ -1,15 +1,11 @@ { - "kind": "JSDocRecordType", + "kind": "TypeLiteral", "pos": 1, "end": 3, - "literal": { - "kind": "TypeLiteral", - "pos": 1, - "end": 3, - "members": { - "length": 0, - "pos": 2, - "end": 2 - } + "flags": "JSDoc", + "members": { + "length": 0, + "pos": 2, + "end": 2 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType2.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType2.json index 4bed6d0b918..274a1abd531 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType2.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType2.json @@ -1,26 +1,24 @@ { - "kind": "JSDocRecordType", + "kind": "TypeLiteral", "pos": 1, "end": 6, - "literal": { - "kind": "TypeLiteral", - "pos": 1, - "end": 6, - "members": { - "0": { - "kind": "PropertySignature", + "flags": "JSDoc", + "members": { + "0": { + "kind": "PropertySignature", + "pos": 2, + "end": 5, + "flags": "JSDoc", + "name": { + "kind": "Identifier", "pos": 2, "end": 5, - "name": { - "kind": "Identifier", - "pos": 2, - "end": 5, - "text": "foo" - } - }, - "length": 1, - "pos": 2, - "end": 5 - } + "flags": "JSDoc", + "text": "foo" + } + }, + "length": 1, + "pos": 2, + "end": 5 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType3.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType3.json index 565738a6ba9..6451edee68b 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType3.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType3.json @@ -1,31 +1,30 @@ { - "kind": "JSDocRecordType", + "kind": "TypeLiteral", "pos": 1, "end": 14, - "literal": { - "kind": "TypeLiteral", - "pos": 1, - "end": 14, - "members": { - "0": { - "kind": "PropertySignature", - "pos": 2, - "end": 13, - "name": { - "kind": "Identifier", - "pos": 2, - "end": 5, - "text": "foo" - }, - "type": { - "kind": "NumberKeyword", - "pos": 6, - "end": 13 - } - }, - "length": 1, + "flags": "JSDoc", + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, - "end": 13 - } + "end": 13, + "flags": "JSDoc", + "name": { + "kind": "Identifier", + "pos": 2, + "end": 5, + "flags": "JSDoc", + "text": "foo" + }, + "type": { + "kind": "NumberKeyword", + "pos": 6, + "end": 13, + "flags": "JSDoc" + } + }, + "length": 1, + "pos": 2, + "end": 13 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType4.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType4.json index 74bb20ab30b..2fb902cc7d3 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType4.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType4.json @@ -1,37 +1,37 @@ { - "kind": "JSDocRecordType", + "kind": "TypeLiteral", "pos": 1, "end": 11, - "literal": { - "kind": "TypeLiteral", - "pos": 1, - "end": 11, - "members": { - "0": { - "kind": "PropertySignature", + "flags": "JSDoc", + "members": { + "0": { + "kind": "PropertySignature", + "pos": 2, + "end": 6, + "flags": "JSDoc", + "name": { + "kind": "Identifier", "pos": 2, - "end": 6, - "name": { - "kind": "Identifier", - "pos": 2, - "end": 5, - "text": "foo" - } - }, - "1": { - "kind": "PropertySignature", + "end": 5, + "flags": "JSDoc", + "text": "foo" + } + }, + "1": { + "kind": "PropertySignature", + "pos": 6, + "end": 10, + "flags": "JSDoc", + "name": { + "kind": "Identifier", "pos": 6, "end": 10, - "name": { - "kind": "Identifier", - "pos": 6, - "end": 10, - "text": "bar" - } - }, - "length": 2, - "pos": 2, - "end": 10 - } + "flags": "JSDoc", + "text": "bar" + } + }, + "length": 2, + "pos": 2, + "end": 10 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType5.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType5.json index b57de3aea3c..083d498df5f 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType5.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType5.json @@ -1,42 +1,43 @@ { - "kind": "JSDocRecordType", + "kind": "TypeLiteral", "pos": 1, "end": 19, - "literal": { - "kind": "TypeLiteral", - "pos": 1, - "end": 19, - "members": { - "0": { - "kind": "PropertySignature", + "flags": "JSDoc", + "members": { + "0": { + "kind": "PropertySignature", + "pos": 2, + "end": 14, + "flags": "JSDoc", + "name": { + "kind": "Identifier", "pos": 2, - "end": 14, - "name": { - "kind": "Identifier", - "pos": 2, - "end": 5, - "text": "foo" - }, - "type": { - "kind": "NumberKeyword", - "pos": 6, - "end": 13 - } + "end": 5, + "flags": "JSDoc", + "text": "foo" }, - "1": { - "kind": "PropertySignature", + "type": { + "kind": "NumberKeyword", + "pos": 6, + "end": 13, + "flags": "JSDoc" + } + }, + "1": { + "kind": "PropertySignature", + "pos": 14, + "end": 18, + "flags": "JSDoc", + "name": { + "kind": "Identifier", "pos": 14, "end": 18, - "name": { - "kind": "Identifier", - "pos": 14, - "end": 18, - "text": "bar" - } - }, - "length": 2, - "pos": 2, - "end": 18 - } + "flags": "JSDoc", + "text": "bar" + } + }, + "length": 2, + "pos": 2, + "end": 18 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType6.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType6.json index 6c980da4085..7c3e7898528 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType6.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType6.json @@ -1,42 +1,43 @@ { - "kind": "JSDocRecordType", + "kind": "TypeLiteral", "pos": 1, "end": 19, - "literal": { - "kind": "TypeLiteral", - "pos": 1, - "end": 19, - "members": { - "0": { - "kind": "PropertySignature", - "pos": 2, - "end": 6, - "name": { - "kind": "Identifier", - "pos": 2, - "end": 5, - "text": "foo" - } - }, - "1": { - "kind": "PropertySignature", - "pos": 6, - "end": 18, - "name": { - "kind": "Identifier", - "pos": 6, - "end": 10, - "text": "bar" - }, - "type": { - "kind": "NumberKeyword", - "pos": 11, - "end": 18 - } - }, - "length": 2, + "flags": "JSDoc", + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, - "end": 18 - } + "end": 6, + "flags": "JSDoc", + "name": { + "kind": "Identifier", + "pos": 2, + "end": 5, + "flags": "JSDoc", + "text": "foo" + } + }, + "1": { + "kind": "PropertySignature", + "pos": 6, + "end": 18, + "flags": "JSDoc", + "name": { + "kind": "Identifier", + "pos": 6, + "end": 10, + "flags": "JSDoc", + "text": "bar" + }, + "type": { + "kind": "NumberKeyword", + "pos": 11, + "end": 18, + "flags": "JSDoc" + } + }, + "length": 2, + "pos": 2, + "end": 18 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType7.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType7.json index fb9f8c055cb..484c8eab770 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType7.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType7.json @@ -1,47 +1,49 @@ { - "kind": "JSDocRecordType", + "kind": "TypeLiteral", "pos": 1, "end": 27, - "literal": { - "kind": "TypeLiteral", - "pos": 1, - "end": 27, - "members": { - "0": { - "kind": "PropertySignature", - "pos": 2, - "end": 14, - "name": { - "kind": "Identifier", - "pos": 2, - "end": 5, - "text": "foo" - }, - "type": { - "kind": "NumberKeyword", - "pos": 6, - "end": 13 - } - }, - "1": { - "kind": "PropertySignature", - "pos": 14, - "end": 26, - "name": { - "kind": "Identifier", - "pos": 14, - "end": 18, - "text": "bar" - }, - "type": { - "kind": "NumberKeyword", - "pos": 19, - "end": 26 - } - }, - "length": 2, + "flags": "JSDoc", + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, - "end": 26 - } + "end": 14, + "flags": "JSDoc", + "name": { + "kind": "Identifier", + "pos": 2, + "end": 5, + "flags": "JSDoc", + "text": "foo" + }, + "type": { + "kind": "NumberKeyword", + "pos": 6, + "end": 13, + "flags": "JSDoc" + } + }, + "1": { + "kind": "PropertySignature", + "pos": 14, + "end": 26, + "flags": "JSDoc", + "name": { + "kind": "Identifier", + "pos": 14, + "end": 18, + "flags": "JSDoc", + "text": "bar" + }, + "type": { + "kind": "NumberKeyword", + "pos": 19, + "end": 26, + "flags": "JSDoc" + } + }, + "length": 2, + "pos": 2, + "end": 26 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType8.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType8.json index 748b593d235..661a02217aa 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType8.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType8.json @@ -1,27 +1,25 @@ { - "kind": "JSDocRecordType", + "kind": "TypeLiteral", "pos": 1, "end": 11, - "literal": { - "kind": "TypeLiteral", - "pos": 1, - "end": 11, - "members": { - "0": { - "kind": "PropertySignature", + "flags": "JSDoc", + "members": { + "0": { + "kind": "PropertySignature", + "pos": 2, + "end": 10, + "flags": "JSDoc", + "name": { + "kind": "Identifier", "pos": 2, "end": 10, - "name": { - "kind": "Identifier", - "pos": 2, - "end": 10, - "originalKeywordKind": "FunctionKeyword", - "text": "function" - } - }, - "length": 1, - "pos": 2, - "end": 10 - } + "flags": "JSDoc", + "originalKeywordKind": "FunctionKeyword", + "text": "function" + } + }, + "length": 1, + "pos": 2, + "end": 10 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.thisType1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.thisType1.json index f0b8038b586..276a3bc4ee9 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.thisType1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.thisType1.json @@ -1,27 +1,51 @@ { - "kind": "JSDocThisType", + "kind": "JSDocFunctionType", "pos": 1, - "end": 9, - "type": { - "kind": "JSDocTypeReference", - "pos": 6, - "end": 9, - "name": { - "kind": "FirstNode", - "pos": 6, - "end": 9, - "left": { + "end": 19, + "flags": "JSDoc", + "parameters": { + "0": { + "kind": "Parameter", + "pos": 10, + "end": 18, + "flags": "JSDoc", + "name": { "kind": "Identifier", - "pos": 6, - "end": 7, - "text": "a" + "pos": 10, + "end": 14, + "flags": "JSDoc", + "originalKeywordKind": "ThisKeyword", + "text": "this" }, - "right": { - "kind": "Identifier", - "pos": 8, - "end": 9, - "text": "b" + "type": { + "kind": "TypeReference", + "pos": 15, + "end": 18, + "flags": "JSDoc", + "typeName": { + "kind": "FirstNode", + "pos": 15, + "end": 18, + "flags": "JSDoc", + "left": { + "kind": "Identifier", + "pos": 15, + "end": 16, + "flags": "JSDoc", + "text": "a" + }, + "right": { + "kind": "Identifier", + "pos": 17, + "end": 18, + "flags": "JSDoc", + "text": "b" + } + } } - } + }, + "length": 1, + "pos": 10, + "end": 18 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.topLevelNoParenUnionType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.topLevelNoParenUnionType.json index dd9ef74f8c6..3ca80d437b5 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.topLevelNoParenUnionType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.topLevelNoParenUnionType.json @@ -1,17 +1,20 @@ { - "kind": "JSDocUnionType", + "kind": "UnionType", "pos": 1, "end": 14, + "flags": "JSDoc", "types": { "0": { "kind": "NumberKeyword", "pos": 1, - "end": 7 + "end": 7, + "flags": "JSDoc" }, "1": { "kind": "StringKeyword", "pos": 8, - "end": 14 + "end": 14, + "flags": "JSDoc" }, "length": 2, "pos": 1, diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.trailingCommaInRecordType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.trailingCommaInRecordType.json index 1694cf9aa73..899fcc6a649 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.trailingCommaInRecordType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.trailingCommaInRecordType.json @@ -1,26 +1,24 @@ { - "kind": "JSDocRecordType", + "kind": "TypeLiteral", "pos": 1, "end": 5, - "literal": { - "kind": "TypeLiteral", - "pos": 1, - "end": 5, - "members": { - "0": { - "kind": "PropertySignature", - "pos": 2, - "end": 4, - "name": { - "kind": "Identifier", - "pos": 2, - "end": 3, - "text": "a" - } - }, - "length": 1, + "flags": "JSDoc", + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, - "end": 4 - } + "end": 4, + "flags": "JSDoc", + "name": { + "kind": "Identifier", + "pos": 2, + "end": 3, + "flags": "JSDoc", + "text": "a" + } + }, + "length": 1, + "pos": 2, + "end": 4 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tsConstructorType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tsConstructorType.json new file mode 100644 index 00000000000..1b124c78dac --- /dev/null +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tsConstructorType.json @@ -0,0 +1,17 @@ +{ + "kind": "ConstructorType", + "pos": 1, + "end": 17, + "flags": "JSDoc", + "parameters": { + "length": 0, + "pos": 6, + "end": 6 + }, + "type": { + "kind": "StringKeyword", + "pos": 10, + "end": 17, + "flags": "JSDoc" + } +} \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tsFunctionType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tsFunctionType.json new file mode 100644 index 00000000000..32dd097a8f9 --- /dev/null +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tsFunctionType.json @@ -0,0 +1,17 @@ +{ + "kind": "FunctionType", + "pos": 1, + "end": 13, + "flags": "JSDoc", + "parameters": { + "length": 0, + "pos": 2, + "end": 2 + }, + "type": { + "kind": "StringKeyword", + "pos": 6, + "end": 13, + "flags": "JSDoc" + } +} \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType0.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType0.json index 2b5580f7622..979f7e1d783 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType0.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType0.json @@ -1,8 +1,9 @@ { - "kind": "JSDocTupleType", + "kind": "TupleType", "pos": 1, "end": 3, - "types": { + "flags": "JSDoc", + "elementTypes": { "length": 0, "pos": 2, "end": 2 diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType1.json index f741169be4b..9f913923b68 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType1.json @@ -1,12 +1,14 @@ { - "kind": "JSDocTupleType", + "kind": "TupleType", "pos": 1, "end": 9, - "types": { + "flags": "JSDoc", + "elementTypes": { "0": { "kind": "NumberKeyword", "pos": 2, - "end": 8 + "end": 8, + "flags": "JSDoc" }, "length": 1, "pos": 2, diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType2.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType2.json index 939eec1cb0c..9b87dc74995 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType2.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType2.json @@ -1,17 +1,20 @@ { - "kind": "JSDocTupleType", + "kind": "TupleType", "pos": 1, "end": 16, - "types": { + "flags": "JSDoc", + "elementTypes": { "0": { "kind": "NumberKeyword", "pos": 2, - "end": 8 + "end": 8, + "flags": "JSDoc" }, "1": { "kind": "StringKeyword", "pos": 9, - "end": 15 + "end": 15, + "flags": "JSDoc" }, "length": 2, "pos": 2, diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType3.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType3.json index 50b0a702a84..5877b92ae64 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType3.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType3.json @@ -1,22 +1,26 @@ { - "kind": "JSDocTupleType", + "kind": "TupleType", "pos": 1, "end": 24, - "types": { + "flags": "JSDoc", + "elementTypes": { "0": { "kind": "NumberKeyword", "pos": 2, - "end": 8 + "end": 8, + "flags": "JSDoc" }, "1": { "kind": "StringKeyword", "pos": 9, - "end": 15 + "end": 15, + "flags": "JSDoc" }, "2": { "kind": "BooleanKeyword", "pos": 16, - "end": 23 + "end": 23, + "flags": "JSDoc" }, "length": 3, "pos": 2, diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleTypeWithTrailingComma.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleTypeWithTrailingComma.json new file mode 100644 index 00000000000..48438f90c68 --- /dev/null +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleTypeWithTrailingComma.json @@ -0,0 +1,18 @@ +{ + "kind": "TupleType", + "pos": 1, + "end": 10, + "flags": "JSDoc", + "elementTypes": { + "0": { + "kind": "NumberKeyword", + "pos": 2, + "end": 8, + "flags": "JSDoc" + }, + "length": 1, + "pos": 2, + "end": 9, + "hasTrailingComma": true + } +} \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeArgumentsNotFollowingDot.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeArgumentsNotFollowingDot.json new file mode 100644 index 00000000000..a7a7ffbdf50 --- /dev/null +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeArgumentsNotFollowingDot.json @@ -0,0 +1,18 @@ +{ + "kind": "TypeReference", + "pos": 1, + "end": 4, + "flags": "JSDoc", + "typeName": { + "kind": "Identifier", + "pos": 1, + "end": 2, + "flags": "JSDoc", + "text": "a" + }, + "typeArguments": { + "length": 0, + "pos": 3, + "end": 3 + } +} \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeOfType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeOfType.json new file mode 100644 index 00000000000..a889c3ef3a1 --- /dev/null +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeOfType.json @@ -0,0 +1,13 @@ +{ + "kind": "TypeQuery", + "pos": 1, + "end": 9, + "flags": "JSDoc", + "exprName": { + "kind": "Identifier", + "pos": 7, + "end": 9, + "flags": "JSDoc", + "text": "M" + } +} \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference1.json index 282bc8c8e64..9c22db0c64d 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference1.json @@ -1,18 +1,22 @@ { - "kind": "JSDocTypeReference", + "kind": "TypeReference", "pos": 1, "end": 11, - "name": { + "flags": "JSDoc", + "typeName": { "kind": "Identifier", "pos": 1, "end": 2, - "text": "a" + "flags": "JSDoc", + "text": "a", + "jsdocDotPos": 2 }, "typeArguments": { "0": { "kind": "NumberKeyword", "pos": 4, - "end": 10 + "end": 10, + "flags": "JSDoc" }, "length": 1, "pos": 4, diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference2.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference2.json index 570db907956..38e2616fc04 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference2.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference2.json @@ -1,23 +1,28 @@ { - "kind": "JSDocTypeReference", + "kind": "TypeReference", "pos": 1, "end": 18, - "name": { + "flags": "JSDoc", + "typeName": { "kind": "Identifier", "pos": 1, "end": 2, - "text": "a" + "flags": "JSDoc", + "text": "a", + "jsdocDotPos": 2 }, "typeArguments": { "0": { "kind": "NumberKeyword", "pos": 4, - "end": 10 + "end": 10, + "flags": "JSDoc" }, "1": { "kind": "StringKeyword", "pos": 11, - "end": 17 + "end": 17, + "flags": "JSDoc" }, "length": 2, "pos": 4, diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference3.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference3.json index 683c17e582e..632c7ba87e9 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference3.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference3.json @@ -1,21 +1,25 @@ { - "kind": "JSDocTypeReference", + "kind": "TypeReference", "pos": 1, "end": 11, - "name": { + "flags": "JSDoc", + "typeName": { "kind": "FirstNode", "pos": 1, "end": 11, + "flags": "JSDoc", "left": { "kind": "Identifier", "pos": 1, "end": 2, + "flags": "JSDoc", "text": "a" }, "right": { "kind": "Identifier", "pos": 3, "end": 11, + "flags": "JSDoc", "originalKeywordKind": "FunctionKeyword", "text": "function" } diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unionType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unionType.json index f9301d05cc5..a6e8ab18df2 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unionType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unionType.json @@ -1,20 +1,29 @@ { - "kind": "JSDocUnionType", + "kind": "ParenthesizedType", "pos": 1, "end": 16, - "types": { - "0": { - "kind": "NumberKeyword", - "pos": 2, - "end": 8 - }, - "1": { - "kind": "StringKeyword", - "pos": 9, - "end": 15 - }, - "length": 2, + "flags": "JSDoc", + "type": { + "kind": "UnionType", "pos": 2, - "end": 15 + "end": 15, + "flags": "JSDoc", + "types": { + "0": { + "kind": "NumberKeyword", + "pos": 2, + "end": 8, + "flags": "JSDoc" + }, + "1": { + "kind": "StringKeyword", + "pos": 9, + "end": 15, + "flags": "JSDoc" + }, + "length": 2, + "pos": 2, + "end": 15 + } } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unknownType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unknownType.json index 0fb7af7ef23..3dff66b0347 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unknownType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unknownType.json @@ -1,5 +1,6 @@ { "kind": "JSDocUnknownType", "pos": 1, - "end": 2 + "end": 2, + "flags": "JSDoc" } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.variadicType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.variadicType.json index 2cf6079533c..00b950750e9 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.variadicType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.variadicType.json @@ -2,9 +2,11 @@ "kind": "JSDocVariadicType", "pos": 1, "end": 10, + "flags": "JSDoc", "type": { "kind": "NumberKeyword", "pos": 4, - "end": 10 + "end": 10, + "flags": "JSDoc" } } \ No newline at end of file diff --git a/tests/baselines/reference/checkJsdocTypeTag1.js b/tests/baselines/reference/checkJsdocTypeTag1.js index 664a02c6047..0613a237d7b 100644 --- a/tests/baselines/reference/checkJsdocTypeTag1.js +++ b/tests/baselines/reference/checkJsdocTypeTag1.js @@ -20,7 +20,7 @@ x(1); /** @type {function} */ const y = (a) => a + 1; -x(1); +y(1); /** @type {function (number)} */ const x1 = (a) => a + 1; @@ -38,7 +38,8 @@ var props = {}; /** * @type {Object} */ -var props = {}; +var props = {}; + //// [0.js] // @ts-check @@ -57,7 +58,7 @@ var x = function (a) { return a + 1; }; x(1); /** @type {function} */ var y = function (a) { return a + 1; }; -x(1); +y(1); /** @type {function (number)} */ var x1 = function (a) { return a + 1; }; x1(0); diff --git a/tests/baselines/reference/checkJsdocTypeTag1.symbols b/tests/baselines/reference/checkJsdocTypeTag1.symbols index cd337f8b556..281b59d37a0 100644 --- a/tests/baselines/reference/checkJsdocTypeTag1.symbols +++ b/tests/baselines/reference/checkJsdocTypeTag1.symbols @@ -37,8 +37,8 @@ const y = (a) => a + 1; >a : Symbol(a, Decl(0.js, 20, 11)) >a : Symbol(a, Decl(0.js, 20, 11)) -x(1); ->x : Symbol(x, Decl(0.js, 16, 5)) +y(1); +>y : Symbol(y, Decl(0.js, 20, 5)) /** @type {function (number)} */ const x1 = (a) => a + 1; diff --git a/tests/baselines/reference/checkJsdocTypeTag1.types b/tests/baselines/reference/checkJsdocTypeTag1.types index 8e59a2cdb7c..a0c0c53cfeb 100644 --- a/tests/baselines/reference/checkJsdocTypeTag1.types +++ b/tests/baselines/reference/checkJsdocTypeTag1.types @@ -53,9 +53,9 @@ const y = (a) => a + 1; >a : any >1 : 1 -x(1); ->x(1) : any ->x : Function +y(1); +>y(1) : any +>y : Function >1 : 1 /** @type {function (number)} */ diff --git a/tests/baselines/reference/initializerReferencingConstructorLocals.errors.txt b/tests/baselines/reference/initializerReferencingConstructorLocals.errors.txt index a3909e481f6..146048ceb93 100644 --- a/tests/baselines/reference/initializerReferencingConstructorLocals.errors.txt +++ b/tests/baselines/reference/initializerReferencingConstructorLocals.errors.txt @@ -1,18 +1,16 @@ tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(4,9): error TS2304: Cannot find name 'z'. tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(5,15): error TS2304: Cannot find name 'z'. tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(6,14): error TS2339: Property 'z' does not exist on type 'C'. -tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(7,15): error TS1003: Identifier expected. -tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(7,20): error TS2339: Property 'z' does not exist on type 'C'. +tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(7,15): error TS2304: Cannot find name 'this'. tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(9,9): error TS2304: Cannot find name 'z'. tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(14,9): error TS2304: Cannot find name 'z'. tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(15,15): error TS2304: Cannot find name 'z'. tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(16,14): error TS2339: Property 'z' does not exist on type 'D'. -tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(17,15): error TS1003: Identifier expected. -tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(17,20): error TS2339: Property 'z' does not exist on type 'D'. +tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(17,15): error TS2304: Cannot find name 'this'. tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(19,9): error TS2304: Cannot find name 'z'. -==== tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts (12 errors) ==== +==== tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts (10 errors) ==== // Initializer expressions for instance member variables are evaluated in the scope of the class constructor body but are not permitted to reference parameters or local variables of the constructor. class C { @@ -27,9 +25,7 @@ tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencin !!! error TS2339: Property 'z' does not exist on type 'C'. d: typeof this.z; // error ~~~~ -!!! error TS1003: Identifier expected. - ~ -!!! error TS2339: Property 'z' does not exist on type 'C'. +!!! error TS2304: Cannot find name 'this'. constructor(x) { z = 1; ~ @@ -49,9 +45,7 @@ tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencin !!! error TS2339: Property 'z' does not exist on type 'D'. d: typeof this.z; // error ~~~~ -!!! error TS1003: Identifier expected. - ~ -!!! error TS2339: Property 'z' does not exist on type 'D'. +!!! error TS2304: Cannot find name 'this'. constructor(x: T) { z = 1; ~ diff --git a/tests/baselines/reference/initializerReferencingConstructorLocals.js b/tests/baselines/reference/initializerReferencingConstructorLocals.js index a4922e954d7..2dd3fdd0745 100644 --- a/tests/baselines/reference/initializerReferencingConstructorLocals.js +++ b/tests/baselines/reference/initializerReferencingConstructorLocals.js @@ -27,7 +27,6 @@ var C = (function () { function C(x) { this.a = z; // error this.c = this.z; // error - this.d = this.z; // error z = 1; } return C; @@ -36,7 +35,6 @@ var D = (function () { function D(x) { this.a = z; // error this.c = this.z; // error - this.d = this.z; // error z = 1; } return D; diff --git a/tests/baselines/reference/initializerReferencingConstructorParameters.errors.txt b/tests/baselines/reference/initializerReferencingConstructorParameters.errors.txt index eb6744d656b..0c92d8c52a6 100644 --- a/tests/baselines/reference/initializerReferencingConstructorParameters.errors.txt +++ b/tests/baselines/reference/initializerReferencingConstructorParameters.errors.txt @@ -2,7 +2,7 @@ tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencin tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(5,15): error TS2304: Cannot find name 'x'. tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(10,9): error TS2663: Cannot find name 'x'. Did you mean the instance member 'this.x'? tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(11,15): error TS2304: Cannot find name 'x'. -tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(17,15): error TS1003: Identifier expected. +tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(17,15): error TS2304: Cannot find name 'this'. tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(23,9): error TS2663: Cannot find name 'x'. Did you mean the instance member 'this.x'? @@ -33,7 +33,7 @@ tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencin a = this.x; // ok b: typeof this.x; // error ~~~~ -!!! error TS1003: Identifier expected. +!!! error TS2304: Cannot find name 'this'. constructor(public x) { } } diff --git a/tests/baselines/reference/initializerReferencingConstructorParameters.js b/tests/baselines/reference/initializerReferencingConstructorParameters.js index 881913d5b5f..9326636fbd6 100644 --- a/tests/baselines/reference/initializerReferencingConstructorParameters.js +++ b/tests/baselines/reference/initializerReferencingConstructorParameters.js @@ -44,7 +44,6 @@ var E = (function () { function E(x) { this.x = x; this.a = this.x; // ok - this.b = this.x; // error } return E; }()); diff --git a/tests/baselines/reference/invalidTypeOfTarget.errors.txt b/tests/baselines/reference/invalidTypeOfTarget.errors.txt index 3c5f43c85d4..e658ab68c81 100644 --- a/tests/baselines/reference/invalidTypeOfTarget.errors.txt +++ b/tests/baselines/reference/invalidTypeOfTarget.errors.txt @@ -4,12 +4,15 @@ tests/cases/conformance/types/specifyingTypes/typeQueries/invalidTypeOfTarget.ts tests/cases/conformance/types/specifyingTypes/typeQueries/invalidTypeOfTarget.ts(3,16): error TS1003: Identifier expected. tests/cases/conformance/types/specifyingTypes/typeQueries/invalidTypeOfTarget.ts(4,16): error TS1003: Identifier expected. tests/cases/conformance/types/specifyingTypes/typeQueries/invalidTypeOfTarget.ts(5,16): error TS1003: Identifier expected. -tests/cases/conformance/types/specifyingTypes/typeQueries/invalidTypeOfTarget.ts(6,16): error TS1003: Identifier expected. -tests/cases/conformance/types/specifyingTypes/typeQueries/invalidTypeOfTarget.ts(7,16): error TS1003: Identifier expected. +tests/cases/conformance/types/specifyingTypes/typeQueries/invalidTypeOfTarget.ts(6,16): error TS2304: Cannot find name 'null'. +tests/cases/conformance/types/specifyingTypes/typeQueries/invalidTypeOfTarget.ts(7,16): error TS2552: Cannot find name 'function'. Did you mean 'Function'? +tests/cases/conformance/types/specifyingTypes/typeQueries/invalidTypeOfTarget.ts(7,25): error TS1005: '=' expected. +tests/cases/conformance/types/specifyingTypes/typeQueries/invalidTypeOfTarget.ts(7,25): error TS2304: Cannot find name 'f'. +tests/cases/conformance/types/specifyingTypes/typeQueries/invalidTypeOfTarget.ts(7,29): error TS1005: ',' expected. tests/cases/conformance/types/specifyingTypes/typeQueries/invalidTypeOfTarget.ts(8,16): error TS1003: Identifier expected. -==== tests/cases/conformance/types/specifyingTypes/typeQueries/invalidTypeOfTarget.ts (9 errors) ==== +==== tests/cases/conformance/types/specifyingTypes/typeQueries/invalidTypeOfTarget.ts (12 errors) ==== var x1: typeof {}; ~ !!! error TS1003: Identifier expected. @@ -29,10 +32,16 @@ tests/cases/conformance/types/specifyingTypes/typeQueries/invalidTypeOfTarget.ts !!! error TS1003: Identifier expected. var x6: typeof null; ~~~~ -!!! error TS1003: Identifier expected. +!!! error TS2304: Cannot find name 'null'. var x7: typeof function f() { }; ~~~~~~~~ -!!! error TS1003: Identifier expected. +!!! error TS2552: Cannot find name 'function'. Did you mean 'Function'? + ~ +!!! error TS1005: '=' expected. + ~ +!!! error TS2304: Cannot find name 'f'. + ~ +!!! error TS1005: ',' expected. var x8: typeof /123/; ~ !!! error TS1003: Identifier expected. \ No newline at end of file diff --git a/tests/baselines/reference/invalidTypeOfTarget.js b/tests/baselines/reference/invalidTypeOfTarget.js index 9945af643e6..ebc5bb70875 100644 --- a/tests/baselines/reference/invalidTypeOfTarget.js +++ b/tests/baselines/reference/invalidTypeOfTarget.js @@ -14,6 +14,6 @@ var x2 = function () { return ; }; var x3 = 1; var x4 = ''; var x5; -var x6 = null; -var x7 = function f() { }; +var x6; +var x7 = f(), _a = void 0; var x8 = /123/; diff --git a/tests/baselines/reference/jsdocDisallowedInTypescript.errors.txt b/tests/baselines/reference/jsdocDisallowedInTypescript.errors.txt new file mode 100644 index 00000000000..554b7af5822 --- /dev/null +++ b/tests/baselines/reference/jsdocDisallowedInTypescript.errors.txt @@ -0,0 +1,65 @@ +tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(2,15): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(4,15): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(4,32): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(7,20): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(10,18): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(11,12): error TS2554: Expected 1 arguments, but got 2. +tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(13,14): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(14,11): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(15,8): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(16,15): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(17,11): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(18,17): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(19,5): error TS2322: Type 'undefined' is not assignable to type 'number | null'. +tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(19,17): error TS8020: JSDoc types can only be used inside documentation comments. + + +==== tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts (14 errors) ==== + // grammar error from checker + var ara: Array. = [1,2,3]; + ~ +!!! error TS8020: JSDoc types can only be used inside documentation comments. + + function f(x: ?number, y: Array.) { + ~~~~~~~ +!!! error TS8020: JSDoc types can only be used inside documentation comments. + ~ +!!! error TS8020: JSDoc types can only be used inside documentation comments. + return x ? x + y[1] : y[0]; + } + function hof(ctor: function(new: number, string)) { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS8020: JSDoc types can only be used inside documentation comments. + return new ctor('hi'); + } + function hof2(f: function(this: number, string): string) { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS8020: JSDoc types can only be used inside documentation comments. + return f(12, 'hullo'); + ~~~~~~~~~~~~~~ +!!! error TS2554: Expected 1 arguments, but got 2. + } + var whatevs: * = 1001; + ~ +!!! error TS8020: JSDoc types can only be used inside documentation comments. + var ques: ? = 'what'; + ~ +!!! error TS8020: JSDoc types can only be used inside documentation comments. + var g: function(number, number): number = (n,m) => n + m; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS8020: JSDoc types can only be used inside documentation comments. + var variadic: ...boolean = [true, false, true]; + ~~~~~~~~~~ +!!! error TS8020: JSDoc types can only be used inside documentation comments. + var most: !string = 'definite'; + ~~~~~~~ +!!! error TS8020: JSDoc types can only be used inside documentation comments. + var postfixdef: number! = 101; + ~~~~~~~ +!!! error TS8020: JSDoc types can only be used inside documentation comments. + var postfixopt: number? = undefined; + ~~~~~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'number | null'. + ~~~~~~~ +!!! error TS8020: JSDoc types can only be used inside documentation comments. + \ No newline at end of file diff --git a/tests/baselines/reference/jsdocDisallowedInTypescript.js b/tests/baselines/reference/jsdocDisallowedInTypescript.js new file mode 100644 index 00000000000..2785eca2073 --- /dev/null +++ b/tests/baselines/reference/jsdocDisallowedInTypescript.js @@ -0,0 +1,42 @@ +//// [jsdocDisallowedInTypescript.ts] +// grammar error from checker +var ara: Array. = [1,2,3]; + +function f(x: ?number, y: Array.) { + return x ? x + y[1] : y[0]; +} +function hof(ctor: function(new: number, string)) { + return new ctor('hi'); +} +function hof2(f: function(this: number, string): string) { + return f(12, 'hullo'); +} +var whatevs: * = 1001; +var ques: ? = 'what'; +var g: function(number, number): number = (n,m) => n + m; +var variadic: ...boolean = [true, false, true]; +var most: !string = 'definite'; +var postfixdef: number! = 101; +var postfixopt: number? = undefined; + + +//// [jsdocDisallowedInTypescript.js] +"use strict"; +// grammar error from checker +var ara = [1, 2, 3]; +function f(x, y) { + return x ? x + y[1] : y[0]; +} +function hof(ctor) { + return new ctor('hi'); +} +function hof2(f) { + return f(12, 'hullo'); +} +var whatevs = 1001; +var ques = 'what'; +var g = function (n, m) { return n + m; }; +var variadic = [true, false, true]; +var most = 'definite'; +var postfixdef = 101; +var postfixopt = undefined; diff --git a/tests/baselines/reference/jsdocFunctionType.symbols b/tests/baselines/reference/jsdocFunctionType.symbols new file mode 100644 index 00000000000..0cac1aa4360 --- /dev/null +++ b/tests/baselines/reference/jsdocFunctionType.symbols @@ -0,0 +1,70 @@ +=== tests/cases/conformance/jsdoc/functions.js === +/** + * @param {function(this: string, number): number} c is just passing on through + * @return {function(this: string, number): number} + */ +function id1(c) { +>id1 : Symbol(id1, Decl(functions.js, 0, 0)) +>c : Symbol(c, Decl(functions.js, 4, 13)) + + return c +>c : Symbol(c, Decl(functions.js, 4, 13)) +} + +var x = id1(function (n) { return this.length + n }); +>x : Symbol(x, Decl(functions.js, 8, 3)) +>id1 : Symbol(id1, Decl(functions.js, 0, 0)) +>n : Symbol(n, Decl(functions.js, 8, 22)) +>this.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>this : Symbol(this, Decl(functions.js, 1, 20)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>n : Symbol(n, Decl(functions.js, 8, 22)) + +/** + * @param {function(new: { length: number }, number): number} c is just passing on through + * @return {function(new: { length: number }, number): number} + */ +function id2(c) { +>id2 : Symbol(id2, Decl(functions.js, 8, 53)) +>c : Symbol(c, Decl(functions.js, 14, 13)) + + return c +>c : Symbol(c, Decl(functions.js, 14, 13)) +} + +class C { +>C : Symbol(C, Decl(functions.js, 16, 1)) + + /** @param {number} n */ + constructor(n) { +>n : Symbol(n, Decl(functions.js, 20, 16)) + + this.length = n; +>this.length : Symbol(C.length, Decl(functions.js, 20, 20)) +>this : Symbol(C, Decl(functions.js, 16, 1)) +>length : Symbol(C.length, Decl(functions.js, 20, 20)) +>n : Symbol(n, Decl(functions.js, 20, 16)) + } +} + +var y = id2(C); +>y : Symbol(y, Decl(functions.js, 25, 3)) +>id2 : Symbol(id2, Decl(functions.js, 8, 53)) +>C : Symbol(C, Decl(functions.js, 16, 1)) + +var z = new y(12); +>z : Symbol(z, Decl(functions.js, 26, 3)) +>y : Symbol(y, Decl(functions.js, 25, 3)) + +z.length; +>z.length : Symbol(length, Decl(functions.js, 12, 27)) +>z : Symbol(z, Decl(functions.js, 26, 3)) +>length : Symbol(length, Decl(functions.js, 12, 27)) + +/** @type {function ("a" | "b", 1 | 2): 3 | 4} */ +var f = function (ab, onetwo) { return ab === "a" ? 3 : 4; } +>f : Symbol(f, Decl(functions.js, 30, 3)) +>ab : Symbol(ab, Decl(functions.js, 30, 18)) +>onetwo : Symbol(onetwo, Decl(functions.js, 30, 21)) +>ab : Symbol(ab, Decl(functions.js, 30, 18)) + diff --git a/tests/baselines/reference/jsdocFunctionType.types b/tests/baselines/reference/jsdocFunctionType.types new file mode 100644 index 00000000000..0f4c0c2febe --- /dev/null +++ b/tests/baselines/reference/jsdocFunctionType.types @@ -0,0 +1,83 @@ +=== tests/cases/conformance/jsdoc/functions.js === +/** + * @param {function(this: string, number): number} c is just passing on through + * @return {function(this: string, number): number} + */ +function id1(c) { +>id1 : (c: (this: string, arg1: number) => number) => (this: string, arg1: number) => number +>c : (this: string, arg1: number) => number + + return c +>c : (this: string, arg1: number) => number +} + +var x = id1(function (n) { return this.length + n }); +>x : (this: string, arg1: number) => number +>id1(function (n) { return this.length + n }) : (this: string, arg1: number) => number +>id1 : (c: (this: string, arg1: number) => number) => (this: string, arg1: number) => number +>function (n) { return this.length + n } : (this: string, n: number) => number +>n : number +>this.length + n : number +>this.length : number +>this : string +>length : number +>n : number + +/** + * @param {function(new: { length: number }, number): number} c is just passing on through + * @return {function(new: { length: number }, number): number} + */ +function id2(c) { +>id2 : (c: new (arg1: number) => { length: number; }) => new (arg1: number) => { length: number; } +>c : new (arg1: number) => { length: number; } + + return c +>c : new (arg1: number) => { length: number; } +} + +class C { +>C : C + + /** @param {number} n */ + constructor(n) { +>n : number + + this.length = n; +>this.length = n : number +>this.length : number +>this : this +>length : number +>n : number + } +} + +var y = id2(C); +>y : new (arg1: number) => { length: number; } +>id2(C) : new (arg1: number) => { length: number; } +>id2 : (c: new (arg1: number) => { length: number; }) => new (arg1: number) => { length: number; } +>C : typeof C + +var z = new y(12); +>z : { length: number; } +>new y(12) : { length: number; } +>y : new (arg1: number) => { length: number; } +>12 : 12 + +z.length; +>z.length : number +>z : { length: number; } +>length : number + +/** @type {function ("a" | "b", 1 | 2): 3 | 4} */ +var f = function (ab, onetwo) { return ab === "a" ? 3 : 4; } +>f : (arg0: "a" | "b", arg1: 1 | 2) => 3 | 4 +>function (ab, onetwo) { return ab === "a" ? 3 : 4; } : (ab: "a" | "b", onetwo: 1 | 2) => 3 | 4 +>ab : "a" | "b" +>onetwo : 1 | 2 +>ab === "a" ? 3 : 4 : 3 | 4 +>ab === "a" : boolean +>ab : "a" | "b" +>"a" : "a" +>3 : 3 +>4 : 4 + diff --git a/tests/baselines/reference/jsdocParseErrorsInTypescript.errors.txt b/tests/baselines/reference/jsdocParseErrorsInTypescript.errors.txt new file mode 100644 index 00000000000..655c27fb89c --- /dev/null +++ b/tests/baselines/reference/jsdocParseErrorsInTypescript.errors.txt @@ -0,0 +1,9 @@ +tests/cases/conformance/jsdoc/jsdocParseErrorsInTypescript.ts(2,27): error TS1109: Expression expected. + + +==== tests/cases/conformance/jsdoc/jsdocParseErrorsInTypescript.ts (1 errors) ==== + // parse error (blocks grammar errors from checker) + function parse1(n: number=) { } + ~ +!!! error TS1109: Expression expected. + \ No newline at end of file diff --git a/tests/baselines/reference/jsdocParseErrorsInTypescript.js b/tests/baselines/reference/jsdocParseErrorsInTypescript.js new file mode 100644 index 00000000000..09fcae6e1b6 --- /dev/null +++ b/tests/baselines/reference/jsdocParseErrorsInTypescript.js @@ -0,0 +1,10 @@ +//// [jsdocParseErrorsInTypescript.ts] +// parse error (blocks grammar errors from checker) +function parse1(n: number=) { } + + +//// [jsdocParseErrorsInTypescript.js] +// parse error (blocks grammar errors from checker) +function parse1(n) { + if (n === void 0) { n = ; } +} diff --git a/tests/baselines/reference/jsdocPrefixPostfixParsing.symbols b/tests/baselines/reference/jsdocPrefixPostfixParsing.symbols new file mode 100644 index 00000000000..c5363a2ba3f --- /dev/null +++ b/tests/baselines/reference/jsdocPrefixPostfixParsing.symbols @@ -0,0 +1,25 @@ +=== tests/cases/conformance/jsdoc/prefixPostfix.js === +/** + * @param {number![]} x - number[] + * @param {!number[]} y - number[] + * @param {(number[])!} z - number[] + * @param {number?[]} a - (number | null)[] + * @param {?number[]} b - number[] | null + * @param {(number[])?} c - number[] | null + * @param {?...number} d - number[] | null + * @param {...?number} e - (number | null)[] + * @param {...number?} f - (number | null)[] + */ +function f(x, y, z, a, b, c, d, e, f) { +>f : Symbol(f, Decl(prefixPostfix.js, 0, 0)) +>x : Symbol(x, Decl(prefixPostfix.js, 11, 11)) +>y : Symbol(y, Decl(prefixPostfix.js, 11, 13)) +>z : Symbol(z, Decl(prefixPostfix.js, 11, 16)) +>a : Symbol(a, Decl(prefixPostfix.js, 11, 19)) +>b : Symbol(b, Decl(prefixPostfix.js, 11, 22)) +>c : Symbol(c, Decl(prefixPostfix.js, 11, 25)) +>d : Symbol(d, Decl(prefixPostfix.js, 11, 28)) +>e : Symbol(e, Decl(prefixPostfix.js, 11, 31)) +>f : Symbol(f, Decl(prefixPostfix.js, 11, 34)) +} + diff --git a/tests/baselines/reference/jsdocPrefixPostfixParsing.types b/tests/baselines/reference/jsdocPrefixPostfixParsing.types new file mode 100644 index 00000000000..46b15304bfa --- /dev/null +++ b/tests/baselines/reference/jsdocPrefixPostfixParsing.types @@ -0,0 +1,25 @@ +=== tests/cases/conformance/jsdoc/prefixPostfix.js === +/** + * @param {number![]} x - number[] + * @param {!number[]} y - number[] + * @param {(number[])!} z - number[] + * @param {number?[]} a - (number | null)[] + * @param {?number[]} b - number[] | null + * @param {(number[])?} c - number[] | null + * @param {?...number} d - number[] | null + * @param {...?number} e - (number | null)[] + * @param {...number?} f - (number | null)[] + */ +function f(x, y, z, a, b, c, d, e, f) { +>f : (x: number[], y: number[], z: number[], a: (number | null)[], b: number[] | null, c: number[] | null, d: number[] | null, ...e: (number | null)[], ...f: (number | null)[]) => void +>x : number[] +>y : number[] +>z : number[] +>a : (number | null)[] +>b : number[] | null +>c : number[] | null +>d : number[] | null +>e : (number | null)[] +>f : (number | null)[] +} + diff --git a/tests/baselines/reference/jsdocTemplateTag.symbols b/tests/baselines/reference/jsdocTemplateTag.symbols index 699e93339ed..98eee628178 100644 --- a/tests/baselines/reference/jsdocTemplateTag.symbols +++ b/tests/baselines/reference/jsdocTemplateTag.symbols @@ -1,36 +1,32 @@ -=== tests/cases/conformance/jsdoc/jsdocTemplateTag.ts === +=== tests/cases/conformance/jsdoc/forgot.js === /** * @param {T} a * @template T */ -function f(a: T) { ->f : Symbol(f, Decl(jsdocTemplateTag.ts, 0, 0)) ->T : Symbol(T, Decl(jsdocTemplateTag.ts, 4, 11)) ->a : Symbol(a, Decl(jsdocTemplateTag.ts, 4, 14)) ->T : Symbol(T, Decl(jsdocTemplateTag.ts, 4, 11)) +function f(a) { +>f : Symbol(f, Decl(forgot.js, 0, 0)) +>a : Symbol(a, Decl(forgot.js, 4, 11)) return () => a ->a : Symbol(a, Decl(jsdocTemplateTag.ts, 4, 14)) +>a : Symbol(a, Decl(forgot.js, 4, 11)) } let n = f(1)() ->n : Symbol(n, Decl(jsdocTemplateTag.ts, 7, 3)) ->f : Symbol(f, Decl(jsdocTemplateTag.ts, 0, 0)) +>n : Symbol(n, Decl(forgot.js, 7, 3)) +>f : Symbol(f, Decl(forgot.js, 0, 0)) /** * @param {T} a * @template T * @returns {function(): T} */ -function g(a: T) { ->g : Symbol(g, Decl(jsdocTemplateTag.ts, 7, 14)) ->T : Symbol(T, Decl(jsdocTemplateTag.ts, 14, 11)) ->a : Symbol(a, Decl(jsdocTemplateTag.ts, 14, 14)) ->T : Symbol(T, Decl(jsdocTemplateTag.ts, 14, 11)) +function g(a) { +>g : Symbol(g, Decl(forgot.js, 7, 14)) +>a : Symbol(a, Decl(forgot.js, 14, 11)) return () => a ->a : Symbol(a, Decl(jsdocTemplateTag.ts, 14, 14)) +>a : Symbol(a, Decl(forgot.js, 14, 11)) } let s = g('hi')() ->s : Symbol(s, Decl(jsdocTemplateTag.ts, 17, 3)) ->g : Symbol(g, Decl(jsdocTemplateTag.ts, 7, 14)) +>s : Symbol(s, Decl(forgot.js, 17, 3)) +>g : Symbol(g, Decl(forgot.js, 7, 14)) diff --git a/tests/baselines/reference/jsdocTemplateTag.types b/tests/baselines/reference/jsdocTemplateTag.types index 72b0529d97e..b1d8c46720d 100644 --- a/tests/baselines/reference/jsdocTemplateTag.types +++ b/tests/baselines/reference/jsdocTemplateTag.types @@ -1,13 +1,11 @@ -=== tests/cases/conformance/jsdoc/jsdocTemplateTag.ts === +=== tests/cases/conformance/jsdoc/forgot.js === /** * @param {T} a * @template T */ -function f(a: T) { +function f(a) { >f : (a: T) => () => T ->T : T >a : T ->T : T return () => a >() => a : () => T @@ -25,11 +23,9 @@ let n = f(1)() * @template T * @returns {function(): T} */ -function g(a: T) { +function g(a) { >g : (a: T) => () => T ->T : T >a : T ->T : T return () => a >() => a : () => T diff --git a/tests/baselines/reference/privateInstanceMemberAccessibility.errors.txt b/tests/baselines/reference/privateInstanceMemberAccessibility.errors.txt index adca4e30e10..ae7dac2f18c 100644 --- a/tests/baselines/reference/privateInstanceMemberAccessibility.errors.txt +++ b/tests/baselines/reference/privateInstanceMemberAccessibility.errors.txt @@ -2,12 +2,11 @@ tests/cases/conformance/classes/members/accessibility/privateInstanceMemberAcces Property 'foo' is private in type 'Base' but not in type 'Derived'. tests/cases/conformance/classes/members/accessibility/privateInstanceMemberAccessibility.ts(6,15): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. tests/cases/conformance/classes/members/accessibility/privateInstanceMemberAccessibility.ts(8,22): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. -tests/cases/conformance/classes/members/accessibility/privateInstanceMemberAccessibility.ts(10,15): error TS1003: Identifier expected. -tests/cases/conformance/classes/members/accessibility/privateInstanceMemberAccessibility.ts(10,21): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. +tests/cases/conformance/classes/members/accessibility/privateInstanceMemberAccessibility.ts(10,15): error TS2304: Cannot find name 'super'. tests/cases/conformance/classes/members/accessibility/privateInstanceMemberAccessibility.ts(12,12): error TS1005: ';' expected. -==== tests/cases/conformance/classes/members/accessibility/privateInstanceMemberAccessibility.ts (6 errors) ==== +==== tests/cases/conformance/classes/members/accessibility/privateInstanceMemberAccessibility.ts (5 errors) ==== class Base { private foo: string; } @@ -26,9 +25,7 @@ tests/cases/conformance/classes/members/accessibility/privateInstanceMemberAcces } z: typeof super.foo; // error ~~~~~ -!!! error TS1003: Identifier expected. - ~~~ -!!! error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. +!!! error TS2304: Cannot find name 'super'. a: this.foo; // error ~ diff --git a/tests/baselines/reference/privateInstanceMemberAccessibility.js b/tests/baselines/reference/privateInstanceMemberAccessibility.js index 8448f142bbb..40b8c886cc0 100644 --- a/tests/baselines/reference/privateInstanceMemberAccessibility.js +++ b/tests/baselines/reference/privateInstanceMemberAccessibility.js @@ -34,7 +34,6 @@ var Derived = (function (_super) { function Derived() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.x = _super.prototype.foo; // error - _this.z = _super.prototype.foo; // error return _this; } Derived.prototype.y = function () { diff --git a/tests/baselines/reference/syntaxErrors.errors.txt b/tests/baselines/reference/syntaxErrors.errors.txt index 8e3005891a5..02ad52a15e5 100644 --- a/tests/baselines/reference/syntaxErrors.errors.txt +++ b/tests/baselines/reference/syntaxErrors.errors.txt @@ -1,31 +1,19 @@ -tests/cases/conformance/jsdoc/foo.js(2,15): error TS1005: '}' expected. -tests/cases/conformance/jsdoc/foo.js(3,19): error TS1005: '}' expected. -tests/cases/conformance/jsdoc/foo.js(4,18): error TS1003: Identifier expected. -tests/cases/conformance/jsdoc/foo.js(4,19): error TS1005: '}' expected. +tests/cases/conformance/jsdoc/badTypeArguments.js(1,15): error TS1099: Type argument list cannot be empty. +tests/cases/conformance/jsdoc/badTypeArguments.js(2,22): error TS1009: Trailing comma not allowed. -==== tests/cases/conformance/jsdoc/foo.js (4 errors) ==== - /** - * @param {(x)=>void} x - ~~ -!!! error TS1005: '}' expected. - * @param {typeof String} y - ~~~~~~ -!!! error TS1005: '}' expected. - * @param {string & number} z - -!!! error TS1003: Identifier expected. - ~ -!!! error TS1005: '}' expected. - **/ - function foo(x, y, z) { } +==== tests/cases/conformance/jsdoc/dummyType.d.ts (0 errors) ==== + declare class C { t: T } -==== tests/cases/conformance/jsdoc/skipped.js (0 errors) ==== - // @ts-nocheck - /** - * @param {(x)=>void} x - * @param {typeof String} y - * @param {string & number} z - **/ - function bar(x, y, z) { } +==== tests/cases/conformance/jsdoc/badTypeArguments.js (2 errors) ==== + /** @param {C.<>} x */ + ~~ +!!! error TS1099: Type argument list cannot be empty. + /** @param {C.} y */ + ~ +!!! error TS1009: Trailing comma not allowed. + function f(x, y) { + return x.t + y.t; + } + var x = f({ t: 1000 }, { t: 3000 }); \ No newline at end of file diff --git a/tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt b/tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt index ad8978847f4..4f566c1a7ae 100644 --- a/tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt +++ b/tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt @@ -88,18 +88,13 @@ tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(170,24): e tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(171,28): error TS1003: Identifier expected. tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(171,32): error TS1005: ',' expected. tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,30): error TS1005: ',' expected. -tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,32): error TS1138: Parameter declaration expected. -tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,39): error TS1005: ';' expected. -tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,40): error TS1128: Declaration or statement expected. -tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,42): error TS2693: 'number' only refers to a type, but is being used as a value here. -tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,49): error TS1005: ';' expected. -tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(175,1): error TS7027: Unreachable code detected. +tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,32): error TS1003: Identifier expected. tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(175,29): error TS2304: Cannot find name 'm'. tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(175,32): error TS1005: ';' expected. tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(175,35): error TS2304: Cannot find name 'm'. -==== tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts (65 errors) ==== +==== tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts (60 errors) ==== class C { n: number; explicitThis(this: this, m: number): number { @@ -419,20 +414,10 @@ tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(175,35): e ~ !!! error TS1005: ',' expected. ~~~ -!!! error TS1138: Parameter declaration expected. - ~ -!!! error TS1005: ';' expected. - ~ -!!! error TS1128: Declaration or statement expected. - ~~~~~~ -!!! error TS2693: 'number' only refers to a type, but is being used as a value here. - ~ -!!! error TS1005: ';' expected. +!!! error TS1003: Identifier expected. // can't name parameters 'this' in a lambda. c.explicitProperty = (this, m) => m + this.n; - ~ -!!! error TS7027: Unreachable code detected. ~ !!! error TS2304: Cannot find name 'm'. ~~ diff --git a/tests/baselines/reference/thisTypeInFunctionsNegative.js b/tests/baselines/reference/thisTypeInFunctionsNegative.js index 6cf6f477827..4b0e18f9b94 100644 --- a/tests/baselines/reference/thisTypeInFunctionsNegative.js +++ b/tests/baselines/reference/thisTypeInFunctionsNegative.js @@ -350,10 +350,8 @@ function decorated(, C) { if ( === void 0) { = this; } return this.n; } -function initializer() { } -new C(); -number; -{ +function initializer() { + if ( === void 0) { = new C(); } return this.n; } // can't name parameters 'this' in a lambda. diff --git a/tests/cases/conformance/jsdoc/checkJsdocTypeTag1.ts b/tests/cases/conformance/jsdoc/checkJsdocTypeTag1.ts index 4dc7b934571..87e799e793c 100644 --- a/tests/cases/conformance/jsdoc/checkJsdocTypeTag1.ts +++ b/tests/cases/conformance/jsdoc/checkJsdocTypeTag1.ts @@ -23,7 +23,7 @@ x(1); /** @type {function} */ const y = (a) => a + 1; -x(1); +y(1); /** @type {function (number)} */ const x1 = (a) => a + 1; @@ -41,4 +41,4 @@ var props = {}; /** * @type {Object} */ -var props = {}; \ No newline at end of file +var props = {}; diff --git a/tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts b/tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts new file mode 100644 index 00000000000..62ad39491d1 --- /dev/null +++ b/tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts @@ -0,0 +1,21 @@ +// @strict: true + +// grammar error from checker +var ara: Array. = [1,2,3]; + +function f(x: ?number, y: Array.) { + return x ? x + y[1] : y[0]; +} +function hof(ctor: function(new: number, string)) { + return new ctor('hi'); +} +function hof2(f: function(this: number, string): string) { + return f(12, 'hullo'); +} +var whatevs: * = 1001; +var ques: ? = 'what'; +var g: function(number, number): number = (n,m) => n + m; +var variadic: ...boolean = [true, false, true]; +var most: !string = 'definite'; +var postfixdef: number! = 101; +var postfixopt: number? = undefined; diff --git a/tests/cases/conformance/jsdoc/jsdocFunctionType.ts b/tests/cases/conformance/jsdoc/jsdocFunctionType.ts new file mode 100644 index 00000000000..b124989f96a --- /dev/null +++ b/tests/cases/conformance/jsdoc/jsdocFunctionType.ts @@ -0,0 +1,38 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @noImplicitAny: true + +// @Filename: functions.js + +/** + * @param {function(this: string, number): number} c is just passing on through + * @return {function(this: string, number): number} + */ +function id1(c) { + return c +} + +var x = id1(function (n) { return this.length + n }); + +/** + * @param {function(new: { length: number }, number): number} c is just passing on through + * @return {function(new: { length: number }, number): number} + */ +function id2(c) { + return c +} + +class C { + /** @param {number} n */ + constructor(n) { + this.length = n; + } +} + +var y = id2(C); +var z = new y(12); +z.length; + +/** @type {function ("a" | "b", 1 | 2): 3 | 4} */ +var f = function (ab, onetwo) { return ab === "a" ? 3 : 4; } diff --git a/tests/cases/conformance/jsdoc/jsdocParseErrorsInTypescript.ts b/tests/cases/conformance/jsdoc/jsdocParseErrorsInTypescript.ts new file mode 100644 index 00000000000..2df22f3e4ab --- /dev/null +++ b/tests/cases/conformance/jsdoc/jsdocParseErrorsInTypescript.ts @@ -0,0 +1,2 @@ +// parse error (blocks grammar errors from checker) +function parse1(n: number=) { } diff --git a/tests/cases/conformance/jsdoc/jsdocPrefixPostfixParsing.ts b/tests/cases/conformance/jsdoc/jsdocPrefixPostfixParsing.ts new file mode 100644 index 00000000000..707ae5a02a2 --- /dev/null +++ b/tests/cases/conformance/jsdoc/jsdocPrefixPostfixParsing.ts @@ -0,0 +1,21 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @strictNullChecks: true +// @noImplicitAny: true + +// @Filename: prefixPostfix.js + +/** + * @param {number![]} x - number[] + * @param {!number[]} y - number[] + * @param {(number[])!} z - number[] + * @param {number?[]} a - (number | null)[] + * @param {?number[]} b - number[] | null + * @param {(number[])?} c - number[] | null + * @param {?...number} d - number[] | null + * @param {...?number} e - (number | null)[] + * @param {...number?} f - (number | null)[] + */ +function f(x, y, z, a, b, c, d, e, f) { +} diff --git a/tests/cases/conformance/jsdoc/jsdocTemplateTag.ts b/tests/cases/conformance/jsdoc/jsdocTemplateTag.ts index 42b21cf935b..79dc083a952 100644 --- a/tests/cases/conformance/jsdoc/jsdocTemplateTag.ts +++ b/tests/cases/conformance/jsdoc/jsdocTemplateTag.ts @@ -1,11 +1,12 @@ // @allowJs: true // @checkJs: true // @noEmit: true +// @Filename: forgot.js /** * @param {T} a * @template T */ -function f(a: T) { +function f(a) { return () => a } let n = f(1)() @@ -15,7 +16,7 @@ let n = f(1)() * @template T * @returns {function(): T} */ -function g(a: T) { +function g(a) { return () => a } let s = g('hi')() diff --git a/tests/cases/conformance/jsdoc/syntaxErrors.ts b/tests/cases/conformance/jsdoc/syntaxErrors.ts index 4f9024810dd..847a99a5a12 100644 --- a/tests/cases/conformance/jsdoc/syntaxErrors.ts +++ b/tests/cases/conformance/jsdoc/syntaxErrors.ts @@ -2,19 +2,13 @@ // @allowJs: true // @noEmit: true -// @Filename: foo.js -/** - * @param {(x)=>void} x - * @param {typeof String} y - * @param {string & number} z - **/ -function foo(x, y, z) { } +// @Filename: dummyType.d.ts +declare class C { t: T } -// @Filename: skipped.js -// @ts-nocheck -/** - * @param {(x)=>void} x - * @param {typeof String} y - * @param {string & number} z - **/ -function bar(x, y, z) { } +// @Filename: badTypeArguments.js +/** @param {C.<>} x */ +/** @param {C.} y */ +function f(x, y) { + return x.t + y.t; +} +var x = f({ t: 1000 }, { t: 3000 }); diff --git a/tests/cases/fourslash/completionInJSDocFunctionNew.ts b/tests/cases/fourslash/completionInJSDocFunctionNew.ts new file mode 100644 index 00000000000..0d3391cf774 --- /dev/null +++ b/tests/cases/fourslash/completionInJSDocFunctionNew.ts @@ -0,0 +1,10 @@ + +/// +// @allowJs: true +// @Filename: Foo.js +/////** @type {function (new: string, string): string} */ +////var f = function () { return new/**/; } + +goTo.marker(); +verify.completionListCount(115); +verify.completionListContains('new'); diff --git a/tests/cases/fourslash/completionInJSDocFunctionThis.ts b/tests/cases/fourslash/completionInJSDocFunctionThis.ts new file mode 100644 index 00000000000..c28eeeb397f --- /dev/null +++ b/tests/cases/fourslash/completionInJSDocFunctionThis.ts @@ -0,0 +1,10 @@ +/// +// @allowJs: true +// @Filename: Foo.js +/////** @type {function (this: string, string): string} */ +////var f = function (s) { return this/**/; } + +goTo.marker(); +verify.completionListCount(116); +verify.completionListContains('this'); + diff --git a/tests/cases/fourslash/findAllReferencesJSDocFunctionNew.ts b/tests/cases/fourslash/findAllReferencesJSDocFunctionNew.ts new file mode 100644 index 00000000000..b094714cefb --- /dev/null +++ b/tests/cases/fourslash/findAllReferencesJSDocFunctionNew.ts @@ -0,0 +1,8 @@ +/// +// @allowJs: true +// @Filename: Foo.js +/////** @type {function ([|{|"isWriteAccess": true, "isDefinition": true|}new|]: string, string): string} */ +////var f; + +const [a0] = test.ranges(); +verify.singleReferenceGroup("(parameter) new: string", [a0]); diff --git a/tests/cases/fourslash/findAllReferencesJSDocFunctionThis.ts b/tests/cases/fourslash/findAllReferencesJSDocFunctionThis.ts new file mode 100644 index 00000000000..1f00e9f5647 --- /dev/null +++ b/tests/cases/fourslash/findAllReferencesJSDocFunctionThis.ts @@ -0,0 +1,11 @@ +/// +// @allowJs: true +// @Filename: Foo.js +/////** @type {function (this: string, string): string} */ +////var f = function (s) { return [|this|] + s; } + +const [a0] = test.ranges(); +// should be: verify.referenceGroups([a0, a1], [{ definition: "this", ranges: [a0] }]); + +// but is currently +verify.referenceGroups([], undefined); diff --git a/tests/cases/fourslash/findAllRefsExportConstEqualToClass.ts b/tests/cases/fourslash/findAllRefsExportConstEqualToClass.ts new file mode 100644 index 00000000000..a5e9bd1cd7d --- /dev/null +++ b/tests/cases/fourslash/findAllRefsExportConstEqualToClass.ts @@ -0,0 +1,17 @@ +/// + +// @Filename: /a.ts +////class [|{| "isWriteAccess": true, "isDefinition": true |}C|] {} +////export const [|{| "isWriteAccess": true, "isDefinition": true |}D|] = [|C|]; + +// @Filename: /b.ts +////import { [|{| "isWriteAccess": true, "isDefinition": true |}D|] } from "./a"; + +const [C0, D0, C1, D1] = test.ranges(); + +verify.singleReferenceGroup("class C", [C0, C1]); + +const d0Group = { definition: "const D: typeof C", ranges: [D0] }; +const d1Group = { definition: "import D", ranges: [D1] }; +verify.referenceGroups(D0, [d0Group, d1Group]); +verify.referenceGroups(D1, [d1Group, d0Group]); diff --git a/tests/cases/fourslash/formatEmptyParamList.ts b/tests/cases/fourslash/formatEmptyParamList.ts index a5372010baa..1822506d486 100644 --- a/tests/cases/fourslash/formatEmptyParamList.ts +++ b/tests/cases/fourslash/formatEmptyParamList.ts @@ -2,4 +2,4 @@ ////function f( f: function){/*1*/ goTo.marker("1"); edit.insert("}"); -verify.currentLineContentIs("function f(f: function){ }") \ No newline at end of file +verify.currentLineContentIs("function f(f: function) { }") diff --git a/tests/cases/fourslash/quickInfoJSDocFunctionNew.ts b/tests/cases/fourslash/quickInfoJSDocFunctionNew.ts new file mode 100644 index 00000000000..5fed7d9a39a --- /dev/null +++ b/tests/cases/fourslash/quickInfoJSDocFunctionNew.ts @@ -0,0 +1,8 @@ +/// +// @allowJs: true +// @Filename: Foo.js +/////** @type {function (new: string, string): string} */ +////var f/**/; + +goTo.marker(); +verify.quickInfoIs('var f: new (arg1: string) => string'); diff --git a/tests/cases/fourslash/quickInfoJSDocFunctionThis.ts b/tests/cases/fourslash/quickInfoJSDocFunctionThis.ts new file mode 100644 index 00000000000..5568ff829f1 --- /dev/null +++ b/tests/cases/fourslash/quickInfoJSDocFunctionThis.ts @@ -0,0 +1,9 @@ + +/// +// @allowJs: true +// @Filename: Foo.js +/////** @type {function (this: string, string): string} */ +////var f/**/ = function (s) { return s; } + +goTo.marker(); +verify.quickInfoIs('var f: (this: string, arg1: string) => string');