From 111e50921c20c120bb123945f84949365e020eb3 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Mon, 22 Aug 2016 13:57:40 -0700 Subject: [PATCH 01/46] Go to Implementation --- src/compiler/checker.ts | 3 +- src/compiler/types.ts | 1 + src/compiler/utilities.ts | 5 + src/harness/fourslash.ts | 62 +++ src/harness/harnessLanguageService.ts | 3 + src/server/client.ts | 22 + src/server/protocol.d.ts | 15 + src/server/session.ts | 27 + src/services/services.ts | 486 ++++++++++++++++-- src/services/shims.ts | 19 + tests/cases/fourslash/fourslash.ts | 3 + .../goToImplementationClassMethod_00.ts | 12 + .../goToImplementationClassMethod_01.ts | 21 + .../fourslash/goToImplementationEnum_00.ts | 13 + .../fourslash/goToImplementationEnum_01.ts | 13 + .../goToImplementationInterfaceMethod_00.ts | 27 + .../goToImplementationInterfaceMethod_01.ts | 25 + .../goToImplementationInterfaceMethod_02.ts | 25 + .../goToImplementationInterfaceMethod_03.ts | 25 + .../goToImplementationInterfaceMethod_04.ts | 26 + .../goToImplementationInterfaceMethod_05.ts | 38 ++ .../goToImplementationInterfaceMethod_06.ts | 49 ++ .../goToImplementationInterfaceMethod_08.ts | 23 + .../goToImplementationInterfaceMethod_09.ts | 30 ++ .../goToImplementationInterfaceMethod_10.ts | 36 ++ .../goToImplementationInterfaceMethod_11.ts | 36 ++ .../goToImplementationInterfaceMethod_12.ts | 12 + .../goToImplementationInterfaceProperty_00.ts | 23 + .../goToImplementationInterfaceProperty_01.ts | 16 + .../goToImplementationInterface_00.ts | 26 + .../goToImplementationInterface_01.ts | 25 + .../goToImplementationInterface_02.ts | 20 + .../goToImplementationInterface_03.ts | 10 + .../goToImplementationInterface_04.ts | 22 + .../goToImplementationInterface_05.ts | 14 + .../goToImplementationInterface_06.ts | 16 + .../fourslash/goToImplementationInvalid.ts | 12 + .../fourslash/goToImplementationLocal_00.ts | 9 + .../fourslash/goToImplementationLocal_01.ts | 9 + .../fourslash/goToImplementationLocal_02.ts | 8 + .../fourslash/goToImplementationLocal_03.ts | 12 + .../fourslash/goToImplementationLocal_04.ts | 10 + .../fourslash/goToImplementationLocal_05.ts | 12 + .../goToImplementationNamespace_00.ts | 12 + .../goToImplementationNamespace_01.ts | 12 + .../goToImplementationNamespace_02.ts | 12 + .../goToImplementationNamespace_03.ts | 12 + .../goToImplementationNamespace_04.ts | 26 + .../goToImplementationNamespace_05.ts | 26 + .../goToImplementationNamespace_06.ts | 28 + .../goToImplementationNamespace_07.ts | 28 + ...mentationShorthandPropertyAssignment_00.ts | 43 ++ ...mentationShorthandPropertyAssignment_01.ts | 48 ++ ...mentationShorthandPropertyAssignment_02.ts | 22 + .../fourslash/goToImplementationSuper_00.ts | 16 + .../fourslash/goToImplementationSuper_01.ts | 16 + .../fourslash/goToImplementationThis_00.ts | 14 + .../fourslash/goToImplementationThis_01.ts | 12 + .../fourslash/server/implementation01.ts | 9 + .../shims-pp/getImplementationAtPosition.ts | 35 ++ .../shims/getImplementationAtPosition.ts | 35 ++ 61 files changed, 1674 insertions(+), 33 deletions(-) create mode 100644 tests/cases/fourslash/goToImplementationClassMethod_00.ts create mode 100644 tests/cases/fourslash/goToImplementationClassMethod_01.ts create mode 100644 tests/cases/fourslash/goToImplementationEnum_00.ts create mode 100644 tests/cases/fourslash/goToImplementationEnum_01.ts create mode 100644 tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts create mode 100644 tests/cases/fourslash/goToImplementationInterfaceMethod_01.ts create mode 100644 tests/cases/fourslash/goToImplementationInterfaceMethod_02.ts create mode 100644 tests/cases/fourslash/goToImplementationInterfaceMethod_03.ts create mode 100644 tests/cases/fourslash/goToImplementationInterfaceMethod_04.ts create mode 100644 tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts create mode 100644 tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts create mode 100644 tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts create mode 100644 tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts create mode 100644 tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts create mode 100644 tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts create mode 100644 tests/cases/fourslash/goToImplementationInterfaceMethod_12.ts create mode 100644 tests/cases/fourslash/goToImplementationInterfaceProperty_00.ts create mode 100644 tests/cases/fourslash/goToImplementationInterfaceProperty_01.ts create mode 100644 tests/cases/fourslash/goToImplementationInterface_00.ts create mode 100644 tests/cases/fourslash/goToImplementationInterface_01.ts create mode 100644 tests/cases/fourslash/goToImplementationInterface_02.ts create mode 100644 tests/cases/fourslash/goToImplementationInterface_03.ts create mode 100644 tests/cases/fourslash/goToImplementationInterface_04.ts create mode 100644 tests/cases/fourslash/goToImplementationInterface_05.ts create mode 100644 tests/cases/fourslash/goToImplementationInterface_06.ts create mode 100644 tests/cases/fourslash/goToImplementationInvalid.ts create mode 100644 tests/cases/fourslash/goToImplementationLocal_00.ts create mode 100644 tests/cases/fourslash/goToImplementationLocal_01.ts create mode 100644 tests/cases/fourslash/goToImplementationLocal_02.ts create mode 100644 tests/cases/fourslash/goToImplementationLocal_03.ts create mode 100644 tests/cases/fourslash/goToImplementationLocal_04.ts create mode 100644 tests/cases/fourslash/goToImplementationLocal_05.ts create mode 100644 tests/cases/fourslash/goToImplementationNamespace_00.ts create mode 100644 tests/cases/fourslash/goToImplementationNamespace_01.ts create mode 100644 tests/cases/fourslash/goToImplementationNamespace_02.ts create mode 100644 tests/cases/fourslash/goToImplementationNamespace_03.ts create mode 100644 tests/cases/fourslash/goToImplementationNamespace_04.ts create mode 100644 tests/cases/fourslash/goToImplementationNamespace_05.ts create mode 100644 tests/cases/fourslash/goToImplementationNamespace_06.ts create mode 100644 tests/cases/fourslash/goToImplementationNamespace_07.ts create mode 100644 tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_00.ts create mode 100644 tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_01.ts create mode 100644 tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_02.ts create mode 100644 tests/cases/fourslash/goToImplementationSuper_00.ts create mode 100644 tests/cases/fourslash/goToImplementationSuper_01.ts create mode 100644 tests/cases/fourslash/goToImplementationThis_00.ts create mode 100644 tests/cases/fourslash/goToImplementationThis_01.ts create mode 100644 tests/cases/fourslash/server/implementation01.ts create mode 100644 tests/cases/fourslash/shims-pp/getImplementationAtPosition.ts create mode 100644 tests/cases/fourslash/shims/getImplementationAtPosition.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 193deded4c5..f7ce30fe4f3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -103,7 +103,8 @@ namespace ts { getJsxElementAttributesType, getJsxIntrinsicTagNames, - isOptionalParameter + isOptionalParameter, + isTypeAssignableTo }; const tupleTypes = createMap(); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a61d4a360b3..adfde2d0605 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1889,6 +1889,7 @@ namespace ts { getJsxElementAttributesType(elementNode: JsxOpeningLikeElement): Type; getJsxIntrinsicTagNames(): Symbol[]; isOptionalParameter(node: ParameterDeclaration): boolean; + isTypeAssignableTo(source: Type, target: Type): boolean; // Should not be called directly. Should only be accessed through the Program instance. /* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 870df4a54af..35dea56cf0b 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1669,6 +1669,11 @@ namespace ts { return false; } + export function isFunctionDeclarationIdentifierName(node: Identifier): boolean { + return node.parent.kind === SyntaxKind.FunctionDeclaration && + (node.parent).name === node; + } + // An alias symbol is created by one of the following declarations: // import = ... // import from ... diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 63731417f48..27baabf652a 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1604,6 +1604,15 @@ namespace FourSlash { assertFn(actualCount, expectedCount, this.messageAtLastKnownMarker("Type definitions Count")); } + public verifyImplementationsCount(negative: boolean, expectedCount: number) { + const assertFn = negative ? assert.notEqual : assert.equal; + + const implementations = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition); + const actualCount = implementations && implementations.length || 0; + + assertFn(actualCount, expectedCount, this.messageAtLastKnownMarker("Implementations Count")); + } + public verifyDefinitionsName(negative: boolean, expectedName: string, expectedContainerName: string) { const definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); const actualDefinitionName = definitions && definitions.length ? definitions[0].name : ""; @@ -1618,6 +1627,47 @@ namespace FourSlash { } } + public goToImplementation(implIndex: number) { + const implementations = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition); + if (!implementations || !implementations.length) { + this.raiseError("goToImplementation failed - expected to at least one implementation location but got 0"); + } + + if (implIndex >= implementations.length) { + this.raiseError(`goToImplementation failed - implIndex value (${implIndex}) exceeds implementation list size (${implementations.length})`); + } + + const implementation = implementations[implIndex]; + this.openFile(implementation.fileName); + this.currentCaretPosition = implementation.textSpan.start; + } + + public verifyRangesInImplementationList() { + const implementations = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition); + if (!implementations || !implementations.length) { + this.raiseError("verifyRangesInImplementationList failed - expected to at least one implementation location but got 0"); + } + + const ranges = this.getRanges(); + + if (!ranges || !ranges.length) { + this.raiseError("verifyRangesInImplementationList failed - expected to at least one range in test source"); + } + + for (const range of ranges) { + let rangeIsPresent = false; + const length = range.end - range.start; + for (const impl of implementations) { + if (range.fileName === impl.fileName && range.start === impl.textSpan.start && length === impl.textSpan.length) { + rangeIsPresent = true; + break; + } + } + assert.isTrue(rangeIsPresent, `No implementation found for range ${range.start}, ${range.end} in ${range.fileName}: ${this.rangeText(range)}`); + } + assert.equal(implementations.length, ranges.length, `Different number of implementations (${implementations.length}) and ranges (${ranges.length})`); + } + public getMarkers(): Marker[] { // Return a copy of the list return this.testData.markers.slice(0); @@ -2768,6 +2818,10 @@ namespace FourSlashInterface { this.state.goToTypeDefinition(definitionIndex); } + public implementation(implementationIndex = 0) { + this.state.goToImplementation(implementationIndex); + } + public position(position: number, fileIndex?: number): void; public position(position: number, fileName?: string): void; public position(position: number, fileNameOrIndex?: any): void { @@ -2876,6 +2930,10 @@ namespace FourSlashInterface { this.state.verifyTypeDefinitionsCount(this.negative, expectedCount); } + public implementationCountIs(expectedCount: number) { + this.state.verifyImplementationsCount(this.negative, expectedCount); + } + public definitionLocationExists() { this.state.verifyDefinitionLocationExists(this.negative); } @@ -3113,6 +3171,10 @@ namespace FourSlashInterface { public ProjectInfo(expected: string[]) { this.state.verifyProjectInfo(expected); } + + public allRangesAppearInImplementationList() { + this.state.verifyRangesInImplementationList(); + } } export class Edit { diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 94124432780..5209c6d7398 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -408,6 +408,9 @@ namespace Harness.LanguageService { getTypeDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] { return unwrapJSONCallResult(this.shim.getTypeDefinitionAtPosition(fileName, position)); } + getImplementationAtPosition(fileName: string, position: number): ts.ImplementationLocation[] { + return unwrapJSONCallResult(this.shim.getImplementationAtPosition(fileName, position)); + } getReferencesAtPosition(fileName: string, position: number): ts.ReferenceEntry[] { return unwrapJSONCallResult(this.shim.getReferencesAtPosition(fileName, position)); } diff --git a/src/server/client.ts b/src/server/client.ts index 88177e91fad..a9938ca85ec 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -353,6 +353,28 @@ namespace ts.server { }); } + getImplementationAtPosition(fileName: string, position: number): ImplementationLocation[] { + const lineOffset = this.positionToOneBasedLineOffset(fileName, position); + const args: protocol.FileLocationRequestArgs = { + file: fileName, + line: lineOffset.line, + offset: lineOffset.offset, + }; + + const request = this.processRequest(CommandNames.Implementation, args); + const response = this.processResponse(request); + + return response.body.map(entry => { + const fileName = entry.file; + const start = this.lineOffsetToPosition(fileName, entry.start); + const end = this.lineOffsetToPosition(fileName, entry.end); + return { + fileName, + textSpan: ts.createTextSpanFromBounds(start, end) + }; + }); + } + findReferences(fileName: string, position: number): ReferencedSymbol[] { // Not yet implemented. return []; diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts index 6442848abbe..5263b86e2a3 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -193,6 +193,14 @@ declare namespace ts.server.protocol { export interface TypeDefinitionRequest extends FileLocationRequest { } + /** + * Go to implementation request; value of command field is + * "implementation". Return response giving the file locations that + * implement the symbol found in file at location line, col. + */ + export interface ImplementationRequest extends FileLocationRequest { + } + /** * Location in source code expressed as (one-based) line and character offset. */ @@ -240,6 +248,13 @@ declare namespace ts.server.protocol { body?: FileSpan[]; } + /** + * Implementation response message. Gives text range for implementations. + */ + export interface ImplementationResponse extends Response { + body?: FileSpan[]; + } + /** * Get occurrences request; value of command field is * "occurrences". Return response giving spans that are relevant diff --git a/src/server/session.ts b/src/server/session.ts index 9383a54bd48..783451e02c6 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -111,6 +111,7 @@ namespace ts.server { export const Formatonkey = "formatonkey"; export const Geterr = "geterr"; export const GeterrForProject = "geterrForProject"; + export const Implementation = "implementation"; export const SemanticDiagnosticsSync = "semanticDiagnosticsSync"; export const SyntacticDiagnosticsSync = "syntacticDiagnosticsSync"; export const NavBar = "navbar"; @@ -357,6 +358,28 @@ namespace ts.server { })); } + private getImplementation(line: number, offset: number, fileName: string): protocol.FileSpan[] { + const file = ts.normalizePath(fileName); + const project = this.projectService.getProjectForFile(file); + if (!project || project.languageServiceDiabled) { + throw Errors.NoProject; + } + + const compilerService = project.compilerService; + const position = compilerService.host.lineOffsetToPosition(file, line, offset); + + const implementations = compilerService.languageService.getImplementationAtPosition(file, position); + if (!implementations) { + return undefined; + } + + return implementations.map(impl => ({ + file: impl.fileName, + start: compilerService.host.positionToLineOffset(impl.fileName, impl.textSpan.start), + end: compilerService.host.positionToLineOffset(impl.fileName, ts.textSpanEnd(impl.textSpan)) + })); + } + private getOccurrences(line: number, offset: number, fileName: string): protocol.OccurrencesResponseItem[] { fileName = ts.normalizePath(fileName); const project = this.projectService.getProjectForFile(fileName); @@ -1074,6 +1097,10 @@ namespace ts.server { const defArgs = request.arguments; return { response: this.getTypeDefinition(defArgs.line, defArgs.offset, defArgs.file), responseRequired: true }; }, + [CommandNames.Implementation]: (request: protocol.Request) => { + const implArgs = request.arguments; + return { response: this.getImplementation(implArgs.line, implArgs.offset, implArgs.file), responseRequired: true }; + }, [CommandNames.References]: (request: protocol.Request) => { const defArgs = request.arguments; return { response: this.getReferences(defArgs.line, defArgs.offset, defArgs.file), responseRequired: true }; diff --git a/src/services/services.ts b/src/services/services.ts index d200e081c5a..bb63f30c603 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1213,6 +1213,7 @@ namespace ts { getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; + getImplementationAtPosition(fileName: string, position: number): ImplementationLocation[]; getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[]; findReferences(fileName: string, position: number): ReferencedSymbol[]; @@ -1301,6 +1302,11 @@ namespace ts { isDefinition: boolean; } + export interface ImplementationLocation { + textSpan: TextSpan; + fileName: string; + } + export interface DocumentHighlights { fileName: string; highlightSpans: HighlightSpan[]; @@ -5288,6 +5294,149 @@ namespace ts { return getDefinitionFromSymbol(type.symbol, node); } + /// Goto implementation + function getImplementationAtPosition(fileName: string, position: number): ImplementationLocation[] { + synchronizeHostData(); + + const entries: ImplementationLocation[] = []; + const node = getTouchingPropertyName(getValidSourceFile(fileName), position); + const typeChecker = program.getTypeChecker(); + + if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { + const entry = getReferenceEntryForShorthandPropertyAssignment(node, typeChecker); + entries.push({ + textSpan: entry.textSpan, + fileName: entry.fileName + }); + } + else if (definitionIsImplementation(node, typeChecker)) { + const definitions = getDefinitionAtPosition(fileName, position); + forEach(definitions, (definition: DefinitionInfo) => { + entries.push({ + textSpan: definition.textSpan, + fileName: definition.fileName + }); + }); + } + else { + // Do a search for all references and filter them down to implementations only + const result = getReferencedSymbolsForNode(node, program.getSourceFiles(), /*findInStrings*/false, /*findInComments*/false, /*implementations*/true); + + forEach(result, referencedSymbol => { + if (referencedSymbol.references) { + forEach(referencedSymbol.references, entry => { + entries.push({ + textSpan: entry.textSpan, + fileName: entry.fileName + }); + }); + } + }); + } + + return entries; + } + + /** + * Returns true if the implementation for this node is the same as its definition + */ + function definitionIsImplementation(node: Node, typeChecker: TypeChecker) { + if (node.kind === SyntaxKind.SuperKeyword || node.kind === SyntaxKind.ThisKeyword) { + return true; + } + + if (node.parent.kind === SyntaxKind.PropertyAccessExpression || node.parent.kind === SyntaxKind.ElementAccessExpression) { + const expression = (node.parent).expression; + + // Members of "this" and "super" only have one possible implementation, so no need to find + // all references. Similarly, for the left hand side of the expression it only really + // makes sense to return the definition + if (node === expression || expression.kind === SyntaxKind.SuperKeyword || expression.kind === SyntaxKind.ThisKeyword) { + return true; + } + + // Check to see if this is a property that can have multiple implementations by determining + // if the parent is an interface (or class, or union/intersection) + const expressionType = typeChecker.getTypeAtLocation(expression); + if (expressionType && expressionType.getFlags() & (TypeFlags.Class | TypeFlags.Interface | TypeFlags.UnionOrIntersection)) { + return false; + } + + // Also check the right hand side to see if this is a type being accessed on a namespace/module + const rightHandType = typeChecker.getTypeAtLocation(node); + return rightHandType && !(rightHandType.getFlags() & (TypeFlags.Class | TypeFlags.Interface | TypeFlags.UnionOrIntersection)); + } + + const symbol = typeChecker.getSymbolAtLocation(node); + return symbol && !isClassOrInterfaceReference(symbol) && !(symbol.parent && isClassOrInterfaceReference(symbol.parent)); + } + + function getReferenceEntryForShorthandPropertyAssignment(node: Node, typeChecker: TypeChecker) { + const refSymbol = typeChecker.getSymbolAtLocation(node); + const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(refSymbol.valueDeclaration); + + if (shorthandSymbol) { + const shorthandDeclarations = shorthandSymbol.getDeclarations(); + if (shorthandDeclarations.length === 1) { + return getReferenceEntryFromNode(shorthandDeclarations[0]); + } + else if (shorthandDeclarations.length > 1) { + // This can happen when the property being assigned is a constructor for a + // class that also has interface declarations with the same name. We just want + // the class itself + + return forEach(shorthandDeclarations, declaration => { + if (declaration.kind === SyntaxKind.ClassDeclaration) { + return getReferenceEntryFromNode(declaration); + } + }); + } + } + } + + function isClassOrInterfaceReference(toCheck: Symbol) { + return toCheck.getFlags() & (SymbolFlags.Class | SymbolFlags.Interface); + } + + function isIdentifierOfImplementation(node: Identifier): boolean { + const parent = node.parent; + + if (isIdentifierName(node) || isFunctionDeclarationIdentifierName(node)) { + // PropertyAccessExpression? + switch (parent.kind) { + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.FunctionExpression: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.Constructor: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + return !!(parent).body; + case SyntaxKind.PropertyDeclaration: + return !!(parent).initializer; + case SyntaxKind.PropertyAssignment: + return true; + } + } + else if (isVariableLike(parent) && parent.name === node) { + return !!parent.initializer; + } + + return isIdentifierOfClass(node) || isIdentifierOfEnumDeclaration(node); + } + + function isIdentifierOfClass(node: Identifier) { + return (node.parent.kind === SyntaxKind.ClassDeclaration || node.parent.kind === SyntaxKind.ClassExpression) && + (node.parent).name === node; + } + + function isIdentifierOfEnumDeclaration(node: Identifier) { + return node.parent.kind === SyntaxKind.EnumDeclaration && (node.parent).name === node; + } + + function isTypeAssertionExpression(node: Node): node is TypeAssertion { + return node.kind === SyntaxKind.TypeAssertionExpression; + } + function getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[] { let results = getOccurrencesAtPositionCore(fileName, position); @@ -5334,7 +5483,7 @@ namespace ts { node.kind === SyntaxKind.StringLiteral || isLiteralNameOfPropertyDeclarationOrIndexAccess(node)) { - const referencedSymbols = getReferencedSymbolsForNode(node, sourceFilesToSearch, /*findInStrings*/ false, /*findInComments*/ false); + const referencedSymbols = getReferencedSymbolsForNode(node, sourceFilesToSearch, /*findInStrings*/ false, /*findInComments*/ false, /*implementations*/false); return convertReferencedSymbols(referencedSymbols); } @@ -6006,7 +6155,7 @@ namespace ts { case SyntaxKind.ThisKeyword: // case SyntaxKind.SuperKeyword: TODO:GH#9268 case SyntaxKind.StringLiteral: - return getReferencedSymbolsForNode(node, program.getSourceFiles(), findInStrings, findInComments); + return getReferencedSymbolsForNode(node, program.getSourceFiles(), findInStrings, findInComments, /*implementations*/false); } return undefined; } @@ -6024,37 +6173,40 @@ namespace ts { } } - function getReferencedSymbolsForNode(node: Node, sourceFiles: SourceFile[], findInStrings: boolean, findInComments: boolean): ReferencedSymbol[] { + function getReferencedSymbolsForNode(node: Node, sourceFiles: SourceFile[], findInStrings: boolean, findInComments: boolean, implementations: boolean): ReferencedSymbol[] { const typeChecker = program.getTypeChecker(); - - // Labels - if (isLabelName(node)) { - if (isJumpStatementTarget(node)) { - const labelDefinition = getTargetLabel((node.parent), (node).text); - // if we have a label definition, look within its statement for references, if not, then - // the label is undefined and we have no results.. - return labelDefinition ? getLabelReferencesInNode(labelDefinition.parent, labelDefinition) : undefined; - } - else { - // it is a label definition and not a target, search within the parent labeledStatement - return getLabelReferencesInNode(node.parent, node); - } - } - - if (isThis(node)) { - return getReferencesForThisKeyword(node, sourceFiles); - } - - if (node.kind === SyntaxKind.SuperKeyword) { - return getReferencesForSuperKeyword(node); - } - const symbol = typeChecker.getSymbolAtLocation(node); - if (!symbol && node.kind === SyntaxKind.StringLiteral) { - return getReferencesForStringLiteral(node, sourceFiles); + if (!implementations) { + // Labels + if (isLabelName(node)) { + if (isJumpStatementTarget(node)) { + const labelDefinition = getTargetLabel((node.parent), (node).text); + // if we have a label definition, look within its statement for references, if not, then + // the label is undefined and we have no results.. + return labelDefinition ? getLabelReferencesInNode(labelDefinition.parent, labelDefinition) : undefined; + } + else { + // it is a label definition and not a target, search within the parent labeledStatement + return getLabelReferencesInNode(node.parent, node); + } + } + + if (isThis(node)) { + return getReferencesForThisKeyword(node, sourceFiles); + } + + if (node.kind === SyntaxKind.SuperKeyword) { + return getReferencesForSuperKeyword(node); + } + + + if (!symbol && node.kind === SyntaxKind.StringLiteral) { + return getReferencesForStringLiteral(node, sourceFiles); + } } + // Could not find a symbol e.g. unknown identifier if (!symbol) { // Can't have references to something that we have no symbol for. @@ -6084,9 +6236,11 @@ namespace ts { // Maps from a symbol ID to the ReferencedSymbol entry in 'result'. const symbolToIndex: number[] = []; + const indexToSymbol: {[index: number]: Symbol} = {}; + if (scope) { result = []; - getReferencesInNode(scope, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex); + getReferencesInNode(scope, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex, indexToSymbol); } else { const internedName = getInternedName(symbol, node, declarations); @@ -6097,11 +6251,15 @@ namespace ts { if (nameTable[internedName] !== undefined) { result = result || []; - getReferencesInNode(sourceFile, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex); + getReferencesInNode(sourceFile, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex, indexToSymbol); } } } + if (implementations) { + return filterToImplementations(node, symbol, result, indexToSymbol); + } + return result; function getDefinition(symbol: Symbol): DefinitionInfo { @@ -6363,7 +6521,8 @@ namespace ts { findInStrings: boolean, findInComments: boolean, result: ReferencedSymbol[], - symbolToIndex: number[]): void { + symbolToIndex: number[], + indexToSymbol: {[index: number]: Symbol}): void { const sourceFile = container.getSourceFile(); const tripleSlashDirectivePrefixRegex = /^\/\/\/\s* { + const impl = getImplementationFromEntry(entry); + if (impl) { + const entryNode = getTokenAtPosition(getValidSourceFile(entry.fileName), entry.textSpan.start); + const element = getContainingObjectLiteralElement(entryNode); + if (element && element.parent && element.parent.kind === SyntaxKind.ObjectLiteralExpression) { + const objType = getDeclaredTypeOfObjectLiteralExpression(element.parent); + + if (objType && typeChecker.isTypeAssignableTo(objType, type)) { + return impl; + } + } + else { + const defClass = getContainingClass(entryNode); + if (defClass) { + const classType = typeChecker.getTypeAtLocation(defClass); + if (typeChecker.isTypeAssignableTo(classType, type)) { + return impl; + } + } + } + } + }); + } + } + + return filterReferenceEntries(refs, getImplementationFromEntry); + } + + function getDeclaredTypeOfObjectLiteralExpression(node: Node): Type { + if (node && node.parent) { + if (node.parent.kind === SyntaxKind.ParenthesizedExpression) { + return getDeclaredTypeOfObjectLiteralExpression(node.parent); + } + + if (isVariableLike(node.parent) && node.parent.type) { + return typeChecker.getTypeAtLocation(node.parent.type); + } + else if (node.parent.kind === SyntaxKind.ReturnStatement) { + const containerSig = typeChecker.getSignatureFromDeclaration(getContainingFunction(node)); + return typeChecker.getReturnTypeOfSignature(containerSig); + } + else if (node.parent.kind === SyntaxKind.TypeAssertionExpression) { + return typeChecker.getTypeAtLocation((node.parent).type); + } + } + return undefined; + } + + function filterReferenceEntries(refs: ReferencedSymbol[], filterer: (x: ReferenceEntry) => ReferenceEntry): ReferencedSymbol[] { + const result: ReferencedSymbol[] = []; + forEach(refs, (ref) => { + const filtered: ReferenceEntry[] = []; + forEach(ref.references, (entry) => { + const filteredEntry = filterer(entry); + if (filteredEntry) { + filtered.push(filteredEntry); + } + }); + if (filtered.length) { + result.push({ definition: ref.definition, references: filtered }); + } + }); + return result; + } + + function filterToClassMemberImplementations(parent: PropertyAccessExpression, searchSymbol: Symbol, refs: ReferencedSymbol[], indexToSymbol: {[index: number]: Symbol}): ReferencedSymbol[] { + // Need to find out what class this member is being accessed on + const type = typeChecker.getTypeAtLocation(parent.expression); + const classHierarchy: Symbol[] = getClassHierarchy(searchSymbol.parent); + + let lowest: ReferencedSymbol[]; + let lowestRank: number; + + // Filter down the references to those that refer to implementations of the symbol. That is, implementations + // from subclasses of the parent class and the lowest implementation in the parent class' class hierarchy + forEach(refs, (refSymbol, index) => { + const actual = indexToSymbol[index]; + + // We only care about implementations in classes in the hierarchy + if (actual.parent.getFlags() & SymbolFlags.Interface) { + return; + } + const rank = classHierarchy.indexOf(actual.parent); + + // No need to check anything past the lowest we have found so far + if (lowest && rank > lowestRank) { + return; + } + + const implementations: ReferenceEntry[] = []; + forEach(refSymbol.references, (entry) => { + const impl = getImplementationFromEntry(entry, type, classHierarchy); + if (impl) { + implementations.push(impl); + } + }); + if (implementations.length) { + if (!lowest || rank < lowestRank) { + lowest = [{ definition: refSymbol.definition, references: implementations }]; + lowestRank = rank; + } + else if (rank === lowestRank) { + lowest.push({ definition: refSymbol.definition, references: implementations }); + } + } + }); + + return lowest; + } + + function getImplementationFromEntry(entry: ReferenceEntry, base?: Type, hierarchy?: Symbol[]): ReferenceEntry { + const sourceFile = getValidSourceFile(entry.fileName); + const refNode = getTouchingPropertyName(sourceFile, entry.textSpan.start); + + // Check to make sure this reference is either part of a sub class or a class that we explicitly + // inherit from in the class hierarchy + if (isMemberOfSubOrParentClass(refNode, base, hierarchy) && refNode.kind === SyntaxKind.Identifier) { + // Check if we found a function/propertyAssignment/method with an implementation or initializer + if (isIdentifierOfImplementation(refNode)) { + return getReferenceEntryFromNode(refNode.parent); + } + else if (refNode.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { + // Go ahead and dereference the shorthand assignment by going to its definition + return getReferenceEntryForShorthandPropertyAssignment(refNode, typeChecker); + } + + // Check if the node is within an extends or implements clause + const containingHeritageClause = getContainingClassHeritageClause(refNode); + if (containingHeritageClause) { + return getReferenceEntryFromNode(containingHeritageClause.parent); + } + + // If we got a type reference, try and see if the reference applies to any expressions that can implement an interface + const containingTypeReference = getContainingTypeReference(refNode); + if (containingTypeReference) { + const parent = containingTypeReference.parent; + if (isVariableLike(parent) && parent.type === containingTypeReference && parent.initializer && isImplementationExpression(parent.initializer)) { + return getReferenceEntryFromNode(parent.initializer); + } + else if (isFunctionLike(parent) && parent.type === containingTypeReference && parent.body && parent.body.kind === SyntaxKind.Block) { + return forEachReturnStatement(parent.body, (returnStatement) => { + if (returnStatement.expression && isImplementationExpression(returnStatement.expression)) { + return getReferenceEntryFromNode(returnStatement.expression); + } + }); + } + else if (isTypeAssertionExpression(parent) && isImplementationExpression(parent.expression)) { + return getReferenceEntryFromNode(parent.expression); + } + } + } + } + + function isMemberOfSubOrParentClass(reference: Node, base: Type, hierarchy: Symbol[]) { + if (!base || !hierarchy) { + return true; + } + const referenceSymbol = typeChecker.getSymbolAtLocation(reference); + if (referenceSymbol && referenceSymbol.parent) { + if (hierarchy.indexOf(referenceSymbol.parent) !== -1) { + return true; + } + + const referenceParentDeclarations = referenceSymbol.parent.getDeclarations(); + if (referenceParentDeclarations.length) { + const referenceParentType = typeChecker.getTypeAtLocation(referenceParentDeclarations[0]); + return typeChecker.isTypeAssignableTo(referenceParentType, base); + } + } + return false; + } + + function getContainingTypeReference(node: Node): Node { + if (node) { + if (node.kind === SyntaxKind.TypeReference) { + return node; + } + + if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) { + return getContainingTypeReference(node.parent); + } + } + return undefined; + } + + function getContainingClassHeritageClause(node: Node): HeritageClause { + if (node) { + if (node.kind === SyntaxKind.ExpressionWithTypeArguments + && node.parent.kind === SyntaxKind.HeritageClause + && isClassLike(node.parent.parent)) { + return node.parent; + } + + else if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression) { + return getContainingClassHeritageClause(node.parent); + } + } + return undefined; + } + + /** + * Returns true if this is an expression that could be used to implement an interface. + */ + function isImplementationExpression(node: Expression): boolean { + // Unwrap parentheses + if (node.kind === SyntaxKind.ParenthesizedExpression) { + return isImplementationExpression((node).expression); + } + + return node.kind === SyntaxKind.ArrowFunction || + node.kind === SyntaxKind.FunctionExpression || + node.kind === SyntaxKind.ObjectLiteralExpression || + node.kind === SyntaxKind.ClassExpression; + } + + function getClassHierarchy(symbol: Symbol) { + const classes: Symbol[] = []; + getClassHierarchyRecursive(symbol, classes, createMap()); + return classes; + + function getClassHierarchyRecursive(symbol: Symbol, result: Symbol[], previousIterationSymbolsCache: SymbolTable) { + if (hasProperty(previousIterationSymbolsCache, symbol.name)) { + return; + } + previousIterationSymbolsCache[symbol.name] = symbol; + + if (result.indexOf(symbol) !== -1) { + return; + } + result.push(symbol); + forEach(symbol.getDeclarations(), (decl) => { + if (isClassLike(decl)) { + const heritage = getClassExtendsHeritageClauseElement(decl); + if (heritage) { + const type = typeChecker.getTypeAtLocation(heritage); + if (type && type.symbol) { + getClassHierarchyRecursive(type.symbol, result, previousIterationSymbolsCache); + } + } + } + }); + } + } + function getReferencesForSuperKeyword(superKeyword: Node): ReferencedSymbol[] { let searchSpaceNode = getSuperContainer(superKeyword, /*stopOnFunctions*/ false); if (!searchSpaceNode) { @@ -8310,6 +8731,7 @@ namespace ts { getQuickInfoAtPosition, getDefinitionAtPosition, getTypeDefinitionAtPosition, + getImplementationAtPosition, getReferencesAtPosition, findReferences, getOccurrencesAtPosition, diff --git a/src/services/shims.ts b/src/services/shims.ts index 9a581ed6be1..612ed955ed4 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -173,6 +173,12 @@ namespace ts { */ getTypeDefinitionAtPosition(fileName: string, position: number): string; + /** + * Returns a JSON-encoded value of the type: + * { fileName: string; textSpan: { start: number; length: number}; isWriteAccess: boolean, isDefinition?: boolean }[] + */ + getImplementationAtPosition(fileName: string, position: number): string; + /** * Returns a JSON-encoded value of the type: * { fileName: string; textSpan: { start: number; length: number}; isWriteAccess: boolean, isDefinition?: boolean }[] @@ -772,6 +778,19 @@ namespace ts { ); } + /// GOTO Implementation + + /** + * Computes the implementation location of the symbol + * at the requested position. + */ + public getImplementationAtPosition(fileName: string, position: number): string { + return this.forwardJSONCall( + `getImplementationAtPosition('${fileName}', ${position})`, + () => this.languageService.getImplementationAtPosition(fileName, position) + ); + } + public getRenameInfo(fileName: string, position: number): string { return this.forwardJSONCall( `getRenameInfo('${fileName}', ${position})`, diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 9ce3197a46f..f35e4fc3e0e 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -110,6 +110,7 @@ declare namespace FourSlashInterface { eof(): void; definition(definitionIndex?: number): void; type(definitionIndex?: number): void; + implementation(implementationIndex?: number): void; position(position: number, fileIndex?: number): any; position(position: number, fileName?: string): any; file(index: number, content?: string, scriptKindName?: string): any; @@ -134,6 +135,7 @@ declare namespace FourSlashInterface { quickInfoExists(): void; definitionCountIs(expectedCount: number): void; typeDefinitionCountIs(expectedCount: number): void; + implementationCountIs(expectedCount: number): void; definitionLocationExists(): void; verifyDefinitionsName(name: string, containerName: string): void; isValidBraceCompletionAtPosition(openingBrace?: string): void; @@ -226,6 +228,7 @@ declare namespace FourSlashInterface { getSyntacticDiagnostics(expected: string): void; getSemanticDiagnostics(expected: string): void; ProjectInfo(expected: string[]): void; + allRangesAppearInImplementationList(): void; } class edit { backspace(count?: number): void; diff --git a/tests/cases/fourslash/goToImplementationClassMethod_00.ts b/tests/cases/fourslash/goToImplementationClassMethod_00.ts new file mode 100644 index 00000000000..465db091d32 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationClassMethod_00.ts @@ -0,0 +1,12 @@ +/// + +// Should handle calls made on members declared in a class + +//// class Bar { +//// [|hello() {}|] +//// } +//// +//// new Bar().hel/*reference*/lo; + +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationClassMethod_01.ts b/tests/cases/fourslash/goToImplementationClassMethod_01.ts new file mode 100644 index 00000000000..8b1cb3e762d --- /dev/null +++ b/tests/cases/fourslash/goToImplementationClassMethod_01.ts @@ -0,0 +1,21 @@ +/// + +// Should handle calls made on member declared in an abstract class + +//// abstract class AbstractBar { +//// abstract he/*declaration*/llo(): void; +//// } +//// +//// class Bar extends AbstractBar{ +//// [|hello() {}|] +//// } +//// +//// function whatever(x: AbstractBar) { +//// x.he/*reference*/llo(); +//// } + +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); + +goTo.marker("declaration"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationEnum_00.ts b/tests/cases/fourslash/goToImplementationEnum_00.ts new file mode 100644 index 00000000000..3a93542f806 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationEnum_00.ts @@ -0,0 +1,13 @@ +/// + +// Should handle calls made on members of an enum + +//// enum Foo { +//// [|Foo1 = function initializer() { return 5 } ()|], +//// Foo2 = 6 +//// } +//// +//// Foo.Fo/*reference*/o1; + +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationEnum_01.ts b/tests/cases/fourslash/goToImplementationEnum_01.ts new file mode 100644 index 00000000000..2e7203f3c8f --- /dev/null +++ b/tests/cases/fourslash/goToImplementationEnum_01.ts @@ -0,0 +1,13 @@ +/// + +// Should handle calls made on enum name + +//// [|enum Foo { +//// Foo1 = function initializer() { return 5 } (), +//// Foo2 = 6 +//// }|] +//// +//// Fo/*reference*/o; + +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts new file mode 100644 index 00000000000..71e6266aa20 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts @@ -0,0 +1,27 @@ +/// + +// Should return method implementations in object literals within variable-like declarations + +//// interface Foo { +//// he/*declaration*/llo: () => void +//// } +//// +//// var bar: Foo = { [|hello: helloImpl|] }; +//// +//// function helloImpl () {} +//// +//// function whatever(x: Foo = { [|hello() {/**1*/}|] }) { +//// x.he/*function_call*/llo() +//// } +//// +//// class Bar { +//// x: Foo = { [|hello() {/*2*/}|] } +//// +//// constructor(public f: Foo = { [|hello() {/**3*/}|] } ) {} +//// } + +goTo.marker("function_call"); +verify.allRangesAppearInImplementationList(); + +goTo.marker("declaration"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_01.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_01.ts new file mode 100644 index 00000000000..5f5ba64338b --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_01.ts @@ -0,0 +1,25 @@ +/// + +// Should return implementations in a simple class + +//// interface Foo { +//// hel/*declaration*/lo(): void; +//// okay?: number; +//// } +//// +//// class Bar implements Foo { +//// [|hello() {}|] +//// public sure() {} +//// } +//// +//// function whatever(a: Foo) { +//// a.he/*function_call*/llo(); +//// } +//// +//// whatever(new Bar()); + +goTo.marker("function_call"); +verify.allRangesAppearInImplementationList(); + +goTo.marker("declaration"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_02.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_02.ts new file mode 100644 index 00000000000..f5b1f1eea93 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_02.ts @@ -0,0 +1,25 @@ +/// + +// Should return implementations when left hand side of function call is an abstract class + +//// interface Foo { +//// he/*declaration*/llo(): void +//// } +//// +//// abstract class AbstractBar implements Foo { +//// abstract hello(): void; +//// } +//// +//// class Bar extends AbstractBar { +//// [|hello() {}|] +//// } +//// +//// function whatever(a: AbstractBar) { +//// a.he/*function_call*/llo(); +//// } + +goTo.marker("function_call"); +verify.allRangesAppearInImplementationList(); + +goTo.marker("declaration"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_03.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_03.ts new file mode 100644 index 00000000000..cc22956bb05 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_03.ts @@ -0,0 +1,25 @@ +/// + +// Should not return super implementations when method is implemented in class + +//// interface Foo { +//// hello (): void; +//// } +//// +//// class Bar extends SuperBar { +//// [|hello() {}|] +//// } +//// +//// class SuperBar implements Foo { +//// hello() {} // should not show up +//// } +//// +//// class OtherBar implements Foo { +//// hello() {} // should not show up +//// } +//// +//// new Bar().hel/*function_call*/lo(); +//// new Bar()["hello"](); + +goTo.marker("function_call"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_04.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_04.ts new file mode 100644 index 00000000000..32f5ff41484 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_04.ts @@ -0,0 +1,26 @@ +/// + +// Should return implementation in class and all sub-classes of target + +//// interface Foo { +//// hello (): void; +//// } +//// +//// class Bar extends SuperBar { +//// [|hello() {}|] +//// } +//// +//// class SuperBar implements Foo { +//// [|hello() {}|] +//// } +//// +//// class OtherBar implements Foo { +//// hello() {} // should not show up +//// } +//// +//// function (x: SuperBar) { +//// x.he/*function_call*/llo() +//// } + +goTo.marker("function_call"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts new file mode 100644 index 00000000000..43079b20dcc --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts @@ -0,0 +1,38 @@ +/// + +// Should not return implementations in classes with a shared parent that implements the interface + +//// interface Foo { +//// hello (): void; +//// } +//// +//// class SuperBar implements Foo { +//// [|hello() {}|] +//// } +//// +//// class Bar extends SuperBar { +//// hello2() {} +//// } +//// +//// class OtherBar extends SuperBar { +//// [|hello() {}|] // This could be considered a false positive because it does not extend Bar. Returned because it shares a common ancestor and is structurally equivalent +//// hello2() {} +//// hello3() {} +//// } +//// +//// class NotRelatedToBar { +//// hello() {} // Equivalent to last case, but shares no common ancestors with Bar and so is not returned +//// hello2() {} +//// hello3() {} +//// } +//// +//// class NotBar extends SuperBar { +//// hello() {} // Should not be returned because it is not structurally equivalent to Bar +//// } +//// +//// function whatever(x: Bar) { +//// x.he/*function_call*/llo() +//// } + +goTo.marker("function_call"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts new file mode 100644 index 00000000000..175b5bd50fc --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts @@ -0,0 +1,49 @@ +/// + +// Should not return references to parent interfaces even if the method is declared there + +//// interface SuperFoo { +//// hello (): void; +//// } +//// +//// interface Foo extends SuperFoo { +//// someOtherFunction(): void; +//// } +//// +//// class Bar implements Foo { +//// [|hello() {}|] +//// someOtherFunction() {} +//// } +//// +//// function createFoo(): Foo { +//// return { +//// [|hello() {}|], +//// someOtherFunction() {} +//// }; +//// } +//// +//// var y: Foo = { +//// [|hello() {}|], +//// someOtherFunction() {} +//// }; +//// +//// class FooLike implements SuperFoo { +//// [|hello() {}|] // This case could be considered a false positive. It does not explicitly implement Foo but does implement it structurally and it shares a common ancestor +//// someOtherFunction() {} +//// } +//// +//// class NotRelatedToFoo { +//// hello() {} // This case is equivalent to the last case, but is not returned because it does not share a common ancestor with Foo +//// someOtherFunction() {} +//// } +//// +//// class NotFoo implements SuperFoo { +//// hello() {} // We only want implementations of Foo, even though the function is declared in SuperFoo +//// } +//// +//// function (x: Foo) { +//// x.he/*function_call*/llo() +//// } + +goTo.marker("function_call"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts new file mode 100644 index 00000000000..7d0be4a38a6 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts @@ -0,0 +1,23 @@ +/// + +// Should handle calls made on this + +//// interface Foo { +//// hello (): void; +//// } +//// +//// class SuperBar implements Foo { +//// [|hello() {}|] +//// } +//// +//// class Bar extends SuperBar { +//// whatever() { this.he/*function_call*/llo(); } +//// } +//// +//// class SubBar extends Bar { +//// hello() {} +//// } + + +goTo.marker("function_call"); +verify.allRangesAppearInImplementationList(); diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts new file mode 100644 index 00000000000..cb32f0203d0 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts @@ -0,0 +1,30 @@ +/// + +// Should handle calls made on super + +//// interface Foo { +//// hello (): void; +//// } +//// +//// class SubBar extends Bar { +//// hello() {} +//// } +//// +//// class Bar extends SuperBar { +//// hello() {} +//// +//// whatever() { +//// super.he/*function_call*/llo(); +//// } +//// } +//// +//// class SuperBar extends MegaBar { +//// [|hello() {}|] +//// } +//// +//// class MegaBar implements Foo { +//// hello() {} +//// } + +goTo.marker("function_call"); +verify.allRangesAppearInImplementationList(); diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts new file mode 100644 index 00000000000..eed8c418043 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts @@ -0,0 +1,36 @@ +/// + +// Should handle intersection types + +//// interface Foo { +//// hello(): void; +//// aloha(): void; +//// } +//// +//// interface Bar { +//// hello(): void; +//// goodbye(): void; +//// } +//// +//// class FooImpl implements Foo { +//// hello() {/**FooImpl*/} +//// aloha() {} +//// } +//// +//// class BarImpl implements Bar { +//// hello() {/**BarImpl*/} +//// goodbye() {} +//// } +//// +//// class FooAndBarImpl implements Foo, Bar { +//// [|hello() {/**FooAndBarImpl*/}|] +//// aloha() {} +//// goodbye() {} +//// } +//// +//// function someFunction(x: Foo & Bar) { +//// x.he/*function_call*/llo(); +//// } + +goTo.marker("function_call"); +verify.allRangesAppearInImplementationList(); diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts new file mode 100644 index 00000000000..7cf0533de5f --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts @@ -0,0 +1,36 @@ +/// + +// Should handle union types + +//// interface Foo { +//// hello(): void; +//// aloha(): void; +//// } +//// +//// interface Bar { +//// hello(): void; +//// goodbye(): void; +//// } +//// +//// class FooImpl implements Foo { +//// [|hello() {/**FooImpl*/}|] +//// aloha() {} +//// } +//// +//// class BarImpl implements Bar { +//// [|hello() {/**BarImpl*/}|] +//// goodbye() {} +//// } +//// +//// class FooAndBarImpl implements Foo, Bar { +//// [|hello() {/**FooAndBarImpl*/}|] +//// aloha() {} +//// goodbye() {} +//// } +//// +//// function someFunction(x: Foo | Bar) { +//// x.he/*function_call*/llo(); +//// } + +goTo.marker("function_call"); +verify.allRangesAppearInImplementationList(); diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_12.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_12.ts new file mode 100644 index 00000000000..7d948006fb3 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_12.ts @@ -0,0 +1,12 @@ +/// + +// Should handle members of object literals in type assertion expressions + +//// interface Foo { +//// hel/*reference*/lo(): void; +//// } +//// +//// var x = { [|hello: () => {}|] }; +//// var y = (((({ [|hello: () => {}|] })))); +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceProperty_00.ts b/tests/cases/fourslash/goToImplementationInterfaceProperty_00.ts new file mode 100644 index 00000000000..43b59d021d3 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterfaceProperty_00.ts @@ -0,0 +1,23 @@ +/// + +// Should handle property assignments in object literals within variable like declarations + +//// interface Foo { +//// hello: number +//// } +//// +//// var bar: Foo = { [|hello: 5|] }; +//// +//// +//// function whatever(x: Foo = { [|hello: 5 * 9|] }) { +//// x.he/*reference*/llo +//// } +//// +//// class Bar { +//// x: Foo = { [|hello: 6|] } +//// +//// constructor(public f: Foo = { [|hello: 7|] } ) {} +//// } + +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceProperty_01.ts b/tests/cases/fourslash/goToImplementationInterfaceProperty_01.ts new file mode 100644 index 00000000000..2725a5ab9d4 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterfaceProperty_01.ts @@ -0,0 +1,16 @@ +/// + +// Should handle property assignments within class declarations + +//// interface Foo { hello: number } +//// +//// class Bar implements Foo { +//// [|hello = 5 * 9;|] +//// } +//// +//// function whatever(foo: Foo) { +//// foo.he/*reference*/llo; +//// } + +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_00.ts b/tests/cases/fourslash/goToImplementationInterface_00.ts new file mode 100644 index 00000000000..6e8ca5f3179 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterface_00.ts @@ -0,0 +1,26 @@ +/// + +// Should go to definitions in object literals in variable like declarations when invoked on interface + +//// interface Fo/*interface_definition*/o { +//// hello: () => void +//// } +//// +//// interface Baz extends Foo {} +//// +//// var bar: Foo = [|{ hello: helloImpl /**0*/ }|]; +//// +//// function helloImpl () {} +//// +//// function whatever(x: Foo = [|{ hello() {/**1*/} }|] ) { +//// } +//// +//// class Bar { +//// x: Foo = [|{ hello() {/*2*/} }|] +//// +//// constructor(public f: Foo = [|{ hello() {/**3*/} }|] ) {} +//// } + + +goTo.marker("interface_definition"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_01.ts b/tests/cases/fourslash/goToImplementationInterface_01.ts new file mode 100644 index 00000000000..6d9d5c97507 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterface_01.ts @@ -0,0 +1,25 @@ +/// + +//// interface Fo/*interface_definition*/o { hello(): void } +//// +//// [|class SuperBar implements Foo { +//// hello () {} +//// }|] +//// +//// [|abstract class AbstractBar implements Foo { +//// abstract hello (): void; +//// }|] +//// +//// class Bar extends SuperBar { +//// } +//// +//// class NotAbstractBar extends AbstractBar { +//// hello () {} +//// } +//// +//// var x = new SuperBar(); +//// var y: SuperBar = new SuperBar(); +//// var z: AbstractBar = new NotAbstractBar(); + +goTo.marker("interface_definition"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_02.ts b/tests/cases/fourslash/goToImplementationInterface_02.ts new file mode 100644 index 00000000000..b22de0e266e --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterface_02.ts @@ -0,0 +1,20 @@ +/// + +// Should go to definitions in object literals in return statements of functions with the type of the interface + +//// interface Fo/*interface_definition*/o { hello: () => void } +//// +//// function createFoo(): Foo { +//// return [|{ +//// hello() {} +//// }|]; +//// } +//// +//// function createFooLike() { +//// return { +//// hello() {} +//// }; +//// } + +goTo.marker("interface_definition"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_03.ts b/tests/cases/fourslash/goToImplementationInterface_03.ts new file mode 100644 index 00000000000..b198269d498 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterface_03.ts @@ -0,0 +1,10 @@ +/// + +// Should go to object literals within cast expressions when invoked on interface + +//// interface Fo/*interface_definition*/o { hello: () => void } +//// +//// var x = [|{ hello: () => {} }|]; + +goTo.marker("interface_definition"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_04.ts b/tests/cases/fourslash/goToImplementationInterface_04.ts new file mode 100644 index 00000000000..3989c194363 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterface_04.ts @@ -0,0 +1,22 @@ +/// + +// Should go to function literals that implement the interface within variable like declarations when invoked on an interface + +//// interface Fo/*interface_definition*/o { +//// (a: number): void +//// } +//// +//// var bar: Foo = [|(a) => {/**0*/}|]; +//// +//// function whatever(x: Foo = [|(a) => {/**1*/}|] ) { +//// } +//// +//// class Bar { +//// x: Foo = [|(a) => {/**2*/}|] +//// +//// constructor(public f: Foo = [|function(a) {}|] ) {} +//// } + + +goTo.marker("interface_definition"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_05.ts b/tests/cases/fourslash/goToImplementationInterface_05.ts new file mode 100644 index 00000000000..d0f87c6d6d4 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterface_05.ts @@ -0,0 +1,14 @@ +/// + +// Should go to function literals that implement the interface within type assertions when invoked on an interface + +//// interface Fo/*interface_definition*/o { +//// (a: number): void +//// } +//// +//// let bar2 = [|function(a) {}|]; +//// + + +goTo.marker("interface_definition"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_06.ts b/tests/cases/fourslash/goToImplementationInterface_06.ts new file mode 100644 index 00000000000..7ba2ebfc023 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterface_06.ts @@ -0,0 +1,16 @@ +/// + +// Should go to class expressions that implement a constructor type + +//// interface Fo/*interface_definition*/o { +//// new (a: number): SomeOtherType; +//// } +//// +//// interface SomeOtherType {} +//// +//// let x: Foo = [|class { constructor (a: number) {} }|]; +//// let y = [|class { constructor (a: number) {} }|]; + + +goTo.marker("interface_definition"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInvalid.ts b/tests/cases/fourslash/goToImplementationInvalid.ts new file mode 100644 index 00000000000..a9739c9fe12 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInvalid.ts @@ -0,0 +1,12 @@ +/// + +// Should not crash when invoked on an invalid location + +//// var x1 = 50/*0*/0; +//// var x2 = "hel/*1*/lo"; +//// /*2*/ + +for(var i = 0; i < 3; i++) { + goTo.marker("" + i); + verify.implementationCountIs(0); +} \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_00.ts b/tests/cases/fourslash/goToImplementationLocal_00.ts new file mode 100644 index 00000000000..0d0ba9001b7 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationLocal_00.ts @@ -0,0 +1,9 @@ +/// + +// Should return definition of locally declared functions + +//// he/*function_call*/llo(); +//// [|function hello() {}|] + +goTo.marker("function_call"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_01.ts b/tests/cases/fourslash/goToImplementationLocal_01.ts new file mode 100644 index 00000000000..d2ccb976e95 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationLocal_01.ts @@ -0,0 +1,9 @@ +/// + +// Should return the defintion of locally defined variables + +//// const [|hello = function() {}|]; +//// he/*function_call*/llo(); + +goTo.marker("function_call"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_02.ts b/tests/cases/fourslash/goToImplementationLocal_02.ts new file mode 100644 index 00000000000..47097652d81 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationLocal_02.ts @@ -0,0 +1,8 @@ +/// + +//// const x = { [|hello: () => {}|] }; +//// +//// x.he/*function_call*/llo(); +//// +goTo.marker("function_call"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_03.ts b/tests/cases/fourslash/goToImplementationLocal_03.ts new file mode 100644 index 00000000000..46ad28a3e1d --- /dev/null +++ b/tests/cases/fourslash/goToImplementationLocal_03.ts @@ -0,0 +1,12 @@ +/// + +// Should return the definition when invoked on variable assignment + +//// let [|he/*local_var*/llo = {}|]; +//// +//// x.hello(); +//// +//// hello = {}; +//// +goTo.marker("local_var"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_04.ts b/tests/cases/fourslash/goToImplementationLocal_04.ts new file mode 100644 index 00000000000..3452749bdcf --- /dev/null +++ b/tests/cases/fourslash/goToImplementationLocal_04.ts @@ -0,0 +1,10 @@ +/// + +// Should return definition of function when invoked on the declaration + +//// [|function he/*local_var*/llo() {}|] +//// +//// hello(); +//// +goTo.marker("local_var"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_05.ts b/tests/cases/fourslash/goToImplementationLocal_05.ts new file mode 100644 index 00000000000..e58343d2505 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationLocal_05.ts @@ -0,0 +1,12 @@ +/// + +// Should handle calls made the left hand side of a property access expression + +//// class Bar { +//// public hello() {} +//// } +//// +//// var [|someVar = new Bar()|]; +//// someVa/*reference*/r.hello(); +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_00.ts b/tests/cases/fourslash/goToImplementationNamespace_00.ts new file mode 100644 index 00000000000..edae50425bd --- /dev/null +++ b/tests/cases/fourslash/goToImplementationNamespace_00.ts @@ -0,0 +1,12 @@ +/// + +// Should handle calls on namespaces + +//// [|namespace Foo { +//// export function hello() {} +//// }|] +//// +//// let x = Fo/*reference*/o; + +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_01.ts b/tests/cases/fourslash/goToImplementationNamespace_01.ts new file mode 100644 index 00000000000..4d5b30efa0c --- /dev/null +++ b/tests/cases/fourslash/goToImplementationNamespace_01.ts @@ -0,0 +1,12 @@ +/// + +// Should handle calls on modules + +//// [|module Foo { +//// export function hello() {} +//// }|] +//// +//// let x = Fo/*reference*/o; + +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_02.ts b/tests/cases/fourslash/goToImplementationNamespace_02.ts new file mode 100644 index 00000000000..ea24336be7e --- /dev/null +++ b/tests/cases/fourslash/goToImplementationNamespace_02.ts @@ -0,0 +1,12 @@ +/// + +// Should handle property access expressions on namespaces + +//// namespace Foo { +//// [|export function hello() {}|] +//// } +//// +//// Foo.hell/*reference*/o(); + +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_03.ts b/tests/cases/fourslash/goToImplementationNamespace_03.ts new file mode 100644 index 00000000000..c4388df7e8a --- /dev/null +++ b/tests/cases/fourslash/goToImplementationNamespace_03.ts @@ -0,0 +1,12 @@ +/// + +// Should handle property access expressions on namespaces + +//// module Foo { +//// [|export function hello() {}|] +//// } +//// +//// Foo.hell/*reference*/o(); + +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_04.ts b/tests/cases/fourslash/goToImplementationNamespace_04.ts new file mode 100644 index 00000000000..5f4267da530 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationNamespace_04.ts @@ -0,0 +1,26 @@ +/// + +// Should handle sub-namespaces + +//// /*parentNamespace*/namespace Foo { +//// export function hello() {} +//// } +//// +//// /*parentNamespace2*/namespace Foo./*childNamespace*/Bar { +//// export function okay() {} +//// } +//// +//// Fo/*parentReference*/o.hello(); +//// Foo.Ba/*childReference*/r.okay(); + +goTo.marker("parentReference"); +goTo.implementation(0); +verify.caretAtMarker("parentNamespace"); + +goTo.marker("parentReference"); +goTo.implementation(1); +verify.caretAtMarker("parentNamespace2"); + +goTo.marker("childReference"); +goTo.implementation(); +verify.caretAtMarker("childNamespace") \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_05.ts b/tests/cases/fourslash/goToImplementationNamespace_05.ts new file mode 100644 index 00000000000..3dfb1fcca49 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationNamespace_05.ts @@ -0,0 +1,26 @@ +/// + +// Should handle sub-modules + +//// /*parentModule*/module Foo { +//// export function hello() {} +//// } +//// +//// /*parentModule2*/module Foo./*childModule*/Bar { +//// export function okay() {} +//// } +//// +//// Fo/*parentReference*/o.hello(); +//// Foo.Ba/*childReference*/r.okay(); + +goTo.marker("parentReference"); +goTo.implementation(0); +verify.caretAtMarker("parentModule"); + +goTo.marker("parentReference"); +goTo.implementation(1); +verify.caretAtMarker("parentModule2"); + +goTo.marker("childReference"); +goTo.implementation(); +verify.caretAtMarker("childModule") \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_06.ts b/tests/cases/fourslash/goToImplementationNamespace_06.ts new file mode 100644 index 00000000000..38aeb47feae --- /dev/null +++ b/tests/cases/fourslash/goToImplementationNamespace_06.ts @@ -0,0 +1,28 @@ +/// + +// Should handle types that are members of a namespace in type references and heritage clauses + +//// namespace Foo { +//// export interface Bar { +//// hello(): void; +//// } +//// +//// [|class BarImpl implements Bar { +//// hello() {} +//// }|] +//// } +//// +//// [|class Baz implements Foo.Bar { +//// hello() {} +//// }|] +//// +//// var someVar1 : Foo.Bar = [|{ hello: () => {/**1*/} }|]; +//// +//// var someVar2 = [|{ hello: () => {/**2*/} }|]; +//// +//// function whatever(x: Foo.Ba/*reference*/r) { +//// +//// } + +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); diff --git a/tests/cases/fourslash/goToImplementationNamespace_07.ts b/tests/cases/fourslash/goToImplementationNamespace_07.ts new file mode 100644 index 00000000000..fc64275d906 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationNamespace_07.ts @@ -0,0 +1,28 @@ +/// + +// Should handle types that are members of a module in type references and heritage clauses + +//// module Foo { +//// export interface Bar { +//// hello(): void; +//// } +//// +//// [|class BarImpl implements Bar { +//// hello() {} +//// }|] +//// } +//// +//// [|class Baz implements Foo.Bar { +//// hello() {} +//// }|] +//// +//// var someVar1 : Foo.Bar = [|{ hello: () => {/**1*/} }|]; +//// +//// var someVar2 = [|{ hello: () => {/**2*/} }|]; +//// +//// function whatever(x: Foo.Ba/*reference*/r) { +//// +//// } + +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); diff --git a/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_00.ts b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_00.ts new file mode 100644 index 00000000000..ad4a0cd6b51 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_00.ts @@ -0,0 +1,43 @@ +/// + +// Should handle shorthand property assignments of class constructors + +//// interface Foo { +//// someFunction(): void; +//// } +//// +//// interface FooConstructor { +//// new (): Foo +//// } +//// +//// interface Bar { +//// Foo: FooConstructor; +//// } +//// +//// var x = /*classExpression*/class Foo { +//// createBarInClassExpression(): Bar { +//// return { +//// Fo/*classExpressionRef*/o +//// }; +//// } +//// +//// someFunction() {} +//// } +//// +//// /*declaredClass*/class Foo { +//// +//// } +//// +//// function createBarUsingClassDeclaration(): Bar { +//// return { +//// Fo/*declaredClassRef*/o +//// }; +//// } + +goTo.marker("classExpressionRef"); +goTo.implementation(); +verify.caretAtMarker("classExpression"); + +goTo.marker("declaredClassRef"); +goTo.implementation(); +verify.caretAtMarker("declaredClass"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_01.ts b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_01.ts new file mode 100644 index 00000000000..abb0aad0602 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_01.ts @@ -0,0 +1,48 @@ +/// + +// Should handle shorthand property assignments of class constructors when invoked on member of interface + +//// interface Foo { +//// someFunction(): void; +//// } +//// +//// interface FooConstructor { +//// new (): Foo +//// } +//// +//// interface Bar { +//// Foo: FooConstructor; +//// } +//// +//// // Class expression that gets used in a bar implementation +//// var x = [|class Foo { +//// createBarInClassExpression(): Bar { +//// return { +//// Foo +//// }; +//// } +//// +//// someFunction() {} +//// }|]; +//// +//// // Class declaration that gets used in a bar implementation. This class has multiple definitions +//// // (the class declaration and the interface above), but we only want the class returned +//// [|class Foo { +//// +//// }|] +//// +//// function createBarUsingClassDeclaration(): Bar { +//// return { +//// Foo +//// }; +//// } +//// +//// // Class expression that does not get used in a bar implementation +//// var y = class Foo { +//// someFunction() {} +//// }; +//// +//// createBarUsingClassDeclaration().Fo/*reference*/o; + +goTo.marker("reference"); +verify.allRangesAppearInImplementationList();; \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_02.ts b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_02.ts new file mode 100644 index 00000000000..8db6cbce5de --- /dev/null +++ b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_02.ts @@ -0,0 +1,22 @@ +/// + +// Should go to implementation of properties that are assigned to implementations of an interface using shorthand notation + +//// interface Foo { +//// hello(): void; +//// } +//// +//// function createFoo(): Foo { +//// return { +//// hello +//// }; +//// +//// [|function hello() {}|] +//// } +//// +//// function whatever(x: Foo) { +//// x.h/*function_call*/ello(); +//// } + +goTo.marker("function_call"); +verify.allRangesAppearInImplementationList(); diff --git a/tests/cases/fourslash/goToImplementationSuper_00.ts b/tests/cases/fourslash/goToImplementationSuper_00.ts new file mode 100644 index 00000000000..b7def58ca59 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationSuper_00.ts @@ -0,0 +1,16 @@ +/// + +// Should go to super class declaration when invoked on a super call expression + +//// [|class Foo { +//// constructor() {} +//// }|] +//// +//// class Bar extends Foo { +//// constructor() { +//// su/*super_call*/per(); +//// } +//// } + +goTo.marker("super_call"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationSuper_01.ts b/tests/cases/fourslash/goToImplementationSuper_01.ts new file mode 100644 index 00000000000..11ba0719e5d --- /dev/null +++ b/tests/cases/fourslash/goToImplementationSuper_01.ts @@ -0,0 +1,16 @@ +/// + +// Should go to the super class declaration when invoked on the super keyword in a property access expression + +//// [|class Foo { +//// hello() {} +//// }|] +//// +//// class Bar extends Foo { +//// hello() { +//// sup/*super_call*/er.hello(); +//// } +//// } + +goTo.marker("super_call"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationThis_00.ts b/tests/cases/fourslash/goToImplementationThis_00.ts new file mode 100644 index 00000000000..0e4a0ff9849 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationThis_00.ts @@ -0,0 +1,14 @@ +/// + +// Should go to class declaration when invoked on this keyword in property access expression + +//// [|class Bar extends Foo { +//// hello() { +//// thi/*this_call*/s.whatever(); +//// } +//// +//// whatever() {} +//// }|] + +goTo.marker("this_call"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationThis_01.ts b/tests/cases/fourslash/goToImplementationThis_01.ts new file mode 100644 index 00000000000..001ebc08b9f --- /dev/null +++ b/tests/cases/fourslash/goToImplementationThis_01.ts @@ -0,0 +1,12 @@ +/// + +// Should go to class declaration when invoked on a this type reference + +//// [|class Bar extends Foo { +//// hello(): th/*this_type*/is { +//// return this; +//// } +//// }|] + +goTo.marker("this_type"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/server/implementation01.ts b/tests/cases/fourslash/server/implementation01.ts new file mode 100644 index 00000000000..24d5f935bda --- /dev/null +++ b/tests/cases/fourslash/server/implementation01.ts @@ -0,0 +1,9 @@ +/// + +// @Filename: a.ts +//// interface Fo/*1*/o {} +//// /*2*/class Bar implements Foo {} + +goTo.marker('1'); +goTo.implementation(); +verify.caretAtMarker('2'); \ No newline at end of file diff --git a/tests/cases/fourslash/shims-pp/getImplementationAtPosition.ts b/tests/cases/fourslash/shims-pp/getImplementationAtPosition.ts new file mode 100644 index 00000000000..a509922f919 --- /dev/null +++ b/tests/cases/fourslash/shims-pp/getImplementationAtPosition.ts @@ -0,0 +1,35 @@ +/// + +// @Filename: goToImplementationDifferentFile_Implementation.ts +//// /*fooClassImplementation*/class FooImpl implements Foo {} +//// +//// /*barClassImplementation*/class Bar { +//// /*barHelloFunctionImplementation*/hello() {} +//// } +//// + +// @Filename: goToImplementationDifferentFile_Consumption.ts +//// interface Fo/*fooClassReference*/o {} +//// +//// var x = new B/*barClassReference*/ar(); +//// +//// x.hel/*barHelloFunctionReference*/lo(); +//// +//// /*thisImplementation*/class SomeClass { +//// someMethod() { +//// thi/*thisReference*/s.someMethod(); +//// } +//// } + +var markerList = [ + "fooClass", + "barClass", + "barHelloFunction", + "this" +]; + +markerList.forEach((marker) => { + goTo.marker(marker + 'Reference'); + goTo.implementation(); + verify.caretAtMarker(marker + 'Implementation'); +}); diff --git a/tests/cases/fourslash/shims/getImplementationAtPosition.ts b/tests/cases/fourslash/shims/getImplementationAtPosition.ts new file mode 100644 index 00000000000..a509922f919 --- /dev/null +++ b/tests/cases/fourslash/shims/getImplementationAtPosition.ts @@ -0,0 +1,35 @@ +/// + +// @Filename: goToImplementationDifferentFile_Implementation.ts +//// /*fooClassImplementation*/class FooImpl implements Foo {} +//// +//// /*barClassImplementation*/class Bar { +//// /*barHelloFunctionImplementation*/hello() {} +//// } +//// + +// @Filename: goToImplementationDifferentFile_Consumption.ts +//// interface Fo/*fooClassReference*/o {} +//// +//// var x = new B/*barClassReference*/ar(); +//// +//// x.hel/*barHelloFunctionReference*/lo(); +//// +//// /*thisImplementation*/class SomeClass { +//// someMethod() { +//// thi/*thisReference*/s.someMethod(); +//// } +//// } + +var markerList = [ + "fooClass", + "barClass", + "barHelloFunction", + "this" +]; + +markerList.forEach((marker) => { + goTo.marker(marker + 'Reference'); + goTo.implementation(); + verify.caretAtMarker(marker + 'Implementation'); +}); From 457b67f67a141097c56807db165f1510d94db47f Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Tue, 23 Aug 2016 11:12:01 -0700 Subject: [PATCH 02/46] PR Feedback --- src/compiler/utilities.ts | 5 ----- src/server/session.ts | 4 ++-- src/services/services.ts | 20 ++++++++++++++++++-- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 35dea56cf0b..870df4a54af 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1669,11 +1669,6 @@ namespace ts { return false; } - export function isFunctionDeclarationIdentifierName(node: Identifier): boolean { - return node.parent.kind === SyntaxKind.FunctionDeclaration && - (node.parent).name === node; - } - // An alias symbol is created by one of the following declarations: // import = ... // import from ... diff --git a/src/server/session.ts b/src/server/session.ts index 783451e02c6..2eb994519b1 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -366,9 +366,9 @@ namespace ts.server { } const compilerService = project.compilerService; - const position = compilerService.host.lineOffsetToPosition(file, line, offset); + const implementations = compilerService.languageService.getImplementationAtPosition(file, + compilerService.host.lineOffsetToPosition(file, line, offset)); - const implementations = compilerService.languageService.getImplementationAtPosition(file, position); if (!implementations) { return undefined; } diff --git a/src/services/services.ts b/src/services/services.ts index bb63f30c603..6f682822bba 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -5302,6 +5302,8 @@ namespace ts { const node = getTouchingPropertyName(getValidSourceFile(fileName), position); const typeChecker = program.getTypeChecker(); + // If invoked directly on a shorthand property assignment, then return + // the declaration of the symbol being assigned (not the symbol being assigned to). if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { const entry = getReferenceEntryForShorthandPropertyAssignment(node, typeChecker); entries.push({ @@ -5309,6 +5311,10 @@ namespace ts { fileName: entry.fileName }); } + + // For most symbols, the definition is the same as the implementation so we can just + // call "Go to Definition". This case should handle anything that is not a type + // reference to or member of an interface, class, or union/intersection type. else if (definitionIsImplementation(node, typeChecker)) { const definitions = getDefinitionAtPosition(fileName, position); forEach(definitions, (definition: DefinitionInfo) => { @@ -5318,8 +5324,12 @@ namespace ts { }); }); } + + // Interfaces, classes, and unions/intersection types separate the implementation and + // definition so "Go to Definition" is not sufficient. This case handles invocations + // on type references and members of those types. else { - // Do a search for all references and filter them down to implementations only + // Perform "Find all References" and filter them down to implementations only const result = getReferencedSymbolsForNode(node, program.getSourceFiles(), /*findInStrings*/false, /*findInComments*/false, /*implementations*/true); forEach(result, referencedSymbol => { @@ -5362,7 +5372,8 @@ namespace ts { return false; } - // Also check the right hand side to see if this is a type being accessed on a namespace/module + // Also check the right hand side to see if this is a type being accessed on a namespace/module. + // For example, SomeModule.SomeType const rightHandType = typeChecker.getTypeAtLocation(node); return rightHandType && !(rightHandType.getFlags() & (TypeFlags.Class | TypeFlags.Interface | TypeFlags.UnionOrIntersection)); } @@ -5424,6 +5435,11 @@ namespace ts { return isIdentifierOfClass(node) || isIdentifierOfEnumDeclaration(node); } + function isFunctionDeclarationIdentifierName(node: Identifier): boolean { + return node.parent.kind === SyntaxKind.FunctionDeclaration && + (node.parent).name === node; + } + function isIdentifierOfClass(node: Identifier) { return (node.parent.kind === SyntaxKind.ClassDeclaration || node.parent.kind === SyntaxKind.ClassExpression) && (node.parent).name === node; From 051c7b0217e85228342d6c1b974735e2978b0689 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Mon, 29 Aug 2016 15:46:26 -0700 Subject: [PATCH 03/46] Refine the search set instead of filtering to implementations --- src/compiler/checker.ts | 3 +- src/compiler/types.ts | 1 - src/services/services.ts | 274 ++++++------------ .../goToImplementationInterfaceMethod_05.ts | 2 +- .../goToImplementationInterfaceMethod_06.ts | 2 +- 5 files changed, 91 insertions(+), 191 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f7ce30fe4f3..193deded4c5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -103,8 +103,7 @@ namespace ts { getJsxElementAttributesType, getJsxIntrinsicTagNames, - isOptionalParameter, - isTypeAssignableTo + isOptionalParameter }; const tupleTypes = createMap(); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index adfde2d0605..a61d4a360b3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1889,7 +1889,6 @@ namespace ts { getJsxElementAttributesType(elementNode: JsxOpeningLikeElement): Type; getJsxIntrinsicTagNames(): Symbol[]; isOptionalParameter(node: ParameterDeclaration): boolean; - isTypeAssignableTo(source: Type, target: Type): boolean; // Should not be called directly. Should only be accessed through the Program instance. /* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; diff --git a/src/services/services.ts b/src/services/services.ts index 6f682822bba..914ae98746a 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -6272,10 +6272,6 @@ namespace ts { } } - if (implementations) { - return filterToImplementations(node, symbol, result, indexToSymbol); - } - return result; function getDefinition(symbol: Symbol): DefinitionInfo { @@ -6546,6 +6542,20 @@ namespace ts { const start = findInComments ? container.getFullStart() : container.getStart(); const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, start, container.getEnd()); + // If we are just looking for implementations and this is a property access expression, we need to get the + // symbol of the local type of the symbol the property is being accessed on. This is because our search + // symbol may have a different parent symbol if the local type's symbol does not declare the property + // being accessed (i.e. it is declared in some parent class or interface) + let parentSymbol: Symbol = undefined; + let inheritanceCache: Map = undefined; + if (implementations && searchLocation.parent && searchLocation.parent.kind === SyntaxKind.PropertyAccessExpression && searchLocation === (searchLocation.parent).name) { + const localParentType = typeChecker.getTypeAtLocation((searchLocation.parent).expression); + if (localParentType && localParentType.symbol && localParentType.symbol.getFlags() & (SymbolFlags.Interface | SymbolFlags.Class) && localParentType.symbol.parent !== searchSymbol.parent) { + parentSymbol = localParentType.symbol; + inheritanceCache = createMap(); + } + } + if (possiblePositions.length) { // Build the set of symbols to search for, initially it has only the current symbol const searchSymbols = populateSearchSymbolSet(searchSymbol, searchLocation); @@ -6554,7 +6564,7 @@ namespace ts { cancellationToken.throwIfCancellationRequested(); const referenceLocation = getTouchingPropertyName(sourceFile, position); - if (!isValidReferencePosition(referenceLocation, searchText)) { + if (!implementations && !isValidReferencePosition(referenceLocation, searchText)) { // This wasn't the start of a token. Check to see if it might be a // match in a comment or string if that's what the caller is asking // for. @@ -6586,11 +6596,15 @@ namespace ts { if (referenceSymbol) { const referenceSymbolDeclaration = referenceSymbol.valueDeclaration; const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); - const relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation); + const relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation, parentSymbol, inheritanceCache); if (relatedSymbol) { - const referencedSymbol = getReferencedSymbol(relatedSymbol); - referencedSymbol.references.push(getReferenceEntryFromNode(referenceLocation)); + const referenceEntry = implementations ? getImplementationReferenceEntryForNode(referenceLocation) : getReferenceEntryFromNode(referenceLocation); + + if (referenceEntry) { + const referencedSymbol = getReferencedSymbol(relatedSymbol); + referencedSymbol.references.push(referenceEntry); + } } /* Because in short-hand property assignment, an identifier which stored as name of the short-hand property assignment * has two meaning : property name and property value. Therefore when we do findAllReference at the position where @@ -6599,8 +6613,11 @@ namespace ts { * position of property accessing, the referenceEntry of such position will be handled in the first case. */ else if (!(referenceSymbol.flags & SymbolFlags.Transient) && searchSymbols.indexOf(shorthandValueSymbol) >= 0) { - const referencedSymbol = getReferencedSymbol(shorthandValueSymbol); - referencedSymbol.references.push(getReferenceEntryFromNode(referenceSymbolDeclaration.name)); + const referenceEntry = implementations ? getImplementationReferenceEntryForNode(referenceSymbolDeclaration.name) : getReferenceEntryFromNode(referenceSymbolDeclaration.name); + if (referenceEntry) { + const referencedSymbol = getReferencedSymbol(shorthandValueSymbol); + referencedSymbol.references.push(referenceEntry); + } } } }); @@ -6634,141 +6651,10 @@ namespace ts { } } - function filterToImplementations(node: Node, searchSymbol: Symbol, refs: ReferencedSymbol[], indexToSymbol: {[index: number]: Symbol}): ReferencedSymbol[] { - if (isPropertyAccessExpression(node.parent) && node.parent.name === node) { - const type = typeChecker.getTypeAtLocation(node.parent.expression); - - if (type.getFlags() & TypeFlags.Class) { - // The search results in refs will contain all implementations of the property. This includes - // all implementations in classes that parentSymbol extends from and sibling implementations - // (i.e. implementations in classes with common ancestors that declare the property). We need to - // filter the results to only the implementation used by parentSymbol's class and any implementations - // in any sub-classes - return filterToClassMemberImplementations(node.parent, searchSymbol, refs, indexToSymbol); - } - else if (type.getFlags() & (TypeFlags.UnionOrIntersection | TypeFlags.Interface)) { - // If parentSymbol did not declare the property being accessed, then the search results - // in refs will also contain references to the interfaces that parentSymbol inherits from. - // We need to filter out any implementations of those parent interfaces in addition to filtering out the - // non-implementation references - return filterReferenceEntries(refs, (entry) => { - const impl = getImplementationFromEntry(entry); - if (impl) { - const entryNode = getTokenAtPosition(getValidSourceFile(entry.fileName), entry.textSpan.start); - const element = getContainingObjectLiteralElement(entryNode); - if (element && element.parent && element.parent.kind === SyntaxKind.ObjectLiteralExpression) { - const objType = getDeclaredTypeOfObjectLiteralExpression(element.parent); - - if (objType && typeChecker.isTypeAssignableTo(objType, type)) { - return impl; - } - } - else { - const defClass = getContainingClass(entryNode); - if (defClass) { - const classType = typeChecker.getTypeAtLocation(defClass); - if (typeChecker.isTypeAssignableTo(classType, type)) { - return impl; - } - } - } - } - }); - } - } - - return filterReferenceEntries(refs, getImplementationFromEntry); - } - - function getDeclaredTypeOfObjectLiteralExpression(node: Node): Type { - if (node && node.parent) { - if (node.parent.kind === SyntaxKind.ParenthesizedExpression) { - return getDeclaredTypeOfObjectLiteralExpression(node.parent); - } - - if (isVariableLike(node.parent) && node.parent.type) { - return typeChecker.getTypeAtLocation(node.parent.type); - } - else if (node.parent.kind === SyntaxKind.ReturnStatement) { - const containerSig = typeChecker.getSignatureFromDeclaration(getContainingFunction(node)); - return typeChecker.getReturnTypeOfSignature(containerSig); - } - else if (node.parent.kind === SyntaxKind.TypeAssertionExpression) { - return typeChecker.getTypeAtLocation((node.parent).type); - } - } - return undefined; - } - - function filterReferenceEntries(refs: ReferencedSymbol[], filterer: (x: ReferenceEntry) => ReferenceEntry): ReferencedSymbol[] { - const result: ReferencedSymbol[] = []; - forEach(refs, (ref) => { - const filtered: ReferenceEntry[] = []; - forEach(ref.references, (entry) => { - const filteredEntry = filterer(entry); - if (filteredEntry) { - filtered.push(filteredEntry); - } - }); - if (filtered.length) { - result.push({ definition: ref.definition, references: filtered }); - } - }); - return result; - } - - function filterToClassMemberImplementations(parent: PropertyAccessExpression, searchSymbol: Symbol, refs: ReferencedSymbol[], indexToSymbol: {[index: number]: Symbol}): ReferencedSymbol[] { - // Need to find out what class this member is being accessed on - const type = typeChecker.getTypeAtLocation(parent.expression); - const classHierarchy: Symbol[] = getClassHierarchy(searchSymbol.parent); - - let lowest: ReferencedSymbol[]; - let lowestRank: number; - - // Filter down the references to those that refer to implementations of the symbol. That is, implementations - // from subclasses of the parent class and the lowest implementation in the parent class' class hierarchy - forEach(refs, (refSymbol, index) => { - const actual = indexToSymbol[index]; - - // We only care about implementations in classes in the hierarchy - if (actual.parent.getFlags() & SymbolFlags.Interface) { - return; - } - const rank = classHierarchy.indexOf(actual.parent); - - // No need to check anything past the lowest we have found so far - if (lowest && rank > lowestRank) { - return; - } - - const implementations: ReferenceEntry[] = []; - forEach(refSymbol.references, (entry) => { - const impl = getImplementationFromEntry(entry, type, classHierarchy); - if (impl) { - implementations.push(impl); - } - }); - if (implementations.length) { - if (!lowest || rank < lowestRank) { - lowest = [{ definition: refSymbol.definition, references: implementations }]; - lowestRank = rank; - } - else if (rank === lowestRank) { - lowest.push({ definition: refSymbol.definition, references: implementations }); - } - } - }); - - return lowest; - } - - function getImplementationFromEntry(entry: ReferenceEntry, base?: Type, hierarchy?: Symbol[]): ReferenceEntry { - const sourceFile = getValidSourceFile(entry.fileName); - const refNode = getTouchingPropertyName(sourceFile, entry.textSpan.start); - + function getImplementationReferenceEntryForNode(refNode: Node): ReferenceEntry { // Check to make sure this reference is either part of a sub class or a class that we explicitly // inherit from in the class hierarchy - if (isMemberOfSubOrParentClass(refNode, base, hierarchy) && refNode.kind === SyntaxKind.Identifier) { + if (refNode.kind === SyntaxKind.Identifier) { // Check if we found a function/propertyAssignment/method with an implementation or initializer if (isIdentifierOfImplementation(refNode)) { return getReferenceEntryFromNode(refNode.parent); @@ -6805,25 +6691,6 @@ namespace ts { } } - function isMemberOfSubOrParentClass(reference: Node, base: Type, hierarchy: Symbol[]) { - if (!base || !hierarchy) { - return true; - } - const referenceSymbol = typeChecker.getSymbolAtLocation(reference); - if (referenceSymbol && referenceSymbol.parent) { - if (hierarchy.indexOf(referenceSymbol.parent) !== -1) { - return true; - } - - const referenceParentDeclarations = referenceSymbol.parent.getDeclarations(); - if (referenceParentDeclarations.length) { - const referenceParentType = typeChecker.getTypeAtLocation(referenceParentDeclarations[0]); - return typeChecker.isTypeAssignableTo(referenceParentType, base); - } - } - return false; - } - function getContainingTypeReference(node: Node): Node { if (node) { if (node.kind === SyntaxKind.TypeReference) { @@ -6867,32 +6734,66 @@ namespace ts { node.kind === SyntaxKind.ClassExpression; } - function getClassHierarchy(symbol: Symbol) { - const classes: Symbol[] = []; - getClassHierarchyRecursive(symbol, classes, createMap()); - return classes; + /** + * Determines if the parent symbol occurs somewhere in the child's ancestry. If the parent symbol + * is an interface, determines if some ancestor of the child symbol extends or inherits from it. + * This also takes in a cache of previous results which makes this slightly more efficient and is + * necessary to avoid potential loops like so: + * class A extends B { } + * class B extends A { } + * + * @param child A class or interface Symbol + * @param parent Another class or interface Symbol + * @param cachedResults A map of symbol names to booleans indicating previous results + */ + function inheritsFrom(child: Symbol, parent: Symbol, cachedResults: Map = createMap()): boolean { + const parentIsInterface = parent.getFlags() & SymbolFlags.Interface; + return searchHierarchy(child, cachedResults); - function getClassHierarchyRecursive(symbol: Symbol, result: Symbol[], previousIterationSymbolsCache: SymbolTable) { - if (hasProperty(previousIterationSymbolsCache, symbol.name)) { - return; + function searchHierarchy(symbol: Symbol, cachedResults: Map): boolean { + if (symbol === parent) { + return true; + } + else if (symbol.name in cachedResults) { + return cachedResults[symbol.name]; } - previousIterationSymbolsCache[symbol.name] = symbol; - if (result.indexOf(symbol) !== -1) { - return; - } - result.push(symbol); - forEach(symbol.getDeclarations(), (decl) => { - if (isClassLike(decl)) { - const heritage = getClassExtendsHeritageClauseElement(decl); - if (heritage) { - const type = typeChecker.getTypeAtLocation(heritage); - if (type && type.symbol) { - getClassHierarchyRecursive(type.symbol, result, previousIterationSymbolsCache); + cachedResults[symbol.name] = false; + + const inherits = forEach(symbol.getDeclarations(), (declaration) => { + if (isClassLike(declaration)) { + if (parentIsInterface) { + const interfaceReferences = getClassImplementsHeritageClauseElements(declaration); + if (interfaceReferences) { + for (const typeReference of interfaceReferences) { + if (searchTypeReference(typeReference, cachedResults)) { + return true; + } + } } } + return searchTypeReference(getClassExtendsHeritageClauseElement(declaration), cachedResults); } + else if (declaration.kind === SyntaxKind.InterfaceDeclaration) { + if (parentIsInterface) { + return forEach(getInterfaceBaseTypeNodes(declaration), base => searchTypeReference(base, cachedResults)); + } + } + return false; }); + + cachedResults[symbol.name] = inherits; + return inherits; + } + + function searchTypeReference(typeReference: ExpressionWithTypeArguments, cachedResults: Map) { + if (typeReference) { + const type = typeChecker.getTypeAtLocation(typeReference); + if (type && type.symbol) { + return searchHierarchy(type.symbol, cachedResults); + } + } + return false; } } @@ -7176,7 +7077,7 @@ namespace ts { } // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions - if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { + if (!implementations && rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ createMap()); } }); @@ -7243,7 +7144,7 @@ namespace ts { } } - function getRelatedSymbol(searchSymbols: Symbol[], referenceSymbol: Symbol, referenceLocation: Node): Symbol { + function getRelatedSymbol(searchSymbols: Symbol[], referenceSymbol: Symbol, referenceLocation: Node, parentSymbol: Symbol, inheritanceCache: Map): Symbol { if (searchSymbols.indexOf(referenceSymbol) >= 0) { return referenceSymbol; } @@ -7252,7 +7153,7 @@ namespace ts { // symbols but by looking up for related symbol of this alias so it can handle multiple level of indirectness. const aliasSymbol = getAliasSymbolForPropertyNameSymbol(referenceSymbol, referenceLocation); if (aliasSymbol) { - return getRelatedSymbol(searchSymbols, aliasSymbol, referenceLocation); + return getRelatedSymbol(searchSymbols, aliasSymbol, referenceLocation, parentSymbol, inheritanceCache); } // If the reference location is in an object literal, try to get the contextual type for the @@ -7295,8 +7196,9 @@ namespace ts { } // Finally, try all properties with the same name in any type the containing type extended or implemented, and - // see if any is in the list - if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { + // see if any is in the list. If we were passed a parent symbol, only include types that are subtypes of the + // parent symbol + if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface) && (!parentSymbol || inheritsFrom(rootSymbol.parent, parentSymbol, inheritanceCache))) { const result: Symbol[] = []; getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ createMap()); return forEach(result, s => searchSymbols.indexOf(s) >= 0 ? s : undefined); diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts index 43079b20dcc..5e8bd76a072 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts @@ -15,7 +15,7 @@ //// } //// //// class OtherBar extends SuperBar { -//// [|hello() {}|] // This could be considered a false positive because it does not extend Bar. Returned because it shares a common ancestor and is structurally equivalent +//// hello() {} //// hello2() {} //// hello3() {} //// } diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts index 175b5bd50fc..b7f275e6c07 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts @@ -28,7 +28,7 @@ //// }; //// //// class FooLike implements SuperFoo { -//// [|hello() {}|] // This case could be considered a false positive. It does not explicitly implement Foo but does implement it structurally and it shares a common ancestor +//// hello() {} //// someOtherFunction() {} //// } //// From 115141cb50c878f4a2d43939252c4e15bd3d85d0 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Mon, 29 Aug 2016 18:09:16 -0700 Subject: [PATCH 04/46] Also check inheritance for union and intersection types --- src/services/services.ts | 58 +++++++++++++++---- .../goToImplementationInterfaceMethod_10.ts | 29 +++++++--- .../goToImplementationInterfaceMethod_11.ts | 48 ++++----------- .../goToImplementationInterfaceMethod_12.ts | 12 ---- 4 files changed, 80 insertions(+), 67 deletions(-) delete mode 100644 tests/cases/fourslash/goToImplementationInterfaceMethod_12.ts diff --git a/src/services/services.ts b/src/services/services.ts index 914ae98746a..511d76d30f7 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1844,6 +1844,13 @@ namespace ts { owners: string[]; } + // Internal interface used for tracking state in find all references when checking + // the inheritance hierarchy of property access expressions + interface SymbolInheritanceState { + symbol: Symbol; + cachedInheritanceResults: Map; + } + export interface DisplayPartsSymbolWriter extends SymbolWriter { displayParts(): SymbolDisplayPart[]; } @@ -6546,13 +6553,17 @@ namespace ts { // symbol of the local type of the symbol the property is being accessed on. This is because our search // symbol may have a different parent symbol if the local type's symbol does not declare the property // being accessed (i.e. it is declared in some parent class or interface) - let parentSymbol: Symbol = undefined; - let inheritanceCache: Map = undefined; - if (implementations && searchLocation.parent && searchLocation.parent.kind === SyntaxKind.PropertyAccessExpression && searchLocation === (searchLocation.parent).name) { + let parentSymbols: SymbolInheritanceState[] = undefined; + + if (implementations && isRightSideOfPropertyAccess(searchLocation)) { const localParentType = typeChecker.getTypeAtLocation((searchLocation.parent).expression); - if (localParentType && localParentType.symbol && localParentType.symbol.getFlags() & (SymbolFlags.Interface | SymbolFlags.Class) && localParentType.symbol.parent !== searchSymbol.parent) { - parentSymbol = localParentType.symbol; - inheritanceCache = createMap(); + if (localParentType) { + if (localParentType.symbol && isClassOrInterfaceReference(localParentType.symbol) && localParentType.symbol.parent !== searchSymbol.parent) { + parentSymbols = [createSymbolInheritanceState(localParentType.symbol)]; + } + else if (localParentType.getFlags() & TypeFlags.UnionOrIntersection) { + parentSymbols = map(getSymbolsForComponentTypes(localParentType), createSymbolInheritanceState); + } } } @@ -6596,7 +6607,7 @@ namespace ts { if (referenceSymbol) { const referenceSymbolDeclaration = referenceSymbol.valueDeclaration; const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); - const relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation, parentSymbol, inheritanceCache); + const relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation, parentSymbols); if (relatedSymbol) { const referenceEntry = implementations ? getImplementationReferenceEntryForNode(referenceLocation) : getReferenceEntryFromNode(referenceLocation); @@ -6691,6 +6702,18 @@ namespace ts { } } + function getSymbolsForComponentTypes(type: UnionOrIntersectionType, result: Symbol[] = []): Symbol[] { + for (const componentType of type.types) { + if (componentType.symbol && componentType.symbol.getFlags() & (SymbolFlags.Class | SymbolFlags.Interface)) { + result.push(componentType.symbol); + } + if (componentType.getFlags() & TypeFlags.UnionOrIntersection) { + getSymbolsForComponentTypes(componentType, result); + } + } + return result; + } + function getContainingTypeReference(node: Node): Node { if (node) { if (node.kind === SyntaxKind.TypeReference) { @@ -6786,7 +6809,7 @@ namespace ts { return inherits; } - function searchTypeReference(typeReference: ExpressionWithTypeArguments, cachedResults: Map) { + function searchTypeReference(typeReference: ExpressionWithTypeArguments, cachedResults: Map): boolean { if (typeReference) { const type = typeChecker.getTypeAtLocation(typeReference); if (type && type.symbol) { @@ -6797,6 +6820,13 @@ namespace ts { } } + function createSymbolInheritanceState(symbol: Symbol): SymbolInheritanceState { + return { + symbol, + cachedInheritanceResults: createMap() + }; + } + function getReferencesForSuperKeyword(superKeyword: Node): ReferencedSymbol[] { let searchSpaceNode = getSuperContainer(superKeyword, /*stopOnFunctions*/ false); if (!searchSpaceNode) { @@ -7144,7 +7174,7 @@ namespace ts { } } - function getRelatedSymbol(searchSymbols: Symbol[], referenceSymbol: Symbol, referenceLocation: Node, parentSymbol: Symbol, inheritanceCache: Map): Symbol { + function getRelatedSymbol(searchSymbols: Symbol[], referenceSymbol: Symbol, referenceLocation: Node, parentSymbols: SymbolInheritanceState[]): Symbol { if (searchSymbols.indexOf(referenceSymbol) >= 0) { return referenceSymbol; } @@ -7153,7 +7183,7 @@ namespace ts { // symbols but by looking up for related symbol of this alias so it can handle multiple level of indirectness. const aliasSymbol = getAliasSymbolForPropertyNameSymbol(referenceSymbol, referenceLocation); if (aliasSymbol) { - return getRelatedSymbol(searchSymbols, aliasSymbol, referenceLocation, parentSymbol, inheritanceCache); + return getRelatedSymbol(searchSymbols, aliasSymbol, referenceLocation, parentSymbols); } // If the reference location is in an object literal, try to get the contextual type for the @@ -7198,7 +7228,13 @@ namespace ts { // Finally, try all properties with the same name in any type the containing type extended or implemented, and // see if any is in the list. If we were passed a parent symbol, only include types that are subtypes of the // parent symbol - if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface) && (!parentSymbol || inheritsFrom(rootSymbol.parent, parentSymbol, inheritanceCache))) { + if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { + if (parentSymbols) { + if (!forEach(parentSymbols, ({symbol, cachedInheritanceResults}) => inheritsFrom(rootSymbol.parent, symbol, cachedInheritanceResults))) { + return undefined; + } + } + const result: Symbol[] = []; getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ createMap()); return forEach(result, s => searchSymbols.indexOf(s) >= 0 ? s : undefined); diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts index eed8c418043..76d4e750ad9 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts @@ -1,9 +1,12 @@ /// -// Should handle intersection types +// Should handle union and intersection types -//// interface Foo { +//// interface BaseFoo { //// hello(): void; +//// } +//// +//// interface Foo extends BaseFoo { //// aloha(): void; //// } //// @@ -13,12 +16,16 @@ //// } //// //// class FooImpl implements Foo { -//// hello() {/**FooImpl*/} +//// [|hello() {/**FooImpl*/}|] //// aloha() {} //// } //// +//// class BaseFooImpl implements BaseFoo { +//// hello() {/**BaseFooImpl*/} // Should not show up +//// } +//// //// class BarImpl implements Bar { -//// hello() {/**BarImpl*/} +//// [|hello() {/**BarImpl*/}|] //// goodbye() {} //// } //// @@ -28,9 +35,15 @@ //// goodbye() {} //// } //// -//// function someFunction(x: Foo & Bar) { -//// x.he/*function_call*/llo(); +//// function someFunction(x: Foo | Bar) { +//// x.he/*function_call0*/llo(); +//// } +//// +//// function anotherFunction(x: Foo & Bar) { +//// x.he/*function_call1*/llo(); //// } -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); +for (var i = 0; i < 2; i++) { + goTo.marker("function_call" + i); + verify.allRangesAppearInImplementationList(); +} diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts index 7cf0533de5f..7d948006fb3 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts @@ -1,36 +1,12 @@ -/// - -// Should handle union types - -//// interface Foo { -//// hello(): void; -//// aloha(): void; -//// } -//// -//// interface Bar { -//// hello(): void; -//// goodbye(): void; -//// } -//// -//// class FooImpl implements Foo { -//// [|hello() {/**FooImpl*/}|] -//// aloha() {} -//// } -//// -//// class BarImpl implements Bar { -//// [|hello() {/**BarImpl*/}|] -//// goodbye() {} -//// } -//// -//// class FooAndBarImpl implements Foo, Bar { -//// [|hello() {/**FooAndBarImpl*/}|] -//// aloha() {} -//// goodbye() {} -//// } -//// -//// function someFunction(x: Foo | Bar) { -//// x.he/*function_call*/llo(); -//// } - -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); +/// + +// Should handle members of object literals in type assertion expressions + +//// interface Foo { +//// hel/*reference*/lo(): void; +//// } +//// +//// var x = { [|hello: () => {}|] }; +//// var y = (((({ [|hello: () => {}|] })))); +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_12.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_12.ts deleted file mode 100644 index 7d948006fb3..00000000000 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_12.ts +++ /dev/null @@ -1,12 +0,0 @@ -/// - -// Should handle members of object literals in type assertion expressions - -//// interface Foo { -//// hel/*reference*/lo(): void; -//// } -//// -//// var x = { [|hello: () => {}|] }; -//// var y = (((({ [|hello: () => {}|] })))); -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file From 65d1079f8f10ae2b070fe5a54b942f8afc045ee5 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 1 Sep 2016 09:15:59 -0700 Subject: [PATCH 05/46] Replace services' jsdoc parser with parsers' Also modify scanner's definition of leading vs trailing comments, with associated changes to emitter and emit baselines (the last is in a separate commit). --- src/compiler/binder.ts | 6 +- src/compiler/checker.ts | 3 +- src/compiler/emitter.ts | 82 ++- src/compiler/parser.ts | 411 ++++++++++----- src/compiler/scanner.ts | 67 ++- src/compiler/types.ts | 12 +- src/compiler/utilities.ts | 162 ++++-- src/harness/unittests/jsDocParsing.ts | 728 +++++++++++++++++--------- src/services/services.ts | 404 ++------------ src/services/utilities.ts | 10 +- 10 files changed, 1053 insertions(+), 832 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index d8017d601ad..d28df13655f 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -262,7 +262,7 @@ namespace ts { Debug.assert(node.parent.kind === SyntaxKind.JSDocFunctionType); let functionType = node.parent; let index = indexOf(functionType.parameters, node); - return "p" + index; + return "arg" + index; case SyntaxKind.JSDocTypedefTag: const parentNode = node.parent && node.parent.parent; let nameFromParentNode: string; @@ -517,9 +517,7 @@ namespace ts { // because the scope of JsDocComment should not be affected by whether the current node is a // container or not. if (isInJavaScriptFile(node) && node.jsDocComments) { - for (const jsDocComment of node.jsDocComments) { - bind(jsDocComment); - } + forEach(node.jsDocComments, bind); } if (checkUnreachable(node)) { forEachChild(node, bind); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 863c9e7c37a..b6209043262 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5629,12 +5629,13 @@ namespace ts { 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: case SyntaxKind.JSDocTypeLiteral: case SyntaxKind.JSDocFunctionType: - case SyntaxKind.JSDocRecordType: return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node, aliasSymbol, aliasTypeArguments); // This function assumes that an identifier or qualified name is a type expression // Callers should first ensure this by calling isTypeNode diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index f02cf266744..ce8d8e44d39 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -851,7 +851,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } } - function emitLinePreservingList(parent: Node, nodes: NodeArray, allowTrailingComma: boolean, spacesBetweenBraces: boolean) { + function emitLinePreservingList(parent: Node, nodes: NodeArray, allowTrailingComma: boolean, spacesBetweenBraces: boolean, commentsBeforePunctuation: boolean) { Debug.assert(nodes.length > 0); increaseIndent(); @@ -877,6 +877,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } emit(nodes[i]); + if (commentsBeforePunctuation) { + emitLeadingCommentsAtEnd(nodes[i]); + } } if (nodes.hasTrailingComma && allowTrailingComma) { @@ -895,7 +898,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } } - function emitList(nodes: TNode[], start: number, count: number, multiLine: boolean, trailingComma: boolean, leadingComma?: boolean, noTrailingNewLine?: boolean, emitNode?: (node: TNode) => void): number { + function emitList(nodes: TNode[], start: number, count: number, multiLine: boolean, trailingComma: boolean, leadingComma?: boolean, noTrailingNewLine?: boolean, commentsBeforePunctuation?: boolean, emitNode?: (node: TNode) => void): number { if (!emitNode) { emitNode = emit; } @@ -913,13 +916,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } } const node = nodes[start + i]; - // This emitting is to make sure we emit following comment properly - // ...(x, /*comment1*/ y)... - // ^ => node.pos - // "comment1" is not considered leading comment for "y" but rather - // considered as trailing comment of the previous node. - emitTrailingCommentsOfPosition(node.pos); emitNode(node); + if (commentsBeforePunctuation) { + emitLeadingCommentsAtEnd(nodes[i]); + } leadingComma = true; } if (trailingComma) { @@ -1897,7 +1897,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } else if (languageVersion >= ScriptTarget.ES6 || !forEach(elements, isSpreadElementExpression)) { write("["); - emitLinePreservingList(node, node.elements, elements.hasTrailingComma, /*spacesBetweenBraces*/ false); + emitLinePreservingList(node, node.elements, elements.hasTrailingComma, /*spacesBetweenBraces*/ false, /*commentsBeforePunctuation*/ true); write("]"); } else { @@ -1921,7 +1921,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge // then try to preserve the original shape of the object literal. // Otherwise just try to preserve the formatting. if (numElements === properties.length) { - emitLinePreservingList(node, properties, /*allowTrailingComma*/ languageVersion >= ScriptTarget.ES5, /*spacesBetweenBraces*/ true); + emitLinePreservingList(node, properties, /*allowTrailingComma*/ languageVersion >= ScriptTarget.ES5, /*spacesBetweenBraces*/ true, /*commentsBeforePunctuation*/ true); } else { const multiLine = node.multiLine; @@ -2166,14 +2166,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge function emitPropertyAssignment(node: PropertyDeclaration) { emit(node.name); write(": "); - // This is to ensure that we emit comment in the following case: - // For example: - // obj = { - // id: /*comment1*/ ()=>void - // } - // "comment1" is not considered to be leading comment for node.initializer - // but rather a trailing comment on the previous node. - emitTrailingCommentsOfPosition(node.initializer.pos); emit(node.initializer); } @@ -2285,6 +2277,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } emit(node.expression); + emitLeadingCommentsAtEnd(node.expression); const dotRangeStart = nodeIsSynthesized(node.expression) ? -1 : node.expression.end; const dotRangeEnd = nodeIsSynthesized(node.expression) ? -1 : skipTrivia(currentText, node.expression.end) + 1; const dotToken = { pos: dotRangeStart, end: dotRangeEnd }; @@ -2501,13 +2494,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge emitThis(expression); if (node.arguments.length) { write(", "); + emitTrailingCommentsOfPosition(node.arguments.pos); emitCommaList(node.arguments); + emitLeadingCommentsAtEnd(node.arguments); } write(")"); } else { write("("); + emitTrailingCommentsOfPosition(node.arguments.pos); emitCommaList(node.arguments); + emitLeadingCommentsAtEnd(node.arguments); write(")"); } } @@ -2608,6 +2605,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge write("("); emit(node.expression); + emitLeadingCommentsAtEnd(node.expression); write(")"); } @@ -2886,6 +2884,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } else { emit(node.left); + emitLeadingCommentsAtEnd(node.left); // Add indentation before emit the operator if the operator is on different line // For example: // 3 @@ -3898,6 +3897,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } emitNodeWithCommentsAndWithoutSourcemap(node.name); emitEnd(node.name); + emitLeadingCommentsAtEnd(node.name); } function createVoidZero(): Expression { @@ -4040,6 +4040,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge emit(name); } + emitLeadingCommentsAtEnd(name); write(" = "); emit(value); }); @@ -4591,6 +4592,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge emitStart(restParam); write("var "); emitNodeWithCommentsAndWithoutSourcemap(restParam.name); + emitLeadingCommentsAtEnd(restParam.name); write(" = [];"); emitEnd(restParam); emitTrailingComments(restParam); @@ -4612,6 +4614,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge writeLine(); emitStart(restParam); emitNodeWithCommentsAndWithoutSourcemap(restParam.name); + emitLeadingCommentsAtEnd(restParam.name); write("[" + tempName + " - " + restIndex + "] = arguments[" + tempName + "];"); emitEnd(restParam); decreaseIndent(); @@ -4633,6 +4636,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge function emitDeclarationName(node: Declaration) { if (node.name) { emitNodeWithCommentsAndWithoutSourcemap(node.name); + emitLeadingCommentsAtEnd(node.name); } else { write(getGeneratedNameForNode(node)); @@ -4660,6 +4664,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge const { kind, parent } = node; if (kind !== SyntaxKind.MethodDeclaration && kind !== SyntaxKind.MethodSignature && + kind !== SyntaxKind.ArrowFunction && parent && parent.kind !== SyntaxKind.PropertyAssignment && parent.kind !== SyntaxKind.CallExpression && @@ -4734,7 +4739,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge const parameters = node.parameters; const skipCount = node.parameters.length && (node.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword ? 1 : 0; const omitCount = languageVersion < ScriptTarget.ES6 && hasDeclaredRestParameter(node) ? 1 : 0; - emitList(parameters, skipCount, parameters.length - omitCount - skipCount, /*multiLine*/ false, /*trailingComma*/ false); + emitTrailingCommentsOfPosition(node.parameters.pos); + emitList(parameters, skipCount, parameters.length - omitCount - skipCount, /*multiLine*/ false, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ false, /*commentsBeforePunctuation*/ true); + if ((parameters.length - omitCount - skipCount) <= 0) { + emitLeadingCommentsAtEnd(node.parameters); + } } write(")"); decreaseIndent(); @@ -5791,7 +5800,7 @@ const _super = (function (geti, seti) { writeLine(); const decoratorCount = decorators ? decorators.length : 0; - let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, + let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, /*commentsBeforePunctuation*/ false, decorator => emit(decorator.expression)); if (firstParameterDecorator) { argumentsWritten += emitDecoratorsOfParameters(constructor, /*leadingComma*/ argumentsWritten > 0); @@ -5891,7 +5900,7 @@ const _super = (function (geti, seti) { writeLine(); const decoratorCount = decorators ? decorators.length : 0; - let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, + let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, /*commentsBeforePunctuation*/ false, decorator => emit(decorator.expression)); if (firstParameterDecorator) { @@ -5933,7 +5942,7 @@ const _super = (function (geti, seti) { for (const parameter of node.parameters) { if (nodeIsDecorated(parameter)) { const decorators = parameter.decorators; - argumentsWritten += emitList(decorators, 0, decorators.length, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ leadingComma, /*noTrailingNewLine*/ true, decorator => { + argumentsWritten += emitList(decorators, 0, decorators.length, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ leadingComma, /*noTrailingNewLine*/ true, /*commentsBeforePunctuation*/ false, decorator => { write(`__param(${parameterIndex}, `); emit(decorator.expression); write(")"); @@ -6347,6 +6356,7 @@ const _super = (function (geti, seti) { emitExpressionForPropertyName(node.name); emitEnd(node); write(";"); + emitLeadingCommentsAtEnd(node.name); } function writeEnumMemberDeclarationValue(member: EnumMember) { @@ -8288,7 +8298,11 @@ const _super = (function (geti, seti) { emitNewLineBeforeLeadingComments(currentLineMap, writer, node, leadingComments); // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space - emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment); + // However, a leading mid-line comment of the end of file token is emitted with spaces before, + // as if it were a trailing comment of the previous token + const commentStartsInMidLine = leadingComments && leadingComments.length && leadingComments[0].pos - 1 > 0 && currentText.charCodeAt(leadingComments[0].pos - 1) !== 10; + const isEndOfFile = node.kind === SyntaxKind.EndOfFileToken && commentStartsInMidLine; + emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ !isEndOfFile, newLine, writeComment); } function emitTrailingComments(node: Node) { @@ -8305,8 +8319,11 @@ const _super = (function (geti, seti) { /** * Emit trailing comments at the position. The term trailing comment is used here to describe following comment: - * x, /comment1/ y - * ^ => pos; the function will emit "comment1" in the emitJS + * x, /*comment1* / // comment2 + * ^ => pos; the function will emit "comment1" and "comment2" in the emitJS + * However, + * x /*comment1* /, y + * 'comment1' is actually a leading comment of ',' and needs to be emitted using emitLeadingCommentsAtEnd */ function emitTrailingCommentsOfPosition(pos: number) { if (compilerOptions.removeComments) { @@ -8319,7 +8336,18 @@ const _super = (function (geti, seti) { emitComments(currentText, currentLineMap, writer, trailingComments, /*trailingSeparator*/ true, newLine, writeComment); } - function emitLeadingCommentsOfPositionWorker(pos: number) { + /** + * Emit leading comments for the token after the current token. + * This is only needed for punctuation tokens. For example, in + * x /*comment1* /, y + * 'comment1' is a leading comment of ',' but needs to be emitted + * from x because there is no token for ','. + */ + function emitLeadingCommentsAtEnd(node: Node | NodeArray) { + emitLeadingCommentsOfPositionWorker(node.end, /*trailingSeparator*/ false); + } + + function emitLeadingCommentsOfPositionWorker(pos: number, trailingSeparator = true) { if (compilerOptions.removeComments) { return; } @@ -8337,7 +8365,7 @@ const _super = (function (geti, seti) { emitNewLineBeforeLeadingComments(currentLineMap, writer, { pos: pos, end: pos }, leadingComments); // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space - emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment); + emitComments(currentText, currentLineMap, writer, leadingComments, trailingSeparator, newLine, writeComment); } function emitDetachedCommentsAndUpdateCommentsInfo(node: TextRange) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index b28f13e438f..342b711a5a6 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -378,7 +378,7 @@ namespace ts { case SyntaxKind.JSDocNullableType: return visitNode(cbNode, (node).type); case SyntaxKind.JSDocRecordType: - return visitNodes(cbNodes, (node).members); + return visitNode(cbNode, (node).literal); case SyntaxKind.JSDocTypeReference: return visitNode(cbNode, (node).name) || visitNodes(cbNodes, (node).typeArguments); @@ -397,7 +397,7 @@ namespace ts { return visitNode(cbNode, (node).name) || visitNode(cbNode, (node).type); case SyntaxKind.JSDocComment: - return visitNodes(cbNodes, (node).tags); + return visitNodes(cbNodes, (node).tags); case SyntaxKind.JSDocParameterTag: return visitNode(cbNode, (node).preParameterName) || visitNode(cbNode, (node).typeExpression) || @@ -450,10 +450,10 @@ namespace ts { /* @internal */ export function parseIsolatedJSDocComment(content: string, start?: number, length?: number) { const result = Parser.JSDocParser.parseIsolatedJSDocComment(content, start, length); - if (result && result.jsDocComment) { + if (result && result.jsDoc) { // because the jsDocComment was parsed out of the source file, it might // not be covered by the fixupParentReferences. - Parser.fixupParentReferences(result.jsDocComment); + Parser.fixupParentReferences(result.jsDoc); } return result; @@ -652,20 +652,18 @@ namespace ts { function addJSDocComment(node: T): T { - if (contextFlags & NodeFlags.JavaScriptFile) { - const comments = getLeadingCommentRangesOfNode(node, sourceFile); - if (comments) { - for (const comment of comments) { - const jsDocComment = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); - if (!jsDocComment) { - continue; - } - - if (!node.jsDocComments) { - node.jsDocComments = []; - } - node.jsDocComments.push(jsDocComment); + const comments = getLeadingCommentRangesOfNode(node, sourceFile); + if (comments) { + for (const comment of comments) { + const jsDoc = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); + if (!jsDoc) { + continue; } + + if (!node.jsDocComments) { + node.jsDocComments = []; + } + node.jsDocComments.push(jsDoc); } } @@ -2201,7 +2199,7 @@ namespace ts { } fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node); parseTypeMemberSemicolon(); - return finishNode(node); + return addJSDocComment(finishNode(node)); } function isIndexSignature(): boolean { @@ -2291,7 +2289,7 @@ namespace ts { // [Yield] nor [Await] fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, method); parseTypeMemberSemicolon(); - return finishNode(method); + return addJSDocComment(finishNode(method)); } else { const property = createNode(SyntaxKind.PropertySignature, fullStart); @@ -2308,7 +2306,7 @@ namespace ts { } parseTypeMemberSemicolon(); - return finishNode(property); + return addJSDocComment(finishNode(property)); } } @@ -2897,7 +2895,7 @@ namespace ts { node.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, "=>"); node.body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier); - return finishNode(node); + return addJSDocComment(finishNode(node)); } function tryParseParenthesizedArrowFunctionExpression(): Expression { @@ -2930,7 +2928,7 @@ namespace ts { ? parseArrowFunctionExpressionBody(isAsync) : parseIdentifier(); - return finishNode(arrowFunction); + return addJSDocComment(finishNode(arrowFunction)); } // True -> We definitely expect a parenthesized arrow function here. @@ -4114,7 +4112,7 @@ namespace ts { function tryParseAccessorDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray): AccessorDeclaration { if (parseContextualModifier(SyntaxKind.GetKeyword)) { - return addJSDocComment(parseAccessorDeclaration(SyntaxKind.GetAccessor, fullStart, decorators, modifiers)); + return parseAccessorDeclaration(SyntaxKind.GetAccessor, fullStart, decorators, modifiers); } else if (parseContextualModifier(SyntaxKind.SetKeyword)) { return parseAccessorDeclaration(SyntaxKind.SetAccessor, fullStart, decorators, modifiers); @@ -4993,7 +4991,7 @@ namespace ts { : doOutsideOfContext(NodeFlags.YieldContext | NodeFlags.DisallowInContext, parseNonParameterInitializer); parseSemicolon(); - return finishNode(property); + return addJSDocComment(finishNode(property)); } function parsePropertyOrMethodDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray): ClassElement { @@ -5022,7 +5020,7 @@ namespace ts { node.name = parsePropertyName(); fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node); node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false, /*isAsync*/ false); - return finishNode(node); + return addJSDocComment(finishNode(node)); } function isClassMemberModifier(idToken: SyntaxKind) { @@ -5265,7 +5263,7 @@ namespace ts { node.members = createMissingList(); } - return finishNode(node); + return addJSDocComment(finishNode(node)); } function parseNameOfClassDeclarationOrExpression(): Identifier { @@ -5333,7 +5331,7 @@ namespace ts { node.typeParameters = parseTypeParameters(); node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ false); node.members = parseObjectTypeMembers(); - return finishNode(node); + return addJSDocComment(finishNode(node)); } function parseTypeAliasDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray): TypeAliasDeclaration { @@ -5357,7 +5355,7 @@ namespace ts { const node = createNode(SyntaxKind.EnumMember, scanner.getStartPos()); node.name = parsePropertyName(); node.initializer = allowInAnd(parseNonParameterInitializer); - return finishNode(node); + return addJSDocComment(finishNode(node)); } function parseEnumDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray): EnumDeclaration { @@ -5373,7 +5371,7 @@ namespace ts { else { node.members = createMissingList(); } - return finishNode(node); + return addJSDocComment(finishNode(node)); } function parseModuleBlock(): ModuleBlock { @@ -5400,7 +5398,7 @@ namespace ts { node.body = parseOptional(SyntaxKind.DotToken) ? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.Export | namespaceFlag) : parseModuleBlock(); - return finishNode(node); + return addJSDocComment(finishNode(node)); } function parseAmbientExternalModuleDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray): ModuleDeclaration { @@ -5489,7 +5487,7 @@ namespace ts { parseExpected(SyntaxKind.EqualsToken); importEqualsDeclaration.moduleReference = parseModuleReference(); parseSemicolon(); - return finishNode(importEqualsDeclaration); + return addJSDocComment(finishNode(importEqualsDeclaration)); } } @@ -5810,6 +5808,7 @@ namespace ts { export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number) { initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); + sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS); scanner.setText(content, start, length); currentToken = scanner.scan(); const jsDocTypeExpression = parseJSDocTypeExpression(); @@ -6028,22 +6027,7 @@ namespace ts { function parseJSDocRecordType(): JSDocRecordType { const result = createNode(SyntaxKind.JSDocRecordType); - nextToken(); - result.members = parseDelimitedList(ParsingContext.JSDocRecordMembers, parseJSDocRecordMember); - checkForTrailingComma(result.members); - parseExpected(SyntaxKind.CloseBraceToken); - return finishNode(result); - } - - function parseJSDocRecordMember(): JSDocRecordMember { - const result = createNode(SyntaxKind.JSDocRecordMember); - result.name = parseSimplePropertyName(); - - if (token() === SyntaxKind.ColonToken) { - nextToken(); - result.type = parseJSDocType(); - } - + result.literal = parseTypeLiteral(); return finishNode(result); } @@ -6143,14 +6127,14 @@ namespace ts { export function parseIsolatedJSDocComment(content: string, start: number, length: number) { initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); sourceFile = { languageVariant: LanguageVariant.Standard, text: content }; - const jsDocComment = parseJSDocCommentWorker(start, length); + const jsDoc = parseJSDocCommentWorker(start, length); const diagnostics = parseDiagnostics; clearState(); - return jsDocComment ? { jsDocComment, diagnostics } : undefined; + return jsDoc ? { jsDoc, diagnostics } : undefined; } - export function parseJSDocComment(parent: Node, start: number, length: number): JSDocComment { + export function parseJSDocComment(parent: Node, start: number, length: number): JSDoc { const saveToken = currentToken; const saveParseDiagnosticsLength = parseDiagnostics.length; const saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode; @@ -6167,7 +6151,7 @@ namespace ts { return comment; } - export function parseJSDocCommentWorker(start: number, length: number): JSDocComment { + export function parseJSDocCommentWorker(start: number, length: number): JSDoc { const content = sourceText; start = start || 0; const end = length === undefined ? content.length : start + length; @@ -6178,76 +6162,145 @@ namespace ts { Debug.assert(end <= content.length); let tags: NodeArray; - let result: JSDocComment; + const comments: string[] = []; + let result: JSDoc; // Check for /** (JSDoc opening part) - if (content.charCodeAt(start) === CharacterCodes.slash && - content.charCodeAt(start + 1) === CharacterCodes.asterisk && - content.charCodeAt(start + 2) === CharacterCodes.asterisk && - content.charCodeAt(start + 3) !== CharacterCodes.asterisk) { + if (!isJsDocStart(content, start)) { + return result; + } + // + 3 for leading /**, - 5 in total for /** */ + scanner.scanRange(start + 3, length - 5, () => { + // Initially we can parse out a tag. We also have seen a starting asterisk. + // This is so that /** * @type */ doesn't parse. + let canParseTag = true; + let seenAsterisk = true; + let advanceToken = true; + let margin: number | undefined = undefined; + let indent = start - Math.max(content.lastIndexOf("\n", start), 0) + 4; + let text: string; - // + 3 for leading /**, - 5 in total for /** */ - scanner.scanRange(start + 3, length - 5, () => { - // Initially we can parse out a tag. We also have seen a starting asterisk. - // This is so that /** * @type */ doesn't parse. - let canParseTag = true; - let seenAsterisk = true; - + nextJSDocToken(); + while (token() === SyntaxKind.WhitespaceTrivia) { nextJSDocToken(); - while (token() !== SyntaxKind.EndOfFileToken) { - switch (token()) { - case SyntaxKind.AtToken: - if (canParseTag) { - parseTag(); - } - // This will take us to the end of the line, so it's OK to parse a tag on the next pass through the loop + } + if (token() === SyntaxKind.NewLineTrivia) { + canParseTag = true; + seenAsterisk = false; + nextJSDocToken(); + } + while (token() !== SyntaxKind.EndOfFileToken) { + switch (token()) { + case SyntaxKind.AtToken: + if (canParseTag) { + removeTrailingNewlines(comments); + parseTag(indent); + // This will take us past the end of the line, so it's OK to parse a tag on the next pass through the loop + // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag. But real-world comments may break this rule. seenAsterisk = false; - break; + advanceToken = false; + margin = undefined; + } + else { + comments.push(scanner.getTokenText()); + } + indent++; + break; - case SyntaxKind.NewLineTrivia: - // After a line break, we can parse a tag, and we haven't seen an asterisk on the next line yet - canParseTag = true; - seenAsterisk = false; - break; + case SyntaxKind.NewLineTrivia: + // After a line break, we can parse a tag, and we haven't seen an asterisk on the next line yet + comments.push(scanner.getTokenText()); + canParseTag = true; + seenAsterisk = false; + indent = 0; + break; - case SyntaxKind.AsteriskToken: - if (seenAsterisk) { - // If we've already seen an asterisk, then we can no longer parse a tag on this line - canParseTag = false; - } - // Ignore the first asterisk on a line - seenAsterisk = true; - break; - - case SyntaxKind.Identifier: - // Anything else is doc comment text. We can't do anything with it. Because it - // wasn't a tag, we can no longer parse a tag on this line until we hit the next - // line break. + case SyntaxKind.AsteriskToken: + text = scanner.getTokenText(); + if (seenAsterisk) { + // If we've already seen an asterisk, then we can no longer parse a tag on this line canParseTag = false; - break; + comments.push(text); + if (!margin) { + margin = indent; + } + } + // Ignore the first asterisk on a line + seenAsterisk = true; + indent += text.length; + break; - case SyntaxKind.EndOfFileToken: - break; - } + case SyntaxKind.Identifier: + // Anything else is doc comment text. We just save it. Because it + // wasn't a tag, we can no longer parse a tag on this line until we hit the next + // line break. + text = scanner.getTokenText(); + comments.push(text); + if (!margin) { + margin = indent; + } + canParseTag = false; + indent += text.length; + break; + + case SyntaxKind.WhitespaceTrivia: + // only collect whitespace if we *know* that we're just looking at comments, not a possible jsdoc tag + text = scanner.getTokenText(); + if (!canParseTag || margin !== undefined && indent + text.length > margin) { + comments.push(text.slice(margin - indent - 1)); + } + indent += text.length; + break; + + case SyntaxKind.EndOfFileToken: + break; + + default: + text = scanner.getTokenText(); + comments.push(text); + indent += text.length; + break; + } + if (advanceToken) { nextJSDocToken(); } + else { + advanceToken = true; + } + } + removeLeadingNewlines(comments); + removeTrailingNewlines(comments); + result = createJSDocComment(); - result = createJSDocComment(); - - }); - } + }); return result; - function createJSDocComment(): JSDocComment { - if (!tags) { - return undefined; + function removeLeadingNewlines(comments: string[]) { + while (comments.length && (comments[0] === "\n" || comments[0] === "\r")) { + comments.shift(); } + } - const result = createNode(SyntaxKind.JSDocComment, start); + function removeTrailingNewlines(comments: string[]) { + while (comments.length && (comments[comments.length - 1] === "\n" || comments[comments.length - 1] === "\r")) { + comments.pop(); + } + } + + function isJsDocStart(content: string, start: number) { + return content.charCodeAt(start) === CharacterCodes.slash && + content.charCodeAt(start + 1) === CharacterCodes.asterisk && + content.charCodeAt(start + 2) === CharacterCodes.asterisk && + content.charCodeAt(start + 3) !== CharacterCodes.asterisk; + } + + function createJSDocComment(): JSDoc { + const result = createNode(SyntaxKind.JSDocComment, start); result.tags = tags; + result.comment = comments.length ? comments.join("") : undefined; return finishNode(result, end); } @@ -6257,78 +6310,158 @@ namespace ts { } } - function parseTag(): void { + function parseTag(indent: number) { Debug.assert(token() === SyntaxKind.AtToken); const atToken = createNode(SyntaxKind.AtToken, scanner.getTokenPos()); atToken.end = scanner.getTextPos(); nextJSDocToken(); const tagName = parseJSDocIdentifierName(); + skipWhitespace(); if (!tagName) { return; } - const tag = handleTag(atToken, tagName) || handleUnknownTag(atToken, tagName); - addTag(tag); - } - - function handleTag(atToken: Node, tagName: Identifier): JSDocTag { + let tag: JSDocTag; if (tagName) { switch (tagName.text) { case "param": - return handleParamTag(atToken, tagName); + tag = parseParamTag(atToken, tagName); + break; case "return": case "returns": - return handleReturnTag(atToken, tagName); + tag = parseReturnTag(atToken, tagName); + break; case "template": - return handleTemplateTag(atToken, tagName); + tag = parseTemplateTag(atToken, tagName); + break; case "type": - return handleTypeTag(atToken, tagName); + tag = parseTypeTag(atToken, tagName); + break; case "typedef": - return handleTypedefTag(atToken, tagName); + tag = parseTypedefTag(atToken, tagName); + break; + default: + tag = parseUnknownTag(atToken, tagName); + break; + } + } + else { + tag = parseUnknownTag(atToken, tagName); + } + + if (!tag) { + // a badly malformed tag should not be added to the list of tags + return; + } + addTag(tag, parseTagComments(indent + tag.end - tag.pos)); + } + + function parseTagComments(indent: number) { + const comments: string[] = []; + let savingComments = false; + let seenAsterisk = true; + let done = false; + let margin: number | undefined; + let text: string; + function pushComment(text: string) { + if (!margin) { + margin = indent; + } + comments.push(text); + indent += text.length; + } + while (!done && token() !== SyntaxKind.EndOfFileToken) { + text = scanner.getTokenText(); + switch (token()) { + case SyntaxKind.NewLineTrivia: + if (seenAsterisk) { + savingComments = false; + seenAsterisk = false; + comments.push(text); + } + indent = 0; + break; + case SyntaxKind.AtToken: + done = true; + break; + case SyntaxKind.WhitespaceTrivia: + if (savingComments && seenAsterisk) { + pushComment(text); + } + else { + // if the whitespace crosses the margin, take only the whitespace that passes the margin + if (margin !== undefined && indent + text.length > margin) { + comments.push(text.slice(margin - indent - 1)); + } + indent += text.length; + } + break; + case SyntaxKind.AsteriskToken: + if (!seenAsterisk) { + // leading asterisks start recording on the *next* (non-whitespace) token + savingComments = false; + indent += text.length; + } + // FALLTHROUGH to gather comments + default: + if (seenAsterisk) { + savingComments = true; // leading identifiers start recording as well + pushComment(text); + } + seenAsterisk = true; + break; + } + if (!done) { + nextJSDocToken(); } } - return undefined; + removeLeadingNewlines(comments); + removeTrailingNewlines(comments); + return comments; } - function handleUnknownTag(atToken: Node, tagName: Identifier) { + function parseUnknownTag(atToken: Node, tagName: Identifier) { const result = createNode(SyntaxKind.JSDocTag, atToken.pos); result.atToken = atToken; result.tagName = tagName; return finishNode(result); } - function addTag(tag: JSDocTag): void { - if (tag) { - if (!tags) { - tags = >[]; - tags.pos = tag.pos; - } + function addTag(tag: JSDocTag, comments: string[]): void { + tag.comment = comments.join(""); - tags.push(tag); - tags.end = tag.end; + if (!tags) { + tags = >[]; + tags.pos = tag.pos; } + + tags.push(tag); + tags.end = tag.end; } function tryParseTypeExpression(): JSDocTypeExpression { - if (token() !== SyntaxKind.OpenBraceToken) { - return undefined; - } + return tryParse(() => { + skipWhitespace(); + if (token() !== SyntaxKind.OpenBraceToken) { + return undefined; + } - const typeExpression = parseJSDocTypeExpression(); - return typeExpression; + return parseJSDocTypeExpression(); + }); } - function handleParamTag(atToken: Node, tagName: Identifier) { + function parseParamTag(atToken: Node, tagName: Identifier) { let typeExpression = tryParseTypeExpression(); - skipWhitespace(); + let name: Identifier; let isBracketed: boolean; // Looking for something like '[foo]' or 'foo' if (parseOptionalToken(SyntaxKind.OpenBracketToken)) { name = parseJSDocIdentifierName(); + skipWhitespace(); isBracketed = true; // May have an optional default, e.g. '[foo = 42]' @@ -6365,11 +6498,12 @@ namespace ts { result.preParameterName = preName; result.typeExpression = typeExpression; result.postParameterName = postName; + result.parameterName = postName || preName; result.isBracketed = isBracketed; return finishNode(result); } - function handleReturnTag(atToken: Node, tagName: Identifier): JSDocReturnTag { + function parseReturnTag(atToken: Node, tagName: Identifier): JSDocReturnTag { if (forEach(tags, t => t.kind === SyntaxKind.JSDocReturnTag)) { parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text); } @@ -6381,7 +6515,7 @@ namespace ts { return finishNode(result); } - function handleTypeTag(atToken: Node, tagName: Identifier): JSDocTypeTag { + function parseTypeTag(atToken: Node, tagName: Identifier): JSDocTypeTag { if (forEach(tags, t => t.kind === SyntaxKind.JSDocTypeTag)) { parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text); } @@ -6393,10 +6527,11 @@ namespace ts { return finishNode(result); } - function handlePropertyTag(atToken: Node, tagName: Identifier): JSDocPropertyTag { + function parsePropertyTag(atToken: Node, tagName: Identifier): JSDocPropertyTag { const typeExpression = tryParseTypeExpression(); skipWhitespace(); const name = parseJSDocIdentifierName(); + skipWhitespace(); if (!name) { parseErrorAtPosition(scanner.getStartPos(), /*length*/ 0, Diagnostics.Identifier_expected); return undefined; @@ -6410,7 +6545,7 @@ namespace ts { return finishNode(result); } - function handleTypedefTag(atToken: Node, tagName: Identifier): JSDocTypedefTag { + function parseTypedefTag(atToken: Node, tagName: Identifier): JSDocTypedefTag { const typeExpression = tryParseTypeExpression(); skipWhitespace(); @@ -6419,6 +6554,7 @@ namespace ts { typedefTag.tagName = tagName; typedefTag.name = parseJSDocIdentifierName(); typedefTag.typeExpression = typeExpression; + skipWhitespace(); if (typeExpression) { if (typeExpression.type.kind === SyntaxKind.JSDocTypeReference) { @@ -6488,6 +6624,7 @@ namespace ts { nextJSDocToken(); const tagName = parseJSDocIdentifierName(); + skipWhitespace(); if (!tagName) { return false; } @@ -6498,21 +6635,21 @@ namespace ts { // already has a @type tag, terminate the parent tag now. return false; } - parentTag.jsDocTypeTag = handleTypeTag(atToken, tagName); + parentTag.jsDocTypeTag = parseTypeTag(atToken, tagName); return true; case "prop": case "property": if (!parentTag.jsDocPropertyTags) { parentTag.jsDocPropertyTags = >[]; } - const propertyTag = handlePropertyTag(atToken, tagName); + const propertyTag = parsePropertyTag(atToken, tagName); parentTag.jsDocPropertyTags.push(propertyTag); return true; } return false; } - function handleTemplateTag(atToken: Node, tagName: Identifier): JSDocTemplateTag { + function parseTemplateTag(atToken: Node, tagName: Identifier): JSDocTemplateTag { if (forEach(tags, t => t.kind === SyntaxKind.JSDocTemplateTag)) { parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text); } @@ -6523,6 +6660,7 @@ namespace ts { while (true) { const name = parseJSDocIdentifierName(); + skipWhitespace(); if (!name) { parseErrorAtPosition(scanner.getStartPos(), 0, Diagnostics.Identifier_expected); return undefined; @@ -6536,6 +6674,7 @@ namespace ts { if (token() === SyntaxKind.CommaToken) { nextJSDocToken(); + skipWhitespace(); } else { break; diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index c1431ca23ed..d8cfc39db87 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -599,10 +599,11 @@ namespace ts { * If false, whitespace is skipped until the first line break and comments between that location * and the next token are returned. * If true, comments occurring between the given position and the next line break are returned. + * If there is no line break, then no comments are returned. */ function getCommentRanges(text: string, pos: number, trailing: boolean): CommentRange[] { let result: CommentRange[]; - let collecting = trailing || pos === 0; + let needToSkipTrailingComment = pos > 0; while (pos < text.length) { const ch = text.charCodeAt(pos); switch (ch) { @@ -615,7 +616,11 @@ namespace ts { if (trailing) { return result; } - collecting = true; + else if (needToSkipTrailingComment) { + // skip the first line if not trailing (it'll be part of the trailing comment). + needToSkipTrailingComment = false; + result = undefined; + } if (result && result.length) { lastOrUndefined(result).hasTrailingNewLine = true; } @@ -651,11 +656,13 @@ namespace ts { pos++; } } - if (collecting) { + + // if we are at the end of the file, don't add trailing comments. + // end-of-file comments are added as leading comment of the end-of-file token. + if (pos < text.length || !trailing) { if (!result) { result = []; } - result.push({ pos: startPos, end: pos, hasTrailingNewLine, kind }); } continue; @@ -671,10 +678,10 @@ namespace ts { } break; } - return result; + return !trailing ? result : undefined; } - return result; + return !trailing ? result : undefined; } export function getLeadingCommentRanges(text: string, pos: number): CommentRange[] { @@ -1689,40 +1696,46 @@ namespace ts { } startPos = pos; - - // Eat leading whitespace - let ch = text.charCodeAt(pos); - while (pos < end) { - ch = text.charCodeAt(pos); - if (isWhiteSpaceSingleLine(ch)) { - pos++; - } - else { - break; - } - } tokenPos = pos; + const ch = text.charCodeAt(pos); switch (ch) { + case CharacterCodes.tab: + case CharacterCodes.verticalTab: + case CharacterCodes.formFeed: + case CharacterCodes.space: + while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) { + pos++; + } + return token = SyntaxKind.WhitespaceTrivia; case CharacterCodes.at: - return pos += 1, token = SyntaxKind.AtToken; + pos++; + return token = SyntaxKind.AtToken; case CharacterCodes.lineFeed: case CharacterCodes.carriageReturn: - return pos += 1, token = SyntaxKind.NewLineTrivia; + pos++; + return token = SyntaxKind.NewLineTrivia; case CharacterCodes.asterisk: - return pos += 1, token = SyntaxKind.AsteriskToken; + pos++; + return token = SyntaxKind.AsteriskToken; case CharacterCodes.openBrace: - return pos += 1, token = SyntaxKind.OpenBraceToken; + pos++; + return token = SyntaxKind.OpenBraceToken; case CharacterCodes.closeBrace: - return pos += 1, token = SyntaxKind.CloseBraceToken; + pos++; + return token = SyntaxKind.CloseBraceToken; case CharacterCodes.openBracket: - return pos += 1, token = SyntaxKind.OpenBracketToken; + pos++; + return token = SyntaxKind.OpenBracketToken; case CharacterCodes.closeBracket: - return pos += 1, token = SyntaxKind.CloseBracketToken; + pos++; + return token = SyntaxKind.CloseBracketToken; case CharacterCodes.equals: - return pos += 1, token = SyntaxKind.EqualsToken; + pos++; + return token = SyntaxKind.EqualsToken; case CharacterCodes.comma: - return pos += 1, token = SyntaxKind.CommaToken; + pos++; + return token = SyntaxKind.CommaToken; } if (isIdentifierStart(ch, ScriptTarget.Latest)) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 50beef52bf8..2ee28d501a9 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -464,7 +464,7 @@ namespace ts { modifiers?: ModifiersArray; // Array of modifiers /* @internal */ id?: number; // Unique id (used to look up NodeLinks) parent?: Node; // Parent node (initialized by binding - /* @internal */ jsDocComments?: JSDocComment[]; // JSDoc for the node, if it has any. Only for .js files. + /* @internal */ jsDocComments?: JSDoc[]; // JSDoc for the node, if it has any. Only for .js files. /* @internal */ symbol?: Symbol; // Symbol declared by node (initialized by binding) /* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding) /* @internal */ nextContainer?: Node; // Next container in declaration order (initialized by binding) @@ -1471,7 +1471,7 @@ namespace ts { // @kind(SyntaxKind.JSDocRecordType) export interface JSDocRecordType extends JSDocType, TypeLiteralNode { - members: NodeArray; + literal: TypeLiteralNode; } // @kind(SyntaxKind.JSDocTypeReference) @@ -1519,14 +1519,16 @@ namespace ts { } // @kind(SyntaxKind.JSDocComment) - export interface JSDocComment extends Node { + export interface JSDoc extends Node { tags: NodeArray; + comment: string | undefined; } // @kind(SyntaxKind.JSDocTag) export interface JSDocTag extends Node { atToken: Node; tagName: Identifier; + comment: string | undefined; } // @kind(SyntaxKind.JSDocTemplateTag) @@ -1565,9 +1567,13 @@ namespace ts { // @kind(SyntaxKind.JSDocParameterTag) export interface JSDocParameterTag extends JSDocTag { + /** the parameter name, if provided *before* the type (TypeScript-style) */ preParameterName?: Identifier; typeExpression?: JSDocTypeExpression; + /** the parameter name, if provided *after* the type (JSDoc-standard) */ postParameterName?: Identifier; + /** the parameter name, regardless of the location it was provided */ + parameterName: Identifier; isBracketed: boolean; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 0c026fc6b6d..52683f0e74b 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -596,13 +596,7 @@ namespace ts { } export function getJsDocCommentsFromText(node: Node, text: string) { - const commentRanges = (node.kind === SyntaxKind.Parameter || - node.kind === SyntaxKind.TypeParameter || - node.kind === SyntaxKind.FunctionExpression || - node.kind === SyntaxKind.ArrowFunction) ? - concatenate(getTrailingCommentRanges(text, node.pos), getLeadingCommentRanges(text, node.pos)) : - getLeadingCommentRangesOfNodeFromText(node, text); - return filter(commentRanges, isJsDocComment); + return filter(getLeadingCommentRanges(text, node.pos), isJsDocComment); function isJsDocComment(comment: CommentRange) { // True if the comment starts with '/**' but not if it is '/**/' @@ -1356,39 +1350,75 @@ namespace ts { return undefined; } - const jsDocComments = getJSDocComments(node, checkParentVariableStatement); - if (!jsDocComments) { + const jsDocTags = getJSDocTags(node, checkParentVariableStatement); + if (!jsDocTags) { return undefined; } - for (const jsDocComment of jsDocComments) { - for (const tag of jsDocComment.tags) { - if (tag.kind === kind) { - return tag; - } + for (const tag of jsDocTags) { + if (tag.kind === kind) { + return tag; } } } - function getJSDocComments(node: Node, checkParentVariableStatement: boolean): JSDocComment[] { - if (node.jsDocComments) { - return node.jsDocComments; + function append(previous: T[] | undefined, additional: T[] | undefined): T[] | undefined { + if (additional) { + if (!previous) { + previous = []; + } + for (const x of additional) { + previous.push(x); + } } - // Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement. - // /** - // * @param {number} name - // * @returns {number} - // */ - // var x = function(name) { return name.length; } - if (checkParentVariableStatement) { - const isInitializerOfVariableDeclarationInStatement = - node.parent.kind === SyntaxKind.VariableDeclaration && - (node.parent).initializer === node && - node.parent.parent.parent.kind === SyntaxKind.VariableStatement; + return previous; + } - const variableStatementNode = isInitializerOfVariableDeclarationInStatement ? node.parent.parent.parent : undefined; + export function getJSDocComments(node: Node, checkParentVariableStatement: boolean): string[] { + return getJSDocs(node, checkParentVariableStatement, docs => map(docs, doc => doc.comment), tags => map(tags, tag => tag.comment)); + } + + function getJSDocTags(node: Node, checkParentVariableStatement: boolean): JSDocTag[] { + return getJSDocs(node, checkParentVariableStatement, docs => { + let result: JSDocTag[] = []; + for (const doc of docs) { + if (doc.tags) { + result.push(...doc.tags); + } + } + return result; + }, tags => tags); + } + + function getJSDocs(node: Node, checkParentVariableStatement: boolean, getDocs: (docs: JSDoc[]) => T[], getTags: (tags: JSDocTag[]) => T[]): T[] { + // TODO: Get rid of getJsDocComments and friends (note the lowercase 's' in Js) + // TODO: A lot of this work should be cached, maybe. I guess it's only used in services right now... + let result: T[] = undefined; + // prepend documentation from parent sources + if (checkParentVariableStatement) { + // Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement. + // /** + // * @param {number} name + // * @returns {number} + // */ + // var x = function(name) { return name.length; } + const isInitializerOfVariableDeclarationInStatement = + isVariableLike(node.parent) && + (node.parent).initializer === node && + node.parent.parent.parent.kind === SyntaxKind.VariableStatement; + const isVariableOfVariableDeclarationStatement = isVariableLike(node) && + node.parent.parent.kind === SyntaxKind.VariableStatement; + + const variableStatementNode = + isInitializerOfVariableDeclarationInStatement ? node.parent.parent.parent : + isVariableOfVariableDeclarationStatement ? node.parent.parent : + undefined; if (variableStatementNode) { - return variableStatementNode.jsDocComments; + result = append(result, getJSDocs(variableStatementNode, checkParentVariableStatement, getDocs, getTags)); + } + if (node.kind === SyntaxKind.ModuleDeclaration && + node.parent && node.parent.kind === SyntaxKind.ModuleDeclaration) { + result = append(result, getJSDocs(node.parent, checkParentVariableStatement, getDocs, getTags)); } // Also recognize when the node is the RHS of an assignment expression @@ -1399,16 +1429,62 @@ namespace ts { (parent as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken && parent.parent.kind === SyntaxKind.ExpressionStatement; if (isSourceOfAssignmentExpressionStatement) { - return parent.parent.jsDocComments; + result = append(result, getJSDocs(parent.parent, checkParentVariableStatement, getDocs, getTags)); } const isPropertyAssignmentExpression = parent && parent.kind === SyntaxKind.PropertyAssignment; if (isPropertyAssignmentExpression) { - return parent.jsDocComments; + result = append(result, getJSDocs(parent, checkParentVariableStatement, getDocs, getTags)); + } + + // Pull parameter comments from declaring function as well + if (node.kind === SyntaxKind.Parameter) { + const paramTags = getJSDocParameterTag(node as ParameterDeclaration, checkParentVariableStatement); + if (paramTags) { + result = append(result, getTags(paramTags)); + } } } - return undefined; + if (isVariableLike(node) && node.initializer) { + result = append(result, getJSDocs(node.initializer, /*checkParentVariableStatement*/ false, getDocs, getTags)); + } + + if (node.jsDocComments) { + if (result) { + result = append(result, getDocs(node.jsDocComments)); + } + else { + return getDocs(node.jsDocComments); + } + } + + return result; + } + + function getJSDocParameterTag(param: ParameterDeclaration, checkParentVariableStatement: boolean): JSDocTag[] { + const func = param.parent as FunctionLikeDeclaration; + const tags = getJSDocTags(func, checkParentVariableStatement); + if (!param.name) { + // this is an anonymous jsdoc param from a `function(type1, type2): type3` specification + const i = func.parameters.indexOf(param); + const paramTags = filter(tags, tag => tag.kind === SyntaxKind.JSDocParameterTag); + if (paramTags && 0 <= i && i < paramTags.length) { + return [paramTags[i]]; + } + } + else if (param.name.kind === SyntaxKind.Identifier) { + const name = (param.name as Identifier).text; + const paramTags = filter(tags, tag => tag.kind === SyntaxKind.JSDocParameterTag && (tag as JSDocParameterTag).parameterName.text === name); + if (paramTags) { + return paramTags; + } + } + else { + // TODO: it's a destructured parameter, so it should look up an "object type" series of multiple lines + // But multi-line object types aren't supported yet either + return undefined; + } } export function getJSDocTypeTag(node: Node): JSDocTypeTag { @@ -1429,17 +1505,15 @@ namespace ts { // annotation. const parameterName = (parameter.name).text; - const jsDocComments = getJSDocComments(parameter.parent, /*checkParentVariableStatement*/ true); - if (jsDocComments) { - for (const jsDocComment of jsDocComments) { - for (const tag of jsDocComment.tags) { - if (tag.kind === SyntaxKind.JSDocParameterTag) { - const parameterTag = tag; - const name = parameterTag.preParameterName || parameterTag.postParameterName; - if (name.text === parameterName) { - return parameterTag; - } - } + const jsDocTags = getJSDocTags(parameter.parent, /*checkParentVariableStatement*/ true); + if (!jsDocTags) { + return undefined; + } + for (const tag of jsDocTags) { + if (tag.kind === SyntaxKind.JSDocParameterTag) { + const parameterTag = tag; + if (parameterTag.parameterName.text === parameterName) { + return parameterTag; } } } diff --git a/src/harness/unittests/jsDocParsing.ts b/src/harness/unittests/jsDocParsing.ts index a9987ef3176..e688dc20750 100644 --- a/src/harness/unittests/jsDocParsing.ts +++ b/src/harness/unittests/jsDocParsing.ts @@ -6,11 +6,11 @@ namespace ts { describe("TypeExpressions", () => { function parsesCorrectly(content: string, expected: string) { const typeAndDiagnostics = ts.parseJSDocTypeExpressionForTests(content); - assert.isTrue(typeAndDiagnostics && typeAndDiagnostics.diagnostics.length === 0); + assert.isTrue(typeAndDiagnostics && typeAndDiagnostics.diagnostics.length === 0, "no errors issued"); const result = Utils.sourceFileToJSON(typeAndDiagnostics.jsDocTypeExpression.type); - assert.equal(result, expected); + assert.equal(result, expected, "result === expected"); } function parsesIncorrectly(content: string) { @@ -99,10 +99,15 @@ namespace ts { "kind": "JSDocRecordType", "pos": 1, "end": 3, - "members": { - "length": 0, - "pos": 2, - "end": 2 + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 3, + "members": { + "length": 0, + "pos": 2, + "end": 2 + } } }`); }); @@ -113,21 +118,26 @@ namespace ts { "kind": "JSDocRecordType", "pos": 1, "end": 6, - "members": { - "0": { - "kind": "JSDocRecordMember", - "pos": 2, - "end": 5, - "name": { - "kind": "Identifier", + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 6, + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, "end": 5, - "text": "foo" - } - }, - "length": 1, - "pos": 2, - "end": 5 + "name": { + "kind": "Identifier", + "pos": 2, + "end": 5, + "text": "foo" + } + }, + "length": 1, + "pos": 2, + "end": 5 + } } }`); }); @@ -138,26 +148,31 @@ namespace ts { "kind": "JSDocRecordType", "pos": 1, "end": 14, - "members": { - "0": { - "kind": "JSDocRecordMember", - "pos": 2, - "end": 13, - "name": { - "kind": "Identifier", + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 14, + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, - "end": 5, - "text": "foo" + "end": 13, + "name": { + "kind": "Identifier", + "pos": 2, + "end": 5, + "text": "foo" + }, + "type": { + "kind": "NumberKeyword", + "pos": 6, + "end": 13 + } }, - "type": { - "kind": "NumberKeyword", - "pos": 6, - "end": 13 - } - }, - "length": 1, - "pos": 2, - "end": 13 + "length": 1, + "pos": 2, + "end": 13 + } } }`); }); @@ -168,32 +183,37 @@ namespace ts { "kind": "JSDocRecordType", "pos": 1, "end": 11, - "members": { - "0": { - "kind": "JSDocRecordMember", - "pos": 2, - "end": 5, - "name": { - "kind": "Identifier", + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 11, + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, - "end": 5, - "text": "foo" - } - }, - "1": { - "kind": "JSDocRecordMember", - "pos": 6, - "end": 10, - "name": { - "kind": "Identifier", + "end": 6, + "name": { + "kind": "Identifier", + "pos": 2, + "end": 5, + "text": "foo" + } + }, + "1": { + "kind": "PropertySignature", "pos": 6, "end": 10, - "text": "bar" - } - }, - "length": 2, - "pos": 2, - "end": 10 + "name": { + "kind": "Identifier", + "pos": 6, + "end": 10, + "text": "bar" + } + }, + "length": 2, + "pos": 2, + "end": 10 + } } }`); }); @@ -204,37 +224,42 @@ namespace ts { "kind": "JSDocRecordType", "pos": 1, "end": 19, - "members": { - "0": { - "kind": "JSDocRecordMember", - "pos": 2, - "end": 13, - "name": { - "kind": "Identifier", + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 19, + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, - "end": 5, - "text": "foo" + "end": 14, + "name": { + "kind": "Identifier", + "pos": 2, + "end": 5, + "text": "foo" + }, + "type": { + "kind": "NumberKeyword", + "pos": 6, + "end": 13 + } }, - "type": { - "kind": "NumberKeyword", - "pos": 6, - "end": 13 - } - }, - "1": { - "kind": "JSDocRecordMember", - "pos": 14, - "end": 18, - "name": { - "kind": "Identifier", + "1": { + "kind": "PropertySignature", "pos": 14, "end": 18, - "text": "bar" - } - }, - "length": 2, - "pos": 2, - "end": 18 + "name": { + "kind": "Identifier", + "pos": 14, + "end": 18, + "text": "bar" + } + }, + "length": 2, + "pos": 2, + "end": 18 + } } }`); }); @@ -245,37 +270,42 @@ namespace ts { "kind": "JSDocRecordType", "pos": 1, "end": 19, - "members": { - "0": { - "kind": "JSDocRecordMember", - "pos": 2, - "end": 5, - "name": { - "kind": "Identifier", + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 19, + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, - "end": 5, - "text": "foo" - } - }, - "1": { - "kind": "JSDocRecordMember", - "pos": 6, - "end": 18, - "name": { - "kind": "Identifier", - "pos": 6, - "end": 10, - "text": "bar" + "end": 6, + "name": { + "kind": "Identifier", + "pos": 2, + "end": 5, + "text": "foo" + } }, - "type": { - "kind": "NumberKeyword", - "pos": 11, - "end": 18 - } - }, - "length": 2, - "pos": 2, - "end": 18 + "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, + "pos": 2, + "end": 18 + } } }`); }); @@ -286,42 +316,47 @@ namespace ts { "kind": "JSDocRecordType", "pos": 1, "end": 27, - "members": { - "0": { - "kind": "JSDocRecordMember", - "pos": 2, - "end": 13, - "name": { - "kind": "Identifier", + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 27, + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, - "end": 5, - "text": "foo" + "end": 14, + "name": { + "kind": "Identifier", + "pos": 2, + "end": 5, + "text": "foo" + }, + "type": { + "kind": "NumberKeyword", + "pos": 6, + "end": 13 + } }, - "type": { - "kind": "NumberKeyword", - "pos": 6, - "end": 13 - } - }, - "1": { - "kind": "JSDocRecordMember", - "pos": 14, - "end": 26, - "name": { - "kind": "Identifier", + "1": { + "kind": "PropertySignature", "pos": 14, - "end": 18, - "text": "bar" + "end": 26, + "name": { + "kind": "Identifier", + "pos": 14, + "end": 18, + "text": "bar" + }, + "type": { + "kind": "NumberKeyword", + "pos": 19, + "end": 26 + } }, - "type": { - "kind": "NumberKeyword", - "pos": 19, - "end": 26 - } - }, - "length": 2, - "pos": 2, - "end": 26 + "length": 2, + "pos": 2, + "end": 26 + } } }`); }); @@ -332,22 +367,128 @@ namespace ts { "kind": "JSDocRecordType", "pos": 1, "end": 11, - "members": { - "0": { - "kind": "JSDocRecordMember", - "pos": 2, - "end": 10, - "name": { - "kind": "Identifier", + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 11, + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, "end": 10, - "originalKeywordKind": "FunctionKeyword", - "text": "function" - } - }, - "length": 1, - "pos": 2, - "end": 10 + "name": { + "kind": "Identifier", + "pos": 2, + "end": 10, + "originalKeywordKind": "FunctionKeyword", + "text": "function" + } + }, + "length": 1, + "pos": 2, + "end": 10 + } + } +}`); + }); + + it("trailingCommaInRecordType", () => { + parsesCorrectly("{{a,}}", `{ + "kind": "JSDocRecordType", + "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, + "pos": 2, + "end": 4 + } + } +}`); + }); + + it("callSignatureInRecordType", () => { + parsesCorrectly("{{(): number}}", `{ + "kind": "JSDocRecordType", + "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, + "pos": 2, + "end": 12 + } + } +}`); + }); + + it("methodInRecordType", () => { + parsesCorrectly("{{foo(): number}}", `{ + "kind": "JSDocRecordType", + "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, + "pos": 2, + "end": 15 + } } }`); }); @@ -872,17 +1013,14 @@ namespace ts { } }`); }); - }); + + }); describe("parsesIncorrectly", () => { it("emptyType", () => { parsesIncorrectly("{}"); }); - it("trailingCommaInRecordType", () => { - parsesIncorrectly("{{a,}}"); - }); - it("unionTypeWithTrailingBar", () => { parsesIncorrectly("{(a|)}"); }); @@ -947,14 +1085,6 @@ namespace ts { parsesIncorrectly("{function(a: number)}"); }); - it("callSignatureInRecordType", () => { - parsesIncorrectly("{{(): number}}"); - }); - - it("methodInRecordType", () => { - parsesIncorrectly("{{foo(): number}}"); - }); - it("tupleTypeWithComma", () => { parsesIncorrectly( "{[,]}"); }); @@ -979,7 +1109,7 @@ namespace ts { Debug.fail("Comment has at least one diagnostic: " + comment.diagnostics[0].messageText); } - const result = toJsonString(comment.jsDocComment); + const result = toJsonString(comment.jsDoc); const expectedString = typeof expected === "string" ? expected @@ -990,7 +1120,7 @@ namespace ts { const chai = require("chai"); chai.config.showDiff = true; // Use deep equal to compare key value data instead of the two objects - chai.expect(JSON.parse(result)).deep.equal(JSON.parse(expectedString)); + chai.expect(JSON.parse(expectedString)).deep.equal(JSON.parse(result)); } else { assert.equal(result, expectedString); @@ -1028,10 +1158,6 @@ namespace ts { parsesIncorrectly("/*** */"); }); - it("asteriskAfterPreamble", () => { - parsesIncorrectly("/** * @type {number} */"); - }); - it("multipleTypes", () => { parsesIncorrectly( `/** @@ -1091,6 +1217,7 @@ namespace ts { "0": { "kind": "JSDocTypeTag", "pos": 8, + "comment": "", "end": 22, "atToken": { "kind": "AtToken", @@ -1112,7 +1239,8 @@ namespace ts { "pos": 15, "end": 21 } - } + }, + "comment": "" }, "length": 1, "pos": 8, @@ -1121,6 +1249,15 @@ namespace ts { }`); }); + it("asteriskAfterPreamble", () => { + parsesCorrectly("/** * @type {number} */", `{ + "comment": "* @type {number} ", + "end": 23, + "kind": "JSDocComment", + "pos": 0 +}`); + }); + it("noType", () => { parsesCorrectly( `/** @@ -1133,8 +1270,9 @@ namespace ts { "tags": { "0": { "kind": "JSDocTypeTag", + "comment": "", "pos": 8, - "end": 13, + "end": 14, "atToken": { "kind": "AtToken", "pos": 8, @@ -1149,7 +1287,7 @@ namespace ts { }, "length": 1, "pos": 8, - "end": 13 + "end": 14 } }`); }); @@ -1166,8 +1304,9 @@ namespace ts { "tags": { "0": { "kind": "JSDocReturnTag", + "comment": "", "pos": 8, - "end": 15, + "end": 16, "atToken": { "kind": "AtToken", "pos": 8, @@ -1182,7 +1321,7 @@ namespace ts { }, "length": 1, "pos": 8, - "end": 15 + "end": 16 } }`); }); @@ -1199,6 +1338,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocTypeTag", + "comment": "", "pos": 8, "end": 22, "atToken": { @@ -1242,6 +1382,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocTypeTag", + "comment": "", "pos": 8, "end": 22, "atToken": { @@ -1285,6 +1426,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocReturnTag", + "comment": "", "pos": 8, "end": 24, "atToken": { @@ -1328,6 +1470,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocReturnTag", + "comment": "Description text follows", "pos": 8, "end": 24, "atToken": { @@ -1371,6 +1514,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocReturnTag", + "comment": "", "pos": 8, "end": 25, "atToken": { @@ -1414,6 +1558,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "", "pos": 8, "end": 29, "atToken": { @@ -1442,6 +1587,12 @@ namespace ts { "pos": 24, "end": 29, "text": "name1" + }, + "parameterName": { + "kind": "Identifier", + "pos": 24, + "end": 29, + "text": "name1" } }, "length": 1, @@ -1464,6 +1615,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "", "pos": 8, "end": 29, "atToken": { @@ -1492,10 +1644,17 @@ namespace ts { "pos": 24, "end": 29, "text": "name1" + }, + "parameterName": { + "kind": "Identifier", + "pos": 24, + "end": 29, + "text": "name1" } }, "1": { "kind": "JSDocParameterTag", + "comment": "", "pos": 34, "end": 55, "atToken": { @@ -1524,6 +1683,12 @@ namespace ts { "pos": 50, "end": 55, "text": "name2" + }, + "parameterName": { + "kind": "Identifier", + "pos": 50, + "end": 55, + "text": "name2" } }, "length": 2, @@ -1545,6 +1710,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "Description text follows", "pos": 8, "end": 29, "atToken": { @@ -1573,6 +1739,12 @@ namespace ts { "pos": 24, "end": 29, "text": "name1" + }, + "parameterName": { + "kind": "Identifier", + "pos": 24, + "end": 29, + "text": "name1" } }, "length": 1, @@ -1594,6 +1766,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "Description text follows", "pos": 8, "end": 31, "atToken": { @@ -1623,6 +1796,12 @@ namespace ts { "end": 30, "text": "name1" }, + "parameterName": { + "kind": "Identifier", + "pos": 25, + "end": 30, + "text": "name1" + }, "isBracketed": true }, "length": 1, @@ -1644,6 +1823,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "Description text follows", "pos": 8, "end": 36, "atToken": { @@ -1673,6 +1853,12 @@ namespace ts { "end": 31, "text": "name1" }, + "parameterName": { + "kind": "Identifier", + "pos": 26, + "end": 31, + "text": "name1" + }, "isBracketed": true }, "length": 1, @@ -1694,6 +1880,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "", "pos": 8, "end": 29, "atToken": { @@ -1722,11 +1909,56 @@ namespace ts { "pos": 24, "end": 29, "text": "name1" + }, + "parameterName": { + "kind": "Identifier", + "pos": 24, + "end": 29, + "text": "name1" } }, - "length": 1, - "pos": 8, - "end": 29 + "1": { + "atToken": { + "end": 31, + "kind": "AtToken", + "pos": 30 + }, + "comment": "", + "end": 51, + "kind": "JSDocParameterTag", + "parameterName": { + "end": 51, + "kind": "Identifier", + "pos": 46, + "text": "name2" + }, + "pos": 30, + "postParameterName": { + "end": 51, + "kind": "Identifier", + "pos": 46, + "text": "name2" + }, + "tagName": { + "end": 36, + "kind": "Identifier", + "pos": 31, + "text": "param" + }, + "typeExpression": { + "end": 45, + "kind": "JSDocTypeExpression", + "pos": 37, + "type": { + "end": 44, + "kind": "NumberKeyword", + "pos": 38 + } + } + }, + "end": 51, + "length": 2, + "pos": 8 } }`); }); @@ -1743,6 +1975,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "", "pos": 8, "end": 29, "atToken": { @@ -1762,6 +1995,12 @@ namespace ts { "end": 20, "text": "name1" }, + "parameterName": { + "kind": "Identifier", + "pos": 15, + "end": 20, + "text": "name1" + }, "typeExpression": { "kind": "JSDocTypeExpression", "pos": 21, @@ -1792,6 +2031,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "Description", "pos": 8, "end": 29, "atToken": { @@ -1811,6 +2051,12 @@ namespace ts { "end": 20, "text": "name1" }, + "parameterName": { + "kind": "Identifier", + "pos": 15, + "end": 20, + "text": "name1" + }, "typeExpression": { "kind": "JSDocTypeExpression", "pos": 21, @@ -1841,8 +2087,9 @@ namespace ts { "tags": { "0": { "kind": "JSDocTemplateTag", + "comment": "", "pos": 8, - "end": 19, + "end": 20, "atToken": { "kind": "AtToken", "pos": 8, @@ -1858,7 +2105,7 @@ namespace ts { "0": { "kind": "TypeParameter", "pos": 18, - "end": 19, + "end": 20, "name": { "kind": "Identifier", "pos": 18, @@ -1867,13 +2114,13 @@ namespace ts { } }, "length": 1, - "pos": 17, - "end": 19 + "pos": 18, + "end": 20 } }, "length": 1, "pos": 8, - "end": 19 + "end": 20 } }`); }); @@ -1890,8 +2137,9 @@ namespace ts { "tags": { "0": { "kind": "JSDocTemplateTag", + "comment": "", "pos": 8, - "end": 21, + "end": 22, "atToken": { "kind": "AtToken", "pos": 8, @@ -1918,7 +2166,7 @@ namespace ts { "1": { "kind": "TypeParameter", "pos": 20, - "end": 21, + "end": 22, "name": { "kind": "Identifier", "pos": 20, @@ -1927,13 +2175,13 @@ namespace ts { } }, "length": 2, - "pos": 17, - "end": 21 + "pos": 18, + "end": 22 } }, "length": 1, "pos": 8, - "end": 21 + "end": 22 } }`); }); @@ -1950,8 +2198,9 @@ namespace ts { "tags": { "0": { "kind": "JSDocTemplateTag", + "comment": "", "pos": 8, - "end": 22, + "end": 23, "atToken": { "kind": "AtToken", "pos": 8, @@ -1967,7 +2216,7 @@ namespace ts { "0": { "kind": "TypeParameter", "pos": 18, - "end": 19, + "end": 20, "name": { "kind": "Identifier", "pos": 18, @@ -1978,7 +2227,7 @@ namespace ts { "1": { "kind": "TypeParameter", "pos": 21, - "end": 22, + "end": 23, "name": { "kind": "Identifier", "pos": 21, @@ -1987,13 +2236,13 @@ namespace ts { } }, "length": 2, - "pos": 17, - "end": 22 + "pos": 18, + "end": 23 } }, "length": 1, "pos": 8, - "end": 22 + "end": 23 } }`); }); @@ -2010,8 +2259,9 @@ namespace ts { "tags": { "0": { "kind": "JSDocTemplateTag", + "comment": "", "pos": 8, - "end": 22, + "end": 23, "atToken": { "kind": "AtToken", "pos": 8, @@ -2038,7 +2288,7 @@ namespace ts { "1": { "kind": "TypeParameter", "pos": 21, - "end": 22, + "end": 23, "name": { "kind": "Identifier", "pos": 21, @@ -2047,13 +2297,13 @@ namespace ts { } }, "length": 2, - "pos": 17, - "end": 22 + "pos": 18, + "end": 23 } }, "length": 1, "pos": 8, - "end": 22 + "end": 23 } }`); }); @@ -2070,8 +2320,9 @@ namespace ts { "tags": { "0": { "kind": "JSDocTemplateTag", + "comment": "", "pos": 8, - "end": 23, + "end": 24, "atToken": { "kind": "AtToken", "pos": 8, @@ -2087,7 +2338,7 @@ namespace ts { "0": { "kind": "TypeParameter", "pos": 18, - "end": 19, + "end": 20, "name": { "kind": "Identifier", "pos": 18, @@ -2098,7 +2349,7 @@ namespace ts { "1": { "kind": "TypeParameter", "pos": 22, - "end": 23, + "end": 24, "name": { "kind": "Identifier", "pos": 22, @@ -2107,13 +2358,13 @@ namespace ts { } }, "length": 2, - "pos": 17, - "end": 23 + "pos": 18, + "end": 24 } }, "length": 1, "pos": 8, - "end": 23 + "end": 24 } }`); }); @@ -2130,8 +2381,9 @@ namespace ts { "tags": { "0": { "kind": "JSDocTemplateTag", + "comment": "Description of type parameters.", "pos": 8, - "end": 23, + "end": 24, "atToken": { "kind": "AtToken", "pos": 8, @@ -2147,7 +2399,7 @@ namespace ts { "0": { "kind": "TypeParameter", "pos": 18, - "end": 19, + "end": 20, "name": { "kind": "Identifier", "pos": 18, @@ -2158,7 +2410,7 @@ namespace ts { "1": { "kind": "TypeParameter", "pos": 22, - "end": 23, + "end": 24, "name": { "kind": "Identifier", "pos": 22, @@ -2167,13 +2419,13 @@ namespace ts { } }, "length": 2, - "pos": 17, - "end": 23 + "pos": 18, + "end": 24 } }, "length": 1, "pos": 8, - "end": 23 + "end": 24 } }`); }); @@ -2190,6 +2442,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "", "pos": 8, "end": 18, "atToken": { @@ -2203,6 +2456,12 @@ namespace ts { "end": 14, "text": "param" }, + "parameterName": { + "kind": "Identifier", + "pos": 15, + "end": 18, + "text": "foo" + }, "preParameterName": { "kind": "Identifier", "pos": 15, @@ -2236,17 +2495,18 @@ namespace ts { "kind": "AtToken", "pos": 8 }, - "end": 97, + "comment": "", + "end": 98, "jsDocTypeLiteral": { - "end": 97, + "end": 98, "jsDocPropertyTags": [ { "atToken": { "end": 48, "kind": "AtToken", - "pos": 46 + "pos": 47 }, - "end": 69, + "end": 72, "kind": "JSDocPropertyTag", "name": { "end": 69, @@ -2254,7 +2514,7 @@ namespace ts { "pos": 66, "text": "age" }, - "pos": 46, + "pos": 47, "tagName": { "end": 56, "kind": "Identifier", @@ -2276,9 +2536,9 @@ namespace ts { "atToken": { "end": 75, "kind": "AtToken", - "pos": 73 + "pos": 74 }, - "end": 97, + "end": 98, "kind": "JSDocPropertyTag", "name": { "end": 97, @@ -2286,7 +2546,7 @@ namespace ts { "pos": 93, "text": "name" }, - "pos": 73, + "pos": 74, "tagName": { "end": 83, "kind": "Identifier", @@ -2309,11 +2569,11 @@ namespace ts { "atToken": { "end": 29, "kind": "AtToken", - "pos": 27 + "pos": 28 }, "end": 42, "kind": "JSDocTypeTag", - "pos": 27, + "pos": 28, "tagName": { "end": 33, "kind": "Identifier", @@ -2338,7 +2598,7 @@ namespace ts { } }, "kind": "JSDocTypeLiteral", - "pos": 23 + "pos": 26 }, "kind": "JSDocTypedefTag", "name": { @@ -2355,7 +2615,7 @@ namespace ts { "text": "typedef" } }, - "end": 97, + "end": 98, "length": 1, "pos": 8 } diff --git a/src/services/services.ts b/src/services/services.ts index c19eb487d75..812ae0643d8 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -194,7 +194,7 @@ namespace ts { public end: number; public flags: NodeFlags; public parent: Node; - public jsDocComments: JSDocComment[]; + public jsDocComments: JSDoc[]; private _children: Node[]; constructor(kind: SyntaxKind, pos: number, end: number) { @@ -355,7 +355,7 @@ namespace ts { public end: number; public flags: NodeFlags; public parent: Node; - public jsDocComments: JSDocComment[]; + public jsDocComments: JSDoc[]; public __tokenTag: any; constructor(pos: number, end: number) { @@ -474,349 +474,48 @@ namespace ts { } function getJsDocCommentsFromDeclarations(declarations: Declaration[], name: string, canUseParsedParamTagComments: boolean) { + // Only collect doc comments from duplicate declarations once: + // In case of a union property there might be same declaration multiple times + // which only varies in type parameter + // Eg. const a: Array | Array; a.length + // The property length will have two declarations of property length coming + // from Array - Array and Array const documentationComment = []; - const docComments = getJsDocCommentsSeparatedByNewLines(); - ts.forEach(docComments, docComment => { - if (documentationComment.length) { - documentationComment.push(lineBreakPart()); + forEachUnique(declarations, declaration => { + const comments = getJSDocComments(declaration, /*checkParentVariableStatement*/ true); + if (!comments) { + return; + } + for (const comment of comments) { + if (comment) { + if (documentationComment.length) { + documentationComment.push(lineBreakPart()); + } + documentationComment.push(textPart(comment)); + } } - documentationComment.push(docComment); }); return documentationComment; + } - function getJsDocCommentsSeparatedByNewLines() { - const paramTag = "@param"; - const jsDocCommentParts: SymbolDisplayPart[] = []; - - ts.forEach(declarations, (declaration, indexOfDeclaration) => { - // Make sure we are collecting doc comment from declaration once, - // In case of union property there might be same declaration multiple times - // which only varies in type parameter - // Eg. const a: Array | Array; a.length - // The property length will have two declarations of property length coming - // from Array - Array and Array - if (indexOf(declarations, declaration) === indexOfDeclaration) { - const sourceFileOfDeclaration = getSourceFileOfNode(declaration); - // If it is parameter - try and get the jsDoc comment with @param tag from function declaration's jsDoc comments - if (canUseParsedParamTagComments && declaration.kind === SyntaxKind.Parameter) { - if ((declaration.parent.kind === SyntaxKind.FunctionExpression || declaration.parent.kind === SyntaxKind.ArrowFunction) && - declaration.parent.parent.kind === SyntaxKind.VariableDeclaration) { - addCommentParts(declaration.parent.parent.parent, sourceFileOfDeclaration, getCleanedParamJsDocComment); - } - addCommentParts(declaration.parent, sourceFileOfDeclaration, getCleanedParamJsDocComment); - } - - // If this is left side of dotted module declaration, there is no doc comments associated with this node - if (declaration.kind === SyntaxKind.ModuleDeclaration && (declaration).body && (declaration).body.kind === SyntaxKind.ModuleDeclaration) { - return; - } - - if ((declaration.kind === SyntaxKind.FunctionExpression || declaration.kind === SyntaxKind.ArrowFunction) && - declaration.parent.kind === SyntaxKind.VariableDeclaration) { - addCommentParts(declaration.parent.parent, sourceFileOfDeclaration, getCleanedJsDocComment); - } - - // If this is dotted module name, get the doc comments from the parent - while (declaration.kind === SyntaxKind.ModuleDeclaration && declaration.parent.kind === SyntaxKind.ModuleDeclaration) { - declaration = declaration.parent; - } - addCommentParts(declaration.kind === SyntaxKind.VariableDeclaration ? declaration.parent.parent : declaration, - sourceFileOfDeclaration, - getCleanedJsDocComment); - - if (declaration.kind === SyntaxKind.VariableDeclaration) { - const init = (declaration as VariableDeclaration).initializer; - if (init && (init.kind === SyntaxKind.FunctionExpression || init.kind === SyntaxKind.ArrowFunction)) { - // Get the cleaned js doc comment text from the initializer - addCommentParts(init, sourceFileOfDeclaration, getCleanedJsDocComment); - } - } - } - }); - - return jsDocCommentParts; - - function addCommentParts(commented: Node, - sourceFileOfDeclaration: SourceFile, - getCommentPart: (pos: number, end: number, file: SourceFile) => SymbolDisplayPart[]): void { - const ranges = getJsDocCommentTextRange(commented, sourceFileOfDeclaration); - // Get the cleaned js doc comment text from the declaration - ts.forEach(ranges, jsDocCommentTextRange => { - const cleanedComment = getCommentPart(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); - if (cleanedComment) { - addRange(jsDocCommentParts, cleanedComment); - } - }); - } - - function getJsDocCommentTextRange(node: Node, sourceFile: SourceFile): TextRange[] { - return ts.map(getJsDocComments(node, sourceFile), - jsDocComment => { - return { - pos: jsDocComment.pos + "/*".length, // Consume /* from the comment - end: jsDocComment.end - "*/".length // Trim off comment end indicator - }; - }); - } - - function consumeWhiteSpacesOnTheLine(pos: number, end: number, sourceFile: SourceFile, maxSpacesToRemove?: number) { - if (maxSpacesToRemove !== undefined) { - end = Math.min(end, pos + maxSpacesToRemove); - } - - for (; pos < end; pos++) { - const ch = sourceFile.text.charCodeAt(pos); - if (!isWhiteSpaceSingleLine(ch)) { - return pos; - } - } - - return end; - } - - function consumeLineBreaks(pos: number, end: number, sourceFile: SourceFile) { - while (pos < end && isLineBreak(sourceFile.text.charCodeAt(pos))) { - pos++; - } - - return pos; - } - - function isName(pos: number, end: number, sourceFile: SourceFile, name: string) { - return pos + name.length < end && - sourceFile.text.substr(pos, name.length) === name && - isWhiteSpace(sourceFile.text.charCodeAt(pos + name.length)); - } - - function isParamTag(pos: number, end: number, sourceFile: SourceFile) { - // If it is @param tag - return isName(pos, end, sourceFile, paramTag); - } - - function pushDocCommentLineText(docComments: SymbolDisplayPart[], text: string, blankLineCount: number) { - // Add the empty lines in between texts - while (blankLineCount) { - blankLineCount--; - docComments.push(textPart("")); - } - - docComments.push(textPart(text)); - } - - function getCleanedJsDocComment(pos: number, end: number, sourceFile: SourceFile) { - let spacesToRemoveAfterAsterisk: number; - const docComments: SymbolDisplayPart[] = []; - let blankLineCount = 0; - let isInParamTag = false; - - while (pos < end) { - let docCommentTextOfLine = ""; - // First consume leading white space - pos = consumeWhiteSpacesOnTheLine(pos, end, sourceFile); - - // If the comment starts with '*' consume the spaces on this line - if (pos < end && sourceFile.text.charCodeAt(pos) === CharacterCodes.asterisk) { - const lineStartPos = pos + 1; - pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, spacesToRemoveAfterAsterisk); - - // Set the spaces to remove after asterisk as margin if not already set - if (spacesToRemoveAfterAsterisk === undefined && pos < end && !isLineBreak(sourceFile.text.charCodeAt(pos))) { - spacesToRemoveAfterAsterisk = pos - lineStartPos; - } - } - else if (spacesToRemoveAfterAsterisk === undefined) { - spacesToRemoveAfterAsterisk = 0; - } - - // Analyze text on this line - while (pos < end && !isLineBreak(sourceFile.text.charCodeAt(pos))) { - const ch = sourceFile.text.charAt(pos); - if (ch === "@") { - // If it is @param tag - if (isParamTag(pos, end, sourceFile)) { - isInParamTag = true; - pos += paramTag.length; - continue; - } - else { - isInParamTag = false; - } - } - - // Add the ch to doc text if we arent in param tag - if (!isInParamTag) { - docCommentTextOfLine += ch; - } - - // Scan next character - pos++; - } - - // Continue with next line - pos = consumeLineBreaks(pos, end, sourceFile); - if (docCommentTextOfLine) { - pushDocCommentLineText(docComments, docCommentTextOfLine, blankLineCount); - blankLineCount = 0; - } - else if (!isInParamTag && docComments.length) { - // This is blank line when there is text already parsed - blankLineCount++; - } - } - - return docComments; - } - - function getCleanedParamJsDocComment(pos: number, end: number, sourceFile: SourceFile) { - let paramHelpStringMargin: number; - const paramDocComments: SymbolDisplayPart[] = []; - while (pos < end) { - if (isParamTag(pos, end, sourceFile)) { - let blankLineCount = 0; - let recordedParamTag = false; - // Consume leading spaces - pos = consumeWhiteSpaces(pos + paramTag.length); - if (pos >= end) { - break; - } - - // Ignore type expression - if (sourceFile.text.charCodeAt(pos) === CharacterCodes.openBrace) { - pos++; - for (let curlies = 1; pos < end; pos++) { - const charCode = sourceFile.text.charCodeAt(pos); - - // { character means we need to find another } to match the found one - if (charCode === CharacterCodes.openBrace) { - curlies++; - continue; - } - - // } char - if (charCode === CharacterCodes.closeBrace) { - curlies--; - if (curlies === 0) { - // We do not have any more } to match the type expression is ignored completely - pos++; - break; - } - else { - // there are more { to be matched with } - continue; - } - } - - // Found start of another tag - if (charCode === CharacterCodes.at) { - break; - } - } - - // Consume white spaces - pos = consumeWhiteSpaces(pos); - if (pos >= end) { - break; - } - } - - // Parameter name - if (isName(pos, end, sourceFile, name)) { - // Found the parameter we are looking for consume white spaces - pos = consumeWhiteSpaces(pos + name.length); - if (pos >= end) { - break; - } - - let paramHelpString = ""; - const firstLineParamHelpStringPos = pos; - while (pos < end) { - const ch = sourceFile.text.charCodeAt(pos); - - // at line break, set this comment line text and go to next line - if (isLineBreak(ch)) { - if (paramHelpString) { - pushDocCommentLineText(paramDocComments, paramHelpString, blankLineCount); - paramHelpString = ""; - blankLineCount = 0; - recordedParamTag = true; - } - else if (recordedParamTag) { - blankLineCount++; - } - - // Get the pos after cleaning start of the line - setPosForParamHelpStringOnNextLine(firstLineParamHelpStringPos); - continue; - } - - // Done scanning param help string - next tag found - if (ch === CharacterCodes.at) { - break; - } - - paramHelpString += sourceFile.text.charAt(pos); - - // Go to next character - pos++; - } - - // If there is param help text, add it top the doc comments - if (paramHelpString) { - pushDocCommentLineText(paramDocComments, paramHelpString, blankLineCount); - } - paramHelpStringMargin = undefined; - } - - // If this is the start of another tag, continue with the loop in search of param tag with symbol name - if (sourceFile.text.charCodeAt(pos) === CharacterCodes.at) { - continue; - } - } - - // Next character - pos++; - } - - return paramDocComments; - - function consumeWhiteSpaces(pos: number) { - while (pos < end && isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(pos))) { - pos++; - } - - return pos; - } - - function setPosForParamHelpStringOnNextLine(firstLineParamHelpStringPos: number) { - // Get the pos after consuming line breaks - pos = consumeLineBreaks(pos, end, sourceFile); - if (pos >= end) { - return; - } - - if (paramHelpStringMargin === undefined) { - paramHelpStringMargin = sourceFile.getLineAndCharacterOfPosition(firstLineParamHelpStringPos).character; - } - - // Now consume white spaces max - const startOfLinePos = pos; - pos = consumeWhiteSpacesOnTheLine(pos, end, sourceFile, paramHelpStringMargin); - if (pos >= end) { - return; - } - - const consumedSpaces = pos - startOfLinePos; - if (consumedSpaces < paramHelpStringMargin) { - const ch = sourceFile.text.charCodeAt(pos); - if (ch === CharacterCodes.asterisk) { - // Consume more spaces after asterisk - pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, paramHelpStringMargin - consumedSpaces - 1); - } + /** + * Iterates through 'array' by index and performs the callback on each element of array until the callback + * returns a truthy value, then returns that value. + * If no such value is found, the callback is applied to each element of array and undefined is returned. + */ + export function forEachUnique(array: T[], callback: (element: T, index: number) => U): U { + if (array) { + for (let i = 0, len = array.length; i < len; i++) { + if (indexOf(array, array[i]) === i) { + const result = callback(array[i], i); + if (result) { + return result; } } } } + return undefined; } class TypeObject implements Type { @@ -7498,9 +7197,9 @@ namespace ts { // See if this is a doc comment. If so, we'll classify certain portions of it // specially. const docCommentAndDiagnostics = parseIsolatedJSDocComment(sourceFile.text, start, width); - if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDocComment) { - docCommentAndDiagnostics.jsDocComment.parent = token; - classifyJSDocComment(docCommentAndDiagnostics.jsDocComment); + if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDoc) { + docCommentAndDiagnostics.jsDoc.parent = token; + classifyJSDocComment(docCommentAndDiagnostics.jsDoc); return; } } @@ -7513,22 +7212,22 @@ namespace ts { pushClassification(start, width, ClassificationType.comment); } - function classifyJSDocComment(docComment: JSDocComment) { + function classifyJSDocComment(docComment: JSDoc) { let pos = docComment.pos; + if (docComment.tags) { + for (const tag of docComment.tags) { + // As we walk through each tag, classify the portion of text from the end of + // the last tag (or the start of the entire doc comment) as 'comment'. + if (tag.pos !== pos) { + pushCommentRange(pos, tag.pos - pos); + } - for (const tag of docComment.tags) { - // As we walk through each tag, classify the portion of text from the end of - // the last tag (or the start of the entire doc comment) as 'comment'. - if (tag.pos !== pos) { - pushCommentRange(pos, tag.pos - pos); - } + pushClassification(tag.atToken.pos, tag.atToken.end - tag.atToken.pos, ClassificationType.punctuation); + pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, ClassificationType.docCommentTagName); - pushClassification(tag.atToken.pos, tag.atToken.end - tag.atToken.pos, ClassificationType.punctuation); - pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, ClassificationType.docCommentTagName); + pos = tag.tagName.end; - pos = tag.tagName.end; - - switch (tag.kind) { + switch (tag.kind) { case SyntaxKind.JSDocParameterTag: processJSDocParameterTag(tag); break; @@ -7541,9 +7240,10 @@ namespace ts { case SyntaxKind.JSDocReturnTag: processElement((tag).typeExpression); break; - } + } - pos = tag.end; + pos = tag.end; + } } if (pos !== docComment.end) { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 9b3469643ba..4ceecb4bf50 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -569,9 +569,11 @@ namespace ts { if (node) { if (node.jsDocComments) { for (const jsDocComment of node.jsDocComments) { - for (const tag of jsDocComment.tags) { - if (tag.pos <= position && position <= tag.end) { - return tag; + if (jsDocComment.tags) { + for (const tag of jsDocComment.tags) { + if (tag.pos <= position && position <= tag.end) { + return tag; + } } } } @@ -946,4 +948,4 @@ namespace ts { } return { configJsonObject, diagnostics }; } -} \ No newline at end of file +} From b14d7c7ebb1aeee3074fa0c9ee2d42b0d964232e Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 1 Sep 2016 09:25:49 -0700 Subject: [PATCH 06/46] Add more jsdoc tests --- tests/cases/conformance/jsdoc/returns.ts | 9 ++++++++ .../fourslash/jsDocFunctionSignatures10.ts | 15 +++++++++++++ .../fourslash/jsDocFunctionSignatures11.ts | 9 ++++++++ .../fourslash/jsDocFunctionSignatures12.ts | 13 +++++++++++ .../fourslash/jsDocFunctionSignatures2.ts | 2 +- .../fourslash/jsDocFunctionSignatures5.ts | 18 +++++++++++++++ .../fourslash/jsDocFunctionSignatures6.ts | 19 ++++++++++++++++ .../fourslash/jsDocFunctionSignatures7.ts | 16 ++++++++++++++ .../fourslash/jsDocFunctionSignatures8.ts | 16 ++++++++++++++ .../fourslash/jsDocFunctionSignatures9.ts | 22 +++++++++++++++++++ tests/cases/fourslash/jsdocReturnsTag.ts | 17 ++++++++++++++ 11 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 tests/cases/conformance/jsdoc/returns.ts create mode 100644 tests/cases/fourslash/jsDocFunctionSignatures10.ts create mode 100644 tests/cases/fourslash/jsDocFunctionSignatures11.ts create mode 100644 tests/cases/fourslash/jsDocFunctionSignatures12.ts create mode 100644 tests/cases/fourslash/jsDocFunctionSignatures5.ts create mode 100644 tests/cases/fourslash/jsDocFunctionSignatures6.ts create mode 100644 tests/cases/fourslash/jsDocFunctionSignatures7.ts create mode 100644 tests/cases/fourslash/jsDocFunctionSignatures8.ts create mode 100644 tests/cases/fourslash/jsDocFunctionSignatures9.ts create mode 100644 tests/cases/fourslash/jsdocReturnsTag.ts diff --git a/tests/cases/conformance/jsdoc/returns.ts b/tests/cases/conformance/jsdoc/returns.ts new file mode 100644 index 00000000000..72cb4a6cb67 --- /dev/null +++ b/tests/cases/conformance/jsdoc/returns.ts @@ -0,0 +1,9 @@ +// @allowJs: true +// @filename: returns.js +// @out: dummy.js +/** + * @returns {string} This comment is not currently exposed + */ +function f() { + return ""; +} diff --git a/tests/cases/fourslash/jsDocFunctionSignatures10.ts b/tests/cases/fourslash/jsDocFunctionSignatures10.ts new file mode 100644 index 00000000000..60810c46e70 --- /dev/null +++ b/tests/cases/fourslash/jsDocFunctionSignatures10.ts @@ -0,0 +1,15 @@ +/// +// @allowJs: true +// @Filename: Foo.js +/////** +//// * Do some foo things +//// * @template T A Foolish template +//// * @param {T} x a parameter +//// */ +////function foo(x) { +////} +//// +////fo/**/o() + +goTo.marker(); +verify.quickInfoIs("function foo(x: T): void", "Do some foo things"); diff --git a/tests/cases/fourslash/jsDocFunctionSignatures11.ts b/tests/cases/fourslash/jsDocFunctionSignatures11.ts new file mode 100644 index 00000000000..26b2cda6d2a --- /dev/null +++ b/tests/cases/fourslash/jsDocFunctionSignatures11.ts @@ -0,0 +1,9 @@ +/// +// @allowJs: true +// @Filename: Foo.js +/////** +//// * @type {{ [name: string]: string; }} variables +//// */ +////const vari/**/ables = {}; +goTo.marker(); +verify.quickInfoIs("const variables: {\n [name: string]: string;\n}"); diff --git a/tests/cases/fourslash/jsDocFunctionSignatures12.ts b/tests/cases/fourslash/jsDocFunctionSignatures12.ts new file mode 100644 index 00000000000..29a8ac4caeb --- /dev/null +++ b/tests/cases/fourslash/jsDocFunctionSignatures12.ts @@ -0,0 +1,13 @@ + +/// +// @allowJs: true +// @Filename: Foo.js +/////** +//// * @param {{ stringProp: string, +//// * numProp: number }} o +//// */ +////function f1(o) { +//// o/**/; +////} +goTo.marker(); +verify.quickInfoIs("(parameter) o: any"); diff --git a/tests/cases/fourslash/jsDocFunctionSignatures2.ts b/tests/cases/fourslash/jsDocFunctionSignatures2.ts index 174ea7d6560..e6430cba5bd 100644 --- a/tests/cases/fourslash/jsDocFunctionSignatures2.ts +++ b/tests/cases/fourslash/jsDocFunctionSignatures2.ts @@ -9,4 +9,4 @@ //// f6('', /**/false) goTo.marker(); -verify.currentSignatureHelpIs('f6(p0: string, p1?: boolean): number') +verify.currentSignatureHelpIs('f6(arg0: string, arg1?: boolean): number') diff --git a/tests/cases/fourslash/jsDocFunctionSignatures5.ts b/tests/cases/fourslash/jsDocFunctionSignatures5.ts new file mode 100644 index 00000000000..08d0da990bc --- /dev/null +++ b/tests/cases/fourslash/jsDocFunctionSignatures5.ts @@ -0,0 +1,18 @@ +/// +// @allowJs: true +// @Filename: Foo.js + +/////** +//// * Filters a path based on a regexp or glob pattern. +//// * @param {String} basePath The base path where the search will be performed. +//// * @param {String} pattern A string defining a regexp of a glob pattern. +//// * @param {String} type The search pattern type, can be a regexp or a glob. +//// * @param {Object} options A object containing options to the search. +//// * @return {Array} A list containing the filtered paths. +//// */ +////function pathFilter(basePath, pattern, type, options){ +//////... +////} +////pathFilter(/**/'foo', 'bar', 'baz', {}); +goTo.marker(); +verify.currentSignatureHelpDocCommentIs("Filters a path based on a regexp or glob pattern."); diff --git a/tests/cases/fourslash/jsDocFunctionSignatures6.ts b/tests/cases/fourslash/jsDocFunctionSignatures6.ts new file mode 100644 index 00000000000..10b290d6d02 --- /dev/null +++ b/tests/cases/fourslash/jsDocFunctionSignatures6.ts @@ -0,0 +1,19 @@ +/// +// @allowJs: true +// @Filename: Foo.js +/////** +//// * @param {string} p1 - A string param +//// * @param {string?} p2 - An optional param +//// * @param {string} [p3] - Another optional param +//// * @param {string} [p4="test"] - An optional param with a default value +//// */ +////function f1(p1, p2, p3, p4){} +////f1(/*1*/'foo', /*2*/'bar', /*3*/'baz', /*4*/'qux'); +goTo.marker('1'); +verify.currentParameterHelpArgumentDocCommentIs("- A string param"); +goTo.marker('2'); +verify.currentParameterHelpArgumentDocCommentIs("- An optional param "); +goTo.marker('3'); +verify.currentParameterHelpArgumentDocCommentIs("- Another optional param"); +goTo.marker('4'); +verify.currentParameterHelpArgumentDocCommentIs("- An optional param with a default value"); diff --git a/tests/cases/fourslash/jsDocFunctionSignatures7.ts b/tests/cases/fourslash/jsDocFunctionSignatures7.ts new file mode 100644 index 00000000000..6bbb8a34dcc --- /dev/null +++ b/tests/cases/fourslash/jsDocFunctionSignatures7.ts @@ -0,0 +1,16 @@ +/// +// @allowJs: true +// @Filename: Foo.js +/////** +//// * @param {string} p0 +//// * @param {string} [p1] +//// */ +////function Test(p0, p1) { +//// this.P0 = p0; +//// this.P1 = p1; +////} +//// +//// +////var /**/test = new Test(""); +goTo.marker(); +verify.quickInfoIs('var test: {\n P0: string;\n P1: string;\n}'); diff --git a/tests/cases/fourslash/jsDocFunctionSignatures8.ts b/tests/cases/fourslash/jsDocFunctionSignatures8.ts new file mode 100644 index 00000000000..3dbe38e34df --- /dev/null +++ b/tests/cases/fourslash/jsDocFunctionSignatures8.ts @@ -0,0 +1,16 @@ +/// +// @allowJs: true +// @Filename: Foo.js +/////** +//// * Represents a person +//// * @constructor +//// * @param {string} name The name of the person +//// * @param {number} age The age of the person +//// */ +////function Person(name, age) { +//// this.name = name; +//// this.age = age; +////} +////var p = new Pers/**/on(); +goTo.marker(); +verify.quickInfoIs("function Person(name: string, age: number): void", "Represents a person"); diff --git a/tests/cases/fourslash/jsDocFunctionSignatures9.ts b/tests/cases/fourslash/jsDocFunctionSignatures9.ts new file mode 100644 index 00000000000..26361bfe106 --- /dev/null +++ b/tests/cases/fourslash/jsDocFunctionSignatures9.ts @@ -0,0 +1,22 @@ +/// +// @allowJs: true +// @Filename: Foo.js +/////** first line of the comment +//// +////third line */ +////function foo() {} +////foo/**/(); +goTo.marker(); +verify.verifyQuickInfoDisplayParts('function', + '', + { start: 63, length: 3 }, + [{"text": "function", "kind": "keyword"}, + {"text": " ", "kind": "space"}, + {"text": "foo", "kind": "functionName"}, + {"text": "(", "kind": "punctuation"}, + {"text": ")", "kind": "punctuation"}, + {"text": ":", "kind": "punctuation"}, + {"text": " ", "kind": "space"}, + {"text": "void", "kind": "keyword"} + ], + [{"text": "first line of the comment\n\nthird line ", "kind": "text"}]); diff --git a/tests/cases/fourslash/jsdocReturnsTag.ts b/tests/cases/fourslash/jsdocReturnsTag.ts new file mode 100644 index 00000000000..9203bd9e036 --- /dev/null +++ b/tests/cases/fourslash/jsdocReturnsTag.ts @@ -0,0 +1,17 @@ +/// +// @allowJs: true +// @Filename: dummy.js +/////** +//// * Find an item +//// * @template T +//// * @param {T[]} l +//// * @param {T} x +//// * @returns {?T} The names of the found item(s). +//// */ +////function find(l, x) { +////} +////find(''/**/); + +goTo.marker(); +verify.currentSignatureHelpIs("find(l: T[], x: T): T") +// There currently isn't a way to display the return tag comment From 2b9624672df3027af28f96741025ec3c3906d82c Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 1 Sep 2016 09:26:44 -0700 Subject: [PATCH 07/46] Update/add baselines for jsdoc/emitter changes --- .../reference/arrowFunctionErrorSpan.js | 4 +- .../reference/augmentExportEquals1.js | 4 +- .../reference/augmentExportEquals1_1.js | 4 +- .../reference/augmentExportEquals2.js | 4 +- .../reference/augmentExportEquals2_1.js | 4 +- .../augmentedTypesExternalModule1.js | 2 +- ...ScopedFunctionDeclarationInStrictModule.js | 2 +- tests/baselines/reference/callOverloads1.js | 2 +- tests/baselines/reference/callOverloads2.js | 2 +- tests/baselines/reference/callOverloads3.js | 2 +- tests/baselines/reference/callOverloads4.js | 2 +- tests/baselines/reference/callOverloads5.js | 2 +- .../reference/collisionArgumentsFunction.js | 1 + .../collisionRestParameterFunction.js | 1 + .../collisionThisExpressionAndParameter.js | 1 + .../reference/commentInEmptyParameterList1.js | 2 +- ...mentOnParenthesizedExpressionOpenParen1.js | 2 +- .../commentsArgumentsOfCallExpression2.js | 2 +- tests/baselines/reference/commentsFunction.js | 4 +- tests/baselines/reference/commentsVarDecl.js | 6 +- .../reference/computedPropertyNames48_ES5.js | 4 +- .../reference/constructorOverloads1.js | 4 +- .../reference/constructorOverloads2.js | 4 +- .../reference/constructorOverloads3.js | 2 +- .../contextuallyTypingRestParameters.js | 4 +- .../declFileObjectLiteralWithAccessors.js | 4 +- .../declFileObjectLiteralWithOnlyGetter.js | 4 +- .../declFileObjectLiteralWithOnlySetter.js | 4 +- tests/baselines/reference/errorSupression1.js | 2 +- .../es6ImportDefaultBindingWithExport.js | 2 +- .../reference/es6ImportNameSpaceImportDts.js | 1 + .../es6ImportNameSpaceImportNoNamedExports.js | 1 + .../es6ImportNamedImportIdentifiersParsing.js | 1 + .../reference/es6modulekindWithES5Target10.js | 1 + ...rtSpecifierReferencingOuterDeclaration4.js | 1 + .../baselines/reference/genericConstraint3.js | 1 + ...ersAndIndexSignaturesFromDifferentBases.js | 1 + ...rsAndIndexSignaturesFromDifferentBases2.js | 1 + ...tedStringIndexersFromDifferentBaseTypes.js | 1 + ...edStringIndexersFromDifferentBaseTypes2.js | 1 + .../reference/jsxInvalidEsprimaTestSuite.js | 4 +- .../nonConflictingRecursiveBaseTypeMembers.js | 1 + .../objectTypesWithOptionalProperties2.js | 3 +- ...parseRegularExpressionMixedWithComments.js | 6 +- .../parserGreaterThanTokenAmbiguity10.js | 1 + .../parserGreaterThanTokenAmbiguity13.js | 2 +- .../parserGreaterThanTokenAmbiguity15.js | 1 + .../parserGreaterThanTokenAmbiguity18.js | 2 +- .../parserGreaterThanTokenAmbiguity20.js | 1 + .../parserGreaterThanTokenAmbiguity3.js | 2 +- .../parserGreaterThanTokenAmbiguity5.js | 1 + .../parserGreaterThanTokenAmbiguity8.js | 2 +- .../reference/parserSkippedTokens5.js | 2 +- .../reference/parserSkippedTokens7.js | 1 + .../reference/parserSkippedTokens8.js | 2 +- .../reference/parserSkippedTokens9.js | 1 + ...siveExportAssignmentAndFindAliasedType1.js | 2 +- ...siveExportAssignmentAndFindAliasedType2.js | 2 +- ...siveExportAssignmentAndFindAliasedType3.js | 2 +- ...siveExportAssignmentAndFindAliasedType4.js | 2 +- ...siveExportAssignmentAndFindAliasedType5.js | 2 +- ...siveExportAssignmentAndFindAliasedType6.js | 2 +- ...siveExportAssignmentAndFindAliasedType7.js | 2 +- tests/baselines/reference/returns.js | 16 ++++ tests/baselines/reference/returns.symbols | 10 +++ tests/baselines/reference/returns.types | 11 +++ .../thisInInvalidContextsExternalModule.js | 2 +- tests/baselines/reference/tsxParseTests2.js | 2 +- .../typeAliasDoesntMakeModuleInstantiated.js | 1 + tests/cases/fourslash/commentsClassMembers.ts | 89 +++++++++---------- .../cases/fourslash/commentsCommentParsing.ts | 54 +++++------ .../fourslash/commentsFunctionExpression.ts | 12 +-- .../fourslash/commentsLinePreservation.ts | 10 +-- tests/cases/fourslash/commentsModules.ts | 26 +++--- .../fourslash/getJavaScriptQuickInfo1.ts | 2 +- .../fourslash/getJavaScriptQuickInfo7.ts | 2 +- 76 files changed, 219 insertions(+), 161 deletions(-) create mode 100644 tests/baselines/reference/returns.js create mode 100644 tests/baselines/reference/returns.symbols create mode 100644 tests/baselines/reference/returns.types diff --git a/tests/baselines/reference/arrowFunctionErrorSpan.js b/tests/baselines/reference/arrowFunctionErrorSpan.js index 2557113e89b..3ead7ed3b31 100644 --- a/tests/baselines/reference/arrowFunctionErrorSpan.js +++ b/tests/baselines/reference/arrowFunctionErrorSpan.js @@ -83,7 +83,9 @@ f(// comment 1 // comment 2 function () { // comment 4 -}); +} + // comment 5 +); // body is not a block f(function (_) { return 1 + 2; }); diff --git a/tests/baselines/reference/augmentExportEquals1.js b/tests/baselines/reference/augmentExportEquals1.js index 98322c01a34..6f7aab92692 100644 --- a/tests/baselines/reference/augmentExportEquals1.js +++ b/tests/baselines/reference/augmentExportEquals1.js @@ -32,5 +32,5 @@ define(["require", "exports"], function (require, exports) { //// [file3.js] define(["require", "exports", "./file2"], function (require, exports) { "use strict"; - var a; // should not work -}); + var a; +}); // should not work diff --git a/tests/baselines/reference/augmentExportEquals1_1.js b/tests/baselines/reference/augmentExportEquals1_1.js index 08f032ff33f..70239663441 100644 --- a/tests/baselines/reference/augmentExportEquals1_1.js +++ b/tests/baselines/reference/augmentExportEquals1_1.js @@ -29,5 +29,5 @@ define(["require", "exports"], function (require, exports) { //// [file3.js] define(["require", "exports", "file2"], function (require, exports) { "use strict"; - var a; // should not work -}); + var a; +}); // should not work diff --git a/tests/baselines/reference/augmentExportEquals2.js b/tests/baselines/reference/augmentExportEquals2.js index fc373173e3c..b444c16b6fc 100644 --- a/tests/baselines/reference/augmentExportEquals2.js +++ b/tests/baselines/reference/augmentExportEquals2.js @@ -31,5 +31,5 @@ define(["require", "exports"], function (require, exports) { //// [file3.js] define(["require", "exports", "./file2"], function (require, exports) { "use strict"; - var a; // should not work -}); + var a; +}); // should not work diff --git a/tests/baselines/reference/augmentExportEquals2_1.js b/tests/baselines/reference/augmentExportEquals2_1.js index 9046157bb26..afa78d1d981 100644 --- a/tests/baselines/reference/augmentExportEquals2_1.js +++ b/tests/baselines/reference/augmentExportEquals2_1.js @@ -29,5 +29,5 @@ define(["require", "exports"], function (require, exports) { //// [file3.js] define(["require", "exports", "file2"], function (require, exports) { "use strict"; - var a; // should not work -}); + var a; +}); // should not work diff --git a/tests/baselines/reference/augmentedTypesExternalModule1.js b/tests/baselines/reference/augmentedTypesExternalModule1.js index 65525e8187e..01358a9e4af 100644 --- a/tests/baselines/reference/augmentedTypesExternalModule1.js +++ b/tests/baselines/reference/augmentedTypesExternalModule1.js @@ -13,4 +13,4 @@ define(["require", "exports"], function (require, exports) { c5.prototype.foo = function () { }; return c5; }()); -}); +}); // should be ok everywhere diff --git a/tests/baselines/reference/blockScopedFunctionDeclarationInStrictModule.js b/tests/baselines/reference/blockScopedFunctionDeclarationInStrictModule.js index d1a8091871c..6d460158478 100644 --- a/tests/baselines/reference/blockScopedFunctionDeclarationInStrictModule.js +++ b/tests/baselines/reference/blockScopedFunctionDeclarationInStrictModule.js @@ -14,4 +14,4 @@ define(["require", "exports"], function (require, exports) { foo(); // ok } return foo; -}); +}); // not ok diff --git a/tests/baselines/reference/callOverloads1.js b/tests/baselines/reference/callOverloads1.js index 756a9099e44..d441deb41d7 100644 --- a/tests/baselines/reference/callOverloads1.js +++ b/tests/baselines/reference/callOverloads1.js @@ -22,7 +22,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function () { }; + Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; return Foo; }()); function F1(a) { return a; } diff --git a/tests/baselines/reference/callOverloads2.js b/tests/baselines/reference/callOverloads2.js index b890ee8bde9..8db26c3b771 100644 --- a/tests/baselines/reference/callOverloads2.js +++ b/tests/baselines/reference/callOverloads2.js @@ -30,7 +30,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function () { }; + Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; return Foo; }()); function F1(s) { return s; } // error diff --git a/tests/baselines/reference/callOverloads3.js b/tests/baselines/reference/callOverloads3.js index e5d678543c6..ee49f4b3297 100644 --- a/tests/baselines/reference/callOverloads3.js +++ b/tests/baselines/reference/callOverloads3.js @@ -23,7 +23,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function () { }; + Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; return Foo; }()); //class Foo(s: String); diff --git a/tests/baselines/reference/callOverloads4.js b/tests/baselines/reference/callOverloads4.js index dfb274dfb6e..fa7a51ae8d1 100644 --- a/tests/baselines/reference/callOverloads4.js +++ b/tests/baselines/reference/callOverloads4.js @@ -23,7 +23,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function () { }; + Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; return Foo; }()); var f1 = new Foo("hey"); diff --git a/tests/baselines/reference/callOverloads5.js b/tests/baselines/reference/callOverloads5.js index cf159d309b0..d95485f85d7 100644 --- a/tests/baselines/reference/callOverloads5.js +++ b/tests/baselines/reference/callOverloads5.js @@ -24,7 +24,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function (a) { }; + Foo.prototype.bar1 = function (a) { /*WScript.Echo(a);*/ }; return Foo; }()); //class Foo(s: String); diff --git a/tests/baselines/reference/collisionArgumentsFunction.js b/tests/baselines/reference/collisionArgumentsFunction.js index 9ce4a5ab0e2..d59efc116ee 100644 --- a/tests/baselines/reference/collisionArgumentsFunction.js +++ b/tests/baselines/reference/collisionArgumentsFunction.js @@ -90,3 +90,4 @@ function f42(i) { function f4NoError(arguments) { var arguments; // No error } + // no codegen no error diff --git a/tests/baselines/reference/collisionRestParameterFunction.js b/tests/baselines/reference/collisionRestParameterFunction.js index 8660e8f5db0..a9e3f510fa1 100644 --- a/tests/baselines/reference/collisionRestParameterFunction.js +++ b/tests/baselines/reference/collisionRestParameterFunction.js @@ -63,3 +63,4 @@ function f4(_i) { } function f4NoError(_i) { } + // no codegen no error diff --git a/tests/baselines/reference/collisionThisExpressionAndParameter.js b/tests/baselines/reference/collisionThisExpressionAndParameter.js index bc15e4b56b5..a445c35295b 100644 --- a/tests/baselines/reference/collisionThisExpressionAndParameter.js +++ b/tests/baselines/reference/collisionThisExpressionAndParameter.js @@ -167,3 +167,4 @@ function f3(_this) { var _this = this; (function (x) { console.log(_this.x); }); } + // no code gen - no error diff --git a/tests/baselines/reference/commentInEmptyParameterList1.js b/tests/baselines/reference/commentInEmptyParameterList1.js index 8f4e13d82d6..09b34f93536 100644 --- a/tests/baselines/reference/commentInEmptyParameterList1.js +++ b/tests/baselines/reference/commentInEmptyParameterList1.js @@ -3,5 +3,5 @@ function foo(/** nothing */) { } //// [commentInEmptyParameterList1.js] -function foo() { +function foo( /** nothing */) { } diff --git a/tests/baselines/reference/commentOnParenthesizedExpressionOpenParen1.js b/tests/baselines/reference/commentOnParenthesizedExpressionOpenParen1.js index d014043dfe0..7a7c25a9b4c 100644 --- a/tests/baselines/reference/commentOnParenthesizedExpressionOpenParen1.js +++ b/tests/baselines/reference/commentOnParenthesizedExpressionOpenParen1.js @@ -7,4 +7,4 @@ var f: () => any; //// [commentOnParenthesizedExpressionOpenParen1.js] var j; var f; -(j = f()); +(/* Preserve */ j = f()); diff --git a/tests/baselines/reference/commentsArgumentsOfCallExpression2.js b/tests/baselines/reference/commentsArgumentsOfCallExpression2.js index a7065410ff4..f89e67ef3d8 100644 --- a/tests/baselines/reference/commentsArgumentsOfCallExpression2.js +++ b/tests/baselines/reference/commentsArgumentsOfCallExpression2.js @@ -14,7 +14,7 @@ foo( function foo(/*c1*/ x, /*d1*/ y, /*e1*/ w) { } var a, b; foo(/*c2*/ 1, /*d2*/ 1 + 2, /*e1*/ a + b); -foo(/*c3*/ function () { }, /*d2*/ function () { }, /*e2*/ a + b); +foo(/*c3*/ function () { }, /*d2*/ function () { }, /*e2*/ a + /*e3*/ b); foo(/*c3*/ function () { }, /*d3*/ function () { }, /*e3*/ (a + b)); foo( /*c4*/ function () { }, diff --git a/tests/baselines/reference/commentsFunction.js b/tests/baselines/reference/commentsFunction.js index 0ffb2714108..86978d7bdf7 100644 --- a/tests/baselines/reference/commentsFunction.js +++ b/tests/baselines/reference/commentsFunction.js @@ -74,8 +74,8 @@ var fooFunc = function FooFunctionValue(/** fooFunctionValue param */ b) { return b; }; /// lamdaFoo var comment -var lambdaFoo = function (/**param a*/ a, /**param b*/ b) { return a + b; }; -var lambddaNoVarComment = function (/**param a*/ a, /**param b*/ b) { return a * b; }; +var lambdaFoo = /** this is lambda comment*/ function (/**param a*/ a, /**param b*/ b) { return a + b; }; +var lambddaNoVarComment = /** this is lambda multiplication*/ function (/**param a*/ a, /**param b*/ b) { return a * b; }; lambdaFoo(10, 20); lambddaNoVarComment(10, 20); function blah(a /* multiline trailing comment diff --git a/tests/baselines/reference/commentsVarDecl.js b/tests/baselines/reference/commentsVarDecl.js index 5ff2a3c1c6a..e9b6776a6d9 100644 --- a/tests/baselines/reference/commentsVarDecl.js +++ b/tests/baselines/reference/commentsVarDecl.js @@ -64,13 +64,13 @@ x = myVariable; /** jsdocstyle comment - only this comment should be in .d.ts file*/ var n = 30; /** var deckaration with comment on type as well*/ -var y = 20; +var y = /** value comment */ 20; /// var deckaration with comment on type as well var yy = /// value comment 20; /** comment2 */ -var z = function (x, y) { return x + y; }; +var z = /** lambda comment */ function (x, y) { return x + y; }; var z2; var x2 = z2; var n4; @@ -98,6 +98,6 @@ declare var y: number; declare var yy: number; /** comment2 */ declare var z: (x: number, y: number) => number; -declare var z2: (x: number) => string; +declare var z2: /** type comment*/ (x: number) => string; declare var x2: (x: number) => string; declare var n4: (x: number) => string; diff --git a/tests/baselines/reference/computedPropertyNames48_ES5.js b/tests/baselines/reference/computedPropertyNames48_ES5.js index 15123a98f30..f2610b7272a 100644 --- a/tests/baselines/reference/computedPropertyNames48_ES5.js +++ b/tests/baselines/reference/computedPropertyNames48_ES5.js @@ -34,5 +34,5 @@ extractIndexer((_b = {}, extractIndexer((_c = {}, _c["" || 0] = "", _c -)); // Should return any (widened form of undefined) -var _a, _b, _c; +)); +var _a, _b, _c; // Should return any (widened form of undefined) diff --git a/tests/baselines/reference/constructorOverloads1.js b/tests/baselines/reference/constructorOverloads1.js index 47906974f6e..d62cb9530c5 100644 --- a/tests/baselines/reference/constructorOverloads1.js +++ b/tests/baselines/reference/constructorOverloads1.js @@ -25,8 +25,8 @@ f1.bar2(); var Foo = (function () { function Foo(x) { } - Foo.prototype.bar1 = function () { }; - Foo.prototype.bar2 = function () { }; + Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; + Foo.prototype.bar2 = function () { /*WScript.Echo("bar1");*/ }; return Foo; }()); var f1 = new Foo("hey"); diff --git a/tests/baselines/reference/constructorOverloads2.js b/tests/baselines/reference/constructorOverloads2.js index 76481ec1bc6..e8d11af4056 100644 --- a/tests/baselines/reference/constructorOverloads2.js +++ b/tests/baselines/reference/constructorOverloads2.js @@ -34,7 +34,7 @@ var __extends = (this && this.__extends) || function (d, b) { var FooBase = (function () { function FooBase(x) { } - FooBase.prototype.bar1 = function () { }; + FooBase.prototype.bar1 = function () { /*WScript.Echo("base bar1");*/ }; return FooBase; }()); var Foo = (function (_super) { @@ -42,7 +42,7 @@ var Foo = (function (_super) { function Foo(x, y) { _super.call(this, x); } - Foo.prototype.bar1 = function () { }; + Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; return Foo; }(FooBase)); var f1 = new Foo("hey"); diff --git a/tests/baselines/reference/constructorOverloads3.js b/tests/baselines/reference/constructorOverloads3.js index 61f0d50db03..7cc27fd5b42 100644 --- a/tests/baselines/reference/constructorOverloads3.js +++ b/tests/baselines/reference/constructorOverloads3.js @@ -32,7 +32,7 @@ var Foo = (function (_super) { __extends(Foo, _super); function Foo(x, y) { } - Foo.prototype.bar1 = function () { }; + Foo.prototype.bar1 = function () { /*WScript.Echo("Yo");*/ }; return Foo; }(FooBase)); var f1 = new Foo("hey"); diff --git a/tests/baselines/reference/contextuallyTypingRestParameters.js b/tests/baselines/reference/contextuallyTypingRestParameters.js index 17561f5d7fc..48589ade408 100644 --- a/tests/baselines/reference/contextuallyTypingRestParameters.js +++ b/tests/baselines/reference/contextuallyTypingRestParameters.js @@ -9,9 +9,9 @@ var x: (...y: string[]) => void = function (.../*3*/y) { //// [contextuallyTypingRestParameters.js] var x = function () { - var y = []; + var /*3*/ y = []; for (var _i = 0; _i < arguments.length; _i++) { - y[_i - 0] = arguments[_i]; + /*3*/ y[_i - 0] = arguments[_i]; } var t = y; var x2 = t; // This should be error diff --git a/tests/baselines/reference/declFileObjectLiteralWithAccessors.js b/tests/baselines/reference/declFileObjectLiteralWithAccessors.js index 7886736f7e4..adc185e269f 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithAccessors.js +++ b/tests/baselines/reference/declFileObjectLiteralWithAccessors.js @@ -12,7 +12,7 @@ var /*2*/x = point.x; point./*3*/x = 30; //// [declFileObjectLiteralWithAccessors.js] -function makePoint(x) { +function /*1*/ makePoint(x) { return { b: 10, get x() { return x; }, @@ -22,7 +22,7 @@ function makePoint(x) { ; var /*4*/ point = makePoint(2); var /*2*/ x = point.x; -point.x = 30; +point./*3*/ x = 30; //// [declFileObjectLiteralWithAccessors.d.ts] diff --git a/tests/baselines/reference/declFileObjectLiteralWithOnlyGetter.js b/tests/baselines/reference/declFileObjectLiteralWithOnlyGetter.js index eb440c028d5..96b4de87bef 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithOnlyGetter.js +++ b/tests/baselines/reference/declFileObjectLiteralWithOnlyGetter.js @@ -10,14 +10,14 @@ var /*2*/x = point./*3*/x; //// [declFileObjectLiteralWithOnlyGetter.js] -function makePoint(x) { +function /*1*/ makePoint(x) { return { get x() { return x; }, }; } ; var /*4*/ point = makePoint(2); -var /*2*/ x = point.x; +var /*2*/ x = point./*3*/ x; //// [declFileObjectLiteralWithOnlyGetter.d.ts] diff --git a/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.js b/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.js index f7a48fe810c..44b28a9bdb2 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.js +++ b/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.js @@ -10,7 +10,7 @@ var /*3*/point = makePoint(2); point./*2*/x = 30; //// [declFileObjectLiteralWithOnlySetter.js] -function makePoint(x) { +function /*1*/ makePoint(x) { return { b: 10, set x(a) { this.b = a; } @@ -18,7 +18,7 @@ function makePoint(x) { } ; var /*3*/ point = makePoint(2); -point.x = 30; +point./*2*/ x = 30; //// [declFileObjectLiteralWithOnlySetter.d.ts] diff --git a/tests/baselines/reference/errorSupression1.js b/tests/baselines/reference/errorSupression1.js index 77545131ce3..285aa525b5f 100644 --- a/tests/baselines/reference/errorSupression1.js +++ b/tests/baselines/reference/errorSupression1.js @@ -18,4 +18,4 @@ var Foo = (function () { var baz = Foo.b; // Foo.b won't bind. baz.concat("y"); -// So we don't want an error on 'concat'. + // So we don't want an error on 'concat'. diff --git a/tests/baselines/reference/es6ImportDefaultBindingWithExport.js b/tests/baselines/reference/es6ImportDefaultBindingWithExport.js index cc90d280914..1e6f49e2414 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingWithExport.js +++ b/tests/baselines/reference/es6ImportDefaultBindingWithExport.js @@ -21,7 +21,7 @@ define(["require", "exports"], function (require, exports) { define(["require", "exports", "server"], function (require, exports, server_1) { "use strict"; exports.x = server_1.default; -}); +}); // non referenced //// [server.d.ts] diff --git a/tests/baselines/reference/es6ImportNameSpaceImportDts.js b/tests/baselines/reference/es6ImportNameSpaceImportDts.js index cf66c08331e..0b522776c4b 100644 --- a/tests/baselines/reference/es6ImportNameSpaceImportDts.js +++ b/tests/baselines/reference/es6ImportNameSpaceImportDts.js @@ -22,6 +22,7 @@ exports.c = c; "use strict"; var nameSpaceBinding = require("./server"); exports.x = new nameSpaceBinding.c(); + // unreferenced //// [server.d.ts] diff --git a/tests/baselines/reference/es6ImportNameSpaceImportNoNamedExports.js b/tests/baselines/reference/es6ImportNameSpaceImportNoNamedExports.js index 8ece816fd3b..79c588dc277 100644 --- a/tests/baselines/reference/es6ImportNameSpaceImportNoNamedExports.js +++ b/tests/baselines/reference/es6ImportNameSpaceImportNoNamedExports.js @@ -14,3 +14,4 @@ var a = 10; module.exports = a; //// [es6ImportNameSpaceImportNoNamedExports_1.js] "use strict"; + // error diff --git a/tests/baselines/reference/es6ImportNamedImportIdentifiersParsing.js b/tests/baselines/reference/es6ImportNamedImportIdentifiersParsing.js index 8db7fcd6f9c..a9a843f3cc9 100644 --- a/tests/baselines/reference/es6ImportNamedImportIdentifiersParsing.js +++ b/tests/baselines/reference/es6ImportNamedImportIdentifiersParsing.js @@ -7,3 +7,4 @@ import { default as yield } from "somemodule"; // no error import { default as default } from "somemodule"; // default as is ok, error of default binding name //// [es6ImportNamedImportIdentifiersParsing.js] + // default as is ok, error of default binding name diff --git a/tests/baselines/reference/es6modulekindWithES5Target10.js b/tests/baselines/reference/es6modulekindWithES5Target10.js index b8a66241780..015a64c3bc0 100644 --- a/tests/baselines/reference/es6modulekindWithES5Target10.js +++ b/tests/baselines/reference/es6modulekindWithES5Target10.js @@ -8,3 +8,4 @@ namespace N { export = N; // Error //// [es6modulekindWithES5Target10.js] + // Error diff --git a/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration4.js b/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration4.js index 1badf469996..1b8e4dd5c4b 100644 --- a/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration4.js +++ b/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration4.js @@ -12,3 +12,4 @@ export declare function bar(): X.bar; // error //// [exportSpecifierReferencingOuterDeclaration2_A.js] //// [exportSpecifierReferencingOuterDeclaration2_B.js] "use strict"; + // error diff --git a/tests/baselines/reference/genericConstraint3.js b/tests/baselines/reference/genericConstraint3.js index 59548c4f4d7..657600ba41a 100644 --- a/tests/baselines/reference/genericConstraint3.js +++ b/tests/baselines/reference/genericConstraint3.js @@ -4,3 +4,4 @@ interface A> { x: U; } interface B extends A<{}, { x: {} }> { } // Should not produce an error //// [genericConstraint3.js] + // Should not produce an error diff --git a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.js b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.js index f4ea5f07eb9..26ef7ca7759 100644 --- a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.js +++ b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.js @@ -28,3 +28,4 @@ interface G extends A, B, C, E { } // should only report one error interface H extends A, F { } // Should report no error at all because error is internal to F //// [inheritedMembersAndIndexSignaturesFromDifferentBases.js] + // Should report no error at all because error is internal to F diff --git a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases2.js b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases2.js index 8a3b2f8d032..9291ab53c1c 100644 --- a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases2.js +++ b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases2.js @@ -10,3 +10,4 @@ interface B { interface C extends B, A { } // Should succeed //// [inheritedMembersAndIndexSignaturesFromDifferentBases2.js] + // Should succeed diff --git a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.js b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.js index 1645dd10a55..c7a008f01fb 100644 --- a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.js +++ b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.js @@ -29,3 +29,4 @@ interface D2 { interface E2 extends A2, D2 { } // error //// [inheritedStringIndexersFromDifferentBaseTypes.js] + // error diff --git a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.js b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.js index aa837b5cf2e..0580b145901 100644 --- a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.js +++ b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.js @@ -25,3 +25,4 @@ interface F extends A, D { } // ok because we overrode D's number index signature //// [inheritedStringIndexersFromDifferentBaseTypes2.js] + // ok because we overrode D's number index signature diff --git a/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js b/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js index 7f01666bd78..85d0d3687be 100644 --- a/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js +++ b/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js @@ -62,7 +62,7 @@ a['foo'] > ; ; ; var x =
one
two
;; -var x =
one
/* intervening comment */ /* intervening comment */
two
;; +var x =
one
/* intervening comment */ /* intervening comment */
two
;;
{"str"}}; id="b" />;
>; @@ -76,4 +76,4 @@ var x =
one
/* intervening comment */ /* intervening comment */
; ; }; - /*hai*//*hai*/asdf/>;; +/*hai*/ /*hai*/asdf/>;; diff --git a/tests/baselines/reference/nonConflictingRecursiveBaseTypeMembers.js b/tests/baselines/reference/nonConflictingRecursiveBaseTypeMembers.js index 6e77029fa94..9663da873b8 100644 --- a/tests/baselines/reference/nonConflictingRecursiveBaseTypeMembers.js +++ b/tests/baselines/reference/nonConflictingRecursiveBaseTypeMembers.js @@ -10,3 +10,4 @@ interface B { interface C extends A, B { } // Should not be an error //// [nonConflictingRecursiveBaseTypeMembers.js] + // Should not be an error diff --git a/tests/baselines/reference/objectTypesWithOptionalProperties2.js b/tests/baselines/reference/objectTypesWithOptionalProperties2.js index eabb1a153a6..28470e04983 100644 --- a/tests/baselines/reference/objectTypesWithOptionalProperties2.js +++ b/tests/baselines/reference/objectTypesWithOptionalProperties2.js @@ -42,6 +42,5 @@ var C2 = (function () { return C2; }()); var b = { - x: function () { }, 1: // error - // error + x: function () { }, 1: // error }; diff --git a/tests/baselines/reference/parseRegularExpressionMixedWithComments.js b/tests/baselines/reference/parseRegularExpressionMixedWithComments.js index 78752a77f75..0ef42cf2ce1 100644 --- a/tests/baselines/reference/parseRegularExpressionMixedWithComments.js +++ b/tests/baselines/reference/parseRegularExpressionMixedWithComments.js @@ -8,7 +8,7 @@ var regex5 = /**// asdf/**/ /; //// [parseRegularExpressionMixedWithComments.js] var regex1 = / asdf /; -var regex2 = / asdf /; +var regex2 = /**/ / asdf /; var regex3 = 1; -var regex4 = Math.pow(/ /, /asdf /); -var regex5 = Math.pow(/ asdf/, / /); +var regex4 = /**/ Math.pow(/ /, /asdf /); +var regex5 = /**/ Math.pow(/ asdf/, / /); diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js index 862722b1a73..eb76d7e0d7c 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js @@ -6,5 +6,6 @@ //// [parserGreaterThanTokenAmbiguity10.js] 1 + // before >>> 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity13.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity13.js index 49130a9dd13..5be4da1c04e 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity13.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity13.js @@ -2,5 +2,5 @@ 1 >>/**/= 2; //// [parserGreaterThanTokenAmbiguity13.js] -1 >> ; /**/ +1 >> /**/ ; 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js index b6f905e12e7..8fadea77fdc 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js @@ -6,5 +6,6 @@ //// [parserGreaterThanTokenAmbiguity15.js] 1 + // before >>= 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity18.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity18.js index 71527689b2c..4cf227f2748 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity18.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity18.js @@ -2,5 +2,5 @@ 1 >>>/**/= 2; //// [parserGreaterThanTokenAmbiguity18.js] -1 >>> ; /**/ +1 >>> /**/ ; 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js index 01d1d6401f2..ab86deeb0d2 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js @@ -6,5 +6,6 @@ //// [parserGreaterThanTokenAmbiguity20.js] 1 + // Before >>>= 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity3.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity3.js index 79f8c139260..f692d1a6324 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity3.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity3.js @@ -2,4 +2,4 @@ 1 >/**/> 2; //// [parserGreaterThanTokenAmbiguity3.js] -1 > /**/ > 2; +1 > /**/ /**/ > 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js index c65b76f504a..24aa9e5316a 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js @@ -6,5 +6,6 @@ //// [parserGreaterThanTokenAmbiguity5.js] 1 + // before >> 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity8.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity8.js index 0006c03219a..d8ea6134a58 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity8.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity8.js @@ -2,4 +2,4 @@ 1 >>/**/> 2; //// [parserGreaterThanTokenAmbiguity8.js] -1 >> /**/ > 2; +1 >> /**/ /**/ > 2; diff --git a/tests/baselines/reference/parserSkippedTokens5.js b/tests/baselines/reference/parserSkippedTokens5.js index 359a98a5969..665db1ef70d 100644 --- a/tests/baselines/reference/parserSkippedTokens5.js +++ b/tests/baselines/reference/parserSkippedTokens5.js @@ -2,4 +2,4 @@ \ /*foo*/ ; //// [parserSkippedTokens5.js] -; +/*foo*/ ; diff --git a/tests/baselines/reference/parserSkippedTokens7.js b/tests/baselines/reference/parserSkippedTokens7.js index 2115614ea1f..b3aa40d9057 100644 --- a/tests/baselines/reference/parserSkippedTokens7.js +++ b/tests/baselines/reference/parserSkippedTokens7.js @@ -2,3 +2,4 @@ /*foo*/ \ /*bar*/ //// [parserSkippedTokens7.js] + /*bar*/ diff --git a/tests/baselines/reference/parserSkippedTokens8.js b/tests/baselines/reference/parserSkippedTokens8.js index c9f00f4b85b..d8433bbd34c 100644 --- a/tests/baselines/reference/parserSkippedTokens8.js +++ b/tests/baselines/reference/parserSkippedTokens8.js @@ -3,4 +3,4 @@ /*foo*/ \ /*bar*/ //// [parserSkippedTokens8.js] -; +; /*bar*/ diff --git a/tests/baselines/reference/parserSkippedTokens9.js b/tests/baselines/reference/parserSkippedTokens9.js index d693b99b2ea..cabf3a48e56 100644 --- a/tests/baselines/reference/parserSkippedTokens9.js +++ b/tests/baselines/reference/parserSkippedTokens9.js @@ -4,3 +4,4 @@ //// [parserSkippedTokens9.js] ; // existing trivia + /*bar*/ diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType1.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType1.js index d759bc2f296..96fff1f8f33 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType1.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType1.js @@ -29,4 +29,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType1_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); +}); // This should result in type ClassB diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType2.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType2.js index 7704b38f68d..e8262c86b4f 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType2.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType2.js @@ -33,4 +33,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType2_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); +}); // This should result in type ClassB diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType3.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType3.js index a46be3bdafc..39303b463ba 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType3.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType3.js @@ -37,4 +37,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType3_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); +}); // This should result in type ClassB diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType4.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType4.js index 8ccd6ecf560..80a4408b10d 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType4.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType4.js @@ -31,4 +31,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType4_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); +}); // This should result in type ClassB diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType5.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType5.js index 4602ed554e5..69f6ff07bd8 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType5.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType5.js @@ -40,4 +40,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType5_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); +}); // This should result in type ClassB diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType6.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType6.js index d3487519218..277a8a168da 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType6.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType6.js @@ -49,4 +49,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType6_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); +}); // This should result in type ClassB diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.js index 9a29c2bf949..fcab82802b2 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.js @@ -51,4 +51,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType7_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); +}); // This should result in type ClassB diff --git a/tests/baselines/reference/returns.js b/tests/baselines/reference/returns.js new file mode 100644 index 00000000000..67390dea72a --- /dev/null +++ b/tests/baselines/reference/returns.js @@ -0,0 +1,16 @@ +//// [returns.js] +/** + * @returns {string} This comment is not currently exposed + */ +function f() { + return ""; +} + + +//// [dummy.js] +/** + * @returns {string} This comment is not currently exposed + */ +function f() { + return ""; +} diff --git a/tests/baselines/reference/returns.symbols b/tests/baselines/reference/returns.symbols new file mode 100644 index 00000000000..e0f0d4dac96 --- /dev/null +++ b/tests/baselines/reference/returns.symbols @@ -0,0 +1,10 @@ +=== tests/cases/conformance/jsdoc/returns.js === +/** + * @returns {string} This comment is not currently exposed + */ +function f() { +>f : Symbol(f, Decl(returns.js, 0, 0)) + + return ""; +} + diff --git a/tests/baselines/reference/returns.types b/tests/baselines/reference/returns.types new file mode 100644 index 00000000000..c1bb1637c45 --- /dev/null +++ b/tests/baselines/reference/returns.types @@ -0,0 +1,11 @@ +=== tests/cases/conformance/jsdoc/returns.js === +/** + * @returns {string} This comment is not currently exposed + */ +function f() { +>f : () => string + + return ""; +>"" : string +} + diff --git a/tests/baselines/reference/thisInInvalidContextsExternalModule.js b/tests/baselines/reference/thisInInvalidContextsExternalModule.js index 2e7e6d8b47c..00553a3fbba 100644 --- a/tests/baselines/reference/thisInInvalidContextsExternalModule.js +++ b/tests/baselines/reference/thisInInvalidContextsExternalModule.js @@ -107,4 +107,4 @@ var SomeEnum; SomeEnum[SomeEnum["A"] = this] = "A"; SomeEnum[SomeEnum["B"] = this.spaaaace] = "B"; // Also should not be allowed })(SomeEnum || (SomeEnum = {})); -module.exports = this; +module.exports = this; // Should be an error diff --git a/tests/baselines/reference/tsxParseTests2.js b/tests/baselines/reference/tsxParseTests2.js index b0cf54f8d1f..c09e9d2c3cb 100644 --- a/tests/baselines/reference/tsxParseTests2.js +++ b/tests/baselines/reference/tsxParseTests2.js @@ -8,4 +8,4 @@ var x =
; //// [file.jsx] -var x =
; +var x =
; diff --git a/tests/baselines/reference/typeAliasDoesntMakeModuleInstantiated.js b/tests/baselines/reference/typeAliasDoesntMakeModuleInstantiated.js index 861e20cb0d1..af2287ef27f 100644 --- a/tests/baselines/reference/typeAliasDoesntMakeModuleInstantiated.js +++ b/tests/baselines/reference/typeAliasDoesntMakeModuleInstantiated.js @@ -11,3 +11,4 @@ declare module m { declare var m: m.IStatic; // Should be ok to have var 'm' as module is non instantiated //// [typeAliasDoesntMakeModuleInstantiated.js] + // Should be ok to have var 'm' as module is non instantiated diff --git a/tests/cases/fourslash/commentsClassMembers.ts b/tests/cases/fourslash/commentsClassMembers.ts index d719253a57b..481baee28af 100644 --- a/tests/cases/fourslash/commentsClassMembers.ts +++ b/tests/cases/fourslash/commentsClassMembers.ts @@ -8,11 +8,11 @@ //// public p/*3*/2(/** number to add*/b: number) { //// return this./*4*/p1 + /*5*/b; //// } -//// /** getter property*/ +//// /** getter property 1*/ //// public get p/*6*/3() { //// return this./*7*/p/*8q*/2(/*8*/this./*9*/p1); //// } -//// /** setter property*/ +//// /** setter property 1*/ //// public set p/*10*/3(/** this is value*/value: number) { //// this./*11*/p1 = this./*12*/p/*13q*/2(/*13*/value); //// } @@ -22,11 +22,11 @@ //// private p/*15*/p2(/** number to add*/b: number) { //// return this./*16*/p1 + /*17*/b; //// } -//// /** getter property*/ +//// /** getter property 2*/ //// private get p/*18*/p3() { //// return this./*19*/p/*20q*/p2(/*20*/this./*21*/pp1); //// } -//// /** setter property*/ +//// /** setter property 2*/ //// private set p/*22*/p3( /** this is value*/value: number) { //// this./*23*/pp1 = this./*24*/p/*25q*/p2(/*25*/value); //// } @@ -43,7 +43,7 @@ //// static get s/*32*/3() { //// return /*33*/c1./*34*/s/*35q*/2(/*35*/c1./*36*/s1); //// } -//// /** setter property*/ +//// /** setter property 3*/ //// static set s/*37*/3( /** this is value*/value: number) { //// /*38*/c1./*39*/s1 = /*40*/c1./*41*/s/*42q*/2(/*42*/value); //// } @@ -131,7 +131,6 @@ //// th/*116*/is./*114*/a = /*115*/a + 2 + bb/*117*/bb; //// } ////} - goTo.marker('1'); verify.quickInfoIs("class c1", "This is comment for c1"); @@ -144,10 +143,10 @@ verify.quickInfoIs("(method) c1.p2(b: number): number", "sum with property"); goTo.marker('4'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -159,15 +158,15 @@ goTo.marker('5'); verify.completionListContains("b", "(parameter) b: number", "number to add"); goTo.marker('6'); -verify.quickInfoIs("(property) c1.p3: number", "getter property\nsetter property"); +verify.quickInfoIs("(property) c1.p3: number", "getter property 1\nsetter property 1"); goTo.marker('7'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -184,10 +183,10 @@ verify.quickInfoIs("(method) c1.p2(b: number): number", "sum with property"); goTo.marker('9'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -196,15 +195,15 @@ verify.memberListContains("nc_pp2", "(method) c1.nc_pp2(b: number): number", "") verify.memberListContains("nc_pp3", "(property) c1.nc_pp3: number", ""); goTo.marker('10'); -verify.quickInfoIs("(property) c1.p3: number", "getter property\nsetter property"); +verify.quickInfoIs("(property) c1.p3: number", "getter property 1\nsetter property 1"); goTo.marker('11'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -215,10 +214,10 @@ verify.memberListContains("nc_pp3", "(property) c1.nc_pp3: number", ""); goTo.marker('12'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -242,10 +241,10 @@ verify.quickInfoIs("(method) c1.pp2(b: number): number", "sum with property"); goTo.marker('16'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -257,15 +256,15 @@ goTo.marker('17'); verify.completionListContains("b", "(parameter) b: number", "number to add"); goTo.marker('18'); -verify.quickInfoIs("(property) c1.pp3: number", "getter property\nsetter property"); +verify.quickInfoIs("(property) c1.pp3: number", "getter property 2\nsetter property 2"); goTo.marker('19'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -282,10 +281,10 @@ verify.quickInfoIs("(method) c1.pp2(b: number): number", "sum with property"); goTo.marker('21'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -294,15 +293,15 @@ verify.memberListContains("nc_pp2", "(method) c1.nc_pp2(b: number): number", "") verify.memberListContains("nc_pp3", "(property) c1.nc_pp3: number", ""); goTo.marker('22'); -verify.quickInfoIs("(property) c1.pp3: number", "getter property\nsetter property"); +verify.quickInfoIs("(property) c1.pp3: number", "getter property 2\nsetter property 2"); goTo.marker('23'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -313,10 +312,10 @@ verify.memberListContains("nc_pp3", "(property) c1.nc_pp3: number", ""); goTo.marker('24'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -346,7 +345,7 @@ verify.completionListContains("c1", "class c1", "This is comment for c1"); goTo.marker('30'); verify.memberListContains("s1", "(property) c1.s1: number", "s1 is static property of c1"); verify.memberListContains("s2", "(method) c1.s2(b: number): number", "static sum with property"); -verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property"); +verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property 3"); verify.memberListContains("nc_s1", "(property) c1.nc_s1: number", ""); verify.memberListContains("nc_s2", "(method) c1.nc_s2(b: number): number", ""); verify.memberListContains("nc_s3", "(property) c1.nc_s3: number", ""); @@ -355,7 +354,7 @@ goTo.marker('31'); verify.completionListContains("b", "(parameter) b: number", "number to add"); goTo.marker('32'); -verify.quickInfoIs("(property) c1.s3: number", "static getter property\nsetter property"); +verify.quickInfoIs("(property) c1.s3: number", "static getter property\nsetter property 3"); goTo.marker('33'); verify.completionListContains("c1", "class c1", "This is comment for c1"); @@ -363,7 +362,7 @@ verify.completionListContains("c1", "class c1", "This is comment for c1"); goTo.marker('34'); verify.memberListContains("s1", "(property) c1.s1: number", "s1 is static property of c1"); verify.memberListContains("s2", "(method) c1.s2(b: number): number", "static sum with property"); -verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property"); +verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property 3"); verify.memberListContains("nc_s1", "(property) c1.nc_s1: number", ""); verify.memberListContains("nc_s2", "(method) c1.nc_s2(b: number): number", ""); verify.memberListContains("nc_s3", "(property) c1.nc_s3: number", ""); @@ -378,13 +377,13 @@ verify.quickInfoIs("(method) c1.s2(b: number): number", "static sum with propert goTo.marker('36'); verify.memberListContains("s1", "(property) c1.s1: number", "s1 is static property of c1"); verify.memberListContains("s2", "(method) c1.s2(b: number): number", "static sum with property"); -verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property"); +verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property 3"); verify.memberListContains("nc_s1", "(property) c1.nc_s1: number", ""); verify.memberListContains("nc_s2", "(method) c1.nc_s2(b: number): number", ""); verify.memberListContains("nc_s3", "(property) c1.nc_s3: number", ""); goTo.marker('37'); -verify.quickInfoIs("(property) c1.s3: number", "static getter property\nsetter property"); +verify.quickInfoIs("(property) c1.s3: number", "static getter property\nsetter property 3"); goTo.marker('38'); verify.completionListContains("c1", "class c1", "This is comment for c1"); @@ -392,7 +391,7 @@ verify.completionListContains("c1", "class c1", "This is comment for c1"); goTo.marker('39'); verify.memberListContains("s1", "(property) c1.s1: number", "s1 is static property of c1"); verify.memberListContains("s2", "(method) c1.s2(b: number): number", "static sum with property"); -verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property"); +verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property 3"); verify.memberListContains("nc_s1", "(property) c1.nc_s1: number", ""); verify.memberListContains("nc_s2", "(method) c1.nc_s2(b: number): number", ""); verify.memberListContains("nc_s3", "(property) c1.nc_s3: number", ""); @@ -403,7 +402,7 @@ verify.completionListContains("c1", "class c1", "This is comment for c1"); goTo.marker('41'); verify.memberListContains("s1", "(property) c1.s1: number", "s1 is static property of c1"); verify.memberListContains("s2", "(method) c1.s2(b: number): number", "static sum with property"); -verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property"); +verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property 3"); verify.memberListContains("nc_s1", "(property) c1.nc_s1: number", ""); verify.memberListContains("nc_s2", "(method) c1.nc_s2(b: number): number", ""); verify.memberListContains("nc_s3", "(property) c1.nc_s3: number", ""); @@ -514,7 +513,7 @@ goTo.marker('67'); verify.quickInfoIs("(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -537,9 +536,9 @@ verify.quickInfoIs("(method) c1.p2(b: number): number", "sum with property"); goTo.marker('72'); verify.quickInfoIs("var i1_prop: number", ""); goTo.marker('73'); -verify.quickInfoIs("(property) c1.p3: number", "getter property\nsetter property"); +verify.quickInfoIs("(property) c1.p3: number", "getter property 1\nsetter property 1"); goTo.marker('74'); -verify.quickInfoIs("(property) c1.p3: number", "getter property\nsetter property"); +verify.quickInfoIs("(property) c1.p3: number", "getter property 1\nsetter property 1"); goTo.marker('75'); verify.quickInfoIs("var i1_prop: number", ""); @@ -584,7 +583,7 @@ goTo.marker('88'); verify.quickInfoIs("(property) c1.s1: number", "s1 is static property of c1"); verify.memberListContains("s1", "(property) c1.s1: number", "s1 is static property of c1"); verify.memberListContains("s2", "(method) c1.s2(b: number): number", "static sum with property"); -verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property"); +verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property 3"); verify.memberListContains("nc_s1", "(property) c1.nc_s1: number", ""); verify.memberListContains("nc_s2", "(method) c1.nc_s2(b: number): number", ""); verify.memberListContains("nc_s3", "(property) c1.nc_s3: number", ""); @@ -607,9 +606,9 @@ verify.quickInfoIs("(method) c1.s2(b: number): number", "static sum with propert goTo.marker('93'); verify.quickInfoIs("var i1_s_prop: number", ""); goTo.marker('94'); -verify.quickInfoIs("(property) c1.s3: number", "static getter property\nsetter property"); +verify.quickInfoIs("(property) c1.s3: number", "static getter property\nsetter property 3"); goTo.marker('95'); -verify.quickInfoIs("(property) c1.s3: number", "static getter property\nsetter property"); +verify.quickInfoIs("(property) c1.s3: number", "static getter property\nsetter property 3"); goTo.marker('96'); verify.quickInfoIs("var i1_s_prop: number", ""); @@ -686,8 +685,8 @@ goTo.marker('113'); verify.quickInfoIs("(property) cProperties.nc_p1: number", ""); goTo.marker('114'); -verify.memberListContains("a", "(property) cWithConstructorProperty.a: number", "more info about a"); -verify.quickInfoIs("(property) cWithConstructorProperty.a: number", "more info about a"); +verify.memberListContains("a", "(property) cWithConstructorProperty.a: number", "this is first parameter a\nmore info about a"); +verify.quickInfoIs("(property) cWithConstructorProperty.a: number", "this is first parameter a\nmore info about a"); goTo.marker('115'); verify.completionListContains("a", "(parameter) a: number", "this is first parameter a\nmore info about a"); diff --git a/tests/cases/fourslash/commentsCommentParsing.ts b/tests/cases/fourslash/commentsCommentParsing.ts index f209f573e2f..a0a86cbc75c 100644 --- a/tests/cases/fourslash/commentsCommentParsing.ts +++ b/tests/cases/fourslash/commentsCommentParsing.ts @@ -48,7 +48,7 @@ ////} ////jsDocMi/*7q*/xedComments2(/*7*/); //// -/////** jsdoc comment */ /*** another jsDocComment*/ +/////** jsdoc comment */ /*** malformed jsDocComment*/ /////// Triple slash comment ////function jsDocMixedComments3() { ////} @@ -238,9 +238,9 @@ goTo.marker('7q'); verify.quickInfoIs("function jsDocMixedComments2(): void", "jsdoc comment \nanother jsDocComment"); goTo.marker('8'); -verify.currentSignatureHelpDocCommentIs("jsdoc comment \n* another jsDocComment"); +verify.currentSignatureHelpDocCommentIs("jsdoc comment "); goTo.marker('8q'); -verify.quickInfoIs("function jsDocMixedComments3(): void", "jsdoc comment \n* another jsDocComment"); +verify.quickInfoIs("function jsDocMixedComments3(): void", "jsdoc comment "); goTo.marker('9'); verify.currentSignatureHelpDocCommentIs("jsdoc comment \nanother jsDocComment"); @@ -295,33 +295,33 @@ verify.completionListContains("a", "(parameter) a: number", "first number"); verify.completionListContains("b", "(parameter) b: number", "second number"); goTo.marker('19'); -verify.currentSignatureHelpDocCommentIs("This is multiplication function\n@anotherTag\n@anotherTag"); +verify.currentSignatureHelpDocCommentIs("This is multiplication function"); verify.currentParameterHelpArgumentDocCommentIs("first number"); goTo.marker('19q'); -verify.quickInfoIs("function multiply(a: number, b: number, c?: number, d?: any, e?: any): void", "This is multiplication function\n@anotherTag\n@anotherTag"); +verify.quickInfoIs("function multiply(a: number, b: number, c?: number, d?: any, e?: any): void", "This is multiplication function"); goTo.marker('19aq'); verify.quickInfoIs("(parameter) a: number", "first number"); goTo.marker('20'); -verify.currentSignatureHelpDocCommentIs("This is multiplication function\n@anotherTag\n@anotherTag"); +verify.currentSignatureHelpDocCommentIs("This is multiplication function"); verify.currentParameterHelpArgumentDocCommentIs(""); goTo.marker('20aq'); verify.quickInfoIs("(parameter) b: number", ""); goTo.marker('21'); -verify.currentSignatureHelpDocCommentIs("This is multiplication function\n@anotherTag\n@anotherTag"); -verify.currentParameterHelpArgumentDocCommentIs("{"); +verify.currentSignatureHelpDocCommentIs("This is multiplication function"); +verify.currentParameterHelpArgumentDocCommentIs(""); goTo.marker('21aq'); -verify.quickInfoIs("(parameter) c: number", "{"); +verify.quickInfoIs("(parameter) c: number", ""); goTo.marker('22'); -verify.currentSignatureHelpDocCommentIs("This is multiplication function\n@anotherTag\n@anotherTag"); +verify.currentSignatureHelpDocCommentIs("This is multiplication function"); verify.currentParameterHelpArgumentDocCommentIs(""); goTo.marker('22aq'); verify.quickInfoIs("(parameter) d: any", ""); goTo.marker('23'); -verify.currentSignatureHelpDocCommentIs("This is multiplication function\n@anotherTag\n@anotherTag"); +verify.currentSignatureHelpDocCommentIs("This is multiplication function"); verify.currentParameterHelpArgumentDocCommentIs("LastParam "); goTo.marker('23aq'); verify.quickInfoIs("(parameter) e: any", "LastParam "); @@ -347,65 +347,65 @@ goTo.marker('26aq'); verify.quickInfoIs("(parameter) b: string", ""); goTo.marker('27'); -verify.completionListContains("multiply", "function multiply(a: number, b: number, c?: number, d?: any, e?: any): void", "This is multiplication function\n@anotherTag\n@anotherTag"); +verify.completionListContains("multiply", "function multiply(a: number, b: number, c?: number, d?: any, e?: any): void", "This is multiplication function"); verify.completionListContains("f1", "function f1(a: number): any (+1 overload)", "fn f1 with number"); goTo.marker('28'); -verify.currentSignatureHelpDocCommentIs("This is subtract function"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs(""); goTo.marker('28q'); -verify.quickInfoIs("function subtract(a: number, b: number, c?: () => string, d?: () => string, e?: () => string, f?: () => string): void", "This is subtract function"); +verify.quickInfoIs("function subtract(a: number, b: number, c?: () => string, d?: () => string, e?: () => string, f?: () => string): void", "This is subtract function{()=>string; } } f this is optional param f"); goTo.marker('28aq'); verify.quickInfoIs("(parameter) a: number", ""); goTo.marker('29'); -verify.currentSignatureHelpDocCommentIs("This is subtract function"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs("this is about b"); goTo.marker('29aq'); verify.quickInfoIs("(parameter) b: number", "this is about b"); goTo.marker('30'); -verify.currentSignatureHelpDocCommentIs("This is subtract function"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs("this is optional param c"); goTo.marker('30aq'); verify.quickInfoIs("(parameter) c: () => string", "this is optional param c"); goTo.marker('31'); -verify.currentSignatureHelpDocCommentIs("This is subtract function"); -verify.currentParameterHelpArgumentDocCommentIs(""); +verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); +verify.currentParameterHelpArgumentDocCommentIs("this is optional param d"); goTo.marker('31aq'); -verify.quickInfoIs("(parameter) d: () => string", ""); +verify.quickInfoIs("(parameter) d: () => string", "this is optional param d"); goTo.marker('32'); -verify.currentSignatureHelpDocCommentIs("This is subtract function"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs("this is optional param e"); goTo.marker('32aq'); verify.quickInfoIs("(parameter) e: () => string", "this is optional param e"); goTo.marker('33'); -verify.currentSignatureHelpDocCommentIs("This is subtract function"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs(""); goTo.marker('33aq'); verify.quickInfoIs("(parameter) f: () => string", ""); goTo.marker('34'); -verify.currentSignatureHelpDocCommentIs("this is square function\n@paramTag { number } a this is input number of paramTag\n@returnType { number } it is return type"); +verify.currentSignatureHelpDocCommentIs("this is square function"); verify.currentParameterHelpArgumentDocCommentIs("this is input number"); goTo.marker('34q'); -verify.quickInfoIs("function square(a: number): number", "this is square function\n@paramTag { number } a this is input number of paramTag\n@returnType { number } it is return type"); +verify.quickInfoIs("function square(a: number): number", "this is square function"); goTo.marker('34aq'); verify.quickInfoIs("(parameter) a: number", "this is input number"); goTo.marker('35'); -verify.currentSignatureHelpDocCommentIs("this is divide function\n@paramTag { number } g this is optional param g"); +verify.currentSignatureHelpDocCommentIs("this is divide function"); verify.currentParameterHelpArgumentDocCommentIs("this is a"); goTo.marker('35q'); -verify.quickInfoIs("function divide(a: number, b: number): void", "this is divide function\n@paramTag { number } g this is optional param g"); +verify.quickInfoIs("function divide(a: number, b: number): void", "this is divide function"); goTo.marker('35aq'); verify.quickInfoIs("(parameter) a: number", "this is a"); goTo.marker('36'); -verify.currentSignatureHelpDocCommentIs("this is divide function\n@paramTag { number } g this is optional param g"); +verify.currentSignatureHelpDocCommentIs("this is divide function"); verify.currentParameterHelpArgumentDocCommentIs("this is b"); goTo.marker('36aq'); verify.quickInfoIs("(parameter) b: number", "this is b"); @@ -492,4 +492,4 @@ goTo.marker('49aq'); verify.quickInfoIs("(parameter) c: any", "this is info about b\nnot aligned text about parameter will eat only one space"); goTo.marker('50'); -verify.quickInfoIs("class NoQuickInfoClass", ""); \ No newline at end of file +verify.quickInfoIs("class NoQuickInfoClass", ""); diff --git a/tests/cases/fourslash/commentsFunctionExpression.ts b/tests/cases/fourslash/commentsFunctionExpression.ts index 048efa3c9c1..f22c49764dd 100644 --- a/tests/cases/fourslash/commentsFunctionExpression.ts +++ b/tests/cases/fourslash/commentsFunctionExpression.ts @@ -64,25 +64,25 @@ verify.quickInfoIs('function anotherFunc(a: number): string', ''); goTo.marker('8'); verify.quickInfoIs('(local var) lambdaVar: (b: string) => string', 'documentation\ninner docs '); goTo.marker('9'); -verify.quickInfoIs('(parameter) b: string', '{string} inner parameter '); +verify.quickInfoIs('(parameter) b: string', 'inner parameter '); goTo.marker('10'); verify.quickInfoIs('(local var) localVar: string', ''); goTo.marker('11'); verify.quickInfoIs('(local var) localVar: string', ''); goTo.marker('12'); -verify.quickInfoIs('(parameter) b: string', '{string} inner parameter '); +verify.quickInfoIs('(parameter) b: string', 'inner parameter '); goTo.marker('13'); verify.quickInfoIs('(local var) lambdaVar: (b: string) => string', 'documentation\ninner docs '); goTo.marker('14'); -verify.quickInfoIs("var assigned: (s: string) => number", "On variable\n@returns the parameter's length\nSummary on expression\n@returns return on expression"); +verify.quickInfoIs("var assigned: (s: string) => number", "On variable\nSummary on expression"); goTo.marker('15'); verify.completionListContains('s', '(parameter) s: string', "the first parameter!\nparam on expression\nOn parameter "); goTo.marker('16'); -verify.quickInfoIs("var assigned: (s: string) => number", "On variable\n@returns the parameter's length\nSummary on expression\n@returns return on expression"); +verify.quickInfoIs("var assigned: (s: string) => number", "On variable\nSummary on expression"); goTo.marker('17'); -verify.completionListContains("assigned", "var assigned: (s: string) => number", "On variable\n@returns the parameter's length\nSummary on expression\n@returns return on expression"); +verify.completionListContains("assigned", "var assigned: (s: string) => number", "On variable\nSummary on expression"); goTo.marker('18'); -verify.currentSignatureHelpDocCommentIs("On variable\n@returns the parameter's length\nSummary on expression\n@returns return on expression"); +verify.currentSignatureHelpDocCommentIs("On variable\nSummary on expression"); verify.currentParameterHelpArgumentDocCommentIs("the first parameter!\nparam on expression\nOn parameter "); diff --git a/tests/cases/fourslash/commentsLinePreservation.ts b/tests/cases/fourslash/commentsLinePreservation.ts index 012272d7544..a1b574ea33b 100644 --- a/tests/cases/fourslash/commentsLinePreservation.ts +++ b/tests/cases/fourslash/commentsLinePreservation.ts @@ -116,7 +116,7 @@ goTo.marker('c'); verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line\n\nThis is fourth Line"); goTo.marker('d'); -verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line\n@random tag This should be third line"); +verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line"); goTo.marker('1'); verify.quickInfoIs(undefined, ""); @@ -126,17 +126,17 @@ goTo.marker('2'); verify.quickInfoIs(undefined, ""); goTo.marker('f'); -verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line\n@random tag This should be third line"); +verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line"); goTo.marker('3'); verify.quickInfoIs(undefined, "first line of param\n\nparam information third line"); goTo.marker('g'); -verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line\n@random tag This should be third line"); +verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line"); goTo.marker('4'); verify.quickInfoIs(undefined, "param information first line"); goTo.marker('h'); -verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line\n@random tag This should be third line"); +verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line"); goTo.marker('5'); verify.quickInfoIs(undefined, "param information first line\n\nparam information third line"); @@ -151,7 +151,7 @@ goTo.marker('7'); verify.quickInfoIs(undefined, "param information first line\n\nparam information third line"); goTo.marker('k'); -verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line\n@randomtag \n\n random information first line\n\n random information third line"); +verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line"); goTo.marker('8'); verify.quickInfoIs(undefined, "hello "); diff --git a/tests/cases/fourslash/commentsModules.ts b/tests/cases/fourslash/commentsModules.ts index 9415c1bc85e..a501e561606 100644 --- a/tests/cases/fourslash/commentsModules.ts +++ b/tests/cases/fourslash/commentsModules.ts @@ -129,8 +129,8 @@ verify.memberListContains("c", "constructor m1.m2.c(): m1.m2.c", ""); verify.memberListContains("i", "var m1.m2.i: m1.m2.c", "i"); goTo.marker('9'); -verify.completionListContains("m2", "namespace m2", ""); -verify.quickInfoIs("namespace m2", ""); +verify.completionListContains("m2", "namespace m2", "namespace comment of m2.m3"); +verify.quickInfoIs("namespace m2", "namespace comment of m2.m3"); goTo.marker('10'); verify.memberListContains("m3", "namespace m2.m3"); @@ -141,12 +141,12 @@ verify.quickInfoIs("constructor m2.m3.c(): m2.m3.c", ""); verify.memberListContains("c", "constructor m2.m3.c(): m2.m3.c", ""); goTo.marker('12'); -verify.completionListContains("m3", "namespace m3", ""); -verify.quickInfoIs("namespace m3", ""); +verify.completionListContains("m3", "namespace m3", "namespace comment of m3.m4.m5"); +verify.quickInfoIs("namespace m3", "namespace comment of m3.m4.m5"); goTo.marker('13'); -verify.memberListContains("m4", "namespace m3.m4", ""); -verify.quickInfoIs("namespace m3.m4", ""); +verify.memberListContains("m4", "namespace m3.m4", "namespace comment of m3.m4.m5"); +verify.quickInfoIs("namespace m3.m4", "namespace comment of m3.m4.m5"); goTo.marker('14'); verify.memberListContains("m5", "namespace m3.m4.m5"); @@ -157,12 +157,12 @@ verify.quickInfoIs("constructor m3.m4.m5.c(): m3.m4.m5.c", ""); verify.memberListContains("c", "constructor m3.m4.m5.c(): m3.m4.m5.c", ""); goTo.marker('16'); -verify.completionListContains("m4", "namespace m4", ""); -verify.quickInfoIs("namespace m4", ""); +verify.completionListContains("m4", "namespace m4", "namespace comment of m4.m5.m6"); +verify.quickInfoIs("namespace m4", "namespace comment of m4.m5.m6"); goTo.marker('17'); -verify.memberListContains("m5", "namespace m4.m5", ""); -verify.quickInfoIs("namespace m4.m5", ""); +verify.memberListContains("m5", "namespace m4.m5", "namespace comment of m4.m5.m6"); +verify.quickInfoIs("namespace m4.m5", "namespace comment of m4.m5.m6"); goTo.marker('18'); verify.memberListContains("m6", "namespace m4.m5.m6"); @@ -178,11 +178,11 @@ verify.quickInfoIs("constructor m4.m5.m6.m7.c(): m4.m5.m6.m7.c", ""); goTo.marker('21'); verify.completionListContains("m5", "namespace m5"); -verify.quickInfoIs("namespace m5", ""); +verify.quickInfoIs("namespace m5", "namespace comment of m5.m6.m7"); goTo.marker('22'); verify.memberListContains("m6", "namespace m5.m6"); -verify.quickInfoIs("namespace m5.m6", ""); +verify.quickInfoIs("namespace m5.m6", "namespace comment of m5.m6.m7"); goTo.marker('23'); verify.memberListContains("m7", "namespace m5.m6.m7"); @@ -248,4 +248,4 @@ goTo.marker('39'); verify.quickInfoIs("(method) complexM.m2.c.foo2(): complexM.m1.c", ""); goTo.marker('40'); -verify.quickInfoIs("(method) complexM.m1.c.foo(): number", ""); \ No newline at end of file +verify.quickInfoIs("(method) complexM.m1.c.foo(): number", ""); diff --git a/tests/cases/fourslash/getJavaScriptQuickInfo1.ts b/tests/cases/fourslash/getJavaScriptQuickInfo1.ts index 71072f1699a..f10068eb612 100644 --- a/tests/cases/fourslash/getJavaScriptQuickInfo1.ts +++ b/tests/cases/fourslash/getJavaScriptQuickInfo1.ts @@ -6,4 +6,4 @@ ////var /**/v; goTo.marker(); -verify.quickInfoIs('var v: new (p1: number) => string'); \ No newline at end of file +verify.quickInfoIs('var v: new (arg1: number) => string'); diff --git a/tests/cases/fourslash/getJavaScriptQuickInfo7.ts b/tests/cases/fourslash/getJavaScriptQuickInfo7.ts index 7b8d967d190..d9f66a97eb8 100644 --- a/tests/cases/fourslash/getJavaScriptQuickInfo7.ts +++ b/tests/cases/fourslash/getJavaScriptQuickInfo7.ts @@ -19,4 +19,4 @@ goTo.marker(); verify.quickInfoExists(); verify.quickInfoIs('function a1(p: any): number', - 'This is a very cool function that is very nice.\n@returns something'); + 'This is a very cool function that is very nice.'); From 275a4bd4f3df74441b9cd56ac212fd37fb35f3b6 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 1 Sep 2016 10:05:56 -0700 Subject: [PATCH 08/46] Use enum for parser state instead of 2 booleans Plus cleanup some lint --- src/compiler/parser.ts | 30 ++++++++++++++++-------------- src/compiler/utilities.ts | 2 +- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 342b711a5a6..445af2243df 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6151,6 +6151,12 @@ namespace ts { return comment; } + const enum TagState { + BeginningOfLine, + SawAsterisk, + SavingComments + } + export function parseJSDocCommentWorker(start: number, length: number): JSDoc { const content = sourceText; start = start || 0; @@ -6359,8 +6365,7 @@ namespace ts { function parseTagComments(indent: number) { const comments: string[] = []; - let savingComments = false; - let seenAsterisk = true; + let state = TagState.SawAsterisk; let done = false; let margin: number | undefined; let text: string; @@ -6375,9 +6380,8 @@ namespace ts { text = scanner.getTokenText(); switch (token()) { case SyntaxKind.NewLineTrivia: - if (seenAsterisk) { - savingComments = false; - seenAsterisk = false; + if (state >= TagState.SawAsterisk) { + state = TagState.BeginningOfLine; comments.push(text); } indent = 0; @@ -6386,7 +6390,7 @@ namespace ts { done = true; break; case SyntaxKind.WhitespaceTrivia: - if (savingComments && seenAsterisk) { + if (state === TagState.SavingComments) { pushComment(text); } else { @@ -6398,18 +6402,16 @@ namespace ts { } break; case SyntaxKind.AsteriskToken: - if (!seenAsterisk) { + if (state === TagState.BeginningOfLine) { // leading asterisks start recording on the *next* (non-whitespace) token - savingComments = false; + state = TagState.SawAsterisk; indent += text.length; + break; } - // FALLTHROUGH to gather comments + // FALLTHROUGH otherwise to record the * as a comment default: - if (seenAsterisk) { - savingComments = true; // leading identifiers start recording as well - pushComment(text); - } - seenAsterisk = true; + state = TagState.SavingComments; // leading identifiers start recording as well + pushComment(text); break; } if (!done) { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 52683f0e74b..5e556278866 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1380,7 +1380,7 @@ namespace ts { function getJSDocTags(node: Node, checkParentVariableStatement: boolean): JSDocTag[] { return getJSDocs(node, checkParentVariableStatement, docs => { - let result: JSDocTag[] = []; + const result: JSDocTag[] = []; for (const doc of docs) { if (doc.tags) { result.push(...doc.tags); From 21439a470ddd7e6a467777c76f26cde82da79578 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 1 Sep 2016 18:41:03 -0700 Subject: [PATCH 09/46] Rebaseline tests to old emitter --- tests/baselines/reference/arrowFunctionErrorSpan.js | 4 +--- tests/baselines/reference/augmentExportEquals1.js | 4 ++-- tests/baselines/reference/augmentExportEquals1_1.js | 4 ++-- tests/baselines/reference/augmentExportEquals2.js | 4 ++-- tests/baselines/reference/augmentExportEquals2_1.js | 4 ++-- tests/baselines/reference/augmentedTypesExternalModule1.js | 2 +- .../blockScopedFunctionDeclarationInStrictModule.js | 2 +- tests/baselines/reference/callOverloads1.js | 2 +- tests/baselines/reference/callOverloads2.js | 2 +- tests/baselines/reference/callOverloads3.js | 2 +- tests/baselines/reference/callOverloads4.js | 2 +- tests/baselines/reference/callOverloads5.js | 2 +- tests/baselines/reference/collisionArgumentsFunction.js | 1 - tests/baselines/reference/collisionRestParameterFunction.js | 1 - .../reference/collisionThisExpressionAndParameter.js | 1 - tests/baselines/reference/commentInEmptyParameterList1.js | 2 +- .../reference/commentOnParenthesizedExpressionOpenParen1.js | 2 +- .../reference/commentsArgumentsOfCallExpression2.js | 2 +- tests/baselines/reference/commentsFunction.js | 4 ++-- tests/baselines/reference/commentsVarDecl.js | 6 +++--- tests/baselines/reference/computedPropertyNames48_ES5.js | 4 ++-- tests/baselines/reference/constructorOverloads1.js | 4 ++-- tests/baselines/reference/constructorOverloads2.js | 4 ++-- tests/baselines/reference/constructorOverloads3.js | 2 +- .../baselines/reference/contextuallyTypingRestParameters.js | 4 ++-- .../reference/declFileObjectLiteralWithAccessors.js | 4 ++-- .../reference/declFileObjectLiteralWithOnlyGetter.js | 4 ++-- .../reference/declFileObjectLiteralWithOnlySetter.js | 4 ++-- .../reference/es6ImportDefaultBindingWithExport.js | 2 +- tests/baselines/reference/es6ImportNameSpaceImportDts.js | 1 - .../reference/es6ImportNameSpaceImportNoNamedExports.js | 1 - .../reference/es6ImportNamedImportIdentifiersParsing.js | 1 - tests/baselines/reference/es6modulekindWithES5Target10.js | 1 - .../exportSpecifierReferencingOuterDeclaration4.js | 1 - tests/baselines/reference/genericConstraint3.js | 1 - .../inheritedMembersAndIndexSignaturesFromDifferentBases.js | 1 - ...inheritedMembersAndIndexSignaturesFromDifferentBases2.js | 1 - .../inheritedStringIndexersFromDifferentBaseTypes.js | 1 - .../inheritedStringIndexersFromDifferentBaseTypes2.js | 1 - tests/baselines/reference/jsxInvalidEsprimaTestSuite.js | 4 ++-- .../reference/nonConflictingRecursiveBaseTypeMembers.js | 1 - .../reference/objectTypesWithOptionalProperties2.js | 3 ++- .../reference/parseRegularExpressionMixedWithComments.js | 6 +++--- .../reference/parserGreaterThanTokenAmbiguity10.js | 1 - .../reference/parserGreaterThanTokenAmbiguity13.js | 2 +- .../reference/parserGreaterThanTokenAmbiguity15.js | 1 - .../reference/parserGreaterThanTokenAmbiguity18.js | 2 +- .../reference/parserGreaterThanTokenAmbiguity20.js | 1 - .../baselines/reference/parserGreaterThanTokenAmbiguity3.js | 2 +- .../baselines/reference/parserGreaterThanTokenAmbiguity5.js | 1 - .../baselines/reference/parserGreaterThanTokenAmbiguity8.js | 2 +- tests/baselines/reference/parserSkippedTokens5.js | 2 +- tests/baselines/reference/parserSkippedTokens7.js | 1 - tests/baselines/reference/parserSkippedTokens8.js | 2 +- tests/baselines/reference/parserSkippedTokens9.js | 1 - .../recursiveExportAssignmentAndFindAliasedType1.js | 2 +- .../recursiveExportAssignmentAndFindAliasedType2.js | 2 +- .../recursiveExportAssignmentAndFindAliasedType3.js | 2 +- .../recursiveExportAssignmentAndFindAliasedType4.js | 2 +- .../recursiveExportAssignmentAndFindAliasedType5.js | 2 +- .../recursiveExportAssignmentAndFindAliasedType6.js | 2 +- .../recursiveExportAssignmentAndFindAliasedType7.js | 2 +- .../reference/thisInInvalidContextsExternalModule.js | 2 +- tests/baselines/reference/tsxParseTests2.js | 2 +- .../reference/typeAliasDoesntMakeModuleInstantiated.js | 1 - 65 files changed, 62 insertions(+), 84 deletions(-) diff --git a/tests/baselines/reference/arrowFunctionErrorSpan.js b/tests/baselines/reference/arrowFunctionErrorSpan.js index 3ead7ed3b31..2557113e89b 100644 --- a/tests/baselines/reference/arrowFunctionErrorSpan.js +++ b/tests/baselines/reference/arrowFunctionErrorSpan.js @@ -83,9 +83,7 @@ f(// comment 1 // comment 2 function () { // comment 4 -} - // comment 5 -); +}); // body is not a block f(function (_) { return 1 + 2; }); diff --git a/tests/baselines/reference/augmentExportEquals1.js b/tests/baselines/reference/augmentExportEquals1.js index 6f7aab92692..98322c01a34 100644 --- a/tests/baselines/reference/augmentExportEquals1.js +++ b/tests/baselines/reference/augmentExportEquals1.js @@ -32,5 +32,5 @@ define(["require", "exports"], function (require, exports) { //// [file3.js] define(["require", "exports", "./file2"], function (require, exports) { "use strict"; - var a; -}); // should not work + var a; // should not work +}); diff --git a/tests/baselines/reference/augmentExportEquals1_1.js b/tests/baselines/reference/augmentExportEquals1_1.js index 70239663441..08f032ff33f 100644 --- a/tests/baselines/reference/augmentExportEquals1_1.js +++ b/tests/baselines/reference/augmentExportEquals1_1.js @@ -29,5 +29,5 @@ define(["require", "exports"], function (require, exports) { //// [file3.js] define(["require", "exports", "file2"], function (require, exports) { "use strict"; - var a; -}); // should not work + var a; // should not work +}); diff --git a/tests/baselines/reference/augmentExportEquals2.js b/tests/baselines/reference/augmentExportEquals2.js index b444c16b6fc..fc373173e3c 100644 --- a/tests/baselines/reference/augmentExportEquals2.js +++ b/tests/baselines/reference/augmentExportEquals2.js @@ -31,5 +31,5 @@ define(["require", "exports"], function (require, exports) { //// [file3.js] define(["require", "exports", "./file2"], function (require, exports) { "use strict"; - var a; -}); // should not work + var a; // should not work +}); diff --git a/tests/baselines/reference/augmentExportEquals2_1.js b/tests/baselines/reference/augmentExportEquals2_1.js index afa78d1d981..9046157bb26 100644 --- a/tests/baselines/reference/augmentExportEquals2_1.js +++ b/tests/baselines/reference/augmentExportEquals2_1.js @@ -29,5 +29,5 @@ define(["require", "exports"], function (require, exports) { //// [file3.js] define(["require", "exports", "file2"], function (require, exports) { "use strict"; - var a; -}); // should not work + var a; // should not work +}); diff --git a/tests/baselines/reference/augmentedTypesExternalModule1.js b/tests/baselines/reference/augmentedTypesExternalModule1.js index 01358a9e4af..65525e8187e 100644 --- a/tests/baselines/reference/augmentedTypesExternalModule1.js +++ b/tests/baselines/reference/augmentedTypesExternalModule1.js @@ -13,4 +13,4 @@ define(["require", "exports"], function (require, exports) { c5.prototype.foo = function () { }; return c5; }()); -}); // should be ok everywhere +}); diff --git a/tests/baselines/reference/blockScopedFunctionDeclarationInStrictModule.js b/tests/baselines/reference/blockScopedFunctionDeclarationInStrictModule.js index 6d460158478..d1a8091871c 100644 --- a/tests/baselines/reference/blockScopedFunctionDeclarationInStrictModule.js +++ b/tests/baselines/reference/blockScopedFunctionDeclarationInStrictModule.js @@ -14,4 +14,4 @@ define(["require", "exports"], function (require, exports) { foo(); // ok } return foo; -}); // not ok +}); diff --git a/tests/baselines/reference/callOverloads1.js b/tests/baselines/reference/callOverloads1.js index d441deb41d7..756a9099e44 100644 --- a/tests/baselines/reference/callOverloads1.js +++ b/tests/baselines/reference/callOverloads1.js @@ -22,7 +22,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; + Foo.prototype.bar1 = function () { }; return Foo; }()); function F1(a) { return a; } diff --git a/tests/baselines/reference/callOverloads2.js b/tests/baselines/reference/callOverloads2.js index 8db26c3b771..b890ee8bde9 100644 --- a/tests/baselines/reference/callOverloads2.js +++ b/tests/baselines/reference/callOverloads2.js @@ -30,7 +30,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; + Foo.prototype.bar1 = function () { }; return Foo; }()); function F1(s) { return s; } // error diff --git a/tests/baselines/reference/callOverloads3.js b/tests/baselines/reference/callOverloads3.js index ee49f4b3297..e5d678543c6 100644 --- a/tests/baselines/reference/callOverloads3.js +++ b/tests/baselines/reference/callOverloads3.js @@ -23,7 +23,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; + Foo.prototype.bar1 = function () { }; return Foo; }()); //class Foo(s: String); diff --git a/tests/baselines/reference/callOverloads4.js b/tests/baselines/reference/callOverloads4.js index fa7a51ae8d1..dfb274dfb6e 100644 --- a/tests/baselines/reference/callOverloads4.js +++ b/tests/baselines/reference/callOverloads4.js @@ -23,7 +23,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; + Foo.prototype.bar1 = function () { }; return Foo; }()); var f1 = new Foo("hey"); diff --git a/tests/baselines/reference/callOverloads5.js b/tests/baselines/reference/callOverloads5.js index d95485f85d7..cf159d309b0 100644 --- a/tests/baselines/reference/callOverloads5.js +++ b/tests/baselines/reference/callOverloads5.js @@ -24,7 +24,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function (a) { /*WScript.Echo(a);*/ }; + Foo.prototype.bar1 = function (a) { }; return Foo; }()); //class Foo(s: String); diff --git a/tests/baselines/reference/collisionArgumentsFunction.js b/tests/baselines/reference/collisionArgumentsFunction.js index d59efc116ee..9ce4a5ab0e2 100644 --- a/tests/baselines/reference/collisionArgumentsFunction.js +++ b/tests/baselines/reference/collisionArgumentsFunction.js @@ -90,4 +90,3 @@ function f42(i) { function f4NoError(arguments) { var arguments; // No error } - // no codegen no error diff --git a/tests/baselines/reference/collisionRestParameterFunction.js b/tests/baselines/reference/collisionRestParameterFunction.js index a9e3f510fa1..8660e8f5db0 100644 --- a/tests/baselines/reference/collisionRestParameterFunction.js +++ b/tests/baselines/reference/collisionRestParameterFunction.js @@ -63,4 +63,3 @@ function f4(_i) { } function f4NoError(_i) { } - // no codegen no error diff --git a/tests/baselines/reference/collisionThisExpressionAndParameter.js b/tests/baselines/reference/collisionThisExpressionAndParameter.js index a445c35295b..bc15e4b56b5 100644 --- a/tests/baselines/reference/collisionThisExpressionAndParameter.js +++ b/tests/baselines/reference/collisionThisExpressionAndParameter.js @@ -167,4 +167,3 @@ function f3(_this) { var _this = this; (function (x) { console.log(_this.x); }); } - // no code gen - no error diff --git a/tests/baselines/reference/commentInEmptyParameterList1.js b/tests/baselines/reference/commentInEmptyParameterList1.js index 09b34f93536..8f4e13d82d6 100644 --- a/tests/baselines/reference/commentInEmptyParameterList1.js +++ b/tests/baselines/reference/commentInEmptyParameterList1.js @@ -3,5 +3,5 @@ function foo(/** nothing */) { } //// [commentInEmptyParameterList1.js] -function foo( /** nothing */) { +function foo() { } diff --git a/tests/baselines/reference/commentOnParenthesizedExpressionOpenParen1.js b/tests/baselines/reference/commentOnParenthesizedExpressionOpenParen1.js index 7a7c25a9b4c..d014043dfe0 100644 --- a/tests/baselines/reference/commentOnParenthesizedExpressionOpenParen1.js +++ b/tests/baselines/reference/commentOnParenthesizedExpressionOpenParen1.js @@ -7,4 +7,4 @@ var f: () => any; //// [commentOnParenthesizedExpressionOpenParen1.js] var j; var f; -(/* Preserve */ j = f()); +(j = f()); diff --git a/tests/baselines/reference/commentsArgumentsOfCallExpression2.js b/tests/baselines/reference/commentsArgumentsOfCallExpression2.js index f89e67ef3d8..a7065410ff4 100644 --- a/tests/baselines/reference/commentsArgumentsOfCallExpression2.js +++ b/tests/baselines/reference/commentsArgumentsOfCallExpression2.js @@ -14,7 +14,7 @@ foo( function foo(/*c1*/ x, /*d1*/ y, /*e1*/ w) { } var a, b; foo(/*c2*/ 1, /*d2*/ 1 + 2, /*e1*/ a + b); -foo(/*c3*/ function () { }, /*d2*/ function () { }, /*e2*/ a + /*e3*/ b); +foo(/*c3*/ function () { }, /*d2*/ function () { }, /*e2*/ a + b); foo(/*c3*/ function () { }, /*d3*/ function () { }, /*e3*/ (a + b)); foo( /*c4*/ function () { }, diff --git a/tests/baselines/reference/commentsFunction.js b/tests/baselines/reference/commentsFunction.js index 86978d7bdf7..0ffb2714108 100644 --- a/tests/baselines/reference/commentsFunction.js +++ b/tests/baselines/reference/commentsFunction.js @@ -74,8 +74,8 @@ var fooFunc = function FooFunctionValue(/** fooFunctionValue param */ b) { return b; }; /// lamdaFoo var comment -var lambdaFoo = /** this is lambda comment*/ function (/**param a*/ a, /**param b*/ b) { return a + b; }; -var lambddaNoVarComment = /** this is lambda multiplication*/ function (/**param a*/ a, /**param b*/ b) { return a * b; }; +var lambdaFoo = function (/**param a*/ a, /**param b*/ b) { return a + b; }; +var lambddaNoVarComment = function (/**param a*/ a, /**param b*/ b) { return a * b; }; lambdaFoo(10, 20); lambddaNoVarComment(10, 20); function blah(a /* multiline trailing comment diff --git a/tests/baselines/reference/commentsVarDecl.js b/tests/baselines/reference/commentsVarDecl.js index e9b6776a6d9..5ff2a3c1c6a 100644 --- a/tests/baselines/reference/commentsVarDecl.js +++ b/tests/baselines/reference/commentsVarDecl.js @@ -64,13 +64,13 @@ x = myVariable; /** jsdocstyle comment - only this comment should be in .d.ts file*/ var n = 30; /** var deckaration with comment on type as well*/ -var y = /** value comment */ 20; +var y = 20; /// var deckaration with comment on type as well var yy = /// value comment 20; /** comment2 */ -var z = /** lambda comment */ function (x, y) { return x + y; }; +var z = function (x, y) { return x + y; }; var z2; var x2 = z2; var n4; @@ -98,6 +98,6 @@ declare var y: number; declare var yy: number; /** comment2 */ declare var z: (x: number, y: number) => number; -declare var z2: /** type comment*/ (x: number) => string; +declare var z2: (x: number) => string; declare var x2: (x: number) => string; declare var n4: (x: number) => string; diff --git a/tests/baselines/reference/computedPropertyNames48_ES5.js b/tests/baselines/reference/computedPropertyNames48_ES5.js index f2610b7272a..15123a98f30 100644 --- a/tests/baselines/reference/computedPropertyNames48_ES5.js +++ b/tests/baselines/reference/computedPropertyNames48_ES5.js @@ -34,5 +34,5 @@ extractIndexer((_b = {}, extractIndexer((_c = {}, _c["" || 0] = "", _c -)); -var _a, _b, _c; // Should return any (widened form of undefined) +)); // Should return any (widened form of undefined) +var _a, _b, _c; diff --git a/tests/baselines/reference/constructorOverloads1.js b/tests/baselines/reference/constructorOverloads1.js index d62cb9530c5..47906974f6e 100644 --- a/tests/baselines/reference/constructorOverloads1.js +++ b/tests/baselines/reference/constructorOverloads1.js @@ -25,8 +25,8 @@ f1.bar2(); var Foo = (function () { function Foo(x) { } - Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; - Foo.prototype.bar2 = function () { /*WScript.Echo("bar1");*/ }; + Foo.prototype.bar1 = function () { }; + Foo.prototype.bar2 = function () { }; return Foo; }()); var f1 = new Foo("hey"); diff --git a/tests/baselines/reference/constructorOverloads2.js b/tests/baselines/reference/constructorOverloads2.js index e8d11af4056..76481ec1bc6 100644 --- a/tests/baselines/reference/constructorOverloads2.js +++ b/tests/baselines/reference/constructorOverloads2.js @@ -34,7 +34,7 @@ var __extends = (this && this.__extends) || function (d, b) { var FooBase = (function () { function FooBase(x) { } - FooBase.prototype.bar1 = function () { /*WScript.Echo("base bar1");*/ }; + FooBase.prototype.bar1 = function () { }; return FooBase; }()); var Foo = (function (_super) { @@ -42,7 +42,7 @@ var Foo = (function (_super) { function Foo(x, y) { _super.call(this, x); } - Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; + Foo.prototype.bar1 = function () { }; return Foo; }(FooBase)); var f1 = new Foo("hey"); diff --git a/tests/baselines/reference/constructorOverloads3.js b/tests/baselines/reference/constructorOverloads3.js index 7cc27fd5b42..61f0d50db03 100644 --- a/tests/baselines/reference/constructorOverloads3.js +++ b/tests/baselines/reference/constructorOverloads3.js @@ -32,7 +32,7 @@ var Foo = (function (_super) { __extends(Foo, _super); function Foo(x, y) { } - Foo.prototype.bar1 = function () { /*WScript.Echo("Yo");*/ }; + Foo.prototype.bar1 = function () { }; return Foo; }(FooBase)); var f1 = new Foo("hey"); diff --git a/tests/baselines/reference/contextuallyTypingRestParameters.js b/tests/baselines/reference/contextuallyTypingRestParameters.js index 48589ade408..17561f5d7fc 100644 --- a/tests/baselines/reference/contextuallyTypingRestParameters.js +++ b/tests/baselines/reference/contextuallyTypingRestParameters.js @@ -9,9 +9,9 @@ var x: (...y: string[]) => void = function (.../*3*/y) { //// [contextuallyTypingRestParameters.js] var x = function () { - var /*3*/ y = []; + var y = []; for (var _i = 0; _i < arguments.length; _i++) { - /*3*/ y[_i - 0] = arguments[_i]; + y[_i - 0] = arguments[_i]; } var t = y; var x2 = t; // This should be error diff --git a/tests/baselines/reference/declFileObjectLiteralWithAccessors.js b/tests/baselines/reference/declFileObjectLiteralWithAccessors.js index adc185e269f..7886736f7e4 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithAccessors.js +++ b/tests/baselines/reference/declFileObjectLiteralWithAccessors.js @@ -12,7 +12,7 @@ var /*2*/x = point.x; point./*3*/x = 30; //// [declFileObjectLiteralWithAccessors.js] -function /*1*/ makePoint(x) { +function makePoint(x) { return { b: 10, get x() { return x; }, @@ -22,7 +22,7 @@ function /*1*/ makePoint(x) { ; var /*4*/ point = makePoint(2); var /*2*/ x = point.x; -point./*3*/ x = 30; +point.x = 30; //// [declFileObjectLiteralWithAccessors.d.ts] diff --git a/tests/baselines/reference/declFileObjectLiteralWithOnlyGetter.js b/tests/baselines/reference/declFileObjectLiteralWithOnlyGetter.js index 96b4de87bef..eb440c028d5 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithOnlyGetter.js +++ b/tests/baselines/reference/declFileObjectLiteralWithOnlyGetter.js @@ -10,14 +10,14 @@ var /*2*/x = point./*3*/x; //// [declFileObjectLiteralWithOnlyGetter.js] -function /*1*/ makePoint(x) { +function makePoint(x) { return { get x() { return x; }, }; } ; var /*4*/ point = makePoint(2); -var /*2*/ x = point./*3*/ x; +var /*2*/ x = point.x; //// [declFileObjectLiteralWithOnlyGetter.d.ts] diff --git a/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.js b/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.js index 44b28a9bdb2..f7a48fe810c 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.js +++ b/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.js @@ -10,7 +10,7 @@ var /*3*/point = makePoint(2); point./*2*/x = 30; //// [declFileObjectLiteralWithOnlySetter.js] -function /*1*/ makePoint(x) { +function makePoint(x) { return { b: 10, set x(a) { this.b = a; } @@ -18,7 +18,7 @@ function /*1*/ makePoint(x) { } ; var /*3*/ point = makePoint(2); -point./*2*/ x = 30; +point.x = 30; //// [declFileObjectLiteralWithOnlySetter.d.ts] diff --git a/tests/baselines/reference/es6ImportDefaultBindingWithExport.js b/tests/baselines/reference/es6ImportDefaultBindingWithExport.js index 1e6f49e2414..cc90d280914 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingWithExport.js +++ b/tests/baselines/reference/es6ImportDefaultBindingWithExport.js @@ -21,7 +21,7 @@ define(["require", "exports"], function (require, exports) { define(["require", "exports", "server"], function (require, exports, server_1) { "use strict"; exports.x = server_1.default; -}); // non referenced +}); //// [server.d.ts] diff --git a/tests/baselines/reference/es6ImportNameSpaceImportDts.js b/tests/baselines/reference/es6ImportNameSpaceImportDts.js index 0b522776c4b..cf66c08331e 100644 --- a/tests/baselines/reference/es6ImportNameSpaceImportDts.js +++ b/tests/baselines/reference/es6ImportNameSpaceImportDts.js @@ -22,7 +22,6 @@ exports.c = c; "use strict"; var nameSpaceBinding = require("./server"); exports.x = new nameSpaceBinding.c(); - // unreferenced //// [server.d.ts] diff --git a/tests/baselines/reference/es6ImportNameSpaceImportNoNamedExports.js b/tests/baselines/reference/es6ImportNameSpaceImportNoNamedExports.js index 79c588dc277..8ece816fd3b 100644 --- a/tests/baselines/reference/es6ImportNameSpaceImportNoNamedExports.js +++ b/tests/baselines/reference/es6ImportNameSpaceImportNoNamedExports.js @@ -14,4 +14,3 @@ var a = 10; module.exports = a; //// [es6ImportNameSpaceImportNoNamedExports_1.js] "use strict"; - // error diff --git a/tests/baselines/reference/es6ImportNamedImportIdentifiersParsing.js b/tests/baselines/reference/es6ImportNamedImportIdentifiersParsing.js index a9a843f3cc9..8db7fcd6f9c 100644 --- a/tests/baselines/reference/es6ImportNamedImportIdentifiersParsing.js +++ b/tests/baselines/reference/es6ImportNamedImportIdentifiersParsing.js @@ -7,4 +7,3 @@ import { default as yield } from "somemodule"; // no error import { default as default } from "somemodule"; // default as is ok, error of default binding name //// [es6ImportNamedImportIdentifiersParsing.js] - // default as is ok, error of default binding name diff --git a/tests/baselines/reference/es6modulekindWithES5Target10.js b/tests/baselines/reference/es6modulekindWithES5Target10.js index 015a64c3bc0..b8a66241780 100644 --- a/tests/baselines/reference/es6modulekindWithES5Target10.js +++ b/tests/baselines/reference/es6modulekindWithES5Target10.js @@ -8,4 +8,3 @@ namespace N { export = N; // Error //// [es6modulekindWithES5Target10.js] - // Error diff --git a/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration4.js b/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration4.js index 1b8e4dd5c4b..1badf469996 100644 --- a/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration4.js +++ b/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration4.js @@ -12,4 +12,3 @@ export declare function bar(): X.bar; // error //// [exportSpecifierReferencingOuterDeclaration2_A.js] //// [exportSpecifierReferencingOuterDeclaration2_B.js] "use strict"; - // error diff --git a/tests/baselines/reference/genericConstraint3.js b/tests/baselines/reference/genericConstraint3.js index 657600ba41a..59548c4f4d7 100644 --- a/tests/baselines/reference/genericConstraint3.js +++ b/tests/baselines/reference/genericConstraint3.js @@ -4,4 +4,3 @@ interface A> { x: U; } interface B extends A<{}, { x: {} }> { } // Should not produce an error //// [genericConstraint3.js] - // Should not produce an error diff --git a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.js b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.js index 26ef7ca7759..f4ea5f07eb9 100644 --- a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.js +++ b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.js @@ -28,4 +28,3 @@ interface G extends A, B, C, E { } // should only report one error interface H extends A, F { } // Should report no error at all because error is internal to F //// [inheritedMembersAndIndexSignaturesFromDifferentBases.js] - // Should report no error at all because error is internal to F diff --git a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases2.js b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases2.js index 9291ab53c1c..8a3b2f8d032 100644 --- a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases2.js +++ b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases2.js @@ -10,4 +10,3 @@ interface B { interface C extends B, A { } // Should succeed //// [inheritedMembersAndIndexSignaturesFromDifferentBases2.js] - // Should succeed diff --git a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.js b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.js index c7a008f01fb..1645dd10a55 100644 --- a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.js +++ b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.js @@ -29,4 +29,3 @@ interface D2 { interface E2 extends A2, D2 { } // error //// [inheritedStringIndexersFromDifferentBaseTypes.js] - // error diff --git a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.js b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.js index 0580b145901..aa837b5cf2e 100644 --- a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.js +++ b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.js @@ -25,4 +25,3 @@ interface F extends A, D { } // ok because we overrode D's number index signature //// [inheritedStringIndexersFromDifferentBaseTypes2.js] - // ok because we overrode D's number index signature diff --git a/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js b/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js index 85d0d3687be..7f01666bd78 100644 --- a/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js +++ b/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js @@ -62,7 +62,7 @@ a['foo'] > ; ; ; var x =
one
two
;; -var x =
one
/* intervening comment */ /* intervening comment */
two
;; +var x =
one
/* intervening comment */ /* intervening comment */
two
;;
{"str"}}; id="b" />;
>; @@ -76,4 +76,4 @@ var x =
one
/* intervening comment */ /* intervening comment */
; ; }; -/*hai*/ /*hai*/asdf/>;; + /*hai*//*hai*/asdf/>;; diff --git a/tests/baselines/reference/nonConflictingRecursiveBaseTypeMembers.js b/tests/baselines/reference/nonConflictingRecursiveBaseTypeMembers.js index 9663da873b8..6e77029fa94 100644 --- a/tests/baselines/reference/nonConflictingRecursiveBaseTypeMembers.js +++ b/tests/baselines/reference/nonConflictingRecursiveBaseTypeMembers.js @@ -10,4 +10,3 @@ interface B { interface C extends A, B { } // Should not be an error //// [nonConflictingRecursiveBaseTypeMembers.js] - // Should not be an error diff --git a/tests/baselines/reference/objectTypesWithOptionalProperties2.js b/tests/baselines/reference/objectTypesWithOptionalProperties2.js index 28470e04983..eabb1a153a6 100644 --- a/tests/baselines/reference/objectTypesWithOptionalProperties2.js +++ b/tests/baselines/reference/objectTypesWithOptionalProperties2.js @@ -42,5 +42,6 @@ var C2 = (function () { return C2; }()); var b = { - x: function () { }, 1: // error + x: function () { }, 1: // error + // error }; diff --git a/tests/baselines/reference/parseRegularExpressionMixedWithComments.js b/tests/baselines/reference/parseRegularExpressionMixedWithComments.js index 0ef42cf2ce1..78752a77f75 100644 --- a/tests/baselines/reference/parseRegularExpressionMixedWithComments.js +++ b/tests/baselines/reference/parseRegularExpressionMixedWithComments.js @@ -8,7 +8,7 @@ var regex5 = /**// asdf/**/ /; //// [parseRegularExpressionMixedWithComments.js] var regex1 = / asdf /; -var regex2 = /**/ / asdf /; +var regex2 = / asdf /; var regex3 = 1; -var regex4 = /**/ Math.pow(/ /, /asdf /); -var regex5 = /**/ Math.pow(/ asdf/, / /); +var regex4 = Math.pow(/ /, /asdf /); +var regex5 = Math.pow(/ asdf/, / /); diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js index eb76d7e0d7c..862722b1a73 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js @@ -6,6 +6,5 @@ //// [parserGreaterThanTokenAmbiguity10.js] 1 - // before >>> 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity13.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity13.js index 5be4da1c04e..49130a9dd13 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity13.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity13.js @@ -2,5 +2,5 @@ 1 >>/**/= 2; //// [parserGreaterThanTokenAmbiguity13.js] -1 >> /**/ ; +1 >> ; /**/ 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js index 8fadea77fdc..b6f905e12e7 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js @@ -6,6 +6,5 @@ //// [parserGreaterThanTokenAmbiguity15.js] 1 - // before >>= 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity18.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity18.js index 4cf227f2748..71527689b2c 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity18.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity18.js @@ -2,5 +2,5 @@ 1 >>>/**/= 2; //// [parserGreaterThanTokenAmbiguity18.js] -1 >>> /**/ ; +1 >>> ; /**/ 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js index ab86deeb0d2..01d1d6401f2 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js @@ -6,6 +6,5 @@ //// [parserGreaterThanTokenAmbiguity20.js] 1 - // Before >>>= 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity3.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity3.js index f692d1a6324..79f8c139260 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity3.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity3.js @@ -2,4 +2,4 @@ 1 >/**/> 2; //// [parserGreaterThanTokenAmbiguity3.js] -1 > /**/ /**/ > 2; +1 > /**/ > 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js index 24aa9e5316a..c65b76f504a 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js @@ -6,6 +6,5 @@ //// [parserGreaterThanTokenAmbiguity5.js] 1 - // before >> 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity8.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity8.js index d8ea6134a58..0006c03219a 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity8.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity8.js @@ -2,4 +2,4 @@ 1 >>/**/> 2; //// [parserGreaterThanTokenAmbiguity8.js] -1 >> /**/ /**/ > 2; +1 >> /**/ > 2; diff --git a/tests/baselines/reference/parserSkippedTokens5.js b/tests/baselines/reference/parserSkippedTokens5.js index 665db1ef70d..359a98a5969 100644 --- a/tests/baselines/reference/parserSkippedTokens5.js +++ b/tests/baselines/reference/parserSkippedTokens5.js @@ -2,4 +2,4 @@ \ /*foo*/ ; //// [parserSkippedTokens5.js] -/*foo*/ ; +; diff --git a/tests/baselines/reference/parserSkippedTokens7.js b/tests/baselines/reference/parserSkippedTokens7.js index b3aa40d9057..2115614ea1f 100644 --- a/tests/baselines/reference/parserSkippedTokens7.js +++ b/tests/baselines/reference/parserSkippedTokens7.js @@ -2,4 +2,3 @@ /*foo*/ \ /*bar*/ //// [parserSkippedTokens7.js] - /*bar*/ diff --git a/tests/baselines/reference/parserSkippedTokens8.js b/tests/baselines/reference/parserSkippedTokens8.js index d8433bbd34c..c9f00f4b85b 100644 --- a/tests/baselines/reference/parserSkippedTokens8.js +++ b/tests/baselines/reference/parserSkippedTokens8.js @@ -3,4 +3,4 @@ /*foo*/ \ /*bar*/ //// [parserSkippedTokens8.js] -; /*bar*/ +; diff --git a/tests/baselines/reference/parserSkippedTokens9.js b/tests/baselines/reference/parserSkippedTokens9.js index cabf3a48e56..d693b99b2ea 100644 --- a/tests/baselines/reference/parserSkippedTokens9.js +++ b/tests/baselines/reference/parserSkippedTokens9.js @@ -4,4 +4,3 @@ //// [parserSkippedTokens9.js] ; // existing trivia - /*bar*/ diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType1.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType1.js index 96fff1f8f33..d759bc2f296 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType1.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType1.js @@ -29,4 +29,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType1_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); // This should result in type ClassB +}); diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType2.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType2.js index e8262c86b4f..7704b38f68d 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType2.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType2.js @@ -33,4 +33,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType2_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); // This should result in type ClassB +}); diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType3.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType3.js index 39303b463ba..a46be3bdafc 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType3.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType3.js @@ -37,4 +37,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType3_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); // This should result in type ClassB +}); diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType4.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType4.js index 80a4408b10d..8ccd6ecf560 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType4.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType4.js @@ -31,4 +31,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType4_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); // This should result in type ClassB +}); diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType5.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType5.js index 69f6ff07bd8..4602ed554e5 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType5.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType5.js @@ -40,4 +40,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType5_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); // This should result in type ClassB +}); diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType6.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType6.js index 277a8a168da..d3487519218 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType6.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType6.js @@ -49,4 +49,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType6_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); // This should result in type ClassB +}); diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.js index fcab82802b2..9a29c2bf949 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.js @@ -51,4 +51,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType7_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); // This should result in type ClassB +}); diff --git a/tests/baselines/reference/thisInInvalidContextsExternalModule.js b/tests/baselines/reference/thisInInvalidContextsExternalModule.js index 00553a3fbba..2e7e6d8b47c 100644 --- a/tests/baselines/reference/thisInInvalidContextsExternalModule.js +++ b/tests/baselines/reference/thisInInvalidContextsExternalModule.js @@ -107,4 +107,4 @@ var SomeEnum; SomeEnum[SomeEnum["A"] = this] = "A"; SomeEnum[SomeEnum["B"] = this.spaaaace] = "B"; // Also should not be allowed })(SomeEnum || (SomeEnum = {})); -module.exports = this; // Should be an error +module.exports = this; diff --git a/tests/baselines/reference/tsxParseTests2.js b/tests/baselines/reference/tsxParseTests2.js index c09e9d2c3cb..b0cf54f8d1f 100644 --- a/tests/baselines/reference/tsxParseTests2.js +++ b/tests/baselines/reference/tsxParseTests2.js @@ -8,4 +8,4 @@ var x =
; //// [file.jsx] -var x =
; +var x =
; diff --git a/tests/baselines/reference/typeAliasDoesntMakeModuleInstantiated.js b/tests/baselines/reference/typeAliasDoesntMakeModuleInstantiated.js index af2287ef27f..861e20cb0d1 100644 --- a/tests/baselines/reference/typeAliasDoesntMakeModuleInstantiated.js +++ b/tests/baselines/reference/typeAliasDoesntMakeModuleInstantiated.js @@ -11,4 +11,3 @@ declare module m { declare var m: m.IStatic; // Should be ok to have var 'm' as module is non instantiated //// [typeAliasDoesntMakeModuleInstantiated.js] - // Should be ok to have var 'm' as module is non instantiated From ff9ccc9b059bd122e8ea88dd7bc08e4f2bf1bf7f Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 1 Sep 2016 18:41:29 -0700 Subject: [PATCH 10/46] Undo scanner/emitter changes --- src/compiler/emitter.ts | 74 +++++++++++++-------------------------- src/compiler/scanner.ts | 19 ++++------ src/compiler/utilities.ts | 8 ++++- 3 files changed, 38 insertions(+), 63 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index ce8d8e44d39..574c496d747 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -851,7 +851,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } } - function emitLinePreservingList(parent: Node, nodes: NodeArray, allowTrailingComma: boolean, spacesBetweenBraces: boolean, commentsBeforePunctuation: boolean) { + function emitLinePreservingList(parent: Node, nodes: NodeArray, allowTrailingComma: boolean, spacesBetweenBraces: boolean) { Debug.assert(nodes.length > 0); increaseIndent(); @@ -877,9 +877,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } emit(nodes[i]); - if (commentsBeforePunctuation) { - emitLeadingCommentsAtEnd(nodes[i]); - } } if (nodes.hasTrailingComma && allowTrailingComma) { @@ -898,7 +895,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } } - function emitList(nodes: TNode[], start: number, count: number, multiLine: boolean, trailingComma: boolean, leadingComma?: boolean, noTrailingNewLine?: boolean, commentsBeforePunctuation?: boolean, emitNode?: (node: TNode) => void): number { + function emitList(nodes: TNode[], start: number, count: number, multiLine: boolean, trailingComma: boolean, leadingComma?: boolean, noTrailingNewLine?: boolean, emitNode?: (node: TNode) => void): number { if (!emitNode) { emitNode = emit; } @@ -916,10 +913,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } } const node = nodes[start + i]; + // This emitting is to make sure we emit following comment properly + // ...(x, /*comment1*/ y)... + // ^ => node.pos + // "comment1" is not considered leading comment for "y" but rather + // considered as trailing comment of the previous node. + emitTrailingCommentsOfPosition(node.pos); emitNode(node); - if (commentsBeforePunctuation) { - emitLeadingCommentsAtEnd(nodes[i]); - } leadingComma = true; } if (trailingComma) { @@ -1897,7 +1897,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } else if (languageVersion >= ScriptTarget.ES6 || !forEach(elements, isSpreadElementExpression)) { write("["); - emitLinePreservingList(node, node.elements, elements.hasTrailingComma, /*spacesBetweenBraces*/ false, /*commentsBeforePunctuation*/ true); + emitLinePreservingList(node, node.elements, elements.hasTrailingComma, /*spacesBetweenBraces*/ false); write("]"); } else { @@ -1921,7 +1921,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge // then try to preserve the original shape of the object literal. // Otherwise just try to preserve the formatting. if (numElements === properties.length) { - emitLinePreservingList(node, properties, /*allowTrailingComma*/ languageVersion >= ScriptTarget.ES5, /*spacesBetweenBraces*/ true, /*commentsBeforePunctuation*/ true); + emitLinePreservingList(node, properties, /*allowTrailingComma*/ languageVersion >= ScriptTarget.ES5, /*spacesBetweenBraces*/ true); } else { const multiLine = node.multiLine; @@ -2166,6 +2166,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge function emitPropertyAssignment(node: PropertyDeclaration) { emit(node.name); write(": "); + // This is to ensure that we emit comment in the following case: + // For example: + // obj = { + // id: /*comment1*/ ()=>void + // } + // "comment1" is not considered to be leading comment for node.initializer + // but rather a trailing comment on the previous node. + emitTrailingCommentsOfPosition(node.initializer.pos); emit(node.initializer); } @@ -2277,7 +2285,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } emit(node.expression); - emitLeadingCommentsAtEnd(node.expression); const dotRangeStart = nodeIsSynthesized(node.expression) ? -1 : node.expression.end; const dotRangeEnd = nodeIsSynthesized(node.expression) ? -1 : skipTrivia(currentText, node.expression.end) + 1; const dotToken = { pos: dotRangeStart, end: dotRangeEnd }; @@ -2494,17 +2501,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge emitThis(expression); if (node.arguments.length) { write(", "); - emitTrailingCommentsOfPosition(node.arguments.pos); emitCommaList(node.arguments); - emitLeadingCommentsAtEnd(node.arguments); } write(")"); } else { write("("); - emitTrailingCommentsOfPosition(node.arguments.pos); emitCommaList(node.arguments); - emitLeadingCommentsAtEnd(node.arguments); write(")"); } } @@ -2605,7 +2608,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge write("("); emit(node.expression); - emitLeadingCommentsAtEnd(node.expression); write(")"); } @@ -2884,7 +2886,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } else { emit(node.left); - emitLeadingCommentsAtEnd(node.left); // Add indentation before emit the operator if the operator is on different line // For example: // 3 @@ -3897,7 +3898,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } emitNodeWithCommentsAndWithoutSourcemap(node.name); emitEnd(node.name); - emitLeadingCommentsAtEnd(node.name); } function createVoidZero(): Expression { @@ -4040,7 +4040,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge emit(name); } - emitLeadingCommentsAtEnd(name); write(" = "); emit(value); }); @@ -4592,7 +4591,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge emitStart(restParam); write("var "); emitNodeWithCommentsAndWithoutSourcemap(restParam.name); - emitLeadingCommentsAtEnd(restParam.name); write(" = [];"); emitEnd(restParam); emitTrailingComments(restParam); @@ -4614,7 +4612,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge writeLine(); emitStart(restParam); emitNodeWithCommentsAndWithoutSourcemap(restParam.name); - emitLeadingCommentsAtEnd(restParam.name); write("[" + tempName + " - " + restIndex + "] = arguments[" + tempName + "];"); emitEnd(restParam); decreaseIndent(); @@ -4636,7 +4633,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge function emitDeclarationName(node: Declaration) { if (node.name) { emitNodeWithCommentsAndWithoutSourcemap(node.name); - emitLeadingCommentsAtEnd(node.name); } else { write(getGeneratedNameForNode(node)); @@ -4664,7 +4660,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge const { kind, parent } = node; if (kind !== SyntaxKind.MethodDeclaration && kind !== SyntaxKind.MethodSignature && - kind !== SyntaxKind.ArrowFunction && parent && parent.kind !== SyntaxKind.PropertyAssignment && parent.kind !== SyntaxKind.CallExpression && @@ -4739,11 +4734,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge const parameters = node.parameters; const skipCount = node.parameters.length && (node.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword ? 1 : 0; const omitCount = languageVersion < ScriptTarget.ES6 && hasDeclaredRestParameter(node) ? 1 : 0; - emitTrailingCommentsOfPosition(node.parameters.pos); - emitList(parameters, skipCount, parameters.length - omitCount - skipCount, /*multiLine*/ false, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ false, /*commentsBeforePunctuation*/ true); - if ((parameters.length - omitCount - skipCount) <= 0) { - emitLeadingCommentsAtEnd(node.parameters); - } + emitList(parameters, skipCount, parameters.length - omitCount - skipCount, /*multiLine*/ false, /*trailingComma*/ false); } write(")"); decreaseIndent(); @@ -5800,7 +5791,7 @@ const _super = (function (geti, seti) { writeLine(); const decoratorCount = decorators ? decorators.length : 0; - let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, /*commentsBeforePunctuation*/ false, + let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, decorator => emit(decorator.expression)); if (firstParameterDecorator) { argumentsWritten += emitDecoratorsOfParameters(constructor, /*leadingComma*/ argumentsWritten > 0); @@ -5900,7 +5891,7 @@ const _super = (function (geti, seti) { writeLine(); const decoratorCount = decorators ? decorators.length : 0; - let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, /*commentsBeforePunctuation*/ false, + let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, decorator => emit(decorator.expression)); if (firstParameterDecorator) { @@ -5942,7 +5933,7 @@ const _super = (function (geti, seti) { for (const parameter of node.parameters) { if (nodeIsDecorated(parameter)) { const decorators = parameter.decorators; - argumentsWritten += emitList(decorators, 0, decorators.length, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ leadingComma, /*noTrailingNewLine*/ true, /*commentsBeforePunctuation*/ false, decorator => { + argumentsWritten += emitList(decorators, 0, decorators.length, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ leadingComma, /*noTrailingNewLine*/ true, decorator => { write(`__param(${parameterIndex}, `); emit(decorator.expression); write(")"); @@ -6356,7 +6347,6 @@ const _super = (function (geti, seti) { emitExpressionForPropertyName(node.name); emitEnd(node); write(";"); - emitLeadingCommentsAtEnd(node.name); } function writeEnumMemberDeclarationValue(member: EnumMember) { @@ -8319,11 +8309,8 @@ const _super = (function (geti, seti) { /** * Emit trailing comments at the position. The term trailing comment is used here to describe following comment: - * x, /*comment1* / // comment2 - * ^ => pos; the function will emit "comment1" and "comment2" in the emitJS - * However, * x /*comment1* /, y - * 'comment1' is actually a leading comment of ',' and needs to be emitted using emitLeadingCommentsAtEnd + * ^ => pos; the function will emit "comment1" */ function emitTrailingCommentsOfPosition(pos: number) { if (compilerOptions.removeComments) { @@ -8336,18 +8323,7 @@ const _super = (function (geti, seti) { emitComments(currentText, currentLineMap, writer, trailingComments, /*trailingSeparator*/ true, newLine, writeComment); } - /** - * Emit leading comments for the token after the current token. - * This is only needed for punctuation tokens. For example, in - * x /*comment1* /, y - * 'comment1' is a leading comment of ',' but needs to be emitted - * from x because there is no token for ','. - */ - function emitLeadingCommentsAtEnd(node: Node | NodeArray) { - emitLeadingCommentsOfPositionWorker(node.end, /*trailingSeparator*/ false); - } - - function emitLeadingCommentsOfPositionWorker(pos: number, trailingSeparator = true) { + function emitLeadingCommentsOfPositionWorker(pos: number) { if (compilerOptions.removeComments) { return; } @@ -8365,7 +8341,7 @@ const _super = (function (geti, seti) { emitNewLineBeforeLeadingComments(currentLineMap, writer, { pos: pos, end: pos }, leadingComments); // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space - emitComments(currentText, currentLineMap, writer, leadingComments, trailingSeparator, newLine, writeComment); + emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment); } function emitDetachedCommentsAndUpdateCommentsInfo(node: TextRange) { diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index d8cfc39db87..a714320639f 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -599,11 +599,10 @@ namespace ts { * If false, whitespace is skipped until the first line break and comments between that location * and the next token are returned. * If true, comments occurring between the given position and the next line break are returned. - * If there is no line break, then no comments are returned. */ function getCommentRanges(text: string, pos: number, trailing: boolean): CommentRange[] { let result: CommentRange[]; - let needToSkipTrailingComment = pos > 0; + let collecting = trailing || pos === 0; while (pos < text.length) { const ch = text.charCodeAt(pos); switch (ch) { @@ -616,11 +615,7 @@ namespace ts { if (trailing) { return result; } - else if (needToSkipTrailingComment) { - // skip the first line if not trailing (it'll be part of the trailing comment). - needToSkipTrailingComment = false; - result = undefined; - } + collecting = true; if (result && result.length) { lastOrUndefined(result).hasTrailingNewLine = true; } @@ -656,13 +651,11 @@ namespace ts { pos++; } } - - // if we are at the end of the file, don't add trailing comments. - // end-of-file comments are added as leading comment of the end-of-file token. - if (pos < text.length || !trailing) { + if (collecting) { if (!result) { result = []; } + result.push({ pos: startPos, end: pos, hasTrailingNewLine, kind }); } continue; @@ -678,10 +671,10 @@ namespace ts { } break; } - return !trailing ? result : undefined; + return result; } - return !trailing ? result : undefined; + return result; } export function getLeadingCommentRanges(text: string, pos: number): CommentRange[] { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 5e556278866..f6f8b1f66b2 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -596,7 +596,13 @@ namespace ts { } export function getJsDocCommentsFromText(node: Node, text: string) { - return filter(getLeadingCommentRanges(text, node.pos), isJsDocComment); + const commentRanges = (node.kind === SyntaxKind.Parameter || + node.kind === SyntaxKind.TypeParameter || + node.kind === SyntaxKind.FunctionExpression || + node.kind === SyntaxKind.ArrowFunction) ? + concatenate(getTrailingCommentRanges(text, node.pos), getLeadingCommentRanges(text, node.pos)) : + getLeadingCommentRangesOfNodeFromText(node, text); + return filter(commentRanges, isJsDocComment); function isJsDocComment(comment: CommentRange) { // True if the comment starts with '/**' but not if it is '/**/' From 643cf302c63fcd107d336c8f8ddd99d81cb8bf78 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 1 Sep 2016 21:39:24 -0700 Subject: [PATCH 11/46] Use getJsDocFromText to get trailing comments Also update a couple of missed spots in the previous undo commits --- src/compiler/emitter.ts | 6 +----- src/compiler/parser.ts | 2 +- tests/baselines/reference/errorSupression1.js | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 574c496d747..1821acd0a1f 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -8288,11 +8288,7 @@ const _super = (function (geti, seti) { emitNewLineBeforeLeadingComments(currentLineMap, writer, node, leadingComments); // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space - // However, a leading mid-line comment of the end of file token is emitted with spaces before, - // as if it were a trailing comment of the previous token - const commentStartsInMidLine = leadingComments && leadingComments.length && leadingComments[0].pos - 1 > 0 && currentText.charCodeAt(leadingComments[0].pos - 1) !== 10; - const isEndOfFile = node.kind === SyntaxKind.EndOfFileToken && commentStartsInMidLine; - emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ !isEndOfFile, newLine, writeComment); + emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment); } function emitTrailingComments(node: Node) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 445af2243df..59fc1ef004b 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -652,7 +652,7 @@ namespace ts { function addJSDocComment(node: T): T { - const comments = getLeadingCommentRangesOfNode(node, sourceFile); + const comments = getJsDocCommentsFromText(node, sourceFile.text); if (comments) { for (const comment of comments) { const jsDoc = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); diff --git a/tests/baselines/reference/errorSupression1.js b/tests/baselines/reference/errorSupression1.js index 285aa525b5f..77545131ce3 100644 --- a/tests/baselines/reference/errorSupression1.js +++ b/tests/baselines/reference/errorSupression1.js @@ -18,4 +18,4 @@ var Foo = (function () { var baz = Foo.b; // Foo.b won't bind. baz.concat("y"); - // So we don't want an error on 'concat'. +// So we don't want an error on 'concat'. From f8e192afb032bc5e1309e939d764d8a0df073e74 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 2 Sep 2016 09:09:02 -0700 Subject: [PATCH 12/46] Use a state enum to parse top-level jsdoc comments Also use a `pushComments` function, which fixes a spacing bug. --- src/compiler/parser.ts | 126 ++++++++---------- .../cases/fourslash/commentsCommentParsing.ts | 14 +- 2 files changed, 64 insertions(+), 76 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 59fc1ef004b..fdc1ccefcd7 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6151,10 +6151,10 @@ namespace ts { return comment; } - const enum TagState { + const enum JSDocState { BeginningOfLine, SawAsterisk, - SavingComments + SavingComments, } export function parseJSDocCommentWorker(start: number, length: number): JSDoc { @@ -6180,93 +6180,81 @@ namespace ts { scanner.scanRange(start + 3, length - 5, () => { // Initially we can parse out a tag. We also have seen a starting asterisk. // This is so that /** * @type */ doesn't parse. - let canParseTag = true; - let seenAsterisk = true; let advanceToken = true; + let state = JSDocState.SawAsterisk; let margin: number | undefined = undefined; let indent = start - Math.max(content.lastIndexOf("\n", start), 0) + 4; - let text: string; + function pushComment(text: string) { + if (!margin) { + margin = indent; + } + comments.push(text); + indent += text.length; + } nextJSDocToken(); while (token() === SyntaxKind.WhitespaceTrivia) { nextJSDocToken(); } if (token() === SyntaxKind.NewLineTrivia) { - canParseTag = true; - seenAsterisk = false; + state = JSDocState.BeginningOfLine; nextJSDocToken(); } while (token() !== SyntaxKind.EndOfFileToken) { switch (token()) { case SyntaxKind.AtToken: - if (canParseTag) { + if (state === JSDocState.BeginningOfLine || state === JSDocState.SawAsterisk) { removeTrailingNewlines(comments); parseTag(indent); - // This will take us past the end of the line, so it's OK to parse a tag on the next pass through the loop - // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag. But real-world comments may break this rule. - seenAsterisk = false; + // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag. + // Real-world comments may break this rule, so "BeginningOfLine" will not be a real line beginning + // for malformed examples like `/** @param {string} x @returns {number} the length */` + state = JSDocState.BeginningOfLine; advanceToken = false; margin = undefined; + indent++; } else { - comments.push(scanner.getTokenText()); + pushComment(scanner.getTokenText()); } - indent++; break; - case SyntaxKind.NewLineTrivia: - // After a line break, we can parse a tag, and we haven't seen an asterisk on the next line yet comments.push(scanner.getTokenText()); - canParseTag = true; - seenAsterisk = false; + state = JSDocState.BeginningOfLine; indent = 0; break; - case SyntaxKind.AsteriskToken: - text = scanner.getTokenText(); - if (seenAsterisk) { + const asterisk = scanner.getTokenText(); + if (state === JSDocState.SawAsterisk) { // If we've already seen an asterisk, then we can no longer parse a tag on this line - canParseTag = false; - comments.push(text); - if (!margin) { - margin = indent; - } + state = JSDocState.SavingComments; + pushComment(asterisk); + } + else { + // Ignore the first asterisk on a line + state = JSDocState.SawAsterisk; + indent += asterisk.length; } - // Ignore the first asterisk on a line - seenAsterisk = true; - indent += text.length; break; - case SyntaxKind.Identifier: // Anything else is doc comment text. We just save it. Because it // wasn't a tag, we can no longer parse a tag on this line until we hit the next // line break. - text = scanner.getTokenText(); - comments.push(text); - if (!margin) { - margin = indent; - } - canParseTag = false; - indent += text.length; + pushComment(scanner.getTokenText()); + state = JSDocState.SavingComments; break; - - case SyntaxKind.WhitespaceTrivia: - // only collect whitespace if we *know* that we're just looking at comments, not a possible jsdoc tag - text = scanner.getTokenText(); - if (!canParseTag || margin !== undefined && indent + text.length > margin) { - comments.push(text.slice(margin - indent - 1)); + // only collect whitespace if we're already saving comments or have just crossed the comment indent margin + const whitespace = scanner.getTokenText(); + if (state === JSDocState.SavingComments || margin !== undefined && indent + whitespace.length > margin) { + comments.push(whitespace.slice(margin - indent - 1)); } - indent += text.length; + indent += whitespace.length; break; - case SyntaxKind.EndOfFileToken: break; - default: - text = scanner.getTokenText(); - comments.push(text); - indent += text.length; + pushComment(scanner.getTokenText()); break; } if (advanceToken) { @@ -6365,10 +6353,8 @@ namespace ts { function parseTagComments(indent: number) { const comments: string[] = []; - let state = TagState.SawAsterisk; - let done = false; + let state = JSDocState.SawAsterisk; let margin: number | undefined; - let text: string; function pushComment(text: string) { if (!margin) { margin = indent; @@ -6376,47 +6362,49 @@ namespace ts { comments.push(text); indent += text.length; } - while (!done && token() !== SyntaxKind.EndOfFileToken) { - text = scanner.getTokenText(); + while (token() !== SyntaxKind.AtToken && token() !== SyntaxKind.EndOfFileToken) { switch (token()) { case SyntaxKind.NewLineTrivia: - if (state >= TagState.SawAsterisk) { - state = TagState.BeginningOfLine; - comments.push(text); + if (state >= JSDocState.SawAsterisk) { + state = JSDocState.BeginningOfLine; + comments.push(scanner.getTokenText()); } indent = 0; break; case SyntaxKind.AtToken: - done = true; + // Done break; case SyntaxKind.WhitespaceTrivia: - if (state === TagState.SavingComments) { - pushComment(text); + if (state === JSDocState.SavingComments) { + pushComment(scanner.getTokenText()); } else { + const whitespace = scanner.getTokenText(); // if the whitespace crosses the margin, take only the whitespace that passes the margin - if (margin !== undefined && indent + text.length > margin) { - comments.push(text.slice(margin - indent - 1)); + if (margin !== undefined && indent + whitespace.length > margin) { + comments.push(whitespace.slice(margin - indent - 1)); } - indent += text.length; + indent += whitespace.length; } break; case SyntaxKind.AsteriskToken: - if (state === TagState.BeginningOfLine) { + if (state === JSDocState.BeginningOfLine) { // leading asterisks start recording on the *next* (non-whitespace) token - state = TagState.SawAsterisk; - indent += text.length; + state = JSDocState.SawAsterisk; + indent += scanner.getTokenText().length; break; } // FALLTHROUGH otherwise to record the * as a comment default: - state = TagState.SavingComments; // leading identifiers start recording as well - pushComment(text); + state = JSDocState.SavingComments; // leading identifiers start recording as well + pushComment(scanner.getTokenText()); break; } - if (!done) { - nextJSDocToken(); + if (token() === SyntaxKind.AtToken) { + // Done + break; } + nextJSDocToken(); } removeLeadingNewlines(comments); diff --git a/tests/cases/fourslash/commentsCommentParsing.ts b/tests/cases/fourslash/commentsCommentParsing.ts index a0a86cbc75c..53c459c9fc1 100644 --- a/tests/cases/fourslash/commentsCommentParsing.ts +++ b/tests/cases/fourslash/commentsCommentParsing.ts @@ -351,39 +351,39 @@ verify.completionListContains("multiply", "function multiply(a: number, b: numbe verify.completionListContains("f1", "function f1(a: number): any (+1 overload)", "fn f1 with number"); goTo.marker('28'); -verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{ () => string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs(""); goTo.marker('28q'); -verify.quickInfoIs("function subtract(a: number, b: number, c?: () => string, d?: () => string, e?: () => string, f?: () => string): void", "This is subtract function{()=>string; } } f this is optional param f"); +verify.quickInfoIs("function subtract(a: number, b: number, c?: () => string, d?: () => string, e?: () => string, f?: () => string): void", "This is subtract function{ () => string; } } f this is optional param f"); goTo.marker('28aq'); verify.quickInfoIs("(parameter) a: number", ""); goTo.marker('29'); -verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{ () => string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs("this is about b"); goTo.marker('29aq'); verify.quickInfoIs("(parameter) b: number", "this is about b"); goTo.marker('30'); -verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{ () => string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs("this is optional param c"); goTo.marker('30aq'); verify.quickInfoIs("(parameter) c: () => string", "this is optional param c"); goTo.marker('31'); -verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{ () => string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs("this is optional param d"); goTo.marker('31aq'); verify.quickInfoIs("(parameter) d: () => string", "this is optional param d"); goTo.marker('32'); -verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{ () => string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs("this is optional param e"); goTo.marker('32aq'); verify.quickInfoIs("(parameter) e: () => string", "this is optional param e"); goTo.marker('33'); -verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{ () => string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs(""); goTo.marker('33aq'); verify.quickInfoIs("(parameter) f: () => string", ""); From 66f30c9841bebaf8e0c62da4ed36a64ee7b35ca0 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Tue, 6 Sep 2016 17:02:23 -0700 Subject: [PATCH 13/46] PR feedback --- src/harness/fourslash.ts | 2 +- src/services/services.ts | 188 ++++++------------ .../goToImplementationInterfaceMethod_00.ts | 1 + .../goToImplementationInterfaceMethod_08.ts | 2 +- .../goToImplementationInterfaceMethod_09.ts | 4 + .../goToImplementationNamespace_00.ts | 33 ++- .../goToImplementationNamespace_01.ts | 10 +- .../goToImplementationNamespace_02.ts | 2 +- .../goToImplementationNamespace_03.ts | 30 ++- .../goToImplementationNamespace_04.ts | 40 ++-- .../goToImplementationNamespace_05.ts | 26 --- .../goToImplementationNamespace_06.ts | 28 --- .../goToImplementationNamespace_07.ts | 28 --- 13 files changed, 146 insertions(+), 248 deletions(-) delete mode 100644 tests/cases/fourslash/goToImplementationNamespace_05.ts delete mode 100644 tests/cases/fourslash/goToImplementationNamespace_06.ts delete mode 100644 tests/cases/fourslash/goToImplementationNamespace_07.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index c577d2dd4bb..80baca88a70 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -3017,7 +3017,7 @@ namespace FourSlashInterface { public typeDefinitionCountIs(expectedCount: number) { this.state.verifyTypeDefinitionsCount(this.negative, expectedCount); } - + public implementationCountIs(expectedCount: number) { this.state.verifyImplementationsCount(this.negative, expectedCount); } diff --git a/src/services/services.ts b/src/services/services.ts index 79172287e6e..013e093336e 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -5010,38 +5010,25 @@ namespace ts { function getImplementationAtPosition(fileName: string, position: number): ImplementationLocation[] { synchronizeHostData(); - const entries: ImplementationLocation[] = []; const node = getTouchingPropertyName(getValidSourceFile(fileName), position); const typeChecker = program.getTypeChecker(); // If invoked directly on a shorthand property assignment, then return // the declaration of the symbol being assigned (not the symbol being assigned to). if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { - const entry = getReferenceEntryForShorthandPropertyAssignment(node, typeChecker); - entries.push({ - textSpan: entry.textSpan, - fileName: entry.fileName - }); + return getReferenceEntryForShorthandPropertyAssignment(node, typeChecker); } - - // For most symbols, the definition is the same as the implementation so we can just - // call "Go to Definition". This case should handle anything that is not a type - // reference to or member of an interface, class, or union/intersection type. - else if (definitionIsImplementation(node, typeChecker)) { - const definitions = getDefinitionAtPosition(fileName, position); - forEach(definitions, (definition: DefinitionInfo) => { - entries.push({ - textSpan: definition.textSpan, - fileName: definition.fileName - }); - }); + else if (node.kind === SyntaxKind.SuperKeyword || isSuperPropertyOrElementAccess(node.parent)) { + // References to and accesses on the super keyword only have one possible implementation, so no + // need to "Find all References" + const symbol = typeChecker.getSymbolAtLocation(node); + if (symbol.valueDeclaration) { + return [getReferenceEntryFromNode(symbol.valueDeclaration)]; + } } - - // Interfaces, classes, and unions/intersection types separate the implementation and - // definition so "Go to Definition" is not sufficient. This case handles invocations - // on type references and members of those types. else { - // Perform "Find all References" and filter them down to implementations only + const entries: ImplementationLocation[] = []; + // Perform "Find all References" and retrieve only those that are implementations const result = getReferencedSymbolsForNode(node, program.getSourceFiles(), /*findInStrings*/false, /*findInComments*/false, /*implementations*/true); forEach(result, referencedSymbol => { @@ -5054,44 +5041,8 @@ namespace ts { }); } }); + return entries; } - - return entries; - } - - /** - * Returns true if the implementation for this node is the same as its definition - */ - function definitionIsImplementation(node: Node, typeChecker: TypeChecker) { - if (node.kind === SyntaxKind.SuperKeyword || node.kind === SyntaxKind.ThisKeyword) { - return true; - } - - if (node.parent.kind === SyntaxKind.PropertyAccessExpression || node.parent.kind === SyntaxKind.ElementAccessExpression) { - const expression = (node.parent).expression; - - // Members of "this" and "super" only have one possible implementation, so no need to find - // all references. Similarly, for the left hand side of the expression it only really - // makes sense to return the definition - if (node === expression || expression.kind === SyntaxKind.SuperKeyword || expression.kind === SyntaxKind.ThisKeyword) { - return true; - } - - // Check to see if this is a property that can have multiple implementations by determining - // if the parent is an interface (or class, or union/intersection) - const expressionType = typeChecker.getTypeAtLocation(expression); - if (expressionType && expressionType.getFlags() & (TypeFlags.Class | TypeFlags.Interface | TypeFlags.UnionOrIntersection)) { - return false; - } - - // Also check the right hand side to see if this is a type being accessed on a namespace/module. - // For example, SomeModule.SomeType - const rightHandType = typeChecker.getTypeAtLocation(node); - return rightHandType && !(rightHandType.getFlags() & (TypeFlags.Class | TypeFlags.Interface | TypeFlags.UnionOrIntersection)); - } - - const symbol = typeChecker.getSymbolAtLocation(node); - return symbol && !isClassOrInterfaceReference(symbol) && !(symbol.parent && isClassOrInterfaceReference(symbol.parent)); } function getReferenceEntryForShorthandPropertyAssignment(node: Node, typeChecker: TypeChecker) { @@ -5099,21 +5050,15 @@ namespace ts { const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(refSymbol.valueDeclaration); if (shorthandSymbol) { - const shorthandDeclarations = shorthandSymbol.getDeclarations(); - if (shorthandDeclarations.length === 1) { - return getReferenceEntryFromNode(shorthandDeclarations[0]); - } - else if (shorthandDeclarations.length > 1) { - // This can happen when the property being assigned is a constructor for a - // class that also has interface declarations with the same name. We just want - // the class itself + const result: ReferenceEntry[] = []; - return forEach(shorthandDeclarations, declaration => { - if (declaration.kind === SyntaxKind.ClassDeclaration) { - return getReferenceEntryFromNode(declaration); - } - }); + for (const declaration of shorthandSymbol.getDeclarations()) { + if (getMeaningFromDeclaration(declaration) & SemanticMeaning.Value) { + result.push(getReferenceEntryFromNode(declaration)); + } } + + return result; } } @@ -5121,11 +5066,14 @@ namespace ts { return toCheck.getFlags() & (SymbolFlags.Class | SymbolFlags.Interface); } - function isIdentifierOfImplementation(node: Identifier): boolean { + function isNameOfImplementation(node: Node): boolean { const parent = node.parent; - if (isIdentifierName(node) || isFunctionDeclarationIdentifierName(node)) { - // PropertyAccessExpression? + if (isDeclarationName(node)) { + if (isVariableLike(parent)) { + return !!parent.initializer; + } + switch (parent.kind) { case SyntaxKind.FunctionDeclaration: case SyntaxKind.FunctionExpression: @@ -5134,31 +5082,15 @@ namespace ts { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: return !!(parent).body; - case SyntaxKind.PropertyDeclaration: - return !!(parent).initializer; case SyntaxKind.PropertyAssignment: + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + case SyntaxKind.EnumDeclaration: return true; } } - else if (isVariableLike(parent) && parent.name === node) { - return !!parent.initializer; - } - return isIdentifierOfClass(node) || isIdentifierOfEnumDeclaration(node); - } - - function isFunctionDeclarationIdentifierName(node: Identifier): boolean { - return node.parent.kind === SyntaxKind.FunctionDeclaration && - (node.parent).name === node; - } - - function isIdentifierOfClass(node: Identifier) { - return (node.parent.kind === SyntaxKind.ClassDeclaration || node.parent.kind === SyntaxKind.ClassExpression) && - (node.parent).name === node; - } - - function isIdentifierOfEnumDeclaration(node: Identifier) { - return node.parent.kind === SyntaxKind.EnumDeclaration && (node.parent).name === node; + return false; } function isTypeAssertionExpression(node: Node): node is TypeAssertion { @@ -5927,12 +5859,11 @@ namespace ts { if (node.kind === SyntaxKind.SuperKeyword) { return getReferencesForSuperKeyword(node); } - } // `getSymbolAtLocation` normally returns the symbol of the class when given the constructor keyword, - // so we have to specify that we want the constructor symbol. - const symbol = typeChecker.getSymbolAtLocation(node); + // so we have to specify that we want the constructor symbol. + const symbol = typeChecker.getSymbolAtLocation(node); if (!implementations && !symbol && node.kind === SyntaxKind.StringLiteral) { return getReferencesForStringLiteral(node, sourceFiles); @@ -6325,12 +6256,7 @@ namespace ts { /*searchLocationIsConstructor*/ searchLocation.kind === SyntaxKind.ConstructorKeyword, parentSymbols); if (relatedSymbol) { - const referenceEntry = implementations ? getImplementationReferenceEntryForNode(referenceLocation) : getReferenceEntryFromNode(referenceLocation); - - if (referenceEntry) { - const referencedSymbol = getReferencedSymbol(relatedSymbol); - referencedSymbol.references.push(referenceEntry); - } + addReferenceToRelatedSymbol(referenceLocation, relatedSymbol); } /* Because in short-hand property assignment, an identifier which stored as name of the short-hand property assignment * has two meaning : property name and property value. Therefore when we do findAllReference at the position where @@ -6339,11 +6265,7 @@ namespace ts { * position of property accessing, the referenceEntry of such position will be handled in the first case. */ else if (!(referenceSymbol.flags & SymbolFlags.Transient) && searchSymbols.indexOf(shorthandValueSymbol) >= 0) { - const referenceEntry = implementations ? getImplementationReferenceEntryForNode(referenceSymbolDeclaration.name) : getReferenceEntryFromNode(referenceSymbolDeclaration.name); - if (referenceEntry) { - const referencedSymbol = getReferencedSymbol(shorthandValueSymbol); - referencedSymbol.references.push(referenceEntry); - } + addReferenceToRelatedSymbol(referenceSymbolDeclaration.name, shorthandValueSymbol); } else if (searchLocation.kind === SyntaxKind.ConstructorKeyword) { findAdditionalConstructorReferences(referenceSymbol, referenceLocation); @@ -6448,25 +6370,43 @@ namespace ts { return result[index]; } + + function addReferenceToRelatedSymbol(node: Node, relatedSymbol: Symbol) { + if (implementations) { + const referenceEntries = getImplementationReferenceEntryForNode(node); + if (referenceEntries && referenceEntries.length) { + const referencedSymbol = getReferencedSymbol(relatedSymbol); + for (const referenceEntry of referenceEntries) { + referencedSymbol.references.push(referenceEntry); + } + } + } + else { + const referenceEntry = getReferenceEntryFromNode(node); + if (referenceEntry) { + getReferencedSymbol(relatedSymbol).references.push(referenceEntry); + } + } + } } - function getImplementationReferenceEntryForNode(refNode: Node): ReferenceEntry { - // Check to make sure this reference is either part of a sub class or a class that we explicitly - // inherit from in the class hierarchy + function getImplementationReferenceEntryForNode(refNode: Node): ReferenceEntry[] { + // Check if we found a function/propertyAssignment/method with an implementation or initializer + if (isNameOfImplementation(refNode)) { + return [getReferenceEntryFromNode(refNode.parent)]; + } + if (refNode.kind === SyntaxKind.Identifier) { - // Check if we found a function/propertyAssignment/method with an implementation or initializer - if (isIdentifierOfImplementation(refNode)) { - return getReferenceEntryFromNode(refNode.parent); - } - else if (refNode.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { + if (refNode.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { // Go ahead and dereference the shorthand assignment by going to its definition - return getReferenceEntryForShorthandPropertyAssignment(refNode, typeChecker); + const referenceEntries = getReferenceEntryForShorthandPropertyAssignment(refNode, typeChecker); + return referenceEntries && referenceEntries.length ? referenceEntries : undefined; } // Check if the node is within an extends or implements clause const containingHeritageClause = getContainingClassHeritageClause(refNode); if (containingHeritageClause) { - return getReferenceEntryFromNode(containingHeritageClause.parent); + return [getReferenceEntryFromNode(containingHeritageClause.parent)]; } // If we got a type reference, try and see if the reference applies to any expressions that can implement an interface @@ -6474,17 +6414,17 @@ namespace ts { if (containingTypeReference) { const parent = containingTypeReference.parent; if (isVariableLike(parent) && parent.type === containingTypeReference && parent.initializer && isImplementationExpression(parent.initializer)) { - return getReferenceEntryFromNode(parent.initializer); + return [getReferenceEntryFromNode(parent.initializer)]; } else if (isFunctionLike(parent) && parent.type === containingTypeReference && parent.body && parent.body.kind === SyntaxKind.Block) { - return forEachReturnStatement(parent.body, (returnStatement) => { + return [forEachReturnStatement(parent.body, (returnStatement) => { if (returnStatement.expression && isImplementationExpression(returnStatement.expression)) { return getReferenceEntryFromNode(returnStatement.expression); } - }); + })]; } else if (isTypeAssertionExpression(parent) && isImplementationExpression(parent.expression)) { - return getReferenceEntryFromNode(parent.expression); + return [getReferenceEntryFromNode(parent.expression)]; } } } diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts index 71e6266aa20..ca5498c3492 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts @@ -7,6 +7,7 @@ //// } //// //// var bar: Foo = { [|hello: helloImpl|] }; +//// var baz: Foo = { [|"hello": helloImpl|] }; //// //// function helloImpl () {} //// diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts index 7d0be4a38a6..e3db4b5157d 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts @@ -15,7 +15,7 @@ //// } //// //// class SubBar extends Bar { -//// hello() {} +//// [|hello() {}|] //// } diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts index cb32f0203d0..922ea026888 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts @@ -15,6 +15,7 @@ //// //// whatever() { //// super.he/*function_call*/llo(); +//// super["hel/*element_access*/lo"](); //// } //// } //// @@ -28,3 +29,6 @@ goTo.marker("function_call"); verify.allRangesAppearInImplementationList(); + +goTo.marker("element_access"); +verify.allRangesAppearInImplementationList(); diff --git a/tests/cases/fourslash/goToImplementationNamespace_00.ts b/tests/cases/fourslash/goToImplementationNamespace_00.ts index edae50425bd..1f2be487e3f 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_00.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_00.ts @@ -1,12 +1,29 @@ /// -// Should handle calls on namespaces +// Should not return results on namespaces and modules -//// [|namespace Foo { -//// export function hello() {} -//// }|] -//// -//// let x = Fo/*reference*/o; +//// namespace Foo { +//// export function hello() {} +//// } +//// +//// namespace Foo.Bar { +//// export function okay() {} +//// } +//// +//// namespace Baz { +//// export function sure() {} +//// } +//// +//// namespace Baz.Bar { +//// export function alright() {} +//// } +//// +//// let w = Fo/*reference0*/o; +//// let x = Foo.B/*reference1*/ar; +//// let w = Ba/*reference2*/z; +//// let x = Baz.B/*reference3*/ar; -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +for (let i = 0; i < 4; i++) { + goTo.marker("reference" + i); + verify.implementationCountIs(0); +} \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_01.ts b/tests/cases/fourslash/goToImplementationNamespace_01.ts index 4d5b30efa0c..ea24336be7e 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_01.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_01.ts @@ -1,12 +1,12 @@ /// -// Should handle calls on modules +// Should handle property access expressions on namespaces -//// [|module Foo { -//// export function hello() {} -//// }|] +//// namespace Foo { +//// [|export function hello() {}|] +//// } //// -//// let x = Fo/*reference*/o; +//// Foo.hell/*reference*/o(); goTo.marker("reference"); verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_02.ts b/tests/cases/fourslash/goToImplementationNamespace_02.ts index ea24336be7e..c4388df7e8a 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_02.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_02.ts @@ -2,7 +2,7 @@ // Should handle property access expressions on namespaces -//// namespace Foo { +//// module Foo { //// [|export function hello() {}|] //// } //// diff --git a/tests/cases/fourslash/goToImplementationNamespace_03.ts b/tests/cases/fourslash/goToImplementationNamespace_03.ts index c4388df7e8a..38aeb47feae 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_03.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_03.ts @@ -1,12 +1,28 @@ /// -// Should handle property access expressions on namespaces +// Should handle types that are members of a namespace in type references and heritage clauses -//// module Foo { -//// [|export function hello() {}|] -//// } -//// -//// Foo.hell/*reference*/o(); +//// namespace Foo { +//// export interface Bar { +//// hello(): void; +//// } +//// +//// [|class BarImpl implements Bar { +//// hello() {} +//// }|] +//// } +//// +//// [|class Baz implements Foo.Bar { +//// hello() {} +//// }|] +//// +//// var someVar1 : Foo.Bar = [|{ hello: () => {/**1*/} }|]; +//// +//// var someVar2 = [|{ hello: () => {/**2*/} }|]; +//// +//// function whatever(x: Foo.Ba/*reference*/r) { +//// +//// } goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList(); diff --git a/tests/cases/fourslash/goToImplementationNamespace_04.ts b/tests/cases/fourslash/goToImplementationNamespace_04.ts index 5f4267da530..fc64275d906 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_04.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_04.ts @@ -1,26 +1,28 @@ /// -// Should handle sub-namespaces +// Should handle types that are members of a module in type references and heritage clauses -//// /*parentNamespace*/namespace Foo { -//// export function hello() {} +//// module Foo { +//// export interface Bar { +//// hello(): void; +//// } +//// +//// [|class BarImpl implements Bar { +//// hello() {} +//// }|] //// } //// -//// /*parentNamespace2*/namespace Foo./*childNamespace*/Bar { -//// export function okay() {} -//// } +//// [|class Baz implements Foo.Bar { +//// hello() {} +//// }|] //// -//// Fo/*parentReference*/o.hello(); -//// Foo.Ba/*childReference*/r.okay(); +//// var someVar1 : Foo.Bar = [|{ hello: () => {/**1*/} }|]; +//// +//// var someVar2 = [|{ hello: () => {/**2*/} }|]; +//// +//// function whatever(x: Foo.Ba/*reference*/r) { +//// +//// } -goTo.marker("parentReference"); -goTo.implementation(0); -verify.caretAtMarker("parentNamespace"); - -goTo.marker("parentReference"); -goTo.implementation(1); -verify.caretAtMarker("parentNamespace2"); - -goTo.marker("childReference"); -goTo.implementation(); -verify.caretAtMarker("childNamespace") \ No newline at end of file +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); diff --git a/tests/cases/fourslash/goToImplementationNamespace_05.ts b/tests/cases/fourslash/goToImplementationNamespace_05.ts deleted file mode 100644 index 3dfb1fcca49..00000000000 --- a/tests/cases/fourslash/goToImplementationNamespace_05.ts +++ /dev/null @@ -1,26 +0,0 @@ -/// - -// Should handle sub-modules - -//// /*parentModule*/module Foo { -//// export function hello() {} -//// } -//// -//// /*parentModule2*/module Foo./*childModule*/Bar { -//// export function okay() {} -//// } -//// -//// Fo/*parentReference*/o.hello(); -//// Foo.Ba/*childReference*/r.okay(); - -goTo.marker("parentReference"); -goTo.implementation(0); -verify.caretAtMarker("parentModule"); - -goTo.marker("parentReference"); -goTo.implementation(1); -verify.caretAtMarker("parentModule2"); - -goTo.marker("childReference"); -goTo.implementation(); -verify.caretAtMarker("childModule") \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_06.ts b/tests/cases/fourslash/goToImplementationNamespace_06.ts deleted file mode 100644 index 38aeb47feae..00000000000 --- a/tests/cases/fourslash/goToImplementationNamespace_06.ts +++ /dev/null @@ -1,28 +0,0 @@ -/// - -// Should handle types that are members of a namespace in type references and heritage clauses - -//// namespace Foo { -//// export interface Bar { -//// hello(): void; -//// } -//// -//// [|class BarImpl implements Bar { -//// hello() {} -//// }|] -//// } -//// -//// [|class Baz implements Foo.Bar { -//// hello() {} -//// }|] -//// -//// var someVar1 : Foo.Bar = [|{ hello: () => {/**1*/} }|]; -//// -//// var someVar2 = [|{ hello: () => {/**2*/} }|]; -//// -//// function whatever(x: Foo.Ba/*reference*/r) { -//// -//// } - -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); diff --git a/tests/cases/fourslash/goToImplementationNamespace_07.ts b/tests/cases/fourslash/goToImplementationNamespace_07.ts deleted file mode 100644 index fc64275d906..00000000000 --- a/tests/cases/fourslash/goToImplementationNamespace_07.ts +++ /dev/null @@ -1,28 +0,0 @@ -/// - -// Should handle types that are members of a module in type references and heritage clauses - -//// module Foo { -//// export interface Bar { -//// hello(): void; -//// } -//// -//// [|class BarImpl implements Bar { -//// hello() {} -//// }|] -//// } -//// -//// [|class Baz implements Foo.Bar { -//// hello() {} -//// }|] -//// -//// var someVar1 : Foo.Bar = [|{ hello: () => {/**1*/} }|]; -//// -//// var someVar2 = [|{ hello: () => {/**2*/} }|]; -//// -//// function whatever(x: Foo.Ba/*reference*/r) { -//// -//// } - -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); From 9c562f867dc18aa279de0c479b3e9dcca350ed85 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Tue, 6 Sep 2016 17:14:21 -0700 Subject: [PATCH 14/46] Handle multiple return statements that implement interface --- src/services/services.ts | 10 +++++++--- .../cases/fourslash/goToImplementationInterface_02.ts | 7 +++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 013e093336e..b287bd735cd 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -6417,11 +6417,15 @@ namespace ts { return [getReferenceEntryFromNode(parent.initializer)]; } else if (isFunctionLike(parent) && parent.type === containingTypeReference && parent.body && parent.body.kind === SyntaxKind.Block) { - return [forEachReturnStatement(parent.body, (returnStatement) => { + let result: ReferenceEntry[]; + + forEachReturnStatement(parent.body, (returnStatement) => { if (returnStatement.expression && isImplementationExpression(returnStatement.expression)) { - return getReferenceEntryFromNode(returnStatement.expression); + (result || (result = [])).push(getReferenceEntryFromNode(returnStatement.expression)); } - })]; + }); + + return result; } else if (isTypeAssertionExpression(parent) && isImplementationExpression(parent.expression)) { return [getReferenceEntryFromNode(parent.expression)]; diff --git a/tests/cases/fourslash/goToImplementationInterface_02.ts b/tests/cases/fourslash/goToImplementationInterface_02.ts index b22de0e266e..af7f188ffa4 100644 --- a/tests/cases/fourslash/goToImplementationInterface_02.ts +++ b/tests/cases/fourslash/goToImplementationInterface_02.ts @@ -4,7 +4,14 @@ //// interface Fo/*interface_definition*/o { hello: () => void } //// +//// let x: number = 9; +//// //// function createFoo(): Foo { +//// if (x === 2) { +//// return [|{ +//// hello() {} +//// }|]; +//// } //// return [|{ //// hello() {} //// }|]; From 5913a350d7c8ae85569bdd17c15aa8b2759178e8 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Tue, 6 Sep 2016 17:34:41 -0700 Subject: [PATCH 15/46] Updating method name that changed in master --- src/services/services.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index a3b36dccc46..d1177c97414 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -192,8 +192,8 @@ namespace ts { } } // For syntactic classifications, all trivia are classcified together, including jsdoc comments. - // For that to work, the jsdoc comments should still be the leading trivia of the first child. - // Restoring the scanner position ensures that. + // For that to work, the jsdoc comments should still be the leading trivia of the first child. + // Restoring the scanner position ensures that. pos = this.pos; forEachChild(this, processNode, processNodes); if (pos < this.end) { @@ -5027,7 +5027,7 @@ namespace ts { if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { return getReferenceEntryForShorthandPropertyAssignment(node, typeChecker); } - else if (node.kind === SyntaxKind.SuperKeyword || isSuperPropertyOrElementAccess(node.parent)) { + else if (node.kind === SyntaxKind.SuperKeyword || isSuperProperty(node.parent)) { // References to and accesses on the super keyword only have one possible implementation, so no // need to "Find all References" const symbol = typeChecker.getSymbolAtLocation(node); From 60b382d1b33d19a5506d81c13f9b44efae89aa93 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 7 Sep 2016 13:54:52 -0700 Subject: [PATCH 16/46] Correct emit comment for decorated class declaration --- src/compiler/transformers/ts.ts | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index efb247ba663..00441c279c7 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -694,19 +694,21 @@ namespace ts { // let ${name} = ${classExpression} where name is either declaredName if the class doesn't contain self-reference // or decoratedClassAlias if the class contain self-reference. + const transformedClassExpression = createVariableStatement( + /*modifiers*/ undefined, + createLetDeclarationList([ + createVariableDeclaration( + classAlias || declaredName, + /*type*/ undefined, + classExpression + ) + ]), + /*location*/ location + ); + setCommentRange(transformedClassExpression, node); statements.push( setOriginalNode( - createVariableStatement( - /*modifiers*/ undefined, - createLetDeclarationList([ - createVariableDeclaration( - classAlias || declaredName, - /*type*/ undefined, - classExpression - ) - ]), - /*location*/ location - ), + /*node*/ transformedClassExpression, /*original*/ node ) ); From 7d91ac808b71e2a5dc7fd4912d7ede960b866a55 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 7 Sep 2016 13:55:02 -0700 Subject: [PATCH 17/46] Add tests and baselines --- .../commentOnDecoratedClassDeclaration.js | 47 +++++++++++++++++++ ...commentOnDecoratedClassDeclaration.symbols | 26 ++++++++++ .../commentOnDecoratedClassDeclaration.types | 30 ++++++++++++ .../commentOnDecoratedClassDeclaration.ts | 17 +++++++ 4 files changed, 120 insertions(+) create mode 100644 tests/baselines/reference/commentOnDecoratedClassDeclaration.js create mode 100644 tests/baselines/reference/commentOnDecoratedClassDeclaration.symbols create mode 100644 tests/baselines/reference/commentOnDecoratedClassDeclaration.types create mode 100644 tests/cases/compiler/commentOnDecoratedClassDeclaration.ts diff --git a/tests/baselines/reference/commentOnDecoratedClassDeclaration.js b/tests/baselines/reference/commentOnDecoratedClassDeclaration.js new file mode 100644 index 00000000000..44a7047a2ac --- /dev/null +++ b/tests/baselines/reference/commentOnDecoratedClassDeclaration.js @@ -0,0 +1,47 @@ +//// [commentOnDecoratedClassDeclaration.ts] +declare function decorator(x: string): any; + +/** + * Leading trivia + */ +@decorator("hello") +class Remote { } + +/** + * Floating Comment + */ + +@decorator("hi") +class AnotherRomote { + constructor() {} +} + +//// [commentOnDecoratedClassDeclaration.js] +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +/** + * Leading trivia + */ +var Remote = (function () { + function Remote() { + } + return Remote; +}()); +Remote = __decorate([ + decorator("hello") +], Remote); +/** + * Floating Comment + */ +var AnotherRomote = (function () { + function AnotherRomote() { + } + return AnotherRomote; +}()); +AnotherRomote = __decorate([ + decorator("hi") +], AnotherRomote); diff --git a/tests/baselines/reference/commentOnDecoratedClassDeclaration.symbols b/tests/baselines/reference/commentOnDecoratedClassDeclaration.symbols new file mode 100644 index 00000000000..92a21ce23ba --- /dev/null +++ b/tests/baselines/reference/commentOnDecoratedClassDeclaration.symbols @@ -0,0 +1,26 @@ +=== tests/cases/compiler/commentOnDecoratedClassDeclaration.ts === +declare function decorator(x: string): any; +>decorator : Symbol(decorator, Decl(commentOnDecoratedClassDeclaration.ts, 0, 0)) +>x : Symbol(x, Decl(commentOnDecoratedClassDeclaration.ts, 0, 27)) + +/** + * Leading trivia + */ +@decorator("hello") +>decorator : Symbol(decorator, Decl(commentOnDecoratedClassDeclaration.ts, 0, 0)) + +class Remote { } +>Remote : Symbol(Remote, Decl(commentOnDecoratedClassDeclaration.ts, 0, 43)) + +/** + * Floating Comment + */ + +@decorator("hi") +>decorator : Symbol(decorator, Decl(commentOnDecoratedClassDeclaration.ts, 0, 0)) + +class AnotherRomote { +>AnotherRomote : Symbol(AnotherRomote, Decl(commentOnDecoratedClassDeclaration.ts, 6, 16)) + + constructor() {} +} diff --git a/tests/baselines/reference/commentOnDecoratedClassDeclaration.types b/tests/baselines/reference/commentOnDecoratedClassDeclaration.types new file mode 100644 index 00000000000..f4850a0b7b7 --- /dev/null +++ b/tests/baselines/reference/commentOnDecoratedClassDeclaration.types @@ -0,0 +1,30 @@ +=== tests/cases/compiler/commentOnDecoratedClassDeclaration.ts === +declare function decorator(x: string): any; +>decorator : (x: string) => any +>x : string + +/** + * Leading trivia + */ +@decorator("hello") +>decorator("hello") : any +>decorator : (x: string) => any +>"hello" : string + +class Remote { } +>Remote : Remote + +/** + * Floating Comment + */ + +@decorator("hi") +>decorator("hi") : any +>decorator : (x: string) => any +>"hi" : string + +class AnotherRomote { +>AnotherRomote : AnotherRomote + + constructor() {} +} diff --git a/tests/cases/compiler/commentOnDecoratedClassDeclaration.ts b/tests/cases/compiler/commentOnDecoratedClassDeclaration.ts new file mode 100644 index 00000000000..aadf63bf757 --- /dev/null +++ b/tests/cases/compiler/commentOnDecoratedClassDeclaration.ts @@ -0,0 +1,17 @@ +// @experimentalDecorators: true +declare function decorator(x: string): any; + +/** + * Leading trivia + */ +@decorator("hello") +class Remote { } + +/** + * Floating Comment + */ + +@decorator("hi") +class AnotherRomote { + constructor() {} +} \ No newline at end of file From a49ce91e00c356d1a9e28c788a2fad56c003c944 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 7 Sep 2016 16:59:22 -0700 Subject: [PATCH 18/46] Only emit comment only once in module declaration with identifier path name --- src/compiler/transformers/ts.ts | 25 ++++++++++++++++++- ...espaceDeclarationWithIdentifierPathName.js | 20 +++++++++++++++ ...eDeclarationWithIdentifierPathName.symbols | 11 ++++++++ ...aceDeclarationWithIdentifierPathName.types | 11 ++++++++ ...espaceDeclarationWithIdentifierPathName.ts | 6 +++++ 5 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/commentInNamespaceDeclarationWithIdentifierPathName.js create mode 100644 tests/baselines/reference/commentInNamespaceDeclarationWithIdentifierPathName.symbols create mode 100644 tests/baselines/reference/commentInNamespaceDeclarationWithIdentifierPathName.types create mode 100644 tests/cases/compiler/commentInNamespaceDeclarationWithIdentifierPathName.ts diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index efb247ba663..1912370998b 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2859,7 +2859,6 @@ namespace ts { const moduleBlock = getInnerMostModuleDeclarationFromDottedModule(node).body; statementsLocation = moveRangePos(moduleBlock.statements, -1); } - addRange(statements, endLexicalEnvironment()); currentNamespaceContainerName = savedCurrentNamespaceContainerName; @@ -2872,6 +2871,30 @@ namespace ts { /*location*/ blockLocation, /*multiLine*/ true ); + + // namespace hello.hi.world { + // function foo() {} + // + // // TODO, blah + // } + // + // should be emitted as + // + // var hello; + // (function (hello) { + // var hi; + // (function (hi) { + // var world; + // (function (world) { + // function foo() { } + // // TODO, blah + // })(world = hi.world || (hi.world = {})); + // })(hi = hello.hi || (hello.hi = {})); + // })(hello || (hello = {})); + // so if the block is a transformed module declaration, turn off the comment emit + if (body.kind !== SyntaxKind.ModuleBlock) { + setNodeEmitFlags(block, block.emitFlags | NodeEmitFlags.NoComments); + } return block; } diff --git a/tests/baselines/reference/commentInNamespaceDeclarationWithIdentifierPathName.js b/tests/baselines/reference/commentInNamespaceDeclarationWithIdentifierPathName.js new file mode 100644 index 00000000000..6f99037a61d --- /dev/null +++ b/tests/baselines/reference/commentInNamespaceDeclarationWithIdentifierPathName.js @@ -0,0 +1,20 @@ +//// [commentInNamespaceDeclarationWithIdentifierPathName.ts] +namespace hello.hi.world +{ + function foo() {} + + // TODO, blah +} + +//// [commentInNamespaceDeclarationWithIdentifierPathName.js] +var hello; +(function (hello) { + var hi; + (function (hi) { + var world; + (function (world) { + function foo() { } + // TODO, blah + })(world = hi.world || (hi.world = {})); + })(hi = hello.hi || (hello.hi = {})); +})(hello || (hello = {})); diff --git a/tests/baselines/reference/commentInNamespaceDeclarationWithIdentifierPathName.symbols b/tests/baselines/reference/commentInNamespaceDeclarationWithIdentifierPathName.symbols new file mode 100644 index 00000000000..6db54887737 --- /dev/null +++ b/tests/baselines/reference/commentInNamespaceDeclarationWithIdentifierPathName.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/commentInNamespaceDeclarationWithIdentifierPathName.ts === +namespace hello.hi.world +>hello : Symbol(hello, Decl(commentInNamespaceDeclarationWithIdentifierPathName.ts, 0, 0)) +>hi : Symbol(hi, Decl(commentInNamespaceDeclarationWithIdentifierPathName.ts, 0, 16)) +>world : Symbol(world, Decl(commentInNamespaceDeclarationWithIdentifierPathName.ts, 0, 19)) +{ + function foo() {} +>foo : Symbol(foo, Decl(commentInNamespaceDeclarationWithIdentifierPathName.ts, 1, 1)) + + // TODO, blah +} diff --git a/tests/baselines/reference/commentInNamespaceDeclarationWithIdentifierPathName.types b/tests/baselines/reference/commentInNamespaceDeclarationWithIdentifierPathName.types new file mode 100644 index 00000000000..6a5064e2700 --- /dev/null +++ b/tests/baselines/reference/commentInNamespaceDeclarationWithIdentifierPathName.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/commentInNamespaceDeclarationWithIdentifierPathName.ts === +namespace hello.hi.world +>hello : typeof hello +>hi : typeof hi +>world : typeof world +{ + function foo() {} +>foo : () => void + + // TODO, blah +} diff --git a/tests/cases/compiler/commentInNamespaceDeclarationWithIdentifierPathName.ts b/tests/cases/compiler/commentInNamespaceDeclarationWithIdentifierPathName.ts new file mode 100644 index 00000000000..a5a32e53502 --- /dev/null +++ b/tests/cases/compiler/commentInNamespaceDeclarationWithIdentifierPathName.ts @@ -0,0 +1,6 @@ +namespace hello.hi.world +{ + function foo() {} + + // TODO, blah +} \ No newline at end of file From 9d63c5a35eb3bab10ea1545cfc293facac6049c9 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 7 Sep 2016 18:02:45 -0700 Subject: [PATCH 19/46] Only emit comment once for export enum declaration --- src/compiler/transformers/module/module.ts | 16 ++++++++-------- .../commentOnExportEnumDeclaration.js | 19 +++++++++++++++++++ .../commentOnExportEnumDeclaration.symbols | 12 ++++++++++++ .../commentOnExportEnumDeclaration.types | 12 ++++++++++++ .../commentOnExportEnumDeclaration.ts | 6 ++++++ 5 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 tests/baselines/reference/commentOnExportEnumDeclaration.js create mode 100644 tests/baselines/reference/commentOnExportEnumDeclaration.symbols create mode 100644 tests/baselines/reference/commentOnExportEnumDeclaration.types create mode 100644 tests/cases/compiler/commentOnExportEnumDeclaration.ts diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 144420b7ae9..17a5a9f0d89 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -802,17 +802,17 @@ namespace ts { * Adds a trailing VariableStatement for an enum or module declaration. */ function addVarForExportedEnumOrNamespaceDeclaration(statements: Statement[], node: EnumDeclaration | ModuleDeclaration) { - statements.push( - createVariableStatement( - /*modifiers*/ undefined, - [createVariableDeclaration( - getDeclarationName(node), + const transformedStatement = createVariableStatement( + /*modifiers*/ undefined, + [createVariableDeclaration( + getDeclarationName(node), /*type*/ undefined, - createPropertyAccess(createIdentifier("exports"), getDeclarationName(node)) - )], + createPropertyAccess(createIdentifier("exports"), getDeclarationName(node)) + )], /*location*/ node - ) ); + setNodeEmitFlags(transformedStatement, NodeEmitFlags.NoComments); + statements.push(transformedStatement); } function getDeclarationName(node: DeclarationStatement) { diff --git a/tests/baselines/reference/commentOnExportEnumDeclaration.js b/tests/baselines/reference/commentOnExportEnumDeclaration.js new file mode 100644 index 00000000000..6ded51456d8 --- /dev/null +++ b/tests/baselines/reference/commentOnExportEnumDeclaration.js @@ -0,0 +1,19 @@ +//// [commentOnExportEnumDeclaration.ts] +/** + * comment + */ +export enum Color { + r, g, b +} + +//// [commentOnExportEnumDeclaration.js] +"use strict"; +/** + * comment + */ +(function (Color) { + Color[Color["r"] = 0] = "r"; + Color[Color["g"] = 1] = "g"; + Color[Color["b"] = 2] = "b"; +})(exports.Color || (exports.Color = {})); +var Color = exports.Color; diff --git a/tests/baselines/reference/commentOnExportEnumDeclaration.symbols b/tests/baselines/reference/commentOnExportEnumDeclaration.symbols new file mode 100644 index 00000000000..76cb7173703 --- /dev/null +++ b/tests/baselines/reference/commentOnExportEnumDeclaration.symbols @@ -0,0 +1,12 @@ +=== tests/cases/compiler/commentOnExportEnumDeclaration.ts === +/** + * comment + */ +export enum Color { +>Color : Symbol(Color, Decl(commentOnExportEnumDeclaration.ts, 0, 0)) + + r, g, b +>r : Symbol(Color.r, Decl(commentOnExportEnumDeclaration.ts, 3, 19)) +>g : Symbol(Color.g, Decl(commentOnExportEnumDeclaration.ts, 4, 6)) +>b : Symbol(Color.b, Decl(commentOnExportEnumDeclaration.ts, 4, 9)) +} diff --git a/tests/baselines/reference/commentOnExportEnumDeclaration.types b/tests/baselines/reference/commentOnExportEnumDeclaration.types new file mode 100644 index 00000000000..522e1175540 --- /dev/null +++ b/tests/baselines/reference/commentOnExportEnumDeclaration.types @@ -0,0 +1,12 @@ +=== tests/cases/compiler/commentOnExportEnumDeclaration.ts === +/** + * comment + */ +export enum Color { +>Color : Color + + r, g, b +>r : Color +>g : Color +>b : Color +} diff --git a/tests/cases/compiler/commentOnExportEnumDeclaration.ts b/tests/cases/compiler/commentOnExportEnumDeclaration.ts new file mode 100644 index 00000000000..d9a120492ff --- /dev/null +++ b/tests/cases/compiler/commentOnExportEnumDeclaration.ts @@ -0,0 +1,6 @@ +/** + * comment + */ +export enum Color { + r, g, b +} \ No newline at end of file From 1cdd1d35a378d837a579fb497c34b38721fee11e Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Fri, 9 Sep 2016 15:13:51 -0700 Subject: [PATCH 20/46] Code cleanup and a few edge cases --- src/harness/fourslash.ts | 58 ++++++- src/services/services.ts | 159 ++++++++---------- .../goToImplementationInterface_00.ts | 1 + .../goToImplementationInterface_07.ts | 29 ++++ .../fourslash/goToImplementationLocal_06.ts | 8 + .../fourslash/goToImplementationLocal_07.ts | 8 + .../fourslash/goToImplementationLocal_08.ts | 8 + .../goToImplementationNamespace_00.ts | 25 +-- .../goToImplementationNamespace_05.ts | 22 +++ .../goToImplementationNamespace_06.ts | 13 ++ 10 files changed, 217 insertions(+), 114 deletions(-) create mode 100644 tests/cases/fourslash/goToImplementationInterface_07.ts create mode 100644 tests/cases/fourslash/goToImplementationLocal_06.ts create mode 100644 tests/cases/fourslash/goToImplementationLocal_07.ts create mode 100644 tests/cases/fourslash/goToImplementationLocal_08.ts create mode 100644 tests/cases/fourslash/goToImplementationNamespace_05.ts create mode 100644 tests/cases/fourslash/goToImplementationNamespace_06.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index f45d27c59f3..94e67cf981c 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -88,6 +88,10 @@ namespace FourSlash { marker?: Marker; } + interface ImplementationLocationInformation extends ts.ImplementationLocation { + matched?: boolean; + } + export interface TextSpan { start: number; end: number; @@ -1693,45 +1697,87 @@ namespace FourSlash { assert.equal(actualDefinitionContainerName, expectedContainerName, this.messageAtLastKnownMarker("Definition Info Container Name")); } - public goToImplementation(implIndex: number) { + public goToImplementation(implIndex?: number) { const implementations = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (!implementations || !implementations.length) { this.raiseError("goToImplementation failed - expected to at least one implementation location but got 0"); } + if (implIndex === undefined && implementations.length > 1) { + this.raiseError(`goToImplementation failed - no index given but more than 1 implementation returned (${implementations.length})`); + } + if (implIndex >= implementations.length) { this.raiseError(`goToImplementation failed - implIndex value (${implIndex}) exceeds implementation list size (${implementations.length})`); } - const implementation = implementations[implIndex]; + const implementation = implementations[implIndex || 0]; this.openFile(implementation.fileName); this.currentCaretPosition = implementation.textSpan.start; } public verifyRangesInImplementationList() { - const implementations = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition); + const implementations: ImplementationLocationInformation[] = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (!implementations || !implementations.length) { this.raiseError("verifyRangesInImplementationList failed - expected to at least one implementation location but got 0"); } + for (let i = 0; i < implementations.length; i++) { + for (let j = 0; j < implementations.length; j++) { + if (i !== j && implementationsAreEqual(implementations[i], implementations[j])) { + const { textSpan, fileName } = implementations[i]; + const end = textSpan.start + textSpan.length; + this.raiseError(`Duplicate implementations returned for range (${textSpan.start}, ${end}) in ${fileName}`); + } + } + } + const ranges = this.getRanges(); if (!ranges || !ranges.length) { this.raiseError("verifyRangesInImplementationList failed - expected to at least one range in test source"); } + const unsatisfiedRanges: Range[] = []; + for (const range of ranges) { let rangeIsPresent = false; const length = range.end - range.start; for (const impl of implementations) { if (range.fileName === impl.fileName && range.start === impl.textSpan.start && length === impl.textSpan.length) { + impl.matched = true; rangeIsPresent = true; break; } } - assert.isTrue(rangeIsPresent, `No implementation found for range ${range.start}, ${range.end} in ${range.fileName}: ${this.rangeText(range)}`); + if (!rangeIsPresent) { + unsatisfiedRanges.push(range); + } + } + + const unmatchedImplementations = implementations.filter(impl => !impl.matched); + if (unmatchedImplementations.length || unsatisfiedRanges.length) { + let error = "Not all ranges or implementations are satisfied"; + if (unsatisfiedRanges.length) { + error += "\nUnsatisfied ranges:"; + for (const range of unsatisfiedRanges) { + error += `\n (${range.start}, ${range.end}) in ${range.fileName}: ${this.rangeText(range)}`; + } + } + + if (unsatisfiedRanges.length) { + error += "\nUnmatched implementations:"; + for (const impl of unmatchedImplementations) { + const end = impl.textSpan.start + impl.textSpan.length; + error += `\n (${impl.textSpan.start}, ${end}) in ${impl.fileName}: ${this.getFileContent(impl.fileName).slice(impl.textSpan.start, end)}`; + } + } + this.raiseError(error); + } + + function implementationsAreEqual(a: ImplementationLocationInformation, b: ImplementationLocationInformation) { + return a.fileName === b.fileName && TestState.textSpansEqual(a.textSpan, b.textSpan); } - assert.equal(implementations.length, ranges.length, `Different number of implementations (${implementations.length}) and ranges (${ranges.length})`); } public getMarkers(): Marker[] { @@ -2911,7 +2957,7 @@ namespace FourSlashInterface { this.state.goToTypeDefinition(definitionIndex); } - public implementation(implementationIndex = 0) { + public implementation(implementationIndex?: number) { this.state.goToImplementation(implementationIndex); } diff --git a/src/services/services.ts b/src/services/services.ts index d1177c97414..568b92f5c06 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -5025,7 +5025,9 @@ namespace ts { // If invoked directly on a shorthand property assignment, then return // the declaration of the symbol being assigned (not the symbol being assigned to). if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { - return getReferenceEntryForShorthandPropertyAssignment(node, typeChecker); + const result: ReferenceEntry[] = []; + getReferenceEntryForShorthandPropertyAssignment(node, typeChecker, result); + return result.length > 0 ? result : undefined; } else if (node.kind === SyntaxKind.SuperKeyword || isSuperProperty(node.parent)) { // References to and accesses on the super keyword only have one possible implementation, so no @@ -5054,47 +5056,42 @@ namespace ts { } } - function getReferenceEntryForShorthandPropertyAssignment(node: Node, typeChecker: TypeChecker) { + function getReferenceEntryForShorthandPropertyAssignment(node: Node, typeChecker: TypeChecker, result: ReferenceEntry[]): void { const refSymbol = typeChecker.getSymbolAtLocation(node); const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(refSymbol.valueDeclaration); if (shorthandSymbol) { - const result: ReferenceEntry[] = []; - for (const declaration of shorthandSymbol.getDeclarations()) { if (getMeaningFromDeclaration(declaration) & SemanticMeaning.Value) { result.push(getReferenceEntryFromNode(declaration)); } } - - return result; } } - function isClassOrInterfaceReference(toCheck: Symbol) { - return toCheck.getFlags() & (SymbolFlags.Class | SymbolFlags.Interface); - } - function isNameOfImplementation(node: Node): boolean { const parent = node.parent; if (isDeclarationName(node)) { if (isVariableLike(parent)) { + if (parent.kind === SyntaxKind.VariableDeclaration) { + const parentStatement = parent.parent && parent.parent.parent; + if (parentStatement && hasModifier(parentStatement, ModifierFlags.Ambient)) { + return true; + } + } return !!parent.initializer; } + else if (isFunctionLike(parent)) { + return !!parent.body || hasModifier(parent, ModifierFlags.Ambient); + } switch (parent.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return !!(parent).body; case SyntaxKind.PropertyAssignment: case SyntaxKind.ClassDeclaration: case SyntaxKind.ClassExpression: case SyntaxKind.EnumDeclaration: + case SyntaxKind.ModuleDeclaration: return true; } } @@ -5870,9 +5867,9 @@ namespace ts { } } - // `getSymbolAtLocation` normally returns the symbol of the class when given the constructor keyword, - // so we have to specify that we want the constructor symbol. - const symbol = typeChecker.getSymbolAtLocation(node); + // `getSymbolAtLocation` normally returns the symbol of the class when given the constructor keyword, + // so we have to specify that we want the constructor symbol. + const symbol = typeChecker.getSymbolAtLocation(node); if (!implementations && !symbol && node.kind === SyntaxKind.StringLiteral) { return getReferencesForStringLiteral(node, sourceFiles); @@ -5908,11 +5905,9 @@ namespace ts { // Maps from a symbol ID to the ReferencedSymbol entry in 'result'. const symbolToIndex: number[] = []; - const indexToSymbol: {[index: number]: Symbol} = {}; - if (scope) { result = []; - getReferencesInNode(scope, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex, indexToSymbol); + getReferencesInNode(scope, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex); } else { const internedName = getInternedName(symbol, node, declarations); @@ -5923,7 +5918,7 @@ namespace ts { if (nameTable[internedName] !== undefined) { result = result || []; - getReferencesInNode(sourceFile, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex, indexToSymbol); + getReferencesInNode(sourceFile, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex); } } } @@ -6195,8 +6190,7 @@ namespace ts { findInStrings: boolean, findInComments: boolean, result: ReferencedSymbol[], - symbolToIndex: number[], - indexToSymbol: {[index: number]: Symbol}): void { + symbolToIndex: number[]): void { const sourceFile = container.getSourceFile(); @@ -6207,16 +6201,17 @@ namespace ts { // symbol of the local type of the symbol the property is being accessed on. This is because our search // symbol may have a different parent symbol if the local type's symbol does not declare the property // being accessed (i.e. it is declared in some parent class or interface) - let parentSymbols: SymbolInheritanceState[] = undefined; + let parents: Symbol[]; + const cache: Map = createMap(); if (implementations && isRightSideOfPropertyAccess(searchLocation)) { const localParentType = typeChecker.getTypeAtLocation((searchLocation.parent).expression); if (localParentType) { - if (localParentType.symbol && isClassOrInterfaceReference(localParentType.symbol) && localParentType.symbol.parent !== searchSymbol.parent) { - parentSymbols = [createSymbolInheritanceState(localParentType.symbol)]; + if (localParentType.symbol && localParentType.symbol.getFlags() & (SymbolFlags.Class | SymbolFlags.Interface) && localParentType.symbol !== searchSymbol.parent) { + parents = [localParentType.symbol]; } else if (localParentType.getFlags() & TypeFlags.UnionOrIntersection) { - parentSymbols = map(getSymbolsForComponentTypes(localParentType), createSymbolInheritanceState); + parents = getSymbolsForComponentTypes(localParentType); } } } @@ -6229,12 +6224,12 @@ namespace ts { cancellationToken.throwIfCancellationRequested(); const referenceLocation = getTouchingPropertyName(sourceFile, position); - if (!implementations && !isValidReferencePosition(referenceLocation, searchText)) { + if (!isValidReferencePosition(referenceLocation, searchText)) { // This wasn't the start of a token. Check to see if it might be a // match in a comment or string if that's what the caller is asking // for. - if ((findInStrings && isInString(sourceFile, position)) || - (findInComments && isInNonReferenceComment(sourceFile, position))) { + if (!implementations && ((findInStrings && isInString(sourceFile, position)) || + (findInComments && isInNonReferenceComment(sourceFile, position)))) { // In the case where we're looking inside comments/strings, we don't have // an actual definition. So just use 'undefined' here. Features like @@ -6262,7 +6257,7 @@ namespace ts { const referenceSymbolDeclaration = referenceSymbol.valueDeclaration; const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); const relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation, - /*searchLocationIsConstructor*/ searchLocation.kind === SyntaxKind.ConstructorKeyword, parentSymbols); + /*searchLocationIsConstructor*/ searchLocation.kind === SyntaxKind.ConstructorKeyword, parents, cache); if (relatedSymbol) { addReferenceToRelatedSymbol(referenceLocation, relatedSymbol); @@ -6369,7 +6364,6 @@ namespace ts { if (index === undefined) { index = result.length; symbolToIndex[symbolId] = index; - indexToSymbol[index] = symbol; result.push({ definition: getDefinition(symbol), @@ -6381,41 +6375,32 @@ namespace ts { } function addReferenceToRelatedSymbol(node: Node, relatedSymbol: Symbol) { + const references = getReferencedSymbol(relatedSymbol).references; if (implementations) { - const referenceEntries = getImplementationReferenceEntryForNode(node); - if (referenceEntries && referenceEntries.length) { - const referencedSymbol = getReferencedSymbol(relatedSymbol); - for (const referenceEntry of referenceEntries) { - referencedSymbol.references.push(referenceEntry); - } - } + getImplementationReferenceEntryForNode(node, references); } else { - const referenceEntry = getReferenceEntryFromNode(node); - if (referenceEntry) { - getReferencedSymbol(relatedSymbol).references.push(referenceEntry); - } + references.push(getReferenceEntryFromNode(node)); } } } - function getImplementationReferenceEntryForNode(refNode: Node): ReferenceEntry[] { + function getImplementationReferenceEntryForNode(refNode: Node, result: ReferenceEntry[]): void { // Check if we found a function/propertyAssignment/method with an implementation or initializer if (isNameOfImplementation(refNode)) { - return [getReferenceEntryFromNode(refNode.parent)]; + result.push(getReferenceEntryFromNode(refNode.parent)); } - - if (refNode.kind === SyntaxKind.Identifier) { + else if (refNode.kind === SyntaxKind.Identifier) { if (refNode.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { // Go ahead and dereference the shorthand assignment by going to its definition - const referenceEntries = getReferenceEntryForShorthandPropertyAssignment(refNode, typeChecker); - return referenceEntries && referenceEntries.length ? referenceEntries : undefined; + getReferenceEntryForShorthandPropertyAssignment(refNode, typeChecker, result); } // Check if the node is within an extends or implements clause const containingHeritageClause = getContainingClassHeritageClause(refNode); if (containingHeritageClause) { - return [getReferenceEntryFromNode(containingHeritageClause.parent)]; + result.push(getReferenceEntryFromNode(containingHeritageClause.parent)); + return; } // If we got a type reference, try and see if the reference applies to any expressions that can implement an interface @@ -6423,21 +6408,17 @@ namespace ts { if (containingTypeReference) { const parent = containingTypeReference.parent; if (isVariableLike(parent) && parent.type === containingTypeReference && parent.initializer && isImplementationExpression(parent.initializer)) { - return [getReferenceEntryFromNode(parent.initializer)]; + result.push(getReferenceEntryFromNode(parent.initializer)); } else if (isFunctionLike(parent) && parent.type === containingTypeReference && parent.body && parent.body.kind === SyntaxKind.Block) { - let result: ReferenceEntry[]; - forEachReturnStatement(parent.body, (returnStatement) => { if (returnStatement.expression && isImplementationExpression(returnStatement.expression)) { - (result || (result = [])).push(getReferenceEntryFromNode(returnStatement.expression)); + result.push(getReferenceEntryFromNode(returnStatement.expression)); } }); - - return result; } else if (isTypeAssertionExpression(parent) && isImplementationExpression(parent.expression)) { - return [getReferenceEntryFromNode(parent.expression)]; + result.push(getReferenceEntryFromNode(parent.expression)); } } } @@ -6456,16 +6437,16 @@ namespace ts { } function getContainingTypeReference(node: Node): Node { - if (node) { - if (node.kind === SyntaxKind.TypeReference) { - return node; - } + let topLevelTypeReference: Node = undefined; - if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) { - return getContainingTypeReference(node.parent); + while (node) { + if (isTypeNode(node)) { + topLevelTypeReference = node; } + node = node.parent; } - return undefined; + + return topLevelTypeReference; } function getContainingClassHeritageClause(node: Node): HeritageClause { @@ -6495,7 +6476,8 @@ namespace ts { return node.kind === SyntaxKind.ArrowFunction || node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ObjectLiteralExpression || - node.kind === SyntaxKind.ClassExpression; + node.kind === SyntaxKind.ClassExpression || + node.kind === SyntaxKind.ArrayLiteralExpression; } /** @@ -6510,19 +6492,21 @@ namespace ts { * @param parent Another class or interface Symbol * @param cachedResults A map of symbol names to booleans indicating previous results */ - function inheritsFrom(child: Symbol, parent: Symbol, cachedResults: Map = createMap()): boolean { + function inheritsFrom(child: Symbol, parent: Symbol, cachedResults: Map): boolean { const parentIsInterface = parent.getFlags() & SymbolFlags.Interface; - return searchHierarchy(child, cachedResults); + return searchHierarchy(child); - function searchHierarchy(symbol: Symbol, cachedResults: Map): boolean { + function searchHierarchy(symbol: Symbol): boolean { if (symbol === parent) { return true; } - else if (symbol.name in cachedResults) { - return cachedResults[symbol.name]; + + const key = getSymbolId(symbol) + "," + getSymbolId(parent); + if (key in cachedResults) { + return cachedResults[key]; } - cachedResults[symbol.name] = false; + cachedResults[key] = false; const inherits = forEach(symbol.getDeclarations(), (declaration) => { if (isClassLike(declaration)) { @@ -6530,44 +6514,37 @@ namespace ts { const interfaceReferences = getClassImplementsHeritageClauseElements(declaration); if (interfaceReferences) { for (const typeReference of interfaceReferences) { - if (searchTypeReference(typeReference, cachedResults)) { + if (searchTypeReference(typeReference)) { return true; } } } } - return searchTypeReference(getClassExtendsHeritageClauseElement(declaration), cachedResults); + return searchTypeReference(getClassExtendsHeritageClauseElement(declaration)); } else if (declaration.kind === SyntaxKind.InterfaceDeclaration) { if (parentIsInterface) { - return forEach(getInterfaceBaseTypeNodes(declaration), base => searchTypeReference(base, cachedResults)); + return forEach(getInterfaceBaseTypeNodes(declaration), searchTypeReference); } } return false; }); - cachedResults[symbol.name] = inherits; + cachedResults[key] = inherits; return inherits; } - function searchTypeReference(typeReference: ExpressionWithTypeArguments, cachedResults: Map): boolean { + function searchTypeReference(typeReference: ExpressionWithTypeArguments): boolean { if (typeReference) { const type = typeChecker.getTypeAtLocation(typeReference); if (type && type.symbol) { - return searchHierarchy(type.symbol, cachedResults); + return searchHierarchy(type.symbol); } } return false; } } - function createSymbolInheritanceState(symbol: Symbol): SymbolInheritanceState { - return { - symbol, - cachedInheritanceResults: createMap() - }; - } - function getReferencesForSuperKeyword(superKeyword: Node): ReferencedSymbol[] { let searchSpaceNode = getSuperContainer(superKeyword, /*stopOnFunctions*/ false); if (!searchSpaceNode) { @@ -6922,7 +6899,7 @@ namespace ts { } } - function getRelatedSymbol(searchSymbols: Symbol[], referenceSymbol: Symbol, referenceLocation: Node, searchLocationIsConstructor: boolean, parentSymbols: SymbolInheritanceState[]): Symbol { + function getRelatedSymbol(searchSymbols: Symbol[], referenceSymbol: Symbol, referenceLocation: Node, searchLocationIsConstructor: boolean, parents: Symbol[], cache: Map): Symbol { if (contains(searchSymbols, referenceSymbol)) { // If we are searching for constructor uses, they must be 'new' expressions. return (!searchLocationIsConstructor || isNewExpressionTarget(referenceLocation)) && referenceSymbol; @@ -6932,7 +6909,7 @@ namespace ts { // symbols but by looking up for related symbol of this alias so it can handle multiple level of indirectness. const aliasSymbol = getAliasSymbolForPropertyNameSymbol(referenceSymbol, referenceLocation); if (aliasSymbol) { - return getRelatedSymbol(searchSymbols, aliasSymbol, referenceLocation, searchLocationIsConstructor, parentSymbols); + return getRelatedSymbol(searchSymbols, aliasSymbol, referenceLocation, searchLocationIsConstructor, parents, cache); } // If the reference location is in an object literal, try to get the contextual type for the @@ -6978,8 +6955,8 @@ namespace ts { // see if any is in the list. If we were passed a parent symbol, only include types that are subtypes of the // parent symbol if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { - if (parentSymbols) { - if (!forEach(parentSymbols, ({symbol, cachedInheritanceResults}) => inheritsFrom(rootSymbol.parent, symbol, cachedInheritanceResults))) { + if (parents) { + if (!forEach(parents, parent => inheritsFrom(rootSymbol.parent, parent, cache))) { return undefined; } } diff --git a/tests/cases/fourslash/goToImplementationInterface_00.ts b/tests/cases/fourslash/goToImplementationInterface_00.ts index 6e8ca5f3179..fc9f6aace07 100644 --- a/tests/cases/fourslash/goToImplementationInterface_00.ts +++ b/tests/cases/fourslash/goToImplementationInterface_00.ts @@ -9,6 +9,7 @@ //// interface Baz extends Foo {} //// //// var bar: Foo = [|{ hello: helloImpl /**0*/ }|]; +//// var baz: Foo[] = [|[{ hello: helloImpl /**4*/ }]|]; //// //// function helloImpl () {} //// diff --git a/tests/cases/fourslash/goToImplementationInterface_07.ts b/tests/cases/fourslash/goToImplementationInterface_07.ts new file mode 100644 index 00000000000..c14a98f9185 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterface_07.ts @@ -0,0 +1,29 @@ +/// + +// Should handle all the various type references + +//// interface Fo/*interface_definition*/o { +//// hello (): void; +//// } +//// +//// interface Bar { +//// hello (): void; +//// } +//// +//// let x1: Foo = [|{ hello () { /**typeReference*/ } }|]; +//// let x2: () => Foo = [|(() => { hello () { /**functionType*/} })|]; +//// let x3: Foo | Bar = [|{ hello () { /**unionType*/} }|]; +//// let x4: Foo & Bar = [|{ hello () { /**intersectionType*/} }|]; +//// let x5: [Foo] = [|[{ hello () { /**tupleType*/} }]|]; +//// let x6: (Foo) = [|{ hello () { /**parenthesizedType*/} }|]; +//// let x7: (new() => Foo) = [|class { hello () { /**constructorType*/} }|]; +//// let x8: Foo[] = [|[{ hello () { /**arrayType*/} }]|]; +//// let x9: { y: Foo } = [|{ y: { hello () { /**typeLiteral*/} } }|]; +//// +//// // Should not do anything for type predicates +//// function isFoo(a: any): a is Foo { +//// return true; +//// } + +goTo.marker("interface_definition"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_06.ts b/tests/cases/fourslash/goToImplementationLocal_06.ts new file mode 100644 index 00000000000..74ef1d77866 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationLocal_06.ts @@ -0,0 +1,8 @@ +/// + +// Should be able to go to ambient variable declarations + +//// declare var [|someVar: string|]; +//// someVa/*reference*/r +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_07.ts b/tests/cases/fourslash/goToImplementationLocal_07.ts new file mode 100644 index 00000000000..53159a45810 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationLocal_07.ts @@ -0,0 +1,8 @@ +/// + +// Should be able to go to ambient function declarations + +//// [|declare function someFunction(): () => void;|] +//// someFun/*reference*/ction(); +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_08.ts b/tests/cases/fourslash/goToImplementationLocal_08.ts new file mode 100644 index 00000000000..53159a45810 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationLocal_08.ts @@ -0,0 +1,8 @@ +/// + +// Should be able to go to ambient function declarations + +//// [|declare function someFunction(): () => void;|] +//// someFun/*reference*/ction(); +goTo.marker("reference"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_00.ts b/tests/cases/fourslash/goToImplementationNamespace_00.ts index 1f2be487e3f..5b71b7bbf9f 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_00.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_00.ts @@ -1,29 +1,20 @@ /// -// Should not return results on namespaces and modules +// Should handle namespace and module implementations -//// namespace Foo { +//// /*implementation0*/namespace Foo { //// export function hello() {} //// } //// -//// namespace Foo.Bar { -//// export function okay() {} -//// } -//// -//// namespace Baz { +//// /*implementation1*/module Bar { //// export function sure() {} //// } //// -//// namespace Baz.Bar { -//// export function alright() {} -//// } -//// -//// let w = Fo/*reference0*/o; -//// let x = Foo.B/*reference1*/ar; -//// let w = Ba/*reference2*/z; -//// let x = Baz.B/*reference3*/ar; +//// let x = Fo/*reference0*/o; +//// let y = Ba/*reference1*/r; -for (let i = 0; i < 4; i++) { +for (let i = 0; i < 2; i ++) { goTo.marker("reference" + i); - verify.implementationCountIs(0); + goTo.implementation(); + verify.caretAtMarker("implementation" + i); } \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_05.ts b/tests/cases/fourslash/goToImplementationNamespace_05.ts new file mode 100644 index 00000000000..6936b79bd9b --- /dev/null +++ b/tests/cases/fourslash/goToImplementationNamespace_05.ts @@ -0,0 +1,22 @@ +/// + +// Should handle namespace and module implementations with qualified names + +//// /*implementation0*/namespace Foo./*implementation2*/Baz { +//// export function hello() {} +//// } +//// +//// /*implementation1*/module Bar./*implementation3*/Baz { +//// export function sure() {} +//// } +//// +//// let x = Fo/*reference0*/o; +//// let y = Ba/*reference1*/r; +//// let x1 = Foo.B/*reference2*/az; +//// let y1 = Bar.B/*reference3*/az; + +for (let i = 0; i < 4; i ++) { + goTo.marker("reference" + i); + goTo.implementation(); + verify.caretAtMarker("implementation" + i); +} \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_06.ts b/tests/cases/fourslash/goToImplementationNamespace_06.ts new file mode 100644 index 00000000000..68b4898c6f7 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationNamespace_06.ts @@ -0,0 +1,13 @@ +/// + +// Should handle type queries + +//// [|namespace F/*declaration*/oo { +//// declare function hello(): void; +//// }|] +//// +//// +//// let x: typeof Foo = [|{ hello() {} }|]; + +goTo.marker("declaration"); +verify.allRangesAppearInImplementationList(); \ No newline at end of file From 2069e1cb0cb9f1054fceacab5a2def1e23603a9c Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Fri, 9 Sep 2016 16:24:09 -0700 Subject: [PATCH 21/46] Prevent duplicate entries from type references --- src/services/services.ts | 17 ++++++++++++++--- .../fourslash/goToImplementationInterface_07.ts | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 568b92f5c06..80cb181a643 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -6408,20 +6408,31 @@ namespace ts { if (containingTypeReference) { const parent = containingTypeReference.parent; if (isVariableLike(parent) && parent.type === containingTypeReference && parent.initializer && isImplementationExpression(parent.initializer)) { - result.push(getReferenceEntryFromNode(parent.initializer)); + maybeAdd(getReferenceEntryFromNode(parent.initializer)); } else if (isFunctionLike(parent) && parent.type === containingTypeReference && parent.body && parent.body.kind === SyntaxKind.Block) { forEachReturnStatement(parent.body, (returnStatement) => { if (returnStatement.expression && isImplementationExpression(returnStatement.expression)) { - result.push(getReferenceEntryFromNode(returnStatement.expression)); + maybeAdd(getReferenceEntryFromNode(returnStatement.expression)); } }); } else if (isTypeAssertionExpression(parent) && isImplementationExpression(parent.expression)) { - result.push(getReferenceEntryFromNode(parent.expression)); + maybeAdd(getReferenceEntryFromNode(parent.expression)); } } } + + // Type nodes can contain multiple references to the same type. For example: + // let x: Foo & (Foo & Bar) = ... + // Because we are returning the implementation locations and not the identifier locations, + // duplicate entries would be returned here as each of the type references is part of + // the same implementation. For that reason, check before we add a new entry + function maybeAdd(a: ReferenceEntry) { + if (!forEach(result, b => a.fileName === b.fileName && a.textSpan.start === b.textSpan.start && a.textSpan.length === b.textSpan.length)) { + result.push(a); + } + } } function getSymbolsForComponentTypes(type: UnionOrIntersectionType, result: Symbol[] = []): Symbol[] { diff --git a/tests/cases/fourslash/goToImplementationInterface_07.ts b/tests/cases/fourslash/goToImplementationInterface_07.ts index c14a98f9185..6a8665ec213 100644 --- a/tests/cases/fourslash/goToImplementationInterface_07.ts +++ b/tests/cases/fourslash/goToImplementationInterface_07.ts @@ -13,7 +13,7 @@ //// let x1: Foo = [|{ hello () { /**typeReference*/ } }|]; //// let x2: () => Foo = [|(() => { hello () { /**functionType*/} })|]; //// let x3: Foo | Bar = [|{ hello () { /**unionType*/} }|]; -//// let x4: Foo & Bar = [|{ hello () { /**intersectionType*/} }|]; +//// let x4: Foo & (Foo & Bar) = [|{ hello () { /**intersectionType*/} }|]; //// let x5: [Foo] = [|[{ hello () { /**tupleType*/} }]|]; //// let x6: (Foo) = [|{ hello () { /**parenthesizedType*/} }|]; //// let x7: (new() => Foo) = [|class { hello () { /**constructorType*/} }|]; From f91a123d2318928e696356e2b9693c2f93ebe0d5 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Mon, 12 Sep 2016 11:10:44 -0700 Subject: [PATCH 22/46] PR feedback --- src/harness/fourslash.ts | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 94e67cf981c..cb9d95868ae 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1700,7 +1700,7 @@ namespace FourSlash { public goToImplementation(implIndex?: number) { const implementations = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (!implementations || !implementations.length) { - this.raiseError("goToImplementation failed - expected to at least one implementation location but got 0"); + this.raiseError("goToImplementation failed - expected to find at least one implementation location but got 0"); } if (implIndex === undefined && implementations.length > 1) { @@ -1719,7 +1719,7 @@ namespace FourSlash { public verifyRangesInImplementationList() { const implementations: ImplementationLocationInformation[] = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (!implementations || !implementations.length) { - this.raiseError("verifyRangesInImplementationList failed - expected to at least one implementation location but got 0"); + this.raiseError("verifyRangesInImplementationList failed - expected to find at least one implementation location but got 0"); } for (let i = 0; i < implementations.length; i++) { @@ -1735,22 +1735,19 @@ namespace FourSlash { const ranges = this.getRanges(); if (!ranges || !ranges.length) { - this.raiseError("verifyRangesInImplementationList failed - expected to at least one range in test source"); + this.raiseError("verifyRangesInImplementationList failed - expected to find at least one range in test source"); } const unsatisfiedRanges: Range[] = []; for (const range of ranges) { - let rangeIsPresent = false; const length = range.end - range.start; - for (const impl of implementations) { - if (range.fileName === impl.fileName && range.start === impl.textSpan.start && length === impl.textSpan.length) { - impl.matched = true; - rangeIsPresent = true; - break; - } + const matchingImpl = ts.find(implementations, impl => + range.fileName === impl.fileName && range.start === impl.textSpan.start && length === impl.textSpan.length); + if (matchingImpl) { + matchingImpl.matched = true; } - if (!rangeIsPresent) { + else { unsatisfiedRanges.push(range); } } @@ -1765,7 +1762,7 @@ namespace FourSlash { } } - if (unsatisfiedRanges.length) { + if (unmatchedImplementations.length) { error += "\nUnmatched implementations:"; for (const impl of unmatchedImplementations) { const end = impl.textSpan.start + impl.textSpan.length; From 4a37fd7bcfa3a10020337dd032fef81dda625bac Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Tue, 13 Sep 2016 17:33:49 -0700 Subject: [PATCH 23/46] More PR feedback --- src/harness/fourslash.ts | 32 ++-- src/services/services.ts | 167 +++++++++--------- src/services/shims.ts | 2 +- tests/cases/fourslash/fourslash.ts | 6 +- .../goToImplementationClassMethod_00.ts | 3 +- .../goToImplementationClassMethod_01.ts | 7 +- .../fourslash/goToImplementationEnum_00.ts | 3 +- .../fourslash/goToImplementationEnum_01.ts | 3 +- .../goToImplementationInterfaceMethod_00.ts | 7 +- .../goToImplementationInterfaceMethod_01.ts | 7 +- .../goToImplementationInterfaceMethod_02.ts | 7 +- .../goToImplementationInterfaceMethod_03.ts | 3 +- .../goToImplementationInterfaceMethod_04.ts | 3 +- .../goToImplementationInterfaceMethod_05.ts | 3 +- .../goToImplementationInterfaceMethod_06.ts | 3 +- .../goToImplementationInterfaceMethod_08.ts | 3 +- .../goToImplementationInterfaceMethod_09.ts | 7 +- .../goToImplementationInterfaceMethod_10.ts | 3 +- .../goToImplementationInterfaceMethod_11.ts | 4 +- .../goToImplementationInterfaceProperty_00.ts | 3 +- .../goToImplementationInterfaceProperty_01.ts | 3 +- .../goToImplementationInterface_00.ts | 4 +- .../goToImplementationInterface_01.ts | 3 +- .../goToImplementationInterface_02.ts | 5 +- .../goToImplementationInterface_03.ts | 3 +- .../goToImplementationInterface_04.ts | 4 +- .../goToImplementationInterface_05.ts | 4 +- .../goToImplementationInterface_06.ts | 4 +- .../goToImplementationInterface_07.ts | 3 +- .../goToImplementationInterface_08.ts | 21 +++ .../fourslash/goToImplementationInvalid.ts | 2 +- .../fourslash/goToImplementationLocal_00.ts | 3 +- .../fourslash/goToImplementationLocal_01.ts | 3 +- .../fourslash/goToImplementationLocal_02.ts | 4 +- .../fourslash/goToImplementationLocal_03.ts | 4 +- .../fourslash/goToImplementationLocal_04.ts | 4 +- .../fourslash/goToImplementationLocal_05.ts | 4 +- .../fourslash/goToImplementationLocal_06.ts | 4 +- .../fourslash/goToImplementationLocal_07.ts | 4 +- .../fourslash/goToImplementationLocal_08.ts | 4 +- .../goToImplementationNamespace_01.ts | 11 +- .../goToImplementationNamespace_02.ts | 11 +- .../goToImplementationNamespace_03.ts | 3 +- .../goToImplementationNamespace_04.ts | 3 +- .../goToImplementationNamespace_06.ts | 3 +- ...mentationShorthandPropertyAssignment_01.ts | 3 +- ...mentationShorthandPropertyAssignment_02.ts | 3 +- .../fourslash/goToImplementationSuper_00.ts | 3 +- .../fourslash/goToImplementationSuper_01.ts | 3 +- .../fourslash/goToImplementationThis_00.ts | 3 +- .../fourslash/goToImplementationThis_01.ts | 3 +- 51 files changed, 191 insertions(+), 224 deletions(-) create mode 100644 tests/cases/fourslash/goToImplementationInterface_08.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index cb9d95868ae..92be81ba3f2 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1680,13 +1680,13 @@ namespace FourSlash { assertFn(actualCount, expectedCount, this.messageAtLastKnownMarker("Type definitions Count")); } - public verifyImplementationsCount(negative: boolean, expectedCount: number) { + public verifyImplementationListIsEmpty(negative: boolean) { const assertFn = negative ? assert.notEqual : assert.equal; const implementations = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition); const actualCount = implementations && implementations.length || 0; - assertFn(actualCount, expectedCount, this.messageAtLastKnownMarker("Implementations Count")); + assertFn(actualCount, 0, this.messageAtLastKnownMarker("Implementations Count")); } public verifyGoToDefinitionName(expectedName: string, expectedContainerName: string) { @@ -1697,26 +1697,22 @@ namespace FourSlash { assert.equal(actualDefinitionContainerName, expectedContainerName, this.messageAtLastKnownMarker("Definition Info Container Name")); } - public goToImplementation(implIndex?: number) { + public goToImplementation() { const implementations = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (!implementations || !implementations.length) { this.raiseError("goToImplementation failed - expected to find at least one implementation location but got 0"); } - - if (implIndex === undefined && implementations.length > 1) { - this.raiseError(`goToImplementation failed - no index given but more than 1 implementation returned (${implementations.length})`); + if (implementations.length > 1) { + this.raiseError(`goToImplementation failed - more than 1 implementation returned (${implementations.length})`); } - if (implIndex >= implementations.length) { - this.raiseError(`goToImplementation failed - implIndex value (${implIndex}) exceeds implementation list size (${implementations.length})`); - } - - const implementation = implementations[implIndex || 0]; + const implementation = implementations[0]; this.openFile(implementation.fileName); this.currentCaretPosition = implementation.textSpan.start; } - public verifyRangesInImplementationList() { + public verifyRangesInImplementationList(markerName: string) { + this.goToMarker(markerName); const implementations: ImplementationLocationInformation[] = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (!implementations || !implementations.length) { this.raiseError("verifyRangesInImplementationList failed - expected to find at least one implementation location but got 0"); @@ -2954,8 +2950,8 @@ namespace FourSlashInterface { this.state.goToTypeDefinition(definitionIndex); } - public implementation(implementationIndex?: number) { - this.state.goToImplementation(implementationIndex); + public implementation() { + this.state.goToImplementation(); } public position(position: number, fileIndex?: number): void; @@ -3062,8 +3058,8 @@ namespace FourSlashInterface { this.state.verifyTypeDefinitionsCount(this.negative, expectedCount); } - public implementationCountIs(expectedCount: number) { - this.state.verifyImplementationsCount(this.negative, expectedCount); + public implementationListIsEmpty() { + this.state.verifyImplementationListIsEmpty(this.negative); } public isValidBraceCompletionAtPosition(openingBrace: string) { @@ -3319,8 +3315,8 @@ namespace FourSlashInterface { this.state.verifyProjectInfo(expected); } - public allRangesAppearInImplementationList() { - this.state.verifyRangesInImplementationList(); + public allRangesAppearInImplementationList(markerName: string) { + this.state.verifyRangesInImplementationList(markerName); } } diff --git a/src/services/services.ts b/src/services/services.ts index 80cb181a643..53eddecee3f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1054,13 +1054,6 @@ namespace ts { moduleDir: string; } - // Internal interface used for tracking state in find all references when checking - // the inheritance hierarchy of property access expressions - interface SymbolInheritanceState { - symbol: Symbol; - cachedInheritanceResults: Map; - } - export interface DisplayPartsSymbolWriter extends SymbolWriter { displayParts(): SymbolDisplayPart[]; } @@ -5026,37 +5019,25 @@ namespace ts { // the declaration of the symbol being assigned (not the symbol being assigned to). if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { const result: ReferenceEntry[] = []; - getReferenceEntryForShorthandPropertyAssignment(node, typeChecker, result); + getReferenceEntriesForShorthandPropertyAssignment(node, typeChecker, result); return result.length > 0 ? result : undefined; } else if (node.kind === SyntaxKind.SuperKeyword || isSuperProperty(node.parent)) { // References to and accesses on the super keyword only have one possible implementation, so no // need to "Find all References" const symbol = typeChecker.getSymbolAtLocation(node); - if (symbol.valueDeclaration) { - return [getReferenceEntryFromNode(symbol.valueDeclaration)]; - } + return symbol.valueDeclaration && [getReferenceEntryFromNode(symbol.valueDeclaration)]; } else { - const entries: ImplementationLocation[] = []; // Perform "Find all References" and retrieve only those that are implementations - const result = getReferencedSymbolsForNode(node, program.getSourceFiles(), /*findInStrings*/false, /*findInComments*/false, /*implementations*/true); + const referencedSymbols = getReferencedSymbolsForNode(node, program.getSourceFiles(), /*findInStrings*/false, /*findInComments*/false, /*implementations*/true); - forEach(result, referencedSymbol => { - if (referencedSymbol.references) { - forEach(referencedSymbol.references, entry => { - entries.push({ - textSpan: entry.textSpan, - fileName: entry.fileName - }); - }); - } - }); - return entries; + return flatMap(referencedSymbols, symbol => + map(symbol.references, ({ textSpan, fileName }) => ({ textSpan, fileName }))); } } - function getReferenceEntryForShorthandPropertyAssignment(node: Node, typeChecker: TypeChecker, result: ReferenceEntry[]): void { + function getReferenceEntriesForShorthandPropertyAssignment(node: Node, typeChecker: TypeChecker, result: ReferenceEntry[]): void { const refSymbol = typeChecker.getSymbolAtLocation(node); const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(refSymbol.valueDeclaration); @@ -5069,25 +5050,26 @@ namespace ts { } } - function isNameOfImplementation(node: Node): boolean { - const parent = node.parent; - - if (isDeclarationName(node)) { - if (isVariableLike(parent)) { - if (parent.kind === SyntaxKind.VariableDeclaration) { - const parentStatement = parent.parent && parent.parent.parent; - if (parentStatement && hasModifier(parentStatement, ModifierFlags.Ambient)) { - return true; - } + function isImplementation(node: Node): boolean { + if (!node) { + return false; + } + else if (isVariableLike(node)) { + if (node.initializer) { + return true; + } + else if (node.kind === SyntaxKind.VariableDeclaration) { + const parentStatement = getParentStatementOfVariableDeclaration(node); + if (parentStatement && hasModifier(parentStatement, ModifierFlags.Ambient)) { + return true; } - return !!parent.initializer; } - else if (isFunctionLike(parent)) { - return !!parent.body || hasModifier(parent, ModifierFlags.Ambient); - } - - switch (parent.kind) { - case SyntaxKind.PropertyAssignment: + } + else if (isFunctionLike(node)) { + return !!node.body || hasModifier(node, ModifierFlags.Ambient); + } + else { + switch (node.kind) { case SyntaxKind.ClassDeclaration: case SyntaxKind.ClassExpression: case SyntaxKind.EnumDeclaration: @@ -5095,12 +5077,12 @@ namespace ts { return true; } } - return false; } - function isTypeAssertionExpression(node: Node): node is TypeAssertion { - return node.kind === SyntaxKind.TypeAssertionExpression; + function getParentStatementOfVariableDeclaration(node: VariableDeclaration): VariableStatement { + return node.parent && node.parent.kind === SyntaxKind.VariableDeclarationList && node.parent.parent + && node.parent.parent.kind === SyntaxKind.VariableStatement && node.parent.parent; } function getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[] { @@ -6197,24 +6179,8 @@ namespace ts { const start = findInComments ? container.getFullStart() : container.getStart(); const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, start, container.getEnd()); - // If we are just looking for implementations and this is a property access expression, we need to get the - // symbol of the local type of the symbol the property is being accessed on. This is because our search - // symbol may have a different parent symbol if the local type's symbol does not declare the property - // being accessed (i.e. it is declared in some parent class or interface) - let parents: Symbol[]; - const cache: Map = createMap(); - - if (implementations && isRightSideOfPropertyAccess(searchLocation)) { - const localParentType = typeChecker.getTypeAtLocation((searchLocation.parent).expression); - if (localParentType) { - if (localParentType.symbol && localParentType.symbol.getFlags() & (SymbolFlags.Class | SymbolFlags.Interface) && localParentType.symbol !== searchSymbol.parent) { - parents = [localParentType.symbol]; - } - else if (localParentType.getFlags() & TypeFlags.UnionOrIntersection) { - parents = getSymbolsForComponentTypes(localParentType); - } - } - } + const parents = getParentSymbolsOfPropertyAccess(); + const inheritsFromCache: Map = createMap(); if (possiblePositions.length) { // Build the set of symbols to search for, initially it has only the current symbol @@ -6257,7 +6223,7 @@ namespace ts { const referenceSymbolDeclaration = referenceSymbol.valueDeclaration; const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); const relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation, - /*searchLocationIsConstructor*/ searchLocation.kind === SyntaxKind.ConstructorKeyword, parents, cache); + /*searchLocationIsConstructor*/ searchLocation.kind === SyntaxKind.ConstructorKeyword, parents, inheritsFromCache); if (relatedSymbol) { addReferenceToRelatedSymbol(referenceLocation, relatedSymbol); @@ -6279,6 +6245,32 @@ namespace ts { } return; + /* If we are just looking for implementations and this is a property access expression, we need to get the + * symbol of the local type of the symbol the property is being accessed on. This is because our search + * symbol may have a different parent symbol if the local type's symbol does not declare the property + * being accessed (i.e. it is declared in some parent class or interface) + */ + function getParentSymbolsOfPropertyAccess(): Symbol[] | undefined { + if (implementations) { + const propertyAccessExpression = getPropertyAccessExpressionFromRightHandSide(searchLocation); + if (propertyAccessExpression) { + const localParentType = typeChecker.getTypeAtLocation(propertyAccessExpression.expression); + if (localParentType) { + if (localParentType.symbol && localParentType.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) && localParentType.symbol !== searchSymbol.parent) { + return [localParentType.symbol]; + } + else if (localParentType.flags & TypeFlags.UnionOrIntersection) { + return getSymbolsForClassAndInterfaceComponents(localParentType); + } + } + } + } + } + + function getPropertyAccessExpressionFromRightHandSide(node: Node): PropertyAccessExpression { + return isRightSideOfPropertyAccess(node) && node.parent; + } + /** Adds references when a constructor is used with `new this()` in its own class and `super()` calls in subclasses. */ function findAdditionalConstructorReferences(referenceSymbol: Symbol, referenceLocation: Node): void { Debug.assert(isClassLike(searchSymbol.valueDeclaration)); @@ -6387,19 +6379,19 @@ namespace ts { function getImplementationReferenceEntryForNode(refNode: Node, result: ReferenceEntry[]): void { // Check if we found a function/propertyAssignment/method with an implementation or initializer - if (isNameOfImplementation(refNode)) { + if (isDeclarationName(refNode) && isImplementation(refNode.parent)) { result.push(getReferenceEntryFromNode(refNode.parent)); } else if (refNode.kind === SyntaxKind.Identifier) { if (refNode.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { // Go ahead and dereference the shorthand assignment by going to its definition - getReferenceEntryForShorthandPropertyAssignment(refNode, typeChecker, result); + getReferenceEntriesForShorthandPropertyAssignment(refNode, typeChecker, result); } // Check if the node is within an extends or implements clause - const containingHeritageClause = getContainingClassHeritageClause(refNode); - if (containingHeritageClause) { - result.push(getReferenceEntryFromNode(containingHeritageClause.parent)); + const containingClass = getContainingClassIfInHeritageClause(refNode); + if (containingClass) { + result.push(getReferenceEntryFromNode(containingClass)); return; } @@ -6410,14 +6402,19 @@ namespace ts { if (isVariableLike(parent) && parent.type === containingTypeReference && parent.initializer && isImplementationExpression(parent.initializer)) { maybeAdd(getReferenceEntryFromNode(parent.initializer)); } - else if (isFunctionLike(parent) && parent.type === containingTypeReference && parent.body && parent.body.kind === SyntaxKind.Block) { - forEachReturnStatement(parent.body, (returnStatement) => { - if (returnStatement.expression && isImplementationExpression(returnStatement.expression)) { - maybeAdd(getReferenceEntryFromNode(returnStatement.expression)); - } - }); + else if (isFunctionLike(parent) && parent.type === containingTypeReference && parent.body) { + if (parent.body.kind === SyntaxKind.Block) { + forEachReturnStatement(parent.body, returnStatement => { + if (returnStatement.expression && isImplementationExpression(returnStatement.expression)) { + maybeAdd(getReferenceEntryFromNode(returnStatement.expression)); + } + }); + } + else if (isImplementationExpression(parent.body)) { + maybeAdd(getReferenceEntryFromNode(parent.body)); + } } - else if (isTypeAssertionExpression(parent) && isImplementationExpression(parent.expression)) { + else if (isAssertionExpression(parent) && isImplementationExpression(parent.expression)) { maybeAdd(getReferenceEntryFromNode(parent.expression)); } } @@ -6435,13 +6432,13 @@ namespace ts { } } - function getSymbolsForComponentTypes(type: UnionOrIntersectionType, result: Symbol[] = []): Symbol[] { + function getSymbolsForClassAndInterfaceComponents(type: UnionOrIntersectionType, result: Symbol[] = []): Symbol[] { for (const componentType of type.types) { if (componentType.symbol && componentType.symbol.getFlags() & (SymbolFlags.Class | SymbolFlags.Interface)) { result.push(componentType.symbol); } if (componentType.getFlags() & TypeFlags.UnionOrIntersection) { - getSymbolsForComponentTypes(componentType, result); + getSymbolsForClassAndInterfaceComponents(componentType, result); } } return result; @@ -6460,23 +6457,23 @@ namespace ts { return topLevelTypeReference; } - function getContainingClassHeritageClause(node: Node): HeritageClause { - if (node) { + function getContainingClassIfInHeritageClause(node: Node): ClassLikeDeclaration { + if (node && node.parent) { if (node.kind === SyntaxKind.ExpressionWithTypeArguments && node.parent.kind === SyntaxKind.HeritageClause && isClassLike(node.parent.parent)) { - return node.parent; + return node.parent.parent; } else if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression) { - return getContainingClassHeritageClause(node.parent); + return getContainingClassIfInHeritageClause(node.parent); } } return undefined; } /** - * Returns true if this is an expression that could be used to implement an interface. + * Returns true if this is an expression that can be considered an implementation */ function isImplementationExpression(node: Expression): boolean { // Unwrap parentheses @@ -6517,6 +6514,7 @@ namespace ts { return cachedResults[key]; } + // Set the key so that we don't infinitely recurse cachedResults[key] = false; const inherits = forEach(symbol.getDeclarations(), (declaration) => { @@ -6910,7 +6908,7 @@ namespace ts { } } - function getRelatedSymbol(searchSymbols: Symbol[], referenceSymbol: Symbol, referenceLocation: Node, searchLocationIsConstructor: boolean, parents: Symbol[], cache: Map): Symbol { + function getRelatedSymbol(searchSymbols: Symbol[], referenceSymbol: Symbol, referenceLocation: Node, searchLocationIsConstructor: boolean, parents: Symbol[] | undefined, cache: Map): Symbol { if (contains(searchSymbols, referenceSymbol)) { // If we are searching for constructor uses, they must be 'new' expressions. return (!searchLocationIsConstructor || isNewExpressionTarget(referenceLocation)) && referenceSymbol; @@ -6966,6 +6964,7 @@ namespace ts { // see if any is in the list. If we were passed a parent symbol, only include types that are subtypes of the // parent symbol if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { + // Parents will only be defined if implementations is true if (parents) { if (!forEach(parents, parent => inheritsFrom(rootSymbol.parent, parent, cache))) { return undefined; diff --git a/src/services/shims.ts b/src/services/shims.ts index 8771e014695..deab2addc87 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -179,7 +179,7 @@ namespace ts { /** * Returns a JSON-encoded value of the type: - * { fileName: string; textSpan: { start: number; length: number}; isWriteAccess: boolean, isDefinition?: boolean }[] + * { fileName: string; textSpan: { start: number; length: number}; }[] */ getImplementationAtPosition(fileName: string, position: number): string; diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index b1adba20c52..e484a1cd782 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -110,7 +110,7 @@ declare namespace FourSlashInterface { bof(): void; eof(): void; type(definitionIndex?: number): void; - implementation(implementationIndex?: number): void; + implementation(): void; position(position: number, fileIndex?: number): any; position(position: number, fileName?: string): any; file(index: number, content?: string, scriptKindName?: string): any; @@ -134,7 +134,7 @@ declare namespace FourSlashInterface { quickInfoIs(expectedText?: string, expectedDocumentation?: string): void; quickInfoExists(): void; typeDefinitionCountIs(expectedCount: number): void; - implementationCountIs(expectedCount: number): void; + implementationListIsEmpty(): void; isValidBraceCompletionAtPosition(openingBrace?: string): void; } class verify extends verifyNegatable { @@ -242,7 +242,7 @@ declare namespace FourSlashInterface { getSyntacticDiagnostics(expected: string): void; getSemanticDiagnostics(expected: string): void; ProjectInfo(expected: string[]): void; - allRangesAppearInImplementationList(): void; + allRangesAppearInImplementationList(markerName: string): void; } class edit { backspace(count?: number): void; diff --git a/tests/cases/fourslash/goToImplementationClassMethod_00.ts b/tests/cases/fourslash/goToImplementationClassMethod_00.ts index 465db091d32..6fc8d9bf7cc 100644 --- a/tests/cases/fourslash/goToImplementationClassMethod_00.ts +++ b/tests/cases/fourslash/goToImplementationClassMethod_00.ts @@ -8,5 +8,4 @@ //// //// new Bar().hel/*reference*/lo; -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationClassMethod_01.ts b/tests/cases/fourslash/goToImplementationClassMethod_01.ts index 8b1cb3e762d..7f59376a6ae 100644 --- a/tests/cases/fourslash/goToImplementationClassMethod_01.ts +++ b/tests/cases/fourslash/goToImplementationClassMethod_01.ts @@ -14,8 +14,5 @@ //// x.he/*reference*/llo(); //// } -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); - -goTo.marker("declaration"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); +verify.allRangesAppearInImplementationList("declaration"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationEnum_00.ts b/tests/cases/fourslash/goToImplementationEnum_00.ts index 3a93542f806..81e72b871a2 100644 --- a/tests/cases/fourslash/goToImplementationEnum_00.ts +++ b/tests/cases/fourslash/goToImplementationEnum_00.ts @@ -9,5 +9,4 @@ //// //// Foo.Fo/*reference*/o1; -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationEnum_01.ts b/tests/cases/fourslash/goToImplementationEnum_01.ts index 2e7203f3c8f..43273b6b03a 100644 --- a/tests/cases/fourslash/goToImplementationEnum_01.ts +++ b/tests/cases/fourslash/goToImplementationEnum_01.ts @@ -9,5 +9,4 @@ //// //// Fo/*reference*/o; -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts index ca5498c3492..38afd0cfb3d 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts @@ -21,8 +21,5 @@ //// constructor(public f: Foo = { [|hello() {/**3*/}|] } ) {} //// } -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); - -goTo.marker("declaration"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); +verify.allRangesAppearInImplementationList("declaration"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_01.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_01.ts index 5f5ba64338b..8bd328bcb54 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_01.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_01.ts @@ -18,8 +18,5 @@ //// //// whatever(new Bar()); -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); - -goTo.marker("declaration"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); +verify.allRangesAppearInImplementationList("declaration"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_02.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_02.ts index f5b1f1eea93..82dceaad91c 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_02.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_02.ts @@ -18,8 +18,5 @@ //// a.he/*function_call*/llo(); //// } -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); - -goTo.marker("declaration"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); +verify.allRangesAppearInImplementationList("declaration"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_03.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_03.ts index cc22956bb05..8826cc1eab4 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_03.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_03.ts @@ -21,5 +21,4 @@ //// new Bar().hel/*function_call*/lo(); //// new Bar()["hello"](); -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_04.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_04.ts index 32f5ff41484..a9b825c717f 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_04.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_04.ts @@ -22,5 +22,4 @@ //// x.he/*function_call*/llo() //// } -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts index 5e8bd76a072..b051e16a929 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts @@ -34,5 +34,4 @@ //// x.he/*function_call*/llo() //// } -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts index b7f275e6c07..b340270096d 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts @@ -45,5 +45,4 @@ //// x.he/*function_call*/llo() //// } -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts index e3db4b5157d..d2038f99efd 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts @@ -19,5 +19,4 @@ //// } -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); +verify.allRangesAppearInImplementationList("function_call"); diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts index 922ea026888..84c57ec2bce 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts @@ -27,8 +27,5 @@ //// hello() {} //// } -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); - -goTo.marker("element_access"); -verify.allRangesAppearInImplementationList(); +verify.allRangesAppearInImplementationList("function_call"); +verify.allRangesAppearInImplementationList("element_access"); diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts index 76d4e750ad9..0604d2511f2 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts @@ -44,6 +44,5 @@ //// } for (var i = 0; i < 2; i++) { - goTo.marker("function_call" + i); - verify.allRangesAppearInImplementationList(); + verify.allRangesAppearInImplementationList("function_call" + i); } diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts index 7d948006fb3..9528aa409b4 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts @@ -8,5 +8,5 @@ //// //// var x = { [|hello: () => {}|] }; //// var y = (((({ [|hello: () => {}|] })))); -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file + +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceProperty_00.ts b/tests/cases/fourslash/goToImplementationInterfaceProperty_00.ts index 43b59d021d3..70e49c10b45 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceProperty_00.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceProperty_00.ts @@ -19,5 +19,4 @@ //// constructor(public f: Foo = { [|hello: 7|] } ) {} //// } -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceProperty_01.ts b/tests/cases/fourslash/goToImplementationInterfaceProperty_01.ts index 2725a5ab9d4..14b80362917 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceProperty_01.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceProperty_01.ts @@ -12,5 +12,4 @@ //// foo.he/*reference*/llo; //// } -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_00.ts b/tests/cases/fourslash/goToImplementationInterface_00.ts index fc9f6aace07..8fc36b4bab5 100644 --- a/tests/cases/fourslash/goToImplementationInterface_00.ts +++ b/tests/cases/fourslash/goToImplementationInterface_00.ts @@ -22,6 +22,4 @@ //// constructor(public f: Foo = [|{ hello() {/**3*/} }|] ) {} //// } - -goTo.marker("interface_definition"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("interface_definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_01.ts b/tests/cases/fourslash/goToImplementationInterface_01.ts index 6d9d5c97507..62d01da6ca8 100644 --- a/tests/cases/fourslash/goToImplementationInterface_01.ts +++ b/tests/cases/fourslash/goToImplementationInterface_01.ts @@ -21,5 +21,4 @@ //// var y: SuperBar = new SuperBar(); //// var z: AbstractBar = new NotAbstractBar(); -goTo.marker("interface_definition"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("interface_definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_02.ts b/tests/cases/fourslash/goToImplementationInterface_02.ts index af7f188ffa4..27f29465a9a 100644 --- a/tests/cases/fourslash/goToImplementationInterface_02.ts +++ b/tests/cases/fourslash/goToImplementationInterface_02.ts @@ -17,11 +17,12 @@ //// }|]; //// } //// +//// let createFoo2 = (): Foo => [|({hello() {}})|]; +//// //// function createFooLike() { //// return { //// hello() {} //// }; //// } -goTo.marker("interface_definition"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("interface_definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_03.ts b/tests/cases/fourslash/goToImplementationInterface_03.ts index b198269d498..1c63852dafc 100644 --- a/tests/cases/fourslash/goToImplementationInterface_03.ts +++ b/tests/cases/fourslash/goToImplementationInterface_03.ts @@ -6,5 +6,4 @@ //// //// var x = [|{ hello: () => {} }|]; -goTo.marker("interface_definition"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("interface_definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_04.ts b/tests/cases/fourslash/goToImplementationInterface_04.ts index 3989c194363..febc511388d 100644 --- a/tests/cases/fourslash/goToImplementationInterface_04.ts +++ b/tests/cases/fourslash/goToImplementationInterface_04.ts @@ -17,6 +17,4 @@ //// constructor(public f: Foo = [|function(a) {}|] ) {} //// } - -goTo.marker("interface_definition"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("interface_definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_05.ts b/tests/cases/fourslash/goToImplementationInterface_05.ts index d0f87c6d6d4..3b31b89b528 100644 --- a/tests/cases/fourslash/goToImplementationInterface_05.ts +++ b/tests/cases/fourslash/goToImplementationInterface_05.ts @@ -9,6 +9,4 @@ //// let bar2 = [|function(a) {}|]; //// - -goTo.marker("interface_definition"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("interface_definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_06.ts b/tests/cases/fourslash/goToImplementationInterface_06.ts index 7ba2ebfc023..15f52132868 100644 --- a/tests/cases/fourslash/goToImplementationInterface_06.ts +++ b/tests/cases/fourslash/goToImplementationInterface_06.ts @@ -11,6 +11,4 @@ //// let x: Foo = [|class { constructor (a: number) {} }|]; //// let y = [|class { constructor (a: number) {} }|]; - -goTo.marker("interface_definition"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("interface_definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_07.ts b/tests/cases/fourslash/goToImplementationInterface_07.ts index 6a8665ec213..6d874b3dc76 100644 --- a/tests/cases/fourslash/goToImplementationInterface_07.ts +++ b/tests/cases/fourslash/goToImplementationInterface_07.ts @@ -25,5 +25,4 @@ //// return true; //// } -goTo.marker("interface_definition"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("interface_definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_08.ts b/tests/cases/fourslash/goToImplementationInterface_08.ts new file mode 100644 index 00000000000..652cfe46246 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterface_08.ts @@ -0,0 +1,21 @@ +/// + +// Should not hang on inheritance loops + +//// interface Base { +//// hello (): void; +//// } +//// +//// interface A extends Base {} +//// interface B extends C, A {} +//// interface C extends B, A {} +//// +//// class X implements B { +//// [|hello() {}|] +//// } +//// +//// function someFunction(d : A) { +//// d.he/*function_call*/llo(); +//// } + +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInvalid.ts b/tests/cases/fourslash/goToImplementationInvalid.ts index a9739c9fe12..52b2773342e 100644 --- a/tests/cases/fourslash/goToImplementationInvalid.ts +++ b/tests/cases/fourslash/goToImplementationInvalid.ts @@ -8,5 +8,5 @@ for(var i = 0; i < 3; i++) { goTo.marker("" + i); - verify.implementationCountIs(0); + verify.implementationListIsEmpty(); } \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_00.ts b/tests/cases/fourslash/goToImplementationLocal_00.ts index 0d0ba9001b7..b97fadfcb02 100644 --- a/tests/cases/fourslash/goToImplementationLocal_00.ts +++ b/tests/cases/fourslash/goToImplementationLocal_00.ts @@ -5,5 +5,4 @@ //// he/*function_call*/llo(); //// [|function hello() {}|] -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_01.ts b/tests/cases/fourslash/goToImplementationLocal_01.ts index d2ccb976e95..0bda3418354 100644 --- a/tests/cases/fourslash/goToImplementationLocal_01.ts +++ b/tests/cases/fourslash/goToImplementationLocal_01.ts @@ -5,5 +5,4 @@ //// const [|hello = function() {}|]; //// he/*function_call*/llo(); -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_02.ts b/tests/cases/fourslash/goToImplementationLocal_02.ts index 47097652d81..62bb8a71a10 100644 --- a/tests/cases/fourslash/goToImplementationLocal_02.ts +++ b/tests/cases/fourslash/goToImplementationLocal_02.ts @@ -4,5 +4,5 @@ //// //// x.he/*function_call*/llo(); //// -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file + +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_03.ts b/tests/cases/fourslash/goToImplementationLocal_03.ts index 46ad28a3e1d..d3f25ea29dc 100644 --- a/tests/cases/fourslash/goToImplementationLocal_03.ts +++ b/tests/cases/fourslash/goToImplementationLocal_03.ts @@ -8,5 +8,5 @@ //// //// hello = {}; //// -goTo.marker("local_var"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file + +verify.allRangesAppearInImplementationList("local_var"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_04.ts b/tests/cases/fourslash/goToImplementationLocal_04.ts index 3452749bdcf..9de9dcd0a9f 100644 --- a/tests/cases/fourslash/goToImplementationLocal_04.ts +++ b/tests/cases/fourslash/goToImplementationLocal_04.ts @@ -6,5 +6,5 @@ //// //// hello(); //// -goTo.marker("local_var"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file + +verify.allRangesAppearInImplementationList("local_var"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_05.ts b/tests/cases/fourslash/goToImplementationLocal_05.ts index e58343d2505..969f4c25fc7 100644 --- a/tests/cases/fourslash/goToImplementationLocal_05.ts +++ b/tests/cases/fourslash/goToImplementationLocal_05.ts @@ -8,5 +8,5 @@ //// //// var [|someVar = new Bar()|]; //// someVa/*reference*/r.hello(); -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file + +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_06.ts b/tests/cases/fourslash/goToImplementationLocal_06.ts index 74ef1d77866..acdbaffc36f 100644 --- a/tests/cases/fourslash/goToImplementationLocal_06.ts +++ b/tests/cases/fourslash/goToImplementationLocal_06.ts @@ -4,5 +4,5 @@ //// declare var [|someVar: string|]; //// someVa/*reference*/r -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file + +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_07.ts b/tests/cases/fourslash/goToImplementationLocal_07.ts index 53159a45810..3556c25abc0 100644 --- a/tests/cases/fourslash/goToImplementationLocal_07.ts +++ b/tests/cases/fourslash/goToImplementationLocal_07.ts @@ -4,5 +4,5 @@ //// [|declare function someFunction(): () => void;|] //// someFun/*reference*/ction(); -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file + +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_08.ts b/tests/cases/fourslash/goToImplementationLocal_08.ts index 53159a45810..3556c25abc0 100644 --- a/tests/cases/fourslash/goToImplementationLocal_08.ts +++ b/tests/cases/fourslash/goToImplementationLocal_08.ts @@ -4,5 +4,5 @@ //// [|declare function someFunction(): () => void;|] //// someFun/*reference*/ction(); -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file + +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_01.ts b/tests/cases/fourslash/goToImplementationNamespace_01.ts index ea24336be7e..b2e267d5378 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_01.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_01.ts @@ -2,11 +2,10 @@ // Should handle property access expressions on namespaces -//// namespace Foo { -//// [|export function hello() {}|] -//// } -//// +//// namespace Foo { +//// [|export function hello() {}|] +//// } +//// //// Foo.hell/*reference*/o(); -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_02.ts b/tests/cases/fourslash/goToImplementationNamespace_02.ts index c4388df7e8a..2d2ae960a99 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_02.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_02.ts @@ -2,11 +2,10 @@ // Should handle property access expressions on namespaces -//// module Foo { -//// [|export function hello() {}|] -//// } -//// +//// module Foo { +//// [|export function hello() {}|] +//// } +//// //// Foo.hell/*reference*/o(); -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_03.ts b/tests/cases/fourslash/goToImplementationNamespace_03.ts index 38aeb47feae..751d182ec00 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_03.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_03.ts @@ -24,5 +24,4 @@ //// //// } -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); +verify.allRangesAppearInImplementationList("reference"); diff --git a/tests/cases/fourslash/goToImplementationNamespace_04.ts b/tests/cases/fourslash/goToImplementationNamespace_04.ts index fc64275d906..ac0b85e43fe 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_04.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_04.ts @@ -24,5 +24,4 @@ //// //// } -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); +verify.allRangesAppearInImplementationList("reference"); diff --git a/tests/cases/fourslash/goToImplementationNamespace_06.ts b/tests/cases/fourslash/goToImplementationNamespace_06.ts index 68b4898c6f7..f5e52d90b1c 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_06.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_06.ts @@ -9,5 +9,4 @@ //// //// let x: typeof Foo = [|{ hello() {} }|]; -goTo.marker("declaration"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("declaration"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_01.ts b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_01.ts index abb0aad0602..fb4763619a4 100644 --- a/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_01.ts +++ b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_01.ts @@ -44,5 +44,4 @@ //// //// createBarUsingClassDeclaration().Fo/*reference*/o; -goTo.marker("reference"); -verify.allRangesAppearInImplementationList();; \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_02.ts b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_02.ts index 8db6cbce5de..a27480c8272 100644 --- a/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_02.ts +++ b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_02.ts @@ -18,5 +18,4 @@ //// x.h/*function_call*/ello(); //// } -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationSuper_00.ts b/tests/cases/fourslash/goToImplementationSuper_00.ts index b7def58ca59..53377bdcdb0 100644 --- a/tests/cases/fourslash/goToImplementationSuper_00.ts +++ b/tests/cases/fourslash/goToImplementationSuper_00.ts @@ -12,5 +12,4 @@ //// } //// } -goTo.marker("super_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("super_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationSuper_01.ts b/tests/cases/fourslash/goToImplementationSuper_01.ts index 11ba0719e5d..fffa7caf716 100644 --- a/tests/cases/fourslash/goToImplementationSuper_01.ts +++ b/tests/cases/fourslash/goToImplementationSuper_01.ts @@ -12,5 +12,4 @@ //// } //// } -goTo.marker("super_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("super_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationThis_00.ts b/tests/cases/fourslash/goToImplementationThis_00.ts index 0e4a0ff9849..19212c9a77a 100644 --- a/tests/cases/fourslash/goToImplementationThis_00.ts +++ b/tests/cases/fourslash/goToImplementationThis_00.ts @@ -10,5 +10,4 @@ //// whatever() {} //// }|] -goTo.marker("this_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("this_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationThis_01.ts b/tests/cases/fourslash/goToImplementationThis_01.ts index 001ebc08b9f..6761c6ec6c9 100644 --- a/tests/cases/fourslash/goToImplementationThis_01.ts +++ b/tests/cases/fourslash/goToImplementationThis_01.ts @@ -8,5 +8,4 @@ //// } //// }|] -goTo.marker("this_type"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("this_type"); \ No newline at end of file From 9ff425b574e5c38847931655374cd70325b6cf3d Mon Sep 17 00:00:00 2001 From: Rostislav Galimsky Date: Wed, 14 Sep 2016 20:05:12 +0300 Subject: [PATCH 24/46] Fix issue 10843 --- lib/lib.es2015.core.d.ts | 2 +- lib/lib.es6.d.ts | 2 +- src/lib/es2015.core.d.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/lib.es2015.core.d.ts b/lib/lib.es2015.core.d.ts index c7c7afb821b..c92a44c2312 100644 --- a/lib/lib.es2015.core.d.ts +++ b/lib/lib.es2015.core.d.ts @@ -37,7 +37,7 @@ interface Array { * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ - findIndex(predicate: (value: T) => boolean, thisArg?: any): number; + findIndex(predicate: (value: T, index: number, obj: Array) => boolean, thisArg?: any): number; /** * Returns the this object after filling the section identified by start and end with value diff --git a/lib/lib.es6.d.ts b/lib/lib.es6.d.ts index 8e9de3f4ec9..a7faa4789a6 100644 --- a/lib/lib.es6.d.ts +++ b/lib/lib.es6.d.ts @@ -4143,7 +4143,7 @@ interface Array { * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ - findIndex(predicate: (value: T) => boolean, thisArg?: any): number; + findIndex(predicate: (value: T, index: number, obj: Array) => boolean, thisArg?: any): number; /** * Returns the this object after filling the section identified by start and end with value diff --git a/src/lib/es2015.core.d.ts b/src/lib/es2015.core.d.ts index 15fbb1b77c5..7395039b1c9 100644 --- a/src/lib/es2015.core.d.ts +++ b/src/lib/es2015.core.d.ts @@ -21,7 +21,7 @@ interface Array { * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ - findIndex(predicate: (value: T) => boolean, thisArg?: any): number; + findIndex(predicate: (value: T, index: number, obj: Array) => boolean, thisArg?: any): number; /** * Returns the this object after filling the section identified by start and end with value @@ -368,7 +368,7 @@ interface ReadonlyArray { * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ - findIndex(predicate: (value: T) => boolean, thisArg?: any): number; + findIndex(predicate: (value: T, index: number, obj: Array) => boolean, thisArg?: any): number; } interface RegExp { From 6aa2427cded86b7dad8a58afab6806a75cf8fc85 Mon Sep 17 00:00:00 2001 From: Rostislav Galimsky Date: Wed, 14 Sep 2016 20:05:57 +0300 Subject: [PATCH 25/46] add test for issue 10843 --- tests/baselines/reference/findIndex.js | 10 ++++++++++ tests/baselines/reference/findIndex.symbols | 11 +++++++++++ tests/baselines/reference/findIndex.types | 16 ++++++++++++++++ .../conformance/es6/arrayMethods/findIndex.ts | 5 +++++ 4 files changed, 42 insertions(+) create mode 100644 tests/baselines/reference/findIndex.js create mode 100644 tests/baselines/reference/findIndex.symbols create mode 100644 tests/baselines/reference/findIndex.types create mode 100644 tests/cases/conformance/es6/arrayMethods/findIndex.ts diff --git a/tests/baselines/reference/findIndex.js b/tests/baselines/reference/findIndex.js new file mode 100644 index 00000000000..434ee095bb0 --- /dev/null +++ b/tests/baselines/reference/findIndex.js @@ -0,0 +1,10 @@ +//// [findIndex.ts] + +[].findIndex(function(elem, i, arr) { + return true; +}); + +//// [findIndex.js] +[].findIndex(function (elem, i, arr) { + return true; +}); diff --git a/tests/baselines/reference/findIndex.symbols b/tests/baselines/reference/findIndex.symbols new file mode 100644 index 00000000000..bebbaf6ff85 --- /dev/null +++ b/tests/baselines/reference/findIndex.symbols @@ -0,0 +1,11 @@ +=== tests/cases/conformance/es6/arrayMethods/findIndex.ts === + +[].findIndex(function(elem, i, arr) { +>[].findIndex : Symbol(Array.findIndex, Decl(lib.es2015.core.d.ts, --, --)) +>findIndex : Symbol(Array.findIndex, Decl(lib.es2015.core.d.ts, --, --)) +>elem : Symbol(elem, Decl(findIndex.ts, 1, 22)) +>i : Symbol(i, Decl(findIndex.ts, 1, 27)) +>arr : Symbol(arr, Decl(findIndex.ts, 1, 30)) + + return true; +}); diff --git a/tests/baselines/reference/findIndex.types b/tests/baselines/reference/findIndex.types new file mode 100644 index 00000000000..8538e1c7be3 --- /dev/null +++ b/tests/baselines/reference/findIndex.types @@ -0,0 +1,16 @@ +=== tests/cases/conformance/es6/arrayMethods/findIndex.ts === + +[].findIndex(function(elem, i, arr) { +>[].findIndex(function(elem, i, arr) { return true;}) : number +>[].findIndex : (predicate: (value: any, index: number, obj: any[]) => boolean, thisArg?: any) => number +>[] : undefined[] +>findIndex : (predicate: (value: any, index: number, obj: any[]) => boolean, thisArg?: any) => number +>function(elem, i, arr) { return true;} : (elem: any, i: number, arr: any[]) => boolean +>elem : any +>i : number +>arr : any[] + + return true; +>true : boolean + +}); diff --git a/tests/cases/conformance/es6/arrayMethods/findIndex.ts b/tests/cases/conformance/es6/arrayMethods/findIndex.ts new file mode 100644 index 00000000000..c726c654acb --- /dev/null +++ b/tests/cases/conformance/es6/arrayMethods/findIndex.ts @@ -0,0 +1,5 @@ +//@target: ES6 + +[].findIndex(function(elem, i, arr) { + return true; +}); \ No newline at end of file From 2468d440d9a8f318774e73dc096edeb5d9807a31 Mon Sep 17 00:00:00 2001 From: Gabe Moothart Date: Wed, 14 Sep 2016 11:06:28 -0700 Subject: [PATCH 26/46] Add readonly typings for Set and Map Similar to ReadonlyArray, these typings remove the mutation methods from Set and Map so that they can only be initialized by the constructor. --- src/lib/es2015.collection.d.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/lib/es2015.collection.d.ts b/src/lib/es2015.collection.d.ts index bde1c6d5811..9b0a484ce36 100644 --- a/src/lib/es2015.collection.d.ts +++ b/src/lib/es2015.collection.d.ts @@ -15,6 +15,21 @@ interface MapConstructor { } declare var Map: MapConstructor; +interface ReadonlyMap { + forEach( + callbackfn: (value: V, index: K, map: ReadonlyMap) => void, + thisArg?: any): void; + get(key: K): V|undefined; + has(key: K): boolean; + readonly size: number; +} + +interface ReadonlyMapConstructor { + new(entries?: [K, V][]): ReadonlyMap; + readonly prototype: ReadonlyMap; +} +declare var ReadonlyMap: ReadonlyMapConstructor; + interface WeakMap { delete(key: K): boolean; get(key: K): V | undefined; @@ -45,6 +60,19 @@ interface SetConstructor { } declare var Set: SetConstructor; +interface ReadonlySet { + forEach(callbackfn: (value: T, index: T, set: ReadonlySet) => void, thisArg?: any): + void; + has(value: T): boolean; + readonly size: number; +} + +interface ReadonlySetConstructor { + new(values?: T[]): ReadonlySet; + readonly prototype: ReadonlySet; +} +declare var ReadonlySet: ReadonlySetConstructor; + interface WeakSet { add(value: T): this; delete(value: T): boolean; From b6f7dd798109f94af1936b2fed5cc18205c9922f Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Wed, 14 Sep 2016 13:57:03 -0700 Subject: [PATCH 27/46] More PR feedback --- src/harness/fourslash.ts | 10 ++++++---- src/services/services.ts | 30 +++++++++++++++++++----------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 92be81ba3f2..cd619a90deb 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1681,12 +1681,14 @@ namespace FourSlash { } public verifyImplementationListIsEmpty(negative: boolean) { - const assertFn = negative ? assert.notEqual : assert.equal; - const implementations = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition); - const actualCount = implementations && implementations.length || 0; - assertFn(actualCount, 0, this.messageAtLastKnownMarker("Implementations Count")); + if (negative) { + assert.isTrue(implementations && implementations.length > 0, "Expected at least one implementation but got 0"); + } + else { + assert.isUndefined(implementations, "Expected implementation list to be empty but implementations returned"); + } } public verifyGoToDefinitionName(expectedName: string, expectedContainerName: string) { diff --git a/src/services/services.ts b/src/services/services.ts index 53eddecee3f..366fc783c43 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -5031,9 +5031,10 @@ namespace ts { else { // Perform "Find all References" and retrieve only those that are implementations const referencedSymbols = getReferencedSymbolsForNode(node, program.getSourceFiles(), /*findInStrings*/false, /*findInComments*/false, /*implementations*/true); - - return flatMap(referencedSymbols, symbol => + const result = flatMap(referencedSymbols, symbol => map(symbol.references, ({ textSpan, fileName }) => ({ textSpan, fileName }))); + + return result && result.length > 0 ? result : undefined; } } @@ -5060,9 +5061,7 @@ namespace ts { } else if (node.kind === SyntaxKind.VariableDeclaration) { const parentStatement = getParentStatementOfVariableDeclaration(node); - if (parentStatement && hasModifier(parentStatement, ModifierFlags.Ambient)) { - return true; - } + return parentStatement && hasModifier(parentStatement, ModifierFlags.Ambient); } } else if (isFunctionLike(node)) { @@ -5081,8 +5080,10 @@ namespace ts { } function getParentStatementOfVariableDeclaration(node: VariableDeclaration): VariableStatement { - return node.parent && node.parent.kind === SyntaxKind.VariableDeclarationList && node.parent.parent - && node.parent.parent.kind === SyntaxKind.VariableStatement && node.parent.parent; + if (node.parent && node.parent.parent && node.parent.parent.kind === SyntaxKind.VariableStatement) { + Debug.assert(node.parent.kind === SyntaxKind.VariableDeclarationList); + return node.parent.parent; + } } function getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[] { @@ -6491,16 +6492,23 @@ namespace ts { /** * Determines if the parent symbol occurs somewhere in the child's ancestry. If the parent symbol * is an interface, determines if some ancestor of the child symbol extends or inherits from it. - * This also takes in a cache of previous results which makes this slightly more efficient and is + * Also takes in a cache of previous results which makes this slightly more efficient and is * necessary to avoid potential loops like so: * class A extends B { } * class B extends A { } * + * We traverse the AST rather than using the type checker because users are typically only interested + * in explicit implementations of an interface/class when calling "Go to Implementation". Sibling + * implementations of types that share a common ancestor with the type whose implementation we are + * searching for need to be filtered out of the results. The type checker doesn't let us make the + * distinction between structurally compatible implementations and explicit implementations, so we + * must use the AST. + * * @param child A class or interface Symbol * @param parent Another class or interface Symbol - * @param cachedResults A map of symbol names to booleans indicating previous results + * @param cachedResults A map of symbol id pairs (i.e. "child,parent") to booleans indicating previous results */ - function inheritsFrom(child: Symbol, parent: Symbol, cachedResults: Map): boolean { + function explicitlyInheritsFrom(child: Symbol, parent: Symbol, cachedResults: Map): boolean { const parentIsInterface = parent.getFlags() & SymbolFlags.Interface; return searchHierarchy(child); @@ -6966,7 +6974,7 @@ namespace ts { if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { // Parents will only be defined if implementations is true if (parents) { - if (!forEach(parents, parent => inheritsFrom(rootSymbol.parent, parent, cache))) { + if (!forEach(parents, parent => explicitlyInheritsFrom(rootSymbol.parent, parent, cache))) { return undefined; } } From 9e6116851f483fbf5d37f7c48a540b80cc5313d4 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 14 Sep 2016 15:52:54 -0700 Subject: [PATCH 28/46] Allow type and NS references to UMD globals from modules Fixes #10638 --- src/compiler/checker.ts | 4 +-- tests/baselines/reference/umd8.errors.txt | 25 +++++++++++++++++++ tests/baselines/reference/umd8.js | 16 +++++++++--- .../cases/conformance/externalModules/umd8.ts | 10 ++++++-- 4 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 tests/baselines/reference/umd8.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e3422abe219..7e3caa511c9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -914,8 +914,8 @@ namespace ts { } } - // If we're in an external module, we can't reference symbols created from UMD export declarations - if (result && isInExternalModule) { + // If we're in an external module, we can't reference value symbols created from UMD export declarations + if (result && isInExternalModule && (meaning & SymbolFlags.Value) === SymbolFlags.Value) { const decls = result.declarations; if (decls && decls.length === 1 && decls[0].kind === SyntaxKind.NamespaceExportDeclaration) { error(errorLocation, Diagnostics.Identifier_0_must_be_imported_from_a_module, name); diff --git a/tests/baselines/reference/umd8.errors.txt b/tests/baselines/reference/umd8.errors.txt new file mode 100644 index 00000000000..9396c8c5450 --- /dev/null +++ b/tests/baselines/reference/umd8.errors.txt @@ -0,0 +1,25 @@ +tests/cases/conformance/externalModules/a.ts(7,14): error TS2686: Identifier 'Foo' must be imported from a module + + +==== tests/cases/conformance/externalModules/a.ts (1 errors) ==== + /// + import * as ff from './foo'; + + let y: Foo; // OK in type position + y.foo(); + let z: Foo.SubThing; // OK in ns position + let x: any = Foo; // Not OK in value position + ~~~ +!!! error TS2686: Identifier 'Foo' must be imported from a module + +==== tests/cases/conformance/externalModules/foo.d.ts (0 errors) ==== + + declare class Thing { + foo(): number; + } + declare namespace Thing { + interface SubThing { } + } + export = Thing; + export as namespace Foo; + \ No newline at end of file diff --git a/tests/baselines/reference/umd8.js b/tests/baselines/reference/umd8.js index b4c6e0fa76b..e76b3902156 100644 --- a/tests/baselines/reference/umd8.js +++ b/tests/baselines/reference/umd8.js @@ -5,17 +5,25 @@ declare class Thing { foo(): number; } +declare namespace Thing { + interface SubThing { } +} export = Thing; export as namespace Foo; //// [a.ts] /// -let y: Foo; -y.foo(); +import * as ff from './foo'; +let y: Foo; // OK in type position +y.foo(); +let z: Foo.SubThing; // OK in ns position +let x: any = Foo; // Not OK in value position //// [a.js] -/// -var y; +"use strict"; +var y; // OK in type position y.foo(); +var z; // OK in ns position +var x = Foo; // Not OK in value position diff --git a/tests/cases/conformance/externalModules/umd8.ts b/tests/cases/conformance/externalModules/umd8.ts index caab734f5e0..9a8331fded3 100644 --- a/tests/cases/conformance/externalModules/umd8.ts +++ b/tests/cases/conformance/externalModules/umd8.ts @@ -5,11 +5,17 @@ declare class Thing { foo(): number; } +declare namespace Thing { + interface SubThing { } +} export = Thing; export as namespace Foo; // @filename: a.ts /// -let y: Foo; -y.foo(); +import * as ff from './foo'; +let y: Foo; // OK in type position +y.foo(); +let z: Foo.SubThing; // OK in ns position +let x: any = Foo; // Not OK in value position From e2ff42f4536c33085b216965b654a04ddce6d7a3 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 14 Sep 2016 16:25:17 -0700 Subject: [PATCH 29/46] Add comment explaining a magic constant in parser --- src/compiler/parser.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index fdc1ccefcd7..5037256d59f 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6183,6 +6183,7 @@ namespace ts { let advanceToken = true; let state = JSDocState.SawAsterisk; let margin: number | undefined = undefined; + // + 4 for leading '/** ' let indent = start - Math.max(content.lastIndexOf("\n", start), 0) + 4; function pushComment(text: string) { if (!margin) { From fd936999b133ac234fbea05bb50863e66978a779 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Wed, 14 Sep 2016 18:20:47 -0700 Subject: [PATCH 30/46] Fixing formatting --- src/services/findAllReferences.ts | 16 +++++------ src/services/goToImplementation.ts | 46 +++++++++++++++--------------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 2127c401315..dcda3e40b1a 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -359,9 +359,9 @@ namespace ts.FindAllReferences { } /** Search within node "container" for references for a search value, where the search value is defined as a - * tuple of(searchSymbol, searchText, searchLocation, and searchMeaning). - * searchLocation: a node where the search value - */ + * tuple of(searchSymbol, searchText, searchLocation, and searchMeaning). + * searchLocation: a node where the search value + */ function getReferencesInNode(container: Node, searchSymbol: Symbol, searchText: string, @@ -444,10 +444,10 @@ namespace ts.FindAllReferences { return; /* If we are just looking for implementations and this is a property access expression, we need to get the - * symbol of the local type of the symbol the property is being accessed on. This is because our search - * symbol may have a different parent symbol if the local type's symbol does not declare the property - * being accessed (i.e. it is declared in some parent class or interface) - */ + * symbol of the local type of the symbol the property is being accessed on. This is because our search + * symbol may have a different parent symbol if the local type's symbol does not declare the property + * being accessed (i.e. it is declared in some parent class or interface) + */ function getParentSymbolsOfPropertyAccess(): Symbol[] | undefined { if (implementations) { const propertyAccessExpression = getPropertyAccessExpressionFromRightHandSide(searchLocation); @@ -722,7 +722,7 @@ namespace ts.FindAllReferences { // Set the key so that we don't infinitely recurse cachedResults[key] = false; - const inherits = forEach(symbol.getDeclarations(), (declaration) => { + const inherits = forEach(symbol.getDeclarations(), declaration => { if (isClassLike(declaration)) { if (parentIsInterface) { const interfaceReferences = getClassImplementsHeritageClauseElements(declaration); diff --git a/src/services/goToImplementation.ts b/src/services/goToImplementation.ts index 48c0791eb04..123d29630ad 100644 --- a/src/services/goToImplementation.ts +++ b/src/services/goToImplementation.ts @@ -1,27 +1,27 @@ /* @internal */ namespace ts.GoToImplementation { - export function getImplementationAtPosition(typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFiles: SourceFile[], node: Node): ImplementationLocation[] { - // If invoked directly on a shorthand property assignment, then return - // the declaration of the symbol being assigned (not the symbol being assigned to). - if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { - const result: ReferenceEntry[] = []; - FindAllReferences.getReferenceEntriesForShorthandPropertyAssignment(node, typeChecker, result); - return result.length > 0 ? result : undefined; - } - else if (node.kind === SyntaxKind.SuperKeyword || isSuperProperty(node.parent)) { - // References to and accesses on the super keyword only have one possible implementation, so no - // need to "Find all References" - const symbol = typeChecker.getSymbolAtLocation(node); - return symbol.valueDeclaration && [FindAllReferences.getReferenceEntryFromNode(symbol.valueDeclaration)]; - } - else { - // Perform "Find all References" and retrieve only those that are implementations - const referencedSymbols = FindAllReferences.getReferencedSymbolsForNode(typeChecker, cancellationToken, - node, sourceFiles, /*findInStrings*/false, /*findInComments*/false, /*implementations*/true); - const result = flatMap(referencedSymbols, symbol => - map(symbol.references, ({ textSpan, fileName }) => ({ textSpan, fileName }))); - - return result && result.length > 0 ? result : undefined; - } + export function getImplementationAtPosition(typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFiles: SourceFile[], node: Node): ImplementationLocation[] { + // If invoked directly on a shorthand property assignment, then return + // the declaration of the symbol being assigned (not the symbol being assigned to). + if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { + const result: ReferenceEntry[] = []; + FindAllReferences.getReferenceEntriesForShorthandPropertyAssignment(node, typeChecker, result); + return result.length > 0 ? result : undefined; } + else if (node.kind === SyntaxKind.SuperKeyword || isSuperProperty(node.parent)) { + // References to and accesses on the super keyword only have one possible implementation, so no + // need to "Find all References" + const symbol = typeChecker.getSymbolAtLocation(node); + return symbol.valueDeclaration && [FindAllReferences.getReferenceEntryFromNode(symbol.valueDeclaration)]; + } + else { + // Perform "Find all References" and retrieve only those that are implementations + const referencedSymbols = FindAllReferences.getReferencedSymbolsForNode(typeChecker, cancellationToken, + node, sourceFiles, /*findInStrings*/false, /*findInComments*/false, /*implementations*/true); + const result = flatMap(referencedSymbols, symbol => + map(symbol.references, ({ textSpan, fileName }) => ({ textSpan, fileName }))); + + return result && result.length > 0 ? result : undefined; + } + } } From 7c8a6cea9cfa01058c196101065e338360c8092c Mon Sep 17 00:00:00 2001 From: Rostislav Galimsky Date: Thu, 15 Sep 2016 08:06:41 +0300 Subject: [PATCH 31/46] revert tests --- tests/baselines/reference/findIndex.js | 10 ---------- tests/baselines/reference/findIndex.symbols | 11 ----------- tests/baselines/reference/findIndex.types | 16 ---------------- .../conformance/es6/arrayMethods/findIndex.ts | 5 ----- 4 files changed, 42 deletions(-) delete mode 100644 tests/baselines/reference/findIndex.js delete mode 100644 tests/baselines/reference/findIndex.symbols delete mode 100644 tests/baselines/reference/findIndex.types delete mode 100644 tests/cases/conformance/es6/arrayMethods/findIndex.ts diff --git a/tests/baselines/reference/findIndex.js b/tests/baselines/reference/findIndex.js deleted file mode 100644 index 434ee095bb0..00000000000 --- a/tests/baselines/reference/findIndex.js +++ /dev/null @@ -1,10 +0,0 @@ -//// [findIndex.ts] - -[].findIndex(function(elem, i, arr) { - return true; -}); - -//// [findIndex.js] -[].findIndex(function (elem, i, arr) { - return true; -}); diff --git a/tests/baselines/reference/findIndex.symbols b/tests/baselines/reference/findIndex.symbols deleted file mode 100644 index bebbaf6ff85..00000000000 --- a/tests/baselines/reference/findIndex.symbols +++ /dev/null @@ -1,11 +0,0 @@ -=== tests/cases/conformance/es6/arrayMethods/findIndex.ts === - -[].findIndex(function(elem, i, arr) { ->[].findIndex : Symbol(Array.findIndex, Decl(lib.es2015.core.d.ts, --, --)) ->findIndex : Symbol(Array.findIndex, Decl(lib.es2015.core.d.ts, --, --)) ->elem : Symbol(elem, Decl(findIndex.ts, 1, 22)) ->i : Symbol(i, Decl(findIndex.ts, 1, 27)) ->arr : Symbol(arr, Decl(findIndex.ts, 1, 30)) - - return true; -}); diff --git a/tests/baselines/reference/findIndex.types b/tests/baselines/reference/findIndex.types deleted file mode 100644 index 8538e1c7be3..00000000000 --- a/tests/baselines/reference/findIndex.types +++ /dev/null @@ -1,16 +0,0 @@ -=== tests/cases/conformance/es6/arrayMethods/findIndex.ts === - -[].findIndex(function(elem, i, arr) { ->[].findIndex(function(elem, i, arr) { return true;}) : number ->[].findIndex : (predicate: (value: any, index: number, obj: any[]) => boolean, thisArg?: any) => number ->[] : undefined[] ->findIndex : (predicate: (value: any, index: number, obj: any[]) => boolean, thisArg?: any) => number ->function(elem, i, arr) { return true;} : (elem: any, i: number, arr: any[]) => boolean ->elem : any ->i : number ->arr : any[] - - return true; ->true : boolean - -}); diff --git a/tests/cases/conformance/es6/arrayMethods/findIndex.ts b/tests/cases/conformance/es6/arrayMethods/findIndex.ts deleted file mode 100644 index c726c654acb..00000000000 --- a/tests/cases/conformance/es6/arrayMethods/findIndex.ts +++ /dev/null @@ -1,5 +0,0 @@ -//@target: ES6 - -[].findIndex(function(elem, i, arr) { - return true; -}); \ No newline at end of file From 62f7c8a23d1ccac64c903b713417aede55f03f7c Mon Sep 17 00:00:00 2001 From: Rostislav Galimsky Date: Thu, 15 Sep 2016 08:29:55 +0300 Subject: [PATCH 32/46] revert fix for generated files --- lib/lib.es2015.core.d.ts | 2 +- lib/lib.es6.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/lib.es2015.core.d.ts b/lib/lib.es2015.core.d.ts index c92a44c2312..c7c7afb821b 100644 --- a/lib/lib.es2015.core.d.ts +++ b/lib/lib.es2015.core.d.ts @@ -37,7 +37,7 @@ interface Array { * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ - findIndex(predicate: (value: T, index: number, obj: Array) => boolean, thisArg?: any): number; + findIndex(predicate: (value: T) => boolean, thisArg?: any): number; /** * Returns the this object after filling the section identified by start and end with value diff --git a/lib/lib.es6.d.ts b/lib/lib.es6.d.ts index a7faa4789a6..8e9de3f4ec9 100644 --- a/lib/lib.es6.d.ts +++ b/lib/lib.es6.d.ts @@ -4143,7 +4143,7 @@ interface Array { * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ - findIndex(predicate: (value: T, index: number, obj: Array) => boolean, thisArg?: any): number; + findIndex(predicate: (value: T) => boolean, thisArg?: any): number; /** * Returns the this object after filling the section identified by start and end with value From df5e176e179aee42a2f67517aafbecf88b0d27b4 Mon Sep 17 00:00:00 2001 From: Rostislav Galimsky Date: Thu, 15 Sep 2016 08:39:45 +0300 Subject: [PATCH 33/46] update findIndex for es5 typed arrays --- src/lib/es5.d.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index e4cbe323c68..4ddf6213ee7 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1539,7 +1539,7 @@ interface Int8Array { * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ - findIndex(predicate: (value: number) => boolean, thisArg?: any): number; + findIndex(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. @@ -1812,7 +1812,7 @@ interface Uint8Array { * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ - findIndex(predicate: (value: number) => boolean, thisArg?: any): number; + findIndex(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. @@ -2086,7 +2086,7 @@ interface Uint8ClampedArray { * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ - findIndex(predicate: (value: number) => boolean, thisArg?: any): number; + findIndex(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. @@ -2359,7 +2359,7 @@ interface Int16Array { * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ - findIndex(predicate: (value: number) => boolean, thisArg?: any): number; + findIndex(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. @@ -2633,7 +2633,7 @@ interface Uint16Array { * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ - findIndex(predicate: (value: number) => boolean, thisArg?: any): number; + findIndex(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. @@ -2906,7 +2906,7 @@ interface Int32Array { * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ - findIndex(predicate: (value: number) => boolean, thisArg?: any): number; + findIndex(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. @@ -3179,7 +3179,7 @@ interface Uint32Array { * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ - findIndex(predicate: (value: number) => boolean, thisArg?: any): number; + findIndex(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. @@ -3452,7 +3452,7 @@ interface Float32Array { * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ - findIndex(predicate: (value: number) => boolean, thisArg?: any): number; + findIndex(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. @@ -3726,7 +3726,7 @@ interface Float64Array { * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ - findIndex(predicate: (value: number) => boolean, thisArg?: any): number; + findIndex(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. From f26921b43a2f3ba6a72d8770077542de681fd6bb Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Thu, 15 Sep 2016 08:59:14 -0700 Subject: [PATCH 34/46] Make declaration emit test name consistent --- ...usage.ts => declarationEmitArrayTypesFromGenericArrayUsage.ts} | 0 ...nEmit_bindingPatterns.ts => declarationEmitBindingPatterns.ts} | 0 ...rNameConflict.ts => declarationEmitClassMemberNameConflict.ts} | 0 ...ameConflict2.ts => declarationEmitClassMemberNameConflict2.ts} | 0 ...mit_exportAssignment.ts => declarationEmitExportAssignment.ts} | 0 ...t_exportDeclaration.ts => declarationEmitExportDeclaration.ts} | 0 ...pressionInExtends.ts => declarationEmitExpressionInExtends.ts} | 0 ...essionInExtends2.ts => declarationEmitExpressionInExtends2.ts} | 0 ...essionInExtends3.ts => declarationEmitExpressionInExtends3.ts} | 0 ...essionInExtends4.ts => declarationEmitExpressionInExtends4.ts} | 0 ...ltExportType.ts => declarationEmitInferedDefaultExportType.ts} | 0 ...ExportType2.ts => declarationEmitInferedDefaultExportType2.ts} | 0 ...ationEmit_invalidExport.ts => declarationEmitInvalidExport.ts} | 0 ...mit_invalidReference.ts => declarationEmitInvalidReference.ts} | 0 ...t_invalidReference2.ts => declarationEmitInvalidReference2.ts} | 0 ...ationEmit_nameConflicts.ts => declarationEmitNameConflicts.ts} | 0 ...ionEmit_nameConflicts2.ts => declarationEmitNameConflicts2.ts} | 0 ...ionEmit_nameConflicts3.ts => declarationEmitNameConflicts3.ts} | 0 ...lictsWithAlias.ts => declarationEmitNameConflictsWithAlias.ts} | 0 ...mit_protectedMembers.ts => declarationEmitProtectedMembers.ts} | 0 ...ationEmit_UnknownImport.ts => declarationEmitUnknownImport.ts} | 0 ...ionEmit_UnknownImport2.ts => declarationEmitUnknownImport2.ts} | 0 22 files changed, 0 insertions(+), 0 deletions(-) rename tests/cases/compiler/{declarationEmit_array-types-from-generic-array-usage.ts => declarationEmitArrayTypesFromGenericArrayUsage.ts} (100%) rename tests/cases/compiler/{declarationEmit_bindingPatterns.ts => declarationEmitBindingPatterns.ts} (100%) rename tests/cases/compiler/{declarationEmit_classMemberNameConflict.ts => declarationEmitClassMemberNameConflict.ts} (100%) rename tests/cases/compiler/{declarationEmit_classMemberNameConflict2.ts => declarationEmitClassMemberNameConflict2.ts} (100%) rename tests/cases/compiler/{declarationEmit_exportAssignment.ts => declarationEmitExportAssignment.ts} (100%) rename tests/cases/compiler/{declarationEmit_exportDeclaration.ts => declarationEmitExportDeclaration.ts} (100%) rename tests/cases/compiler/{declarationEmit_expressionInExtends.ts => declarationEmitExpressionInExtends.ts} (100%) rename tests/cases/compiler/{declarationEmit_expressionInExtends2.ts => declarationEmitExpressionInExtends2.ts} (100%) rename tests/cases/compiler/{declarationEmit_expressionInExtends3.ts => declarationEmitExpressionInExtends3.ts} (100%) rename tests/cases/compiler/{declarationEmit_expressionInExtends4.ts => declarationEmitExpressionInExtends4.ts} (100%) rename tests/cases/compiler/{declarationEmit_inferedDefaultExportType.ts => declarationEmitInferedDefaultExportType.ts} (100%) rename tests/cases/compiler/{declarationEmit_inferedDefaultExportType2.ts => declarationEmitInferedDefaultExportType2.ts} (100%) rename tests/cases/compiler/{declarationEmit_invalidExport.ts => declarationEmitInvalidExport.ts} (100%) rename tests/cases/compiler/{declarationEmit_invalidReference.ts => declarationEmitInvalidReference.ts} (100%) rename tests/cases/compiler/{declarationEmit_invalidReference2.ts => declarationEmitInvalidReference2.ts} (100%) rename tests/cases/compiler/{declarationEmit_nameConflicts.ts => declarationEmitNameConflicts.ts} (100%) rename tests/cases/compiler/{declarationEmit_nameConflicts2.ts => declarationEmitNameConflicts2.ts} (100%) rename tests/cases/compiler/{declarationEmit_nameConflicts3.ts => declarationEmitNameConflicts3.ts} (100%) rename tests/cases/compiler/{declarationEmit_nameConflictsWithAlias.ts => declarationEmitNameConflictsWithAlias.ts} (100%) rename tests/cases/compiler/{declarationEmit_protectedMembers.ts => declarationEmitProtectedMembers.ts} (100%) rename tests/cases/compiler/{declarationEmit_UnknownImport.ts => declarationEmitUnknownImport.ts} (100%) rename tests/cases/compiler/{declarationEmit_UnknownImport2.ts => declarationEmitUnknownImport2.ts} (100%) diff --git a/tests/cases/compiler/declarationEmit_array-types-from-generic-array-usage.ts b/tests/cases/compiler/declarationEmitArrayTypesFromGenericArrayUsage.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_array-types-from-generic-array-usage.ts rename to tests/cases/compiler/declarationEmitArrayTypesFromGenericArrayUsage.ts diff --git a/tests/cases/compiler/declarationEmit_bindingPatterns.ts b/tests/cases/compiler/declarationEmitBindingPatterns.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_bindingPatterns.ts rename to tests/cases/compiler/declarationEmitBindingPatterns.ts diff --git a/tests/cases/compiler/declarationEmit_classMemberNameConflict.ts b/tests/cases/compiler/declarationEmitClassMemberNameConflict.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_classMemberNameConflict.ts rename to tests/cases/compiler/declarationEmitClassMemberNameConflict.ts diff --git a/tests/cases/compiler/declarationEmit_classMemberNameConflict2.ts b/tests/cases/compiler/declarationEmitClassMemberNameConflict2.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_classMemberNameConflict2.ts rename to tests/cases/compiler/declarationEmitClassMemberNameConflict2.ts diff --git a/tests/cases/compiler/declarationEmit_exportAssignment.ts b/tests/cases/compiler/declarationEmitExportAssignment.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_exportAssignment.ts rename to tests/cases/compiler/declarationEmitExportAssignment.ts diff --git a/tests/cases/compiler/declarationEmit_exportDeclaration.ts b/tests/cases/compiler/declarationEmitExportDeclaration.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_exportDeclaration.ts rename to tests/cases/compiler/declarationEmitExportDeclaration.ts diff --git a/tests/cases/compiler/declarationEmit_expressionInExtends.ts b/tests/cases/compiler/declarationEmitExpressionInExtends.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_expressionInExtends.ts rename to tests/cases/compiler/declarationEmitExpressionInExtends.ts diff --git a/tests/cases/compiler/declarationEmit_expressionInExtends2.ts b/tests/cases/compiler/declarationEmitExpressionInExtends2.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_expressionInExtends2.ts rename to tests/cases/compiler/declarationEmitExpressionInExtends2.ts diff --git a/tests/cases/compiler/declarationEmit_expressionInExtends3.ts b/tests/cases/compiler/declarationEmitExpressionInExtends3.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_expressionInExtends3.ts rename to tests/cases/compiler/declarationEmitExpressionInExtends3.ts diff --git a/tests/cases/compiler/declarationEmit_expressionInExtends4.ts b/tests/cases/compiler/declarationEmitExpressionInExtends4.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_expressionInExtends4.ts rename to tests/cases/compiler/declarationEmitExpressionInExtends4.ts diff --git a/tests/cases/compiler/declarationEmit_inferedDefaultExportType.ts b/tests/cases/compiler/declarationEmitInferedDefaultExportType.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_inferedDefaultExportType.ts rename to tests/cases/compiler/declarationEmitInferedDefaultExportType.ts diff --git a/tests/cases/compiler/declarationEmit_inferedDefaultExportType2.ts b/tests/cases/compiler/declarationEmitInferedDefaultExportType2.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_inferedDefaultExportType2.ts rename to tests/cases/compiler/declarationEmitInferedDefaultExportType2.ts diff --git a/tests/cases/compiler/declarationEmit_invalidExport.ts b/tests/cases/compiler/declarationEmitInvalidExport.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_invalidExport.ts rename to tests/cases/compiler/declarationEmitInvalidExport.ts diff --git a/tests/cases/compiler/declarationEmit_invalidReference.ts b/tests/cases/compiler/declarationEmitInvalidReference.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_invalidReference.ts rename to tests/cases/compiler/declarationEmitInvalidReference.ts diff --git a/tests/cases/compiler/declarationEmit_invalidReference2.ts b/tests/cases/compiler/declarationEmitInvalidReference2.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_invalidReference2.ts rename to tests/cases/compiler/declarationEmitInvalidReference2.ts diff --git a/tests/cases/compiler/declarationEmit_nameConflicts.ts b/tests/cases/compiler/declarationEmitNameConflicts.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_nameConflicts.ts rename to tests/cases/compiler/declarationEmitNameConflicts.ts diff --git a/tests/cases/compiler/declarationEmit_nameConflicts2.ts b/tests/cases/compiler/declarationEmitNameConflicts2.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_nameConflicts2.ts rename to tests/cases/compiler/declarationEmitNameConflicts2.ts diff --git a/tests/cases/compiler/declarationEmit_nameConflicts3.ts b/tests/cases/compiler/declarationEmitNameConflicts3.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_nameConflicts3.ts rename to tests/cases/compiler/declarationEmitNameConflicts3.ts diff --git a/tests/cases/compiler/declarationEmit_nameConflictsWithAlias.ts b/tests/cases/compiler/declarationEmitNameConflictsWithAlias.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_nameConflictsWithAlias.ts rename to tests/cases/compiler/declarationEmitNameConflictsWithAlias.ts diff --git a/tests/cases/compiler/declarationEmit_protectedMembers.ts b/tests/cases/compiler/declarationEmitProtectedMembers.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_protectedMembers.ts rename to tests/cases/compiler/declarationEmitProtectedMembers.ts diff --git a/tests/cases/compiler/declarationEmit_UnknownImport.ts b/tests/cases/compiler/declarationEmitUnknownImport.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_UnknownImport.ts rename to tests/cases/compiler/declarationEmitUnknownImport.ts diff --git a/tests/cases/compiler/declarationEmit_UnknownImport2.ts b/tests/cases/compiler/declarationEmitUnknownImport2.ts similarity index 100% rename from tests/cases/compiler/declarationEmit_UnknownImport2.ts rename to tests/cases/compiler/declarationEmitUnknownImport2.ts From dc501f47c20fff0e0ed728f18a6914db166b35e0 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Thu, 15 Sep 2016 09:21:14 -0700 Subject: [PATCH 35/46] Update baselines --- ...tionEmitArrayTypesFromGenericArrayUsage.js | 10 ++ ...mitArrayTypesFromGenericArrayUsage.symbols | 5 + ...nEmitArrayTypesFromGenericArrayUsage.types | 5 + ...s.js => declarationEmitBindingPatterns.js} | 6 +- .../declarationEmitBindingPatterns.symbols | 17 +++ ...s => declarationEmitBindingPatterns.types} | 2 +- ...declarationEmitClassMemberNameConflict.js} | 6 +- ...arationEmitClassMemberNameConflict.symbols | 70 +++++++++++ ...larationEmitClassMemberNameConflict.types} | 2 +- ...eclarationEmitClassMemberNameConflict2.js} | 6 +- ...rationEmitClassMemberNameConflict2.symbols | 37 ++++++ ...arationEmitClassMemberNameConflict2.types} | 2 +- ....js => declarationEmitExportAssignment.js} | 2 +- ...> declarationEmitExportAssignment.symbols} | 0 ... => declarationEmitExportAssignment.types} | 0 ...js => declarationEmitExportDeclaration.js} | 2 +- ... declarationEmitExportDeclaration.symbols} | 0 ...=> declarationEmitExportDeclaration.types} | 0 ... => declarationEmitExpressionInExtends.js} | 6 +- ...declarationEmitExpressionInExtends.symbols | 32 +++++ ... declarationEmitExpressionInExtends.types} | 2 +- ...=> declarationEmitExpressionInExtends2.js} | 6 +- ...eclarationEmitExpressionInExtends2.symbols | 30 +++++ ...declarationEmitExpressionInExtends2.types} | 2 +- ...rationEmitExpressionInExtends3.errors.txt} | 6 +- ...=> declarationEmitExpressionInExtends3.js} | 4 +- ...rationEmitExpressionInExtends4.errors.txt} | 12 +- ...=> declarationEmitExpressionInExtends4.js} | 4 +- ...eclarationEmitInferedDefaultExportType.js} | 6 +- ...rationEmitInferedDefaultExportType.symbols | 14 +++ ...arationEmitInferedDefaultExportType.types} | 2 +- ...clarationEmitInferedDefaultExportType2.js} | 6 +- ...ationEmitInferedDefaultExportType2.symbols | 14 +++ ...rationEmitInferedDefaultExportType2.types} | 2 +- .../declarationEmitInvalidExport.errors.txt | 19 +++ ...ort.js => declarationEmitInvalidExport.js} | 4 +- .../declarationEmitInvalidReference.js | 11 ++ .../declarationEmitInvalidReference.symbols | 5 + .../declarationEmitInvalidReference.types | 6 + ...eclarationEmitInvalidReference2.errors.txt | 8 ++ .../declarationEmitInvalidReference2.js | 11 ++ ...cts.js => declarationEmitNameConflicts.js} | 2 +- ...s => declarationEmitNameConflicts.symbols} | 0 ...pes => declarationEmitNameConflicts.types} | 0 ...s2.js => declarationEmitNameConflicts2.js} | 6 +- .../declarationEmitNameConflicts2.symbols | 68 +++++++++++ ...es => declarationEmitNameConflicts2.types} | 2 +- ...s3.js => declarationEmitNameConflicts3.js} | 6 +- .../declarationEmitNameConflicts3.symbols | 76 ++++++++++++ ...es => declarationEmitNameConflicts3.types} | 2 +- ... declarationEmitNameConflictsWithAlias.js} | 6 +- ...larationEmitNameConflictsWithAlias.symbols | 21 ++++ ...clarationEmitNameConflictsWithAlias.types} | 2 +- ....js => declarationEmitProtectedMembers.js} | 6 +- .../declarationEmitProtectedMembers.symbols | 114 ++++++++++++++++++ ... => declarationEmitProtectedMembers.types} | 2 +- ...readonly.js => declarationEmitReadonly.js} | 6 +- .../reference/declarationEmitReadonly.symbols | 8 ++ ...ly.types => declarationEmitReadonly.types} | 2 +- .../declarationEmitUnknownImport.errors.txt | 15 +++ ...ort.js => declarationEmitUnknownImport.js} | 4 +- .../declarationEmitUnknownImport2.errors.txt | 21 ++++ ...t2.js => declarationEmitUnknownImport2.js} | 4 +- .../declarationEmit_UnknownImport.errors.txt | 15 --- .../declarationEmit_UnknownImport2.errors.txt | 21 ---- ...it_array-types-from-generic-array-usage.js | 10 -- ...ray-types-from-generic-array-usage.symbols | 5 - ...array-types-from-generic-array-usage.types | 5 - .../declarationEmit_bindingPatterns.symbols | 17 --- ...rationEmit_classMemberNameConflict.symbols | 70 ----------- ...ationEmit_classMemberNameConflict2.symbols | 37 ------ ...eclarationEmit_expressionInExtends.symbols | 32 ----- ...clarationEmit_expressionInExtends2.symbols | 30 ----- ...ationEmit_inferedDefaultExportType.symbols | 14 --- ...tionEmit_inferedDefaultExportType2.symbols | 14 --- .../declarationEmit_invalidExport.errors.txt | 19 --- .../declarationEmit_invalidReference.js | 11 -- .../declarationEmit_invalidReference.symbols | 5 - .../declarationEmit_invalidReference.types | 6 - ...clarationEmit_invalidReference2.errors.txt | 8 -- .../declarationEmit_invalidReference2.js | 11 -- .../declarationEmit_nameConflicts2.symbols | 68 ----------- .../declarationEmit_nameConflicts3.symbols | 76 ------------ ...arationEmit_nameConflictsWithAlias.symbols | 21 ---- .../declarationEmit_protectedMembers.symbols | 114 ------------------ .../declarationEmit_readonly.symbols | 8 -- ...readonly.ts => declarationEmitReadonly.ts} | 0 87 files changed, 687 insertions(+), 687 deletions(-) create mode 100644 tests/baselines/reference/declarationEmitArrayTypesFromGenericArrayUsage.js create mode 100644 tests/baselines/reference/declarationEmitArrayTypesFromGenericArrayUsage.symbols create mode 100644 tests/baselines/reference/declarationEmitArrayTypesFromGenericArrayUsage.types rename tests/baselines/reference/{declarationEmit_bindingPatterns.js => declarationEmitBindingPatterns.js} (74%) create mode 100644 tests/baselines/reference/declarationEmitBindingPatterns.symbols rename tests/baselines/reference/{declarationEmit_bindingPatterns.types => declarationEmitBindingPatterns.types} (79%) rename tests/baselines/reference/{declarationEmit_classMemberNameConflict.js => declarationEmitClassMemberNameConflict.js} (90%) create mode 100644 tests/baselines/reference/declarationEmitClassMemberNameConflict.symbols rename tests/baselines/reference/{declarationEmit_classMemberNameConflict.types => declarationEmitClassMemberNameConflict.types} (89%) rename tests/baselines/reference/{declarationEmit_classMemberNameConflict2.js => declarationEmitClassMemberNameConflict2.js} (82%) create mode 100644 tests/baselines/reference/declarationEmitClassMemberNameConflict2.symbols rename tests/baselines/reference/{declarationEmit_classMemberNameConflict2.types => declarationEmitClassMemberNameConflict2.types} (80%) rename tests/baselines/reference/{declarationEmit_exportAssignment.js => declarationEmitExportAssignment.js} (84%) rename tests/baselines/reference/{declarationEmit_exportAssignment.symbols => declarationEmitExportAssignment.symbols} (100%) rename tests/baselines/reference/{declarationEmit_exportAssignment.types => declarationEmitExportAssignment.types} (100%) rename tests/baselines/reference/{declarationEmit_exportDeclaration.js => declarationEmitExportDeclaration.js} (85%) rename tests/baselines/reference/{declarationEmit_exportDeclaration.symbols => declarationEmitExportDeclaration.symbols} (100%) rename tests/baselines/reference/{declarationEmit_exportDeclaration.types => declarationEmitExportDeclaration.types} (100%) rename tests/baselines/reference/{declarationEmit_expressionInExtends.js => declarationEmitExpressionInExtends.js} (80%) create mode 100644 tests/baselines/reference/declarationEmitExpressionInExtends.symbols rename tests/baselines/reference/{declarationEmit_expressionInExtends.types => declarationEmitExpressionInExtends.types} (71%) rename tests/baselines/reference/{declarationEmit_expressionInExtends2.js => declarationEmitExpressionInExtends2.js} (82%) create mode 100644 tests/baselines/reference/declarationEmitExpressionInExtends2.symbols rename tests/baselines/reference/{declarationEmit_expressionInExtends2.types => declarationEmitExpressionInExtends2.types} (78%) rename tests/baselines/reference/{declarationEmit_expressionInExtends3.errors.txt => declarationEmitExpressionInExtends3.errors.txt} (73%) rename tests/baselines/reference/{declarationEmit_expressionInExtends3.js => declarationEmitExpressionInExtends3.js} (93%) rename tests/baselines/reference/{declarationEmit_expressionInExtends4.errors.txt => declarationEmitExpressionInExtends4.errors.txt} (51%) rename tests/baselines/reference/{declarationEmit_expressionInExtends4.js => declarationEmitExpressionInExtends4.js} (89%) rename tests/baselines/reference/{declarationEmit_inferedDefaultExportType.js => declarationEmitInferedDefaultExportType.js} (62%) create mode 100644 tests/baselines/reference/declarationEmitInferedDefaultExportType.symbols rename tests/baselines/reference/{declarationEmit_inferedDefaultExportType.types => declarationEmitInferedDefaultExportType.types} (74%) rename tests/baselines/reference/{declarationEmit_inferedDefaultExportType2.js => declarationEmitInferedDefaultExportType2.js} (57%) create mode 100644 tests/baselines/reference/declarationEmitInferedDefaultExportType2.symbols rename tests/baselines/reference/{declarationEmit_inferedDefaultExportType2.types => declarationEmitInferedDefaultExportType2.types} (74%) create mode 100644 tests/baselines/reference/declarationEmitInvalidExport.errors.txt rename tests/baselines/reference/{declarationEmit_invalidExport.js => declarationEmitInvalidExport.js} (61%) create mode 100644 tests/baselines/reference/declarationEmitInvalidReference.js create mode 100644 tests/baselines/reference/declarationEmitInvalidReference.symbols create mode 100644 tests/baselines/reference/declarationEmitInvalidReference.types create mode 100644 tests/baselines/reference/declarationEmitInvalidReference2.errors.txt create mode 100644 tests/baselines/reference/declarationEmitInvalidReference2.js rename tests/baselines/reference/{declarationEmit_nameConflicts.js => declarationEmitNameConflicts.js} (94%) rename tests/baselines/reference/{declarationEmit_nameConflicts.symbols => declarationEmitNameConflicts.symbols} (100%) rename tests/baselines/reference/{declarationEmit_nameConflicts.types => declarationEmitNameConflicts.types} (100%) rename tests/baselines/reference/{declarationEmit_nameConflicts2.js => declarationEmitNameConflicts2.js} (90%) create mode 100644 tests/baselines/reference/declarationEmitNameConflicts2.symbols rename tests/baselines/reference/{declarationEmit_nameConflicts2.types => declarationEmitNameConflicts2.types} (89%) rename tests/baselines/reference/{declarationEmit_nameConflicts3.js => declarationEmitNameConflicts3.js} (91%) create mode 100644 tests/baselines/reference/declarationEmitNameConflicts3.symbols rename tests/baselines/reference/{declarationEmit_nameConflicts3.types => declarationEmitNameConflicts3.types} (88%) rename tests/baselines/reference/{declarationEmit_nameConflictsWithAlias.js => declarationEmitNameConflictsWithAlias.js} (72%) create mode 100644 tests/baselines/reference/declarationEmitNameConflictsWithAlias.symbols rename tests/baselines/reference/{declarationEmit_nameConflictsWithAlias.types => declarationEmitNameConflictsWithAlias.types} (76%) rename tests/baselines/reference/{declarationEmit_protectedMembers.js => declarationEmitProtectedMembers.js} (93%) create mode 100644 tests/baselines/reference/declarationEmitProtectedMembers.symbols rename tests/baselines/reference/{declarationEmit_protectedMembers.types => declarationEmitProtectedMembers.types} (91%) rename tests/baselines/reference/{declarationEmit_readonly.js => declarationEmitReadonly.js} (63%) create mode 100644 tests/baselines/reference/declarationEmitReadonly.symbols rename tests/baselines/reference/{declarationEmit_readonly.types => declarationEmitReadonly.types} (70%) create mode 100644 tests/baselines/reference/declarationEmitUnknownImport.errors.txt rename tests/baselines/reference/{declarationEmit_UnknownImport.js => declarationEmitUnknownImport.js} (56%) create mode 100644 tests/baselines/reference/declarationEmitUnknownImport2.errors.txt rename tests/baselines/reference/{declarationEmit_UnknownImport2.js => declarationEmitUnknownImport2.js} (69%) delete mode 100644 tests/baselines/reference/declarationEmit_UnknownImport.errors.txt delete mode 100644 tests/baselines/reference/declarationEmit_UnknownImport2.errors.txt delete mode 100644 tests/baselines/reference/declarationEmit_array-types-from-generic-array-usage.js delete mode 100644 tests/baselines/reference/declarationEmit_array-types-from-generic-array-usage.symbols delete mode 100644 tests/baselines/reference/declarationEmit_array-types-from-generic-array-usage.types delete mode 100644 tests/baselines/reference/declarationEmit_bindingPatterns.symbols delete mode 100644 tests/baselines/reference/declarationEmit_classMemberNameConflict.symbols delete mode 100644 tests/baselines/reference/declarationEmit_classMemberNameConflict2.symbols delete mode 100644 tests/baselines/reference/declarationEmit_expressionInExtends.symbols delete mode 100644 tests/baselines/reference/declarationEmit_expressionInExtends2.symbols delete mode 100644 tests/baselines/reference/declarationEmit_inferedDefaultExportType.symbols delete mode 100644 tests/baselines/reference/declarationEmit_inferedDefaultExportType2.symbols delete mode 100644 tests/baselines/reference/declarationEmit_invalidExport.errors.txt delete mode 100644 tests/baselines/reference/declarationEmit_invalidReference.js delete mode 100644 tests/baselines/reference/declarationEmit_invalidReference.symbols delete mode 100644 tests/baselines/reference/declarationEmit_invalidReference.types delete mode 100644 tests/baselines/reference/declarationEmit_invalidReference2.errors.txt delete mode 100644 tests/baselines/reference/declarationEmit_invalidReference2.js delete mode 100644 tests/baselines/reference/declarationEmit_nameConflicts2.symbols delete mode 100644 tests/baselines/reference/declarationEmit_nameConflicts3.symbols delete mode 100644 tests/baselines/reference/declarationEmit_nameConflictsWithAlias.symbols delete mode 100644 tests/baselines/reference/declarationEmit_protectedMembers.symbols delete mode 100644 tests/baselines/reference/declarationEmit_readonly.symbols rename tests/cases/conformance/classes/constructorDeclarations/constructorParameters/{declarationEmit_readonly.ts => declarationEmitReadonly.ts} (100%) diff --git a/tests/baselines/reference/declarationEmitArrayTypesFromGenericArrayUsage.js b/tests/baselines/reference/declarationEmitArrayTypesFromGenericArrayUsage.js new file mode 100644 index 00000000000..4fd9534080f --- /dev/null +++ b/tests/baselines/reference/declarationEmitArrayTypesFromGenericArrayUsage.js @@ -0,0 +1,10 @@ +//// [declarationEmitArrayTypesFromGenericArrayUsage.ts] +interface A extends Array { } + + +//// [declarationEmitArrayTypesFromGenericArrayUsage.js] + + +//// [declarationEmitArrayTypesFromGenericArrayUsage.d.ts] +interface A extends Array { +} diff --git a/tests/baselines/reference/declarationEmitArrayTypesFromGenericArrayUsage.symbols b/tests/baselines/reference/declarationEmitArrayTypesFromGenericArrayUsage.symbols new file mode 100644 index 00000000000..33c9d38355a --- /dev/null +++ b/tests/baselines/reference/declarationEmitArrayTypesFromGenericArrayUsage.symbols @@ -0,0 +1,5 @@ +=== tests/cases/compiler/declarationEmitArrayTypesFromGenericArrayUsage.ts === +interface A extends Array { } +>A : Symbol(A, Decl(declarationEmitArrayTypesFromGenericArrayUsage.ts, 0, 0)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + diff --git a/tests/baselines/reference/declarationEmitArrayTypesFromGenericArrayUsage.types b/tests/baselines/reference/declarationEmitArrayTypesFromGenericArrayUsage.types new file mode 100644 index 00000000000..25350552a5f --- /dev/null +++ b/tests/baselines/reference/declarationEmitArrayTypesFromGenericArrayUsage.types @@ -0,0 +1,5 @@ +=== tests/cases/compiler/declarationEmitArrayTypesFromGenericArrayUsage.ts === +interface A extends Array { } +>A : A +>Array : T[] + diff --git a/tests/baselines/reference/declarationEmit_bindingPatterns.js b/tests/baselines/reference/declarationEmitBindingPatterns.js similarity index 74% rename from tests/baselines/reference/declarationEmit_bindingPatterns.js rename to tests/baselines/reference/declarationEmitBindingPatterns.js index 8cc52af53b8..c55d885a1ca 100644 --- a/tests/baselines/reference/declarationEmit_bindingPatterns.js +++ b/tests/baselines/reference/declarationEmitBindingPatterns.js @@ -1,4 +1,4 @@ -//// [declarationEmit_bindingPatterns.ts] +//// [declarationEmitBindingPatterns.ts] const k = ({x: z = 'y'}) => { } @@ -6,7 +6,7 @@ var a; function f({} = a, [] = a, { p: {} = a} = a) { } -//// [declarationEmit_bindingPatterns.js] +//// [declarationEmitBindingPatterns.js] var k = function (_a) { var _b = _a.x, z = _b === void 0 ? 'y' : _b; }; @@ -18,7 +18,7 @@ function f(_a, _b, _c) { } -//// [declarationEmit_bindingPatterns.d.ts] +//// [declarationEmitBindingPatterns.d.ts] declare const k: ({x: z}: { x?: string; }) => void; diff --git a/tests/baselines/reference/declarationEmitBindingPatterns.symbols b/tests/baselines/reference/declarationEmitBindingPatterns.symbols new file mode 100644 index 00000000000..705610bf04f --- /dev/null +++ b/tests/baselines/reference/declarationEmitBindingPatterns.symbols @@ -0,0 +1,17 @@ +=== tests/cases/compiler/declarationEmitBindingPatterns.ts === + +const k = ({x: z = 'y'}) => { } +>k : Symbol(k, Decl(declarationEmitBindingPatterns.ts, 1, 5)) +>x : Symbol(x) +>z : Symbol(z, Decl(declarationEmitBindingPatterns.ts, 1, 12)) + +var a; +>a : Symbol(a, Decl(declarationEmitBindingPatterns.ts, 3, 3)) + +function f({} = a, [] = a, { p: {} = a} = a) { +>f : Symbol(f, Decl(declarationEmitBindingPatterns.ts, 3, 6)) +>a : Symbol(a, Decl(declarationEmitBindingPatterns.ts, 3, 3)) +>a : Symbol(a, Decl(declarationEmitBindingPatterns.ts, 3, 3)) +>a : Symbol(a, Decl(declarationEmitBindingPatterns.ts, 3, 3)) +>a : Symbol(a, Decl(declarationEmitBindingPatterns.ts, 3, 3)) +} diff --git a/tests/baselines/reference/declarationEmit_bindingPatterns.types b/tests/baselines/reference/declarationEmitBindingPatterns.types similarity index 79% rename from tests/baselines/reference/declarationEmit_bindingPatterns.types rename to tests/baselines/reference/declarationEmitBindingPatterns.types index b3da24a2b95..a0ae3f5aa14 100644 --- a/tests/baselines/reference/declarationEmit_bindingPatterns.types +++ b/tests/baselines/reference/declarationEmitBindingPatterns.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/declarationEmit_bindingPatterns.ts === +=== tests/cases/compiler/declarationEmitBindingPatterns.ts === const k = ({x: z = 'y'}) => { } >k : ({x: z}: { x?: string; }) => void diff --git a/tests/baselines/reference/declarationEmit_classMemberNameConflict.js b/tests/baselines/reference/declarationEmitClassMemberNameConflict.js similarity index 90% rename from tests/baselines/reference/declarationEmit_classMemberNameConflict.js rename to tests/baselines/reference/declarationEmitClassMemberNameConflict.js index 55acb13d2b9..23c83276201 100644 --- a/tests/baselines/reference/declarationEmit_classMemberNameConflict.js +++ b/tests/baselines/reference/declarationEmitClassMemberNameConflict.js @@ -1,4 +1,4 @@ -//// [declarationEmit_classMemberNameConflict.ts] +//// [declarationEmitClassMemberNameConflict.ts] export class C1 { C1() { } // has to be the same as the class name @@ -36,7 +36,7 @@ export class C4 { } } -//// [declarationEmit_classMemberNameConflict.js] +//// [declarationEmitClassMemberNameConflict.js] "use strict"; var C1 = (function () { function C1() { @@ -93,7 +93,7 @@ var C4 = (function () { exports.C4 = C4; -//// [declarationEmit_classMemberNameConflict.d.ts] +//// [declarationEmitClassMemberNameConflict.d.ts] export declare class C1 { C1(): void; bar(): (t: typeof C1) => void; diff --git a/tests/baselines/reference/declarationEmitClassMemberNameConflict.symbols b/tests/baselines/reference/declarationEmitClassMemberNameConflict.symbols new file mode 100644 index 00000000000..02ea2f015f3 --- /dev/null +++ b/tests/baselines/reference/declarationEmitClassMemberNameConflict.symbols @@ -0,0 +1,70 @@ +=== tests/cases/compiler/declarationEmitClassMemberNameConflict.ts === + +export class C1 { +>C1 : Symbol(C1, Decl(declarationEmitClassMemberNameConflict.ts, 0, 0)) + + C1() { } // has to be the same as the class name +>C1 : Symbol(C1.C1, Decl(declarationEmitClassMemberNameConflict.ts, 1, 17)) + + bar() { +>bar : Symbol(C1.bar, Decl(declarationEmitClassMemberNameConflict.ts, 2, 12)) + + return function (t: typeof C1) { +>t : Symbol(t, Decl(declarationEmitClassMemberNameConflict.ts, 5, 25)) +>C1 : Symbol(C1, Decl(declarationEmitClassMemberNameConflict.ts, 0, 0)) + + }; + } +} + +export class C2 { +>C2 : Symbol(C2, Decl(declarationEmitClassMemberNameConflict.ts, 8, 1)) + + C2: any // has to be the same as the class name +>C2 : Symbol(C2.C2, Decl(declarationEmitClassMemberNameConflict.ts, 10, 17)) + + bar() { +>bar : Symbol(C2.bar, Decl(declarationEmitClassMemberNameConflict.ts, 11, 11)) + + return function (t: typeof C2) { +>t : Symbol(t, Decl(declarationEmitClassMemberNameConflict.ts, 14, 25)) +>C2 : Symbol(C2, Decl(declarationEmitClassMemberNameConflict.ts, 8, 1)) + + }; + } +} + +export class C3 { +>C3 : Symbol(C3, Decl(declarationEmitClassMemberNameConflict.ts, 17, 1)) + + get C3() { return 0; } // has to be the same as the class name +>C3 : Symbol(C3.C3, Decl(declarationEmitClassMemberNameConflict.ts, 19, 17)) + + bar() { +>bar : Symbol(C3.bar, Decl(declarationEmitClassMemberNameConflict.ts, 20, 26)) + + return function (t: typeof C3) { +>t : Symbol(t, Decl(declarationEmitClassMemberNameConflict.ts, 23, 25)) +>C3 : Symbol(C3, Decl(declarationEmitClassMemberNameConflict.ts, 17, 1)) + + }; + } +} + +export class C4 { +>C4 : Symbol(C4, Decl(declarationEmitClassMemberNameConflict.ts, 26, 1)) + + set C4(v) { } // has to be the same as the class name +>C4 : Symbol(C4.C4, Decl(declarationEmitClassMemberNameConflict.ts, 28, 17)) +>v : Symbol(v, Decl(declarationEmitClassMemberNameConflict.ts, 29, 11)) + + bar() { +>bar : Symbol(C4.bar, Decl(declarationEmitClassMemberNameConflict.ts, 29, 17)) + + return function (t: typeof C4) { +>t : Symbol(t, Decl(declarationEmitClassMemberNameConflict.ts, 32, 25)) +>C4 : Symbol(C4, Decl(declarationEmitClassMemberNameConflict.ts, 26, 1)) + + }; + } +} diff --git a/tests/baselines/reference/declarationEmit_classMemberNameConflict.types b/tests/baselines/reference/declarationEmitClassMemberNameConflict.types similarity index 89% rename from tests/baselines/reference/declarationEmit_classMemberNameConflict.types rename to tests/baselines/reference/declarationEmitClassMemberNameConflict.types index 66bc493b2ee..266942f29c5 100644 --- a/tests/baselines/reference/declarationEmit_classMemberNameConflict.types +++ b/tests/baselines/reference/declarationEmitClassMemberNameConflict.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/declarationEmit_classMemberNameConflict.ts === +=== tests/cases/compiler/declarationEmitClassMemberNameConflict.ts === export class C1 { >C1 : C1 diff --git a/tests/baselines/reference/declarationEmit_classMemberNameConflict2.js b/tests/baselines/reference/declarationEmitClassMemberNameConflict2.js similarity index 82% rename from tests/baselines/reference/declarationEmit_classMemberNameConflict2.js rename to tests/baselines/reference/declarationEmitClassMemberNameConflict2.js index d3ebddc8d17..233ca0fe138 100644 --- a/tests/baselines/reference/declarationEmit_classMemberNameConflict2.js +++ b/tests/baselines/reference/declarationEmitClassMemberNameConflict2.js @@ -1,4 +1,4 @@ -//// [declarationEmit_classMemberNameConflict2.ts] +//// [declarationEmitClassMemberNameConflict2.ts] const Bar = 'bar'; @@ -21,7 +21,7 @@ class Foo { Hello2 = Hello1; } -//// [declarationEmit_classMemberNameConflict2.js] +//// [declarationEmitClassMemberNameConflict2.js] var Bar = 'bar'; var Hello; (function (Hello) { @@ -44,7 +44,7 @@ var Foo = (function () { }()); -//// [declarationEmit_classMemberNameConflict2.d.ts] +//// [declarationEmitClassMemberNameConflict2.d.ts] declare const Bar: "bar"; declare enum Hello { World = 0, diff --git a/tests/baselines/reference/declarationEmitClassMemberNameConflict2.symbols b/tests/baselines/reference/declarationEmitClassMemberNameConflict2.symbols new file mode 100644 index 00000000000..059200c6074 --- /dev/null +++ b/tests/baselines/reference/declarationEmitClassMemberNameConflict2.symbols @@ -0,0 +1,37 @@ +=== tests/cases/compiler/declarationEmitClassMemberNameConflict2.ts === + +const Bar = 'bar'; +>Bar : Symbol(Bar, Decl(declarationEmitClassMemberNameConflict2.ts, 1, 5)) + +enum Hello { +>Hello : Symbol(Hello, Decl(declarationEmitClassMemberNameConflict2.ts, 1, 18)) + + World +>World : Symbol(Hello.World, Decl(declarationEmitClassMemberNameConflict2.ts, 3, 12)) +} + +enum Hello1 { +>Hello1 : Symbol(Hello1, Decl(declarationEmitClassMemberNameConflict2.ts, 5, 1)) + + World1 +>World1 : Symbol(Hello1.World1, Decl(declarationEmitClassMemberNameConflict2.ts, 7, 13)) +} + +class Foo { +>Foo : Symbol(Foo, Decl(declarationEmitClassMemberNameConflict2.ts, 9, 1)) + + // Same names + string => OK + Bar = Bar; +>Bar : Symbol(Foo.Bar, Decl(declarationEmitClassMemberNameConflict2.ts, 11, 11)) +>Bar : Symbol(Bar, Decl(declarationEmitClassMemberNameConflict2.ts, 1, 5)) + + // Same names + enum => OK + Hello = Hello; +>Hello : Symbol(Foo.Hello, Decl(declarationEmitClassMemberNameConflict2.ts, 13, 14)) +>Hello : Symbol(Hello, Decl(declarationEmitClassMemberNameConflict2.ts, 1, 18)) + + // Different names + enum => OK + Hello2 = Hello1; +>Hello2 : Symbol(Foo.Hello2, Decl(declarationEmitClassMemberNameConflict2.ts, 16, 18)) +>Hello1 : Symbol(Hello1, Decl(declarationEmitClassMemberNameConflict2.ts, 5, 1)) +} diff --git a/tests/baselines/reference/declarationEmit_classMemberNameConflict2.types b/tests/baselines/reference/declarationEmitClassMemberNameConflict2.types similarity index 80% rename from tests/baselines/reference/declarationEmit_classMemberNameConflict2.types rename to tests/baselines/reference/declarationEmitClassMemberNameConflict2.types index dd184f7ba34..f355a9002c8 100644 --- a/tests/baselines/reference/declarationEmit_classMemberNameConflict2.types +++ b/tests/baselines/reference/declarationEmitClassMemberNameConflict2.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/declarationEmit_classMemberNameConflict2.ts === +=== tests/cases/compiler/declarationEmitClassMemberNameConflict2.ts === const Bar = 'bar'; >Bar : "bar" diff --git a/tests/baselines/reference/declarationEmit_exportAssignment.js b/tests/baselines/reference/declarationEmitExportAssignment.js similarity index 84% rename from tests/baselines/reference/declarationEmit_exportAssignment.js rename to tests/baselines/reference/declarationEmitExportAssignment.js index 36f698ec6c7..8c97ef8eb07 100644 --- a/tests/baselines/reference/declarationEmit_exportAssignment.js +++ b/tests/baselines/reference/declarationEmitExportAssignment.js @@ -1,4 +1,4 @@ -//// [tests/cases/compiler/declarationEmit_exportAssignment.ts] //// +//// [tests/cases/compiler/declarationEmitExportAssignment.ts] //// //// [utils.ts] diff --git a/tests/baselines/reference/declarationEmit_exportAssignment.symbols b/tests/baselines/reference/declarationEmitExportAssignment.symbols similarity index 100% rename from tests/baselines/reference/declarationEmit_exportAssignment.symbols rename to tests/baselines/reference/declarationEmitExportAssignment.symbols diff --git a/tests/baselines/reference/declarationEmit_exportAssignment.types b/tests/baselines/reference/declarationEmitExportAssignment.types similarity index 100% rename from tests/baselines/reference/declarationEmit_exportAssignment.types rename to tests/baselines/reference/declarationEmitExportAssignment.types diff --git a/tests/baselines/reference/declarationEmit_exportDeclaration.js b/tests/baselines/reference/declarationEmitExportDeclaration.js similarity index 85% rename from tests/baselines/reference/declarationEmit_exportDeclaration.js rename to tests/baselines/reference/declarationEmitExportDeclaration.js index 6c6c37bbcfd..dfbed90742d 100644 --- a/tests/baselines/reference/declarationEmit_exportDeclaration.js +++ b/tests/baselines/reference/declarationEmitExportDeclaration.js @@ -1,4 +1,4 @@ -//// [tests/cases/compiler/declarationEmit_exportDeclaration.ts] //// +//// [tests/cases/compiler/declarationEmitExportDeclaration.ts] //// //// [utils.ts] diff --git a/tests/baselines/reference/declarationEmit_exportDeclaration.symbols b/tests/baselines/reference/declarationEmitExportDeclaration.symbols similarity index 100% rename from tests/baselines/reference/declarationEmit_exportDeclaration.symbols rename to tests/baselines/reference/declarationEmitExportDeclaration.symbols diff --git a/tests/baselines/reference/declarationEmit_exportDeclaration.types b/tests/baselines/reference/declarationEmitExportDeclaration.types similarity index 100% rename from tests/baselines/reference/declarationEmit_exportDeclaration.types rename to tests/baselines/reference/declarationEmitExportDeclaration.types diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends.js b/tests/baselines/reference/declarationEmitExpressionInExtends.js similarity index 80% rename from tests/baselines/reference/declarationEmit_expressionInExtends.js rename to tests/baselines/reference/declarationEmitExpressionInExtends.js index 061042aa34b..a7b2a6c7873 100644 --- a/tests/baselines/reference/declarationEmit_expressionInExtends.js +++ b/tests/baselines/reference/declarationEmitExpressionInExtends.js @@ -1,4 +1,4 @@ -//// [declarationEmit_expressionInExtends.ts] +//// [declarationEmitExpressionInExtends.ts] var x: { new(s: any): Q; @@ -14,7 +14,7 @@ class B extends x { var q: B; q.s; -//// [declarationEmit_expressionInExtends.js] +//// [declarationEmitExpressionInExtends.js] var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -37,7 +37,7 @@ var q; q.s; -//// [declarationEmit_expressionInExtends.d.ts] +//// [declarationEmitExpressionInExtends.d.ts] declare var x: { new (s: any): Q; }; diff --git a/tests/baselines/reference/declarationEmitExpressionInExtends.symbols b/tests/baselines/reference/declarationEmitExpressionInExtends.symbols new file mode 100644 index 00000000000..8ae1e2928fd --- /dev/null +++ b/tests/baselines/reference/declarationEmitExpressionInExtends.symbols @@ -0,0 +1,32 @@ +=== tests/cases/compiler/declarationEmitExpressionInExtends.ts === + +var x: { +>x : Symbol(x, Decl(declarationEmitExpressionInExtends.ts, 1, 3)) + + new(s: any): Q; +>T : Symbol(T, Decl(declarationEmitExpressionInExtends.ts, 2, 8)) +>s : Symbol(s, Decl(declarationEmitExpressionInExtends.ts, 2, 11)) +>Q : Symbol(Q, Decl(declarationEmitExpressionInExtends.ts, 3, 1)) +} + +class Q { +>Q : Symbol(Q, Decl(declarationEmitExpressionInExtends.ts, 3, 1)) + + s: string; +>s : Symbol(Q.s, Decl(declarationEmitExpressionInExtends.ts, 5, 9)) +} + +class B extends x { +>B : Symbol(B, Decl(declarationEmitExpressionInExtends.ts, 7, 1)) +>x : Symbol(x, Decl(declarationEmitExpressionInExtends.ts, 1, 3)) +} + +var q: B; +>q : Symbol(q, Decl(declarationEmitExpressionInExtends.ts, 12, 3)) +>B : Symbol(B, Decl(declarationEmitExpressionInExtends.ts, 7, 1)) + +q.s; +>q.s : Symbol(Q.s, Decl(declarationEmitExpressionInExtends.ts, 5, 9)) +>q : Symbol(q, Decl(declarationEmitExpressionInExtends.ts, 12, 3)) +>s : Symbol(Q.s, Decl(declarationEmitExpressionInExtends.ts, 5, 9)) + diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends.types b/tests/baselines/reference/declarationEmitExpressionInExtends.types similarity index 71% rename from tests/baselines/reference/declarationEmit_expressionInExtends.types rename to tests/baselines/reference/declarationEmitExpressionInExtends.types index 2e810fccf68..fdbec3f9c48 100644 --- a/tests/baselines/reference/declarationEmit_expressionInExtends.types +++ b/tests/baselines/reference/declarationEmitExpressionInExtends.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/declarationEmit_expressionInExtends.ts === +=== tests/cases/compiler/declarationEmitExpressionInExtends.ts === var x: { >x : new (s: any) => Q diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends2.js b/tests/baselines/reference/declarationEmitExpressionInExtends2.js similarity index 82% rename from tests/baselines/reference/declarationEmit_expressionInExtends2.js rename to tests/baselines/reference/declarationEmitExpressionInExtends2.js index da0478e26d0..09298fbd92d 100644 --- a/tests/baselines/reference/declarationEmit_expressionInExtends2.js +++ b/tests/baselines/reference/declarationEmitExpressionInExtends2.js @@ -1,4 +1,4 @@ -//// [declarationEmit_expressionInExtends2.ts] +//// [declarationEmitExpressionInExtends2.ts] class C { x: T; @@ -12,7 +12,7 @@ function getClass(c: T) { class MyClass extends getClass(2) { } -//// [declarationEmit_expressionInExtends2.js] +//// [declarationEmitExpressionInExtends2.js] var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -35,7 +35,7 @@ var MyClass = (function (_super) { }(getClass(2))); -//// [declarationEmit_expressionInExtends2.d.ts] +//// [declarationEmitExpressionInExtends2.d.ts] declare class C { x: T; y: U; diff --git a/tests/baselines/reference/declarationEmitExpressionInExtends2.symbols b/tests/baselines/reference/declarationEmitExpressionInExtends2.symbols new file mode 100644 index 00000000000..a07590a14c7 --- /dev/null +++ b/tests/baselines/reference/declarationEmitExpressionInExtends2.symbols @@ -0,0 +1,30 @@ +=== tests/cases/compiler/declarationEmitExpressionInExtends2.ts === + +class C { +>C : Symbol(C, Decl(declarationEmitExpressionInExtends2.ts, 0, 0)) +>T : Symbol(T, Decl(declarationEmitExpressionInExtends2.ts, 1, 8)) +>U : Symbol(U, Decl(declarationEmitExpressionInExtends2.ts, 1, 10)) + + x: T; +>x : Symbol(C.x, Decl(declarationEmitExpressionInExtends2.ts, 1, 15)) +>T : Symbol(T, Decl(declarationEmitExpressionInExtends2.ts, 1, 8)) + + y: U; +>y : Symbol(C.y, Decl(declarationEmitExpressionInExtends2.ts, 2, 9)) +>U : Symbol(U, Decl(declarationEmitExpressionInExtends2.ts, 1, 10)) +} + +function getClass(c: T) { +>getClass : Symbol(getClass, Decl(declarationEmitExpressionInExtends2.ts, 4, 1)) +>T : Symbol(T, Decl(declarationEmitExpressionInExtends2.ts, 6, 18)) +>c : Symbol(c, Decl(declarationEmitExpressionInExtends2.ts, 6, 21)) +>T : Symbol(T, Decl(declarationEmitExpressionInExtends2.ts, 6, 18)) + + return C; +>C : Symbol(C, Decl(declarationEmitExpressionInExtends2.ts, 0, 0)) +} + +class MyClass extends getClass(2) { +>MyClass : Symbol(MyClass, Decl(declarationEmitExpressionInExtends2.ts, 8, 1)) +>getClass : Symbol(getClass, Decl(declarationEmitExpressionInExtends2.ts, 4, 1)) +} diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends2.types b/tests/baselines/reference/declarationEmitExpressionInExtends2.types similarity index 78% rename from tests/baselines/reference/declarationEmit_expressionInExtends2.types rename to tests/baselines/reference/declarationEmitExpressionInExtends2.types index 3f2b8964a2d..04265e9f74e 100644 --- a/tests/baselines/reference/declarationEmit_expressionInExtends2.types +++ b/tests/baselines/reference/declarationEmitExpressionInExtends2.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/declarationEmit_expressionInExtends2.ts === +=== tests/cases/compiler/declarationEmitExpressionInExtends2.ts === class C { >C : C diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends3.errors.txt b/tests/baselines/reference/declarationEmitExpressionInExtends3.errors.txt similarity index 73% rename from tests/baselines/reference/declarationEmit_expressionInExtends3.errors.txt rename to tests/baselines/reference/declarationEmitExpressionInExtends3.errors.txt index 2783810c568..5ed622caafe 100644 --- a/tests/baselines/reference/declarationEmit_expressionInExtends3.errors.txt +++ b/tests/baselines/reference/declarationEmitExpressionInExtends3.errors.txt @@ -1,8 +1,8 @@ -tests/cases/compiler/declarationEmit_expressionInExtends3.ts(29,30): error TS4020: Extends clause of exported class 'MyClass' has or is using private name 'LocalClass'. -tests/cases/compiler/declarationEmit_expressionInExtends3.ts(37,31): error TS4020: Extends clause of exported class 'MyClass3' has or is using private name 'LocalInterface'. +tests/cases/compiler/declarationEmitExpressionInExtends3.ts(29,30): error TS4020: Extends clause of exported class 'MyClass' has or is using private name 'LocalClass'. +tests/cases/compiler/declarationEmitExpressionInExtends3.ts(37,31): error TS4020: Extends clause of exported class 'MyClass3' has or is using private name 'LocalInterface'. -==== tests/cases/compiler/declarationEmit_expressionInExtends3.ts (2 errors) ==== +==== tests/cases/compiler/declarationEmitExpressionInExtends3.ts (2 errors) ==== export class ExportedClass { x: T; diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends3.js b/tests/baselines/reference/declarationEmitExpressionInExtends3.js similarity index 93% rename from tests/baselines/reference/declarationEmit_expressionInExtends3.js rename to tests/baselines/reference/declarationEmitExpressionInExtends3.js index 10ef42d6838..c21074fc3b7 100644 --- a/tests/baselines/reference/declarationEmit_expressionInExtends3.js +++ b/tests/baselines/reference/declarationEmitExpressionInExtends3.js @@ -1,4 +1,4 @@ -//// [declarationEmit_expressionInExtends3.ts] +//// [declarationEmitExpressionInExtends3.ts] export class ExportedClass { x: T; @@ -43,7 +43,7 @@ export class MyClass4 extends getExportedClass(undefined)foo : Symbol(foo, Decl(declarationEmitInferedDefaultExportType.ts, 2, 16)) + + bar: undefined, +>bar : Symbol(bar, Decl(declarationEmitInferedDefaultExportType.ts, 3, 10)) +>undefined : Symbol(undefined) + + baz: null +>baz : Symbol(baz, Decl(declarationEmitInferedDefaultExportType.ts, 4, 17)) +} diff --git a/tests/baselines/reference/declarationEmit_inferedDefaultExportType.types b/tests/baselines/reference/declarationEmitInferedDefaultExportType.types similarity index 74% rename from tests/baselines/reference/declarationEmit_inferedDefaultExportType.types rename to tests/baselines/reference/declarationEmitInferedDefaultExportType.types index 0f5d0ceed91..5c01d22b32e 100644 --- a/tests/baselines/reference/declarationEmit_inferedDefaultExportType.types +++ b/tests/baselines/reference/declarationEmitInferedDefaultExportType.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/declarationEmit_inferedDefaultExportType.ts === +=== tests/cases/compiler/declarationEmitInferedDefaultExportType.ts === // test.ts export default { diff --git a/tests/baselines/reference/declarationEmit_inferedDefaultExportType2.js b/tests/baselines/reference/declarationEmitInferedDefaultExportType2.js similarity index 57% rename from tests/baselines/reference/declarationEmit_inferedDefaultExportType2.js rename to tests/baselines/reference/declarationEmitInferedDefaultExportType2.js index 617d4a9966b..a81c7fc0bb7 100644 --- a/tests/baselines/reference/declarationEmit_inferedDefaultExportType2.js +++ b/tests/baselines/reference/declarationEmitInferedDefaultExportType2.js @@ -1,4 +1,4 @@ -//// [declarationEmit_inferedDefaultExportType2.ts] +//// [declarationEmitInferedDefaultExportType2.ts] // test.ts export = { @@ -7,7 +7,7 @@ export = { baz: null } -//// [declarationEmit_inferedDefaultExportType2.js] +//// [declarationEmitInferedDefaultExportType2.js] "use strict"; module.exports = { foo: [], @@ -16,7 +16,7 @@ module.exports = { }; -//// [declarationEmit_inferedDefaultExportType2.d.ts] +//// [declarationEmitInferedDefaultExportType2.d.ts] declare var _default: { foo: any[]; bar: any; diff --git a/tests/baselines/reference/declarationEmitInferedDefaultExportType2.symbols b/tests/baselines/reference/declarationEmitInferedDefaultExportType2.symbols new file mode 100644 index 00000000000..7ae974cca05 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedDefaultExportType2.symbols @@ -0,0 +1,14 @@ +=== tests/cases/compiler/declarationEmitInferedDefaultExportType2.ts === + +// test.ts +export = { + foo: [], +>foo : Symbol(foo, Decl(declarationEmitInferedDefaultExportType2.ts, 2, 10)) + + bar: undefined, +>bar : Symbol(bar, Decl(declarationEmitInferedDefaultExportType2.ts, 3, 10)) +>undefined : Symbol(undefined) + + baz: null +>baz : Symbol(baz, Decl(declarationEmitInferedDefaultExportType2.ts, 4, 17)) +} diff --git a/tests/baselines/reference/declarationEmit_inferedDefaultExportType2.types b/tests/baselines/reference/declarationEmitInferedDefaultExportType2.types similarity index 74% rename from tests/baselines/reference/declarationEmit_inferedDefaultExportType2.types rename to tests/baselines/reference/declarationEmitInferedDefaultExportType2.types index 5c8cbbb158c..a334434ea45 100644 --- a/tests/baselines/reference/declarationEmit_inferedDefaultExportType2.types +++ b/tests/baselines/reference/declarationEmitInferedDefaultExportType2.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/declarationEmit_inferedDefaultExportType2.ts === +=== tests/cases/compiler/declarationEmitInferedDefaultExportType2.ts === // test.ts export = { diff --git a/tests/baselines/reference/declarationEmitInvalidExport.errors.txt b/tests/baselines/reference/declarationEmitInvalidExport.errors.txt new file mode 100644 index 00000000000..529a6167973 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInvalidExport.errors.txt @@ -0,0 +1,19 @@ +tests/cases/compiler/declarationEmitInvalidExport.ts(3,3): error TS7027: Unreachable code detected. +tests/cases/compiler/declarationEmitInvalidExport.ts(5,30): error TS4081: Exported type alias 'MyClass' has or is using private name 'myClass'. +tests/cases/compiler/declarationEmitInvalidExport.ts(6,1): error TS1128: Declaration or statement expected. + + +==== tests/cases/compiler/declarationEmitInvalidExport.ts (3 errors) ==== + + if (false) { + export var myClass = 0; + ~~~~~~ +!!! error TS7027: Unreachable code detected. + } + export type MyClass = typeof myClass; + ~~~~~~~ +!!! error TS4081: Exported type alias 'MyClass' has or is using private name 'myClass'. + } + ~ +!!! error TS1128: Declaration or statement expected. + \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmit_invalidExport.js b/tests/baselines/reference/declarationEmitInvalidExport.js similarity index 61% rename from tests/baselines/reference/declarationEmit_invalidExport.js rename to tests/baselines/reference/declarationEmitInvalidExport.js index 74b5bfd8019..18ed73b0a5a 100644 --- a/tests/baselines/reference/declarationEmit_invalidExport.js +++ b/tests/baselines/reference/declarationEmitInvalidExport.js @@ -1,4 +1,4 @@ -//// [declarationEmit_invalidExport.ts] +//// [declarationEmitInvalidExport.ts] if (false) { export var myClass = 0; @@ -7,7 +7,7 @@ export type MyClass = typeof myClass; } -//// [declarationEmit_invalidExport.js] +//// [declarationEmitInvalidExport.js] "use strict"; if (false) { export var myClass = 0; diff --git a/tests/baselines/reference/declarationEmitInvalidReference.js b/tests/baselines/reference/declarationEmitInvalidReference.js new file mode 100644 index 00000000000..e5a8bf5f289 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInvalidReference.js @@ -0,0 +1,11 @@ +//// [declarationEmitInvalidReference.ts] +/// +var x = 0; + +//// [declarationEmitInvalidReference.js] +/// +var x = 0; + + +//// [declarationEmitInvalidReference.d.ts] +declare var x: number; diff --git a/tests/baselines/reference/declarationEmitInvalidReference.symbols b/tests/baselines/reference/declarationEmitInvalidReference.symbols new file mode 100644 index 00000000000..9607e5434ca --- /dev/null +++ b/tests/baselines/reference/declarationEmitInvalidReference.symbols @@ -0,0 +1,5 @@ +=== tests/cases/compiler/declarationEmitInvalidReference.ts === +/// +var x = 0; +>x : Symbol(x, Decl(declarationEmitInvalidReference.ts, 1, 3)) + diff --git a/tests/baselines/reference/declarationEmitInvalidReference.types b/tests/baselines/reference/declarationEmitInvalidReference.types new file mode 100644 index 00000000000..aa2658874bc --- /dev/null +++ b/tests/baselines/reference/declarationEmitInvalidReference.types @@ -0,0 +1,6 @@ +=== tests/cases/compiler/declarationEmitInvalidReference.ts === +/// +var x = 0; +>x : number +>0 : 0 + diff --git a/tests/baselines/reference/declarationEmitInvalidReference2.errors.txt b/tests/baselines/reference/declarationEmitInvalidReference2.errors.txt new file mode 100644 index 00000000000..32423b8d849 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInvalidReference2.errors.txt @@ -0,0 +1,8 @@ +tests/cases/compiler/declarationEmitInvalidReference2.ts(1,1): error TS6053: File 'tests/cases/compiler/invalid.ts' not found. + + +==== tests/cases/compiler/declarationEmitInvalidReference2.ts (1 errors) ==== + /// + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS6053: File 'tests/cases/compiler/invalid.ts' not found. + var x = 0; \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitInvalidReference2.js b/tests/baselines/reference/declarationEmitInvalidReference2.js new file mode 100644 index 00000000000..e14da1dabb6 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInvalidReference2.js @@ -0,0 +1,11 @@ +//// [declarationEmitInvalidReference2.ts] +/// +var x = 0; + +//// [declarationEmitInvalidReference2.js] +/// +var x = 0; + + +//// [declarationEmitInvalidReference2.d.ts] +declare var x: number; diff --git a/tests/baselines/reference/declarationEmit_nameConflicts.js b/tests/baselines/reference/declarationEmitNameConflicts.js similarity index 94% rename from tests/baselines/reference/declarationEmit_nameConflicts.js rename to tests/baselines/reference/declarationEmitNameConflicts.js index 957a0da472a..2ce92501409 100644 --- a/tests/baselines/reference/declarationEmit_nameConflicts.js +++ b/tests/baselines/reference/declarationEmitNameConflicts.js @@ -1,4 +1,4 @@ -//// [tests/cases/compiler/declarationEmit_nameConflicts.ts] //// +//// [tests/cases/compiler/declarationEmitNameConflicts.ts] //// //// [declarationEmit_nameConflicts_1.ts] module f { export class c { } } diff --git a/tests/baselines/reference/declarationEmit_nameConflicts.symbols b/tests/baselines/reference/declarationEmitNameConflicts.symbols similarity index 100% rename from tests/baselines/reference/declarationEmit_nameConflicts.symbols rename to tests/baselines/reference/declarationEmitNameConflicts.symbols diff --git a/tests/baselines/reference/declarationEmit_nameConflicts.types b/tests/baselines/reference/declarationEmitNameConflicts.types similarity index 100% rename from tests/baselines/reference/declarationEmit_nameConflicts.types rename to tests/baselines/reference/declarationEmitNameConflicts.types diff --git a/tests/baselines/reference/declarationEmit_nameConflicts2.js b/tests/baselines/reference/declarationEmitNameConflicts2.js similarity index 90% rename from tests/baselines/reference/declarationEmit_nameConflicts2.js rename to tests/baselines/reference/declarationEmitNameConflicts2.js index b93745c3a12..b7b345979d7 100644 --- a/tests/baselines/reference/declarationEmit_nameConflicts2.js +++ b/tests/baselines/reference/declarationEmitNameConflicts2.js @@ -1,4 +1,4 @@ -//// [declarationEmit_nameConflicts2.ts] +//// [declarationEmitNameConflicts2.ts] module X.Y.base { export function f() { } export class C { } @@ -15,7 +15,7 @@ module X.Y.base.Z { export var E = X.Y.base.E; // Should be base.E } -//// [declarationEmit_nameConflicts2.js] +//// [declarationEmitNameConflicts2.js] var X; (function (X) { var Y; @@ -57,7 +57,7 @@ var X; })(X || (X = {})); -//// [declarationEmit_nameConflicts2.d.ts] +//// [declarationEmitNameConflicts2.d.ts] declare module X.Y.base { function f(): void; class C { diff --git a/tests/baselines/reference/declarationEmitNameConflicts2.symbols b/tests/baselines/reference/declarationEmitNameConflicts2.symbols new file mode 100644 index 00000000000..eba4dd0bf4d --- /dev/null +++ b/tests/baselines/reference/declarationEmitNameConflicts2.symbols @@ -0,0 +1,68 @@ +=== tests/cases/compiler/declarationEmitNameConflicts2.ts === +module X.Y.base { +>X : Symbol(X, Decl(declarationEmitNameConflicts2.ts, 0, 0), Decl(declarationEmitNameConflicts2.ts, 7, 1)) +>Y : Symbol(Y, Decl(declarationEmitNameConflicts2.ts, 0, 9), Decl(declarationEmitNameConflicts2.ts, 9, 9)) +>base : Symbol(base, Decl(declarationEmitNameConflicts2.ts, 0, 11), Decl(declarationEmitNameConflicts2.ts, 9, 11)) + + export function f() { } +>f : Symbol(f, Decl(declarationEmitNameConflicts2.ts, 0, 17)) + + export class C { } +>C : Symbol(C, Decl(declarationEmitNameConflicts2.ts, 1, 27)) + + export module M { +>M : Symbol(M, Decl(declarationEmitNameConflicts2.ts, 2, 22)) + + export var v; +>v : Symbol(v, Decl(declarationEmitNameConflicts2.ts, 4, 18)) + } + export enum E { } +>E : Symbol(E, Decl(declarationEmitNameConflicts2.ts, 5, 5)) +} + +module X.Y.base.Z { +>X : Symbol(X, Decl(declarationEmitNameConflicts2.ts, 0, 0), Decl(declarationEmitNameConflicts2.ts, 7, 1)) +>Y : Symbol(Y, Decl(declarationEmitNameConflicts2.ts, 0, 9), Decl(declarationEmitNameConflicts2.ts, 9, 9)) +>base : Symbol(base, Decl(declarationEmitNameConflicts2.ts, 0, 11), Decl(declarationEmitNameConflicts2.ts, 9, 11)) +>Z : Symbol(Z, Decl(declarationEmitNameConflicts2.ts, 9, 16)) + + export var f = X.Y.base.f; // Should be base.f +>f : Symbol(f, Decl(declarationEmitNameConflicts2.ts, 10, 14)) +>X.Y.base.f : Symbol(f, Decl(declarationEmitNameConflicts2.ts, 0, 17)) +>X.Y.base : Symbol(base, Decl(declarationEmitNameConflicts2.ts, 0, 11), Decl(declarationEmitNameConflicts2.ts, 9, 11)) +>X.Y : Symbol(Y, Decl(declarationEmitNameConflicts2.ts, 0, 9), Decl(declarationEmitNameConflicts2.ts, 9, 9)) +>X : Symbol(X, Decl(declarationEmitNameConflicts2.ts, 0, 0), Decl(declarationEmitNameConflicts2.ts, 7, 1)) +>Y : Symbol(Y, Decl(declarationEmitNameConflicts2.ts, 0, 9), Decl(declarationEmitNameConflicts2.ts, 9, 9)) +>base : Symbol(base, Decl(declarationEmitNameConflicts2.ts, 0, 11), Decl(declarationEmitNameConflicts2.ts, 9, 11)) +>f : Symbol(f, Decl(declarationEmitNameConflicts2.ts, 0, 17)) + + export var C = X.Y.base.C; // Should be base.C +>C : Symbol(C, Decl(declarationEmitNameConflicts2.ts, 11, 14)) +>X.Y.base.C : Symbol(C, Decl(declarationEmitNameConflicts2.ts, 1, 27)) +>X.Y.base : Symbol(base, Decl(declarationEmitNameConflicts2.ts, 0, 11), Decl(declarationEmitNameConflicts2.ts, 9, 11)) +>X.Y : Symbol(Y, Decl(declarationEmitNameConflicts2.ts, 0, 9), Decl(declarationEmitNameConflicts2.ts, 9, 9)) +>X : Symbol(X, Decl(declarationEmitNameConflicts2.ts, 0, 0), Decl(declarationEmitNameConflicts2.ts, 7, 1)) +>Y : Symbol(Y, Decl(declarationEmitNameConflicts2.ts, 0, 9), Decl(declarationEmitNameConflicts2.ts, 9, 9)) +>base : Symbol(base, Decl(declarationEmitNameConflicts2.ts, 0, 11), Decl(declarationEmitNameConflicts2.ts, 9, 11)) +>C : Symbol(C, Decl(declarationEmitNameConflicts2.ts, 1, 27)) + + export var M = X.Y.base.M; // Should be base.M +>M : Symbol(M, Decl(declarationEmitNameConflicts2.ts, 12, 14)) +>X.Y.base.M : Symbol(M, Decl(declarationEmitNameConflicts2.ts, 2, 22)) +>X.Y.base : Symbol(base, Decl(declarationEmitNameConflicts2.ts, 0, 11), Decl(declarationEmitNameConflicts2.ts, 9, 11)) +>X.Y : Symbol(Y, Decl(declarationEmitNameConflicts2.ts, 0, 9), Decl(declarationEmitNameConflicts2.ts, 9, 9)) +>X : Symbol(X, Decl(declarationEmitNameConflicts2.ts, 0, 0), Decl(declarationEmitNameConflicts2.ts, 7, 1)) +>Y : Symbol(Y, Decl(declarationEmitNameConflicts2.ts, 0, 9), Decl(declarationEmitNameConflicts2.ts, 9, 9)) +>base : Symbol(base, Decl(declarationEmitNameConflicts2.ts, 0, 11), Decl(declarationEmitNameConflicts2.ts, 9, 11)) +>M : Symbol(M, Decl(declarationEmitNameConflicts2.ts, 2, 22)) + + export var E = X.Y.base.E; // Should be base.E +>E : Symbol(E, Decl(declarationEmitNameConflicts2.ts, 13, 14)) +>X.Y.base.E : Symbol(E, Decl(declarationEmitNameConflicts2.ts, 5, 5)) +>X.Y.base : Symbol(base, Decl(declarationEmitNameConflicts2.ts, 0, 11), Decl(declarationEmitNameConflicts2.ts, 9, 11)) +>X.Y : Symbol(Y, Decl(declarationEmitNameConflicts2.ts, 0, 9), Decl(declarationEmitNameConflicts2.ts, 9, 9)) +>X : Symbol(X, Decl(declarationEmitNameConflicts2.ts, 0, 0), Decl(declarationEmitNameConflicts2.ts, 7, 1)) +>Y : Symbol(Y, Decl(declarationEmitNameConflicts2.ts, 0, 9), Decl(declarationEmitNameConflicts2.ts, 9, 9)) +>base : Symbol(base, Decl(declarationEmitNameConflicts2.ts, 0, 11), Decl(declarationEmitNameConflicts2.ts, 9, 11)) +>E : Symbol(E, Decl(declarationEmitNameConflicts2.ts, 5, 5)) +} diff --git a/tests/baselines/reference/declarationEmit_nameConflicts2.types b/tests/baselines/reference/declarationEmitNameConflicts2.types similarity index 89% rename from tests/baselines/reference/declarationEmit_nameConflicts2.types rename to tests/baselines/reference/declarationEmitNameConflicts2.types index 026cfed0989..7da15138c16 100644 --- a/tests/baselines/reference/declarationEmit_nameConflicts2.types +++ b/tests/baselines/reference/declarationEmitNameConflicts2.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/declarationEmit_nameConflicts2.ts === +=== tests/cases/compiler/declarationEmitNameConflicts2.ts === module X.Y.base { >X : typeof X >Y : typeof Y diff --git a/tests/baselines/reference/declarationEmit_nameConflicts3.js b/tests/baselines/reference/declarationEmitNameConflicts3.js similarity index 91% rename from tests/baselines/reference/declarationEmit_nameConflicts3.js rename to tests/baselines/reference/declarationEmitNameConflicts3.js index f1ea96973b8..e9d5ea3b98e 100644 --- a/tests/baselines/reference/declarationEmit_nameConflicts3.js +++ b/tests/baselines/reference/declarationEmitNameConflicts3.js @@ -1,4 +1,4 @@ -//// [declarationEmit_nameConflicts3.ts] +//// [declarationEmitNameConflicts3.ts] module M { export interface D { } export module D { @@ -26,7 +26,7 @@ module M.P { export var x = M.E.f; // error, should be typeof M.E.f } -//// [declarationEmit_nameConflicts3.js] +//// [declarationEmitNameConflicts3.js] var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -80,7 +80,7 @@ var M; })(M || (M = {})); -//// [declarationEmit_nameConflicts3.d.ts] +//// [declarationEmitNameConflicts3.d.ts] declare module M { interface D { } diff --git a/tests/baselines/reference/declarationEmitNameConflicts3.symbols b/tests/baselines/reference/declarationEmitNameConflicts3.symbols new file mode 100644 index 00000000000..b4bd4615da9 --- /dev/null +++ b/tests/baselines/reference/declarationEmitNameConflicts3.symbols @@ -0,0 +1,76 @@ +=== tests/cases/compiler/declarationEmitNameConflicts3.ts === +module M { +>M : Symbol(M, Decl(declarationEmitNameConflicts3.ts, 0, 0), Decl(declarationEmitNameConflicts3.ts, 11, 1)) + + export interface D { } +>D : Symbol(D, Decl(declarationEmitNameConflicts3.ts, 0, 10), Decl(declarationEmitNameConflicts3.ts, 1, 26)) + + export module D { +>D : Symbol(D, Decl(declarationEmitNameConflicts3.ts, 0, 10), Decl(declarationEmitNameConflicts3.ts, 1, 26)) + + export function f() { } +>f : Symbol(f, Decl(declarationEmitNameConflicts3.ts, 2, 21)) + } + export module C { +>C : Symbol(C, Decl(declarationEmitNameConflicts3.ts, 4, 5)) + + export function f() { } +>f : Symbol(f, Decl(declarationEmitNameConflicts3.ts, 5, 21)) + } + export module E { +>E : Symbol(E, Decl(declarationEmitNameConflicts3.ts, 7, 5)) + + export function f() { } +>f : Symbol(f, Decl(declarationEmitNameConflicts3.ts, 8, 21)) + } +} + +module M.P { +>M : Symbol(M, Decl(declarationEmitNameConflicts3.ts, 0, 0), Decl(declarationEmitNameConflicts3.ts, 11, 1)) +>P : Symbol(P, Decl(declarationEmitNameConflicts3.ts, 13, 9)) + + export class C { +>C : Symbol(C, Decl(declarationEmitNameConflicts3.ts, 13, 12)) + + static f() { } +>f : Symbol(C.f, Decl(declarationEmitNameConflicts3.ts, 14, 20)) + } + export class E extends C { } +>E : Symbol(E, Decl(declarationEmitNameConflicts3.ts, 16, 5)) +>C : Symbol(C, Decl(declarationEmitNameConflicts3.ts, 13, 12)) + + export enum D { +>D : Symbol(D, Decl(declarationEmitNameConflicts3.ts, 17, 32)) + + f +>f : Symbol(D.f, Decl(declarationEmitNameConflicts3.ts, 18, 19)) + } + export var v: M.D; // ok +>v : Symbol(v, Decl(declarationEmitNameConflicts3.ts, 21, 14)) +>M : Symbol(M, Decl(declarationEmitNameConflicts3.ts, 0, 0), Decl(declarationEmitNameConflicts3.ts, 11, 1)) +>D : Symbol(D, Decl(declarationEmitNameConflicts3.ts, 0, 10), Decl(declarationEmitNameConflicts3.ts, 1, 26)) + + export var w = M.D.f; // error, should be typeof M.D.f +>w : Symbol(w, Decl(declarationEmitNameConflicts3.ts, 22, 14)) +>M.D.f : Symbol(M.D.f, Decl(declarationEmitNameConflicts3.ts, 2, 21)) +>M.D : Symbol(D, Decl(declarationEmitNameConflicts3.ts, 0, 10), Decl(declarationEmitNameConflicts3.ts, 1, 26)) +>M : Symbol(M, Decl(declarationEmitNameConflicts3.ts, 0, 0), Decl(declarationEmitNameConflicts3.ts, 11, 1)) +>D : Symbol(D, Decl(declarationEmitNameConflicts3.ts, 0, 10), Decl(declarationEmitNameConflicts3.ts, 1, 26)) +>f : Symbol(M.D.f, Decl(declarationEmitNameConflicts3.ts, 2, 21)) + + export var x = M.C.f; // error, should be typeof M.C.f +>x : Symbol(x, Decl(declarationEmitNameConflicts3.ts, 23, 14), Decl(declarationEmitNameConflicts3.ts, 24, 14)) +>M.C.f : Symbol(C.f, Decl(declarationEmitNameConflicts3.ts, 5, 21)) +>M.C : Symbol(C, Decl(declarationEmitNameConflicts3.ts, 4, 5)) +>M : Symbol(M, Decl(declarationEmitNameConflicts3.ts, 0, 0), Decl(declarationEmitNameConflicts3.ts, 11, 1)) +>C : Symbol(C, Decl(declarationEmitNameConflicts3.ts, 4, 5)) +>f : Symbol(C.f, Decl(declarationEmitNameConflicts3.ts, 5, 21)) + + export var x = M.E.f; // error, should be typeof M.E.f +>x : Symbol(x, Decl(declarationEmitNameConflicts3.ts, 23, 14), Decl(declarationEmitNameConflicts3.ts, 24, 14)) +>M.E.f : Symbol(E.f, Decl(declarationEmitNameConflicts3.ts, 8, 21)) +>M.E : Symbol(E, Decl(declarationEmitNameConflicts3.ts, 7, 5)) +>M : Symbol(M, Decl(declarationEmitNameConflicts3.ts, 0, 0), Decl(declarationEmitNameConflicts3.ts, 11, 1)) +>E : Symbol(E, Decl(declarationEmitNameConflicts3.ts, 7, 5)) +>f : Symbol(E.f, Decl(declarationEmitNameConflicts3.ts, 8, 21)) +} diff --git a/tests/baselines/reference/declarationEmit_nameConflicts3.types b/tests/baselines/reference/declarationEmitNameConflicts3.types similarity index 88% rename from tests/baselines/reference/declarationEmit_nameConflicts3.types rename to tests/baselines/reference/declarationEmitNameConflicts3.types index 8d52bda68f5..2443f2c78d7 100644 --- a/tests/baselines/reference/declarationEmit_nameConflicts3.types +++ b/tests/baselines/reference/declarationEmitNameConflicts3.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/declarationEmit_nameConflicts3.ts === +=== tests/cases/compiler/declarationEmitNameConflicts3.ts === module M { >M : typeof M diff --git a/tests/baselines/reference/declarationEmit_nameConflictsWithAlias.js b/tests/baselines/reference/declarationEmitNameConflictsWithAlias.js similarity index 72% rename from tests/baselines/reference/declarationEmit_nameConflictsWithAlias.js rename to tests/baselines/reference/declarationEmitNameConflictsWithAlias.js index 0b99d3e1efe..b49e3ad314d 100644 --- a/tests/baselines/reference/declarationEmit_nameConflictsWithAlias.js +++ b/tests/baselines/reference/declarationEmitNameConflictsWithAlias.js @@ -1,4 +1,4 @@ -//// [declarationEmit_nameConflictsWithAlias.ts] +//// [declarationEmitNameConflictsWithAlias.ts] export module C { export interface I { } } export import v = C; export module M { @@ -6,14 +6,14 @@ export module M { export var w: v.I; // Gets emitted as C.I, which is the wrong interface } -//// [declarationEmit_nameConflictsWithAlias.js] +//// [declarationEmitNameConflictsWithAlias.js] "use strict"; var M; (function (M) { })(M = exports.M || (exports.M = {})); -//// [declarationEmit_nameConflictsWithAlias.d.ts] +//// [declarationEmitNameConflictsWithAlias.d.ts] export declare module C { interface I { } diff --git a/tests/baselines/reference/declarationEmitNameConflictsWithAlias.symbols b/tests/baselines/reference/declarationEmitNameConflictsWithAlias.symbols new file mode 100644 index 00000000000..8690cffaa80 --- /dev/null +++ b/tests/baselines/reference/declarationEmitNameConflictsWithAlias.symbols @@ -0,0 +1,21 @@ +=== tests/cases/compiler/declarationEmitNameConflictsWithAlias.ts === +export module C { export interface I { } } +>C : Symbol(C, Decl(declarationEmitNameConflictsWithAlias.ts, 0, 0)) +>I : Symbol(I, Decl(declarationEmitNameConflictsWithAlias.ts, 0, 17)) + +export import v = C; +>v : Symbol(v, Decl(declarationEmitNameConflictsWithAlias.ts, 0, 42)) +>C : Symbol(C, Decl(declarationEmitNameConflictsWithAlias.ts, 0, 0)) + +export module M { +>M : Symbol(M, Decl(declarationEmitNameConflictsWithAlias.ts, 1, 20)) + + export module C { export interface I { } } +>C : Symbol(C, Decl(declarationEmitNameConflictsWithAlias.ts, 2, 17)) +>I : Symbol(I, Decl(declarationEmitNameConflictsWithAlias.ts, 3, 21)) + + export var w: v.I; // Gets emitted as C.I, which is the wrong interface +>w : Symbol(w, Decl(declarationEmitNameConflictsWithAlias.ts, 4, 14)) +>v : Symbol(v, Decl(declarationEmitNameConflictsWithAlias.ts, 0, 42)) +>I : Symbol(v.I, Decl(declarationEmitNameConflictsWithAlias.ts, 0, 17)) +} diff --git a/tests/baselines/reference/declarationEmit_nameConflictsWithAlias.types b/tests/baselines/reference/declarationEmitNameConflictsWithAlias.types similarity index 76% rename from tests/baselines/reference/declarationEmit_nameConflictsWithAlias.types rename to tests/baselines/reference/declarationEmitNameConflictsWithAlias.types index 744869f0e3a..f00982eb70c 100644 --- a/tests/baselines/reference/declarationEmit_nameConflictsWithAlias.types +++ b/tests/baselines/reference/declarationEmitNameConflictsWithAlias.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/declarationEmit_nameConflictsWithAlias.ts === +=== tests/cases/compiler/declarationEmitNameConflictsWithAlias.ts === export module C { export interface I { } } >C : any >I : I diff --git a/tests/baselines/reference/declarationEmit_protectedMembers.js b/tests/baselines/reference/declarationEmitProtectedMembers.js similarity index 93% rename from tests/baselines/reference/declarationEmit_protectedMembers.js rename to tests/baselines/reference/declarationEmitProtectedMembers.js index 192f0647ed6..f391e143d72 100644 --- a/tests/baselines/reference/declarationEmit_protectedMembers.js +++ b/tests/baselines/reference/declarationEmitProtectedMembers.js @@ -1,4 +1,4 @@ -//// [declarationEmit_protectedMembers.ts] +//// [declarationEmitProtectedMembers.ts] // Class with protected members class C1 { @@ -50,7 +50,7 @@ class C4 { constructor(protected a: number, protected b) { } } -//// [declarationEmit_protectedMembers.js] +//// [declarationEmitProtectedMembers.js] var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } @@ -127,7 +127,7 @@ var C4 = (function () { }()); -//// [declarationEmit_protectedMembers.d.ts] +//// [declarationEmitProtectedMembers.d.ts] declare class C1 { protected x: number; protected f(): number; diff --git a/tests/baselines/reference/declarationEmitProtectedMembers.symbols b/tests/baselines/reference/declarationEmitProtectedMembers.symbols new file mode 100644 index 00000000000..31f1a9a67e4 --- /dev/null +++ b/tests/baselines/reference/declarationEmitProtectedMembers.symbols @@ -0,0 +1,114 @@ +=== tests/cases/compiler/declarationEmitProtectedMembers.ts === + +// Class with protected members +class C1 { +>C1 : Symbol(C1, Decl(declarationEmitProtectedMembers.ts, 0, 0)) + + protected x: number; +>x : Symbol(C1.x, Decl(declarationEmitProtectedMembers.ts, 2, 10)) + + protected f() { +>f : Symbol(C1.f, Decl(declarationEmitProtectedMembers.ts, 3, 24)) + + return this.x; +>this.x : Symbol(C1.x, Decl(declarationEmitProtectedMembers.ts, 2, 10)) +>this : Symbol(C1, Decl(declarationEmitProtectedMembers.ts, 0, 0)) +>x : Symbol(C1.x, Decl(declarationEmitProtectedMembers.ts, 2, 10)) + } + + protected set accessor(a: number) { } +>accessor : Symbol(C1.accessor, Decl(declarationEmitProtectedMembers.ts, 7, 5), Decl(declarationEmitProtectedMembers.ts, 9, 41)) +>a : Symbol(a, Decl(declarationEmitProtectedMembers.ts, 9, 27)) + + protected get accessor() { return 0; } +>accessor : Symbol(C1.accessor, Decl(declarationEmitProtectedMembers.ts, 7, 5), Decl(declarationEmitProtectedMembers.ts, 9, 41)) + + protected static sx: number; +>sx : Symbol(C1.sx, Decl(declarationEmitProtectedMembers.ts, 10, 42)) + + protected static sf() { +>sf : Symbol(C1.sf, Decl(declarationEmitProtectedMembers.ts, 12, 32)) + + return this.sx; +>this.sx : Symbol(C1.sx, Decl(declarationEmitProtectedMembers.ts, 10, 42)) +>this : Symbol(C1, Decl(declarationEmitProtectedMembers.ts, 0, 0)) +>sx : Symbol(C1.sx, Decl(declarationEmitProtectedMembers.ts, 10, 42)) + } + + protected static set staticSetter(a: number) { } +>staticSetter : Symbol(C1.staticSetter, Decl(declarationEmitProtectedMembers.ts, 16, 5)) +>a : Symbol(a, Decl(declarationEmitProtectedMembers.ts, 18, 38)) + + protected static get staticGetter() { return 0; } +>staticGetter : Symbol(C1.staticGetter, Decl(declarationEmitProtectedMembers.ts, 18, 52)) +} + +// Derived class overriding protected members +class C2 extends C1 { +>C2 : Symbol(C2, Decl(declarationEmitProtectedMembers.ts, 20, 1)) +>C1 : Symbol(C1, Decl(declarationEmitProtectedMembers.ts, 0, 0)) + + protected f() { +>f : Symbol(C2.f, Decl(declarationEmitProtectedMembers.ts, 23, 21)) + + return super.f() + this.x; +>super.f : Symbol(C1.f, Decl(declarationEmitProtectedMembers.ts, 3, 24)) +>super : Symbol(C1, Decl(declarationEmitProtectedMembers.ts, 0, 0)) +>f : Symbol(C1.f, Decl(declarationEmitProtectedMembers.ts, 3, 24)) +>this.x : Symbol(C1.x, Decl(declarationEmitProtectedMembers.ts, 2, 10)) +>this : Symbol(C2, Decl(declarationEmitProtectedMembers.ts, 20, 1)) +>x : Symbol(C1.x, Decl(declarationEmitProtectedMembers.ts, 2, 10)) + } + protected static sf() { +>sf : Symbol(C2.sf, Decl(declarationEmitProtectedMembers.ts, 26, 5)) + + return super.sf() + this.sx; +>super.sf : Symbol(C1.sf, Decl(declarationEmitProtectedMembers.ts, 12, 32)) +>super : Symbol(C1, Decl(declarationEmitProtectedMembers.ts, 0, 0)) +>sf : Symbol(C1.sf, Decl(declarationEmitProtectedMembers.ts, 12, 32)) +>this.sx : Symbol(C1.sx, Decl(declarationEmitProtectedMembers.ts, 10, 42)) +>this : Symbol(C2, Decl(declarationEmitProtectedMembers.ts, 20, 1)) +>sx : Symbol(C1.sx, Decl(declarationEmitProtectedMembers.ts, 10, 42)) + } +} + +// Derived class making protected members public +class C3 extends C2 { +>C3 : Symbol(C3, Decl(declarationEmitProtectedMembers.ts, 30, 1)) +>C2 : Symbol(C2, Decl(declarationEmitProtectedMembers.ts, 20, 1)) + + x: number; +>x : Symbol(C3.x, Decl(declarationEmitProtectedMembers.ts, 33, 21)) + + static sx: number; +>sx : Symbol(C3.sx, Decl(declarationEmitProtectedMembers.ts, 34, 14)) + + f() { +>f : Symbol(C3.f, Decl(declarationEmitProtectedMembers.ts, 35, 22)) + + return super.f(); +>super.f : Symbol(C2.f, Decl(declarationEmitProtectedMembers.ts, 23, 21)) +>super : Symbol(C2, Decl(declarationEmitProtectedMembers.ts, 20, 1)) +>f : Symbol(C2.f, Decl(declarationEmitProtectedMembers.ts, 23, 21)) + } + static sf() { +>sf : Symbol(C3.sf, Decl(declarationEmitProtectedMembers.ts, 38, 5)) + + return super.sf(); +>super.sf : Symbol(C2.sf, Decl(declarationEmitProtectedMembers.ts, 26, 5)) +>super : Symbol(C2, Decl(declarationEmitProtectedMembers.ts, 20, 1)) +>sf : Symbol(C2.sf, Decl(declarationEmitProtectedMembers.ts, 26, 5)) + } + + static get staticGetter() { return 1; } +>staticGetter : Symbol(C3.staticGetter, Decl(declarationEmitProtectedMembers.ts, 41, 5)) +} + +// Protected properties in constructors +class C4 { +>C4 : Symbol(C4, Decl(declarationEmitProtectedMembers.ts, 44, 1)) + + constructor(protected a: number, protected b) { } +>a : Symbol(C4.a, Decl(declarationEmitProtectedMembers.ts, 48, 16)) +>b : Symbol(C4.b, Decl(declarationEmitProtectedMembers.ts, 48, 36)) +} diff --git a/tests/baselines/reference/declarationEmit_protectedMembers.types b/tests/baselines/reference/declarationEmitProtectedMembers.types similarity index 91% rename from tests/baselines/reference/declarationEmit_protectedMembers.types rename to tests/baselines/reference/declarationEmitProtectedMembers.types index dd2f0012bf9..b293487d57d 100644 --- a/tests/baselines/reference/declarationEmit_protectedMembers.types +++ b/tests/baselines/reference/declarationEmitProtectedMembers.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/declarationEmit_protectedMembers.ts === +=== tests/cases/compiler/declarationEmitProtectedMembers.ts === // Class with protected members class C1 { diff --git a/tests/baselines/reference/declarationEmit_readonly.js b/tests/baselines/reference/declarationEmitReadonly.js similarity index 63% rename from tests/baselines/reference/declarationEmit_readonly.js rename to tests/baselines/reference/declarationEmitReadonly.js index 4925e5dafae..fd90188940c 100644 --- a/tests/baselines/reference/declarationEmit_readonly.js +++ b/tests/baselines/reference/declarationEmitReadonly.js @@ -1,10 +1,10 @@ -//// [declarationEmit_readonly.ts] +//// [declarationEmitReadonly.ts] class C { constructor(readonly x: number) {} } -//// [declarationEmit_readonly.js] +//// [declarationEmitReadonly.js] var C = (function () { function C(x) { this.x = x; @@ -13,7 +13,7 @@ var C = (function () { }()); -//// [declarationEmit_readonly.d.ts] +//// [declarationEmitReadonly.d.ts] declare class C { readonly x: number; constructor(x: number); diff --git a/tests/baselines/reference/declarationEmitReadonly.symbols b/tests/baselines/reference/declarationEmitReadonly.symbols new file mode 100644 index 00000000000..2ef310cf7df --- /dev/null +++ b/tests/baselines/reference/declarationEmitReadonly.symbols @@ -0,0 +1,8 @@ +=== tests/cases/conformance/classes/constructorDeclarations/constructorParameters/declarationEmitReadonly.ts === + +class C { +>C : Symbol(C, Decl(declarationEmitReadonly.ts, 0, 0)) + + constructor(readonly x: number) {} +>x : Symbol(C.x, Decl(declarationEmitReadonly.ts, 2, 16)) +} diff --git a/tests/baselines/reference/declarationEmit_readonly.types b/tests/baselines/reference/declarationEmitReadonly.types similarity index 70% rename from tests/baselines/reference/declarationEmit_readonly.types rename to tests/baselines/reference/declarationEmitReadonly.types index 3036c234ae5..e64256698cf 100644 --- a/tests/baselines/reference/declarationEmit_readonly.types +++ b/tests/baselines/reference/declarationEmitReadonly.types @@ -1,4 +1,4 @@ -=== tests/cases/conformance/classes/constructorDeclarations/constructorParameters/declarationEmit_readonly.ts === +=== tests/cases/conformance/classes/constructorDeclarations/constructorParameters/declarationEmitReadonly.ts === class C { >C : C diff --git a/tests/baselines/reference/declarationEmitUnknownImport.errors.txt b/tests/baselines/reference/declarationEmitUnknownImport.errors.txt new file mode 100644 index 00000000000..a2bee225fe8 --- /dev/null +++ b/tests/baselines/reference/declarationEmitUnknownImport.errors.txt @@ -0,0 +1,15 @@ +tests/cases/compiler/declarationEmitUnknownImport.ts(2,14): error TS2304: Cannot find name 'SomeNonExistingName'. +tests/cases/compiler/declarationEmitUnknownImport.ts(2,14): error TS2503: Cannot find namespace 'SomeNonExistingName'. +tests/cases/compiler/declarationEmitUnknownImport.ts(2,14): error TS4000: Import declaration 'Foo' is using private name 'SomeNonExistingName'. + + +==== tests/cases/compiler/declarationEmitUnknownImport.ts (3 errors) ==== + + import Foo = SomeNonExistingName + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'SomeNonExistingName'. + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2503: Cannot find namespace 'SomeNonExistingName'. + ~~~~~~~~~~~~~~~~~~~ +!!! error TS4000: Import declaration 'Foo' is using private name 'SomeNonExistingName'. + export {Foo} \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmit_UnknownImport.js b/tests/baselines/reference/declarationEmitUnknownImport.js similarity index 56% rename from tests/baselines/reference/declarationEmit_UnknownImport.js rename to tests/baselines/reference/declarationEmitUnknownImport.js index 05449c08b6a..bccf2337e08 100644 --- a/tests/baselines/reference/declarationEmit_UnknownImport.js +++ b/tests/baselines/reference/declarationEmitUnknownImport.js @@ -1,9 +1,9 @@ -//// [declarationEmit_UnknownImport.ts] +//// [declarationEmitUnknownImport.ts] import Foo = SomeNonExistingName export {Foo} -//// [declarationEmit_UnknownImport.js] +//// [declarationEmitUnknownImport.js] "use strict"; var Foo = SomeNonExistingName; exports.Foo = Foo; diff --git a/tests/baselines/reference/declarationEmitUnknownImport2.errors.txt b/tests/baselines/reference/declarationEmitUnknownImport2.errors.txt new file mode 100644 index 00000000000..db017d3c89a --- /dev/null +++ b/tests/baselines/reference/declarationEmitUnknownImport2.errors.txt @@ -0,0 +1,21 @@ +tests/cases/compiler/declarationEmitUnknownImport2.ts(2,12): error TS1005: '=' expected. +tests/cases/compiler/declarationEmitUnknownImport2.ts(2,12): error TS2304: Cannot find name 'From'. +tests/cases/compiler/declarationEmitUnknownImport2.ts(2,12): error TS2503: Cannot find namespace 'From'. +tests/cases/compiler/declarationEmitUnknownImport2.ts(2,12): error TS4000: Import declaration 'Foo' is using private name 'From'. +tests/cases/compiler/declarationEmitUnknownImport2.ts(2,17): error TS1005: ';' expected. + + +==== tests/cases/compiler/declarationEmitUnknownImport2.ts (5 errors) ==== + + import Foo From './Foo'; // Syntax error + ~~~~ +!!! error TS1005: '=' expected. + ~~~~ +!!! error TS2304: Cannot find name 'From'. + ~~~~ +!!! error TS2503: Cannot find namespace 'From'. + ~~~~ +!!! error TS4000: Import declaration 'Foo' is using private name 'From'. + ~~~~~~~ +!!! error TS1005: ';' expected. + export default Foo \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmit_UnknownImport2.js b/tests/baselines/reference/declarationEmitUnknownImport2.js similarity index 69% rename from tests/baselines/reference/declarationEmit_UnknownImport2.js rename to tests/baselines/reference/declarationEmitUnknownImport2.js index 7f20d9ec9b8..08afa34f8c8 100644 --- a/tests/baselines/reference/declarationEmit_UnknownImport2.js +++ b/tests/baselines/reference/declarationEmitUnknownImport2.js @@ -1,9 +1,9 @@ -//// [declarationEmit_UnknownImport2.ts] +//// [declarationEmitUnknownImport2.ts] import Foo From './Foo'; // Syntax error export default Foo -//// [declarationEmit_UnknownImport2.js] +//// [declarationEmitUnknownImport2.js] "use strict"; var Foo = From; './Foo'; // Syntax error diff --git a/tests/baselines/reference/declarationEmit_UnknownImport.errors.txt b/tests/baselines/reference/declarationEmit_UnknownImport.errors.txt deleted file mode 100644 index 9d333e66129..00000000000 --- a/tests/baselines/reference/declarationEmit_UnknownImport.errors.txt +++ /dev/null @@ -1,15 +0,0 @@ -tests/cases/compiler/declarationEmit_UnknownImport.ts(2,14): error TS2304: Cannot find name 'SomeNonExistingName'. -tests/cases/compiler/declarationEmit_UnknownImport.ts(2,14): error TS2503: Cannot find namespace 'SomeNonExistingName'. -tests/cases/compiler/declarationEmit_UnknownImport.ts(2,14): error TS4000: Import declaration 'Foo' is using private name 'SomeNonExistingName'. - - -==== tests/cases/compiler/declarationEmit_UnknownImport.ts (3 errors) ==== - - import Foo = SomeNonExistingName - ~~~~~~~~~~~~~~~~~~~ -!!! error TS2304: Cannot find name 'SomeNonExistingName'. - ~~~~~~~~~~~~~~~~~~~ -!!! error TS2503: Cannot find namespace 'SomeNonExistingName'. - ~~~~~~~~~~~~~~~~~~~ -!!! error TS4000: Import declaration 'Foo' is using private name 'SomeNonExistingName'. - export {Foo} \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmit_UnknownImport2.errors.txt b/tests/baselines/reference/declarationEmit_UnknownImport2.errors.txt deleted file mode 100644 index 72dbde546f1..00000000000 --- a/tests/baselines/reference/declarationEmit_UnknownImport2.errors.txt +++ /dev/null @@ -1,21 +0,0 @@ -tests/cases/compiler/declarationEmit_UnknownImport2.ts(2,12): error TS1005: '=' expected. -tests/cases/compiler/declarationEmit_UnknownImport2.ts(2,12): error TS2304: Cannot find name 'From'. -tests/cases/compiler/declarationEmit_UnknownImport2.ts(2,12): error TS2503: Cannot find namespace 'From'. -tests/cases/compiler/declarationEmit_UnknownImport2.ts(2,12): error TS4000: Import declaration 'Foo' is using private name 'From'. -tests/cases/compiler/declarationEmit_UnknownImport2.ts(2,17): error TS1005: ';' expected. - - -==== tests/cases/compiler/declarationEmit_UnknownImport2.ts (5 errors) ==== - - import Foo From './Foo'; // Syntax error - ~~~~ -!!! error TS1005: '=' expected. - ~~~~ -!!! error TS2304: Cannot find name 'From'. - ~~~~ -!!! error TS2503: Cannot find namespace 'From'. - ~~~~ -!!! error TS4000: Import declaration 'Foo' is using private name 'From'. - ~~~~~~~ -!!! error TS1005: ';' expected. - export default Foo \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmit_array-types-from-generic-array-usage.js b/tests/baselines/reference/declarationEmit_array-types-from-generic-array-usage.js deleted file mode 100644 index 59974d0fb85..00000000000 --- a/tests/baselines/reference/declarationEmit_array-types-from-generic-array-usage.js +++ /dev/null @@ -1,10 +0,0 @@ -//// [declarationEmit_array-types-from-generic-array-usage.ts] -interface A extends Array { } - - -//// [declarationEmit_array-types-from-generic-array-usage.js] - - -//// [declarationEmit_array-types-from-generic-array-usage.d.ts] -interface A extends Array { -} diff --git a/tests/baselines/reference/declarationEmit_array-types-from-generic-array-usage.symbols b/tests/baselines/reference/declarationEmit_array-types-from-generic-array-usage.symbols deleted file mode 100644 index 9c9e757afb9..00000000000 --- a/tests/baselines/reference/declarationEmit_array-types-from-generic-array-usage.symbols +++ /dev/null @@ -1,5 +0,0 @@ -=== tests/cases/compiler/declarationEmit_array-types-from-generic-array-usage.ts === -interface A extends Array { } ->A : Symbol(A, Decl(declarationEmit_array-types-from-generic-array-usage.ts, 0, 0)) ->Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) - diff --git a/tests/baselines/reference/declarationEmit_array-types-from-generic-array-usage.types b/tests/baselines/reference/declarationEmit_array-types-from-generic-array-usage.types deleted file mode 100644 index 63f35d0f263..00000000000 --- a/tests/baselines/reference/declarationEmit_array-types-from-generic-array-usage.types +++ /dev/null @@ -1,5 +0,0 @@ -=== tests/cases/compiler/declarationEmit_array-types-from-generic-array-usage.ts === -interface A extends Array { } ->A : A ->Array : T[] - diff --git a/tests/baselines/reference/declarationEmit_bindingPatterns.symbols b/tests/baselines/reference/declarationEmit_bindingPatterns.symbols deleted file mode 100644 index b39aca17ea3..00000000000 --- a/tests/baselines/reference/declarationEmit_bindingPatterns.symbols +++ /dev/null @@ -1,17 +0,0 @@ -=== tests/cases/compiler/declarationEmit_bindingPatterns.ts === - -const k = ({x: z = 'y'}) => { } ->k : Symbol(k, Decl(declarationEmit_bindingPatterns.ts, 1, 5)) ->x : Symbol(x) ->z : Symbol(z, Decl(declarationEmit_bindingPatterns.ts, 1, 12)) - -var a; ->a : Symbol(a, Decl(declarationEmit_bindingPatterns.ts, 3, 3)) - -function f({} = a, [] = a, { p: {} = a} = a) { ->f : Symbol(f, Decl(declarationEmit_bindingPatterns.ts, 3, 6)) ->a : Symbol(a, Decl(declarationEmit_bindingPatterns.ts, 3, 3)) ->a : Symbol(a, Decl(declarationEmit_bindingPatterns.ts, 3, 3)) ->a : Symbol(a, Decl(declarationEmit_bindingPatterns.ts, 3, 3)) ->a : Symbol(a, Decl(declarationEmit_bindingPatterns.ts, 3, 3)) -} diff --git a/tests/baselines/reference/declarationEmit_classMemberNameConflict.symbols b/tests/baselines/reference/declarationEmit_classMemberNameConflict.symbols deleted file mode 100644 index 2b8959289a8..00000000000 --- a/tests/baselines/reference/declarationEmit_classMemberNameConflict.symbols +++ /dev/null @@ -1,70 +0,0 @@ -=== tests/cases/compiler/declarationEmit_classMemberNameConflict.ts === - -export class C1 { ->C1 : Symbol(C1, Decl(declarationEmit_classMemberNameConflict.ts, 0, 0)) - - C1() { } // has to be the same as the class name ->C1 : Symbol(C1.C1, Decl(declarationEmit_classMemberNameConflict.ts, 1, 17)) - - bar() { ->bar : Symbol(C1.bar, Decl(declarationEmit_classMemberNameConflict.ts, 2, 12)) - - return function (t: typeof C1) { ->t : Symbol(t, Decl(declarationEmit_classMemberNameConflict.ts, 5, 25)) ->C1 : Symbol(C1, Decl(declarationEmit_classMemberNameConflict.ts, 0, 0)) - - }; - } -} - -export class C2 { ->C2 : Symbol(C2, Decl(declarationEmit_classMemberNameConflict.ts, 8, 1)) - - C2: any // has to be the same as the class name ->C2 : Symbol(C2.C2, Decl(declarationEmit_classMemberNameConflict.ts, 10, 17)) - - bar() { ->bar : Symbol(C2.bar, Decl(declarationEmit_classMemberNameConflict.ts, 11, 11)) - - return function (t: typeof C2) { ->t : Symbol(t, Decl(declarationEmit_classMemberNameConflict.ts, 14, 25)) ->C2 : Symbol(C2, Decl(declarationEmit_classMemberNameConflict.ts, 8, 1)) - - }; - } -} - -export class C3 { ->C3 : Symbol(C3, Decl(declarationEmit_classMemberNameConflict.ts, 17, 1)) - - get C3() { return 0; } // has to be the same as the class name ->C3 : Symbol(C3.C3, Decl(declarationEmit_classMemberNameConflict.ts, 19, 17)) - - bar() { ->bar : Symbol(C3.bar, Decl(declarationEmit_classMemberNameConflict.ts, 20, 26)) - - return function (t: typeof C3) { ->t : Symbol(t, Decl(declarationEmit_classMemberNameConflict.ts, 23, 25)) ->C3 : Symbol(C3, Decl(declarationEmit_classMemberNameConflict.ts, 17, 1)) - - }; - } -} - -export class C4 { ->C4 : Symbol(C4, Decl(declarationEmit_classMemberNameConflict.ts, 26, 1)) - - set C4(v) { } // has to be the same as the class name ->C4 : Symbol(C4.C4, Decl(declarationEmit_classMemberNameConflict.ts, 28, 17)) ->v : Symbol(v, Decl(declarationEmit_classMemberNameConflict.ts, 29, 11)) - - bar() { ->bar : Symbol(C4.bar, Decl(declarationEmit_classMemberNameConflict.ts, 29, 17)) - - return function (t: typeof C4) { ->t : Symbol(t, Decl(declarationEmit_classMemberNameConflict.ts, 32, 25)) ->C4 : Symbol(C4, Decl(declarationEmit_classMemberNameConflict.ts, 26, 1)) - - }; - } -} diff --git a/tests/baselines/reference/declarationEmit_classMemberNameConflict2.symbols b/tests/baselines/reference/declarationEmit_classMemberNameConflict2.symbols deleted file mode 100644 index e7c4b6f060c..00000000000 --- a/tests/baselines/reference/declarationEmit_classMemberNameConflict2.symbols +++ /dev/null @@ -1,37 +0,0 @@ -=== tests/cases/compiler/declarationEmit_classMemberNameConflict2.ts === - -const Bar = 'bar'; ->Bar : Symbol(Bar, Decl(declarationEmit_classMemberNameConflict2.ts, 1, 5)) - -enum Hello { ->Hello : Symbol(Hello, Decl(declarationEmit_classMemberNameConflict2.ts, 1, 18)) - - World ->World : Symbol(Hello.World, Decl(declarationEmit_classMemberNameConflict2.ts, 3, 12)) -} - -enum Hello1 { ->Hello1 : Symbol(Hello1, Decl(declarationEmit_classMemberNameConflict2.ts, 5, 1)) - - World1 ->World1 : Symbol(Hello1.World1, Decl(declarationEmit_classMemberNameConflict2.ts, 7, 13)) -} - -class Foo { ->Foo : Symbol(Foo, Decl(declarationEmit_classMemberNameConflict2.ts, 9, 1)) - - // Same names + string => OK - Bar = Bar; ->Bar : Symbol(Foo.Bar, Decl(declarationEmit_classMemberNameConflict2.ts, 11, 11)) ->Bar : Symbol(Bar, Decl(declarationEmit_classMemberNameConflict2.ts, 1, 5)) - - // Same names + enum => OK - Hello = Hello; ->Hello : Symbol(Foo.Hello, Decl(declarationEmit_classMemberNameConflict2.ts, 13, 14)) ->Hello : Symbol(Hello, Decl(declarationEmit_classMemberNameConflict2.ts, 1, 18)) - - // Different names + enum => OK - Hello2 = Hello1; ->Hello2 : Symbol(Foo.Hello2, Decl(declarationEmit_classMemberNameConflict2.ts, 16, 18)) ->Hello1 : Symbol(Hello1, Decl(declarationEmit_classMemberNameConflict2.ts, 5, 1)) -} diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends.symbols b/tests/baselines/reference/declarationEmit_expressionInExtends.symbols deleted file mode 100644 index 319914702ac..00000000000 --- a/tests/baselines/reference/declarationEmit_expressionInExtends.symbols +++ /dev/null @@ -1,32 +0,0 @@ -=== tests/cases/compiler/declarationEmit_expressionInExtends.ts === - -var x: { ->x : Symbol(x, Decl(declarationEmit_expressionInExtends.ts, 1, 3)) - - new(s: any): Q; ->T : Symbol(T, Decl(declarationEmit_expressionInExtends.ts, 2, 8)) ->s : Symbol(s, Decl(declarationEmit_expressionInExtends.ts, 2, 11)) ->Q : Symbol(Q, Decl(declarationEmit_expressionInExtends.ts, 3, 1)) -} - -class Q { ->Q : Symbol(Q, Decl(declarationEmit_expressionInExtends.ts, 3, 1)) - - s: string; ->s : Symbol(Q.s, Decl(declarationEmit_expressionInExtends.ts, 5, 9)) -} - -class B extends x { ->B : Symbol(B, Decl(declarationEmit_expressionInExtends.ts, 7, 1)) ->x : Symbol(x, Decl(declarationEmit_expressionInExtends.ts, 1, 3)) -} - -var q: B; ->q : Symbol(q, Decl(declarationEmit_expressionInExtends.ts, 12, 3)) ->B : Symbol(B, Decl(declarationEmit_expressionInExtends.ts, 7, 1)) - -q.s; ->q.s : Symbol(Q.s, Decl(declarationEmit_expressionInExtends.ts, 5, 9)) ->q : Symbol(q, Decl(declarationEmit_expressionInExtends.ts, 12, 3)) ->s : Symbol(Q.s, Decl(declarationEmit_expressionInExtends.ts, 5, 9)) - diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends2.symbols b/tests/baselines/reference/declarationEmit_expressionInExtends2.symbols deleted file mode 100644 index 03a36a49b15..00000000000 --- a/tests/baselines/reference/declarationEmit_expressionInExtends2.symbols +++ /dev/null @@ -1,30 +0,0 @@ -=== tests/cases/compiler/declarationEmit_expressionInExtends2.ts === - -class C { ->C : Symbol(C, Decl(declarationEmit_expressionInExtends2.ts, 0, 0)) ->T : Symbol(T, Decl(declarationEmit_expressionInExtends2.ts, 1, 8)) ->U : Symbol(U, Decl(declarationEmit_expressionInExtends2.ts, 1, 10)) - - x: T; ->x : Symbol(C.x, Decl(declarationEmit_expressionInExtends2.ts, 1, 15)) ->T : Symbol(T, Decl(declarationEmit_expressionInExtends2.ts, 1, 8)) - - y: U; ->y : Symbol(C.y, Decl(declarationEmit_expressionInExtends2.ts, 2, 9)) ->U : Symbol(U, Decl(declarationEmit_expressionInExtends2.ts, 1, 10)) -} - -function getClass(c: T) { ->getClass : Symbol(getClass, Decl(declarationEmit_expressionInExtends2.ts, 4, 1)) ->T : Symbol(T, Decl(declarationEmit_expressionInExtends2.ts, 6, 18)) ->c : Symbol(c, Decl(declarationEmit_expressionInExtends2.ts, 6, 21)) ->T : Symbol(T, Decl(declarationEmit_expressionInExtends2.ts, 6, 18)) - - return C; ->C : Symbol(C, Decl(declarationEmit_expressionInExtends2.ts, 0, 0)) -} - -class MyClass extends getClass(2) { ->MyClass : Symbol(MyClass, Decl(declarationEmit_expressionInExtends2.ts, 8, 1)) ->getClass : Symbol(getClass, Decl(declarationEmit_expressionInExtends2.ts, 4, 1)) -} diff --git a/tests/baselines/reference/declarationEmit_inferedDefaultExportType.symbols b/tests/baselines/reference/declarationEmit_inferedDefaultExportType.symbols deleted file mode 100644 index 7e8cdea2c75..00000000000 --- a/tests/baselines/reference/declarationEmit_inferedDefaultExportType.symbols +++ /dev/null @@ -1,14 +0,0 @@ -=== tests/cases/compiler/declarationEmit_inferedDefaultExportType.ts === - -// test.ts -export default { - foo: [], ->foo : Symbol(foo, Decl(declarationEmit_inferedDefaultExportType.ts, 2, 16)) - - bar: undefined, ->bar : Symbol(bar, Decl(declarationEmit_inferedDefaultExportType.ts, 3, 10)) ->undefined : Symbol(undefined) - - baz: null ->baz : Symbol(baz, Decl(declarationEmit_inferedDefaultExportType.ts, 4, 17)) -} diff --git a/tests/baselines/reference/declarationEmit_inferedDefaultExportType2.symbols b/tests/baselines/reference/declarationEmit_inferedDefaultExportType2.symbols deleted file mode 100644 index d04c50c0d7c..00000000000 --- a/tests/baselines/reference/declarationEmit_inferedDefaultExportType2.symbols +++ /dev/null @@ -1,14 +0,0 @@ -=== tests/cases/compiler/declarationEmit_inferedDefaultExportType2.ts === - -// test.ts -export = { - foo: [], ->foo : Symbol(foo, Decl(declarationEmit_inferedDefaultExportType2.ts, 2, 10)) - - bar: undefined, ->bar : Symbol(bar, Decl(declarationEmit_inferedDefaultExportType2.ts, 3, 10)) ->undefined : Symbol(undefined) - - baz: null ->baz : Symbol(baz, Decl(declarationEmit_inferedDefaultExportType2.ts, 4, 17)) -} diff --git a/tests/baselines/reference/declarationEmit_invalidExport.errors.txt b/tests/baselines/reference/declarationEmit_invalidExport.errors.txt deleted file mode 100644 index 19d650d6d6f..00000000000 --- a/tests/baselines/reference/declarationEmit_invalidExport.errors.txt +++ /dev/null @@ -1,19 +0,0 @@ -tests/cases/compiler/declarationEmit_invalidExport.ts(3,3): error TS7027: Unreachable code detected. -tests/cases/compiler/declarationEmit_invalidExport.ts(5,30): error TS4081: Exported type alias 'MyClass' has or is using private name 'myClass'. -tests/cases/compiler/declarationEmit_invalidExport.ts(6,1): error TS1128: Declaration or statement expected. - - -==== tests/cases/compiler/declarationEmit_invalidExport.ts (3 errors) ==== - - if (false) { - export var myClass = 0; - ~~~~~~ -!!! error TS7027: Unreachable code detected. - } - export type MyClass = typeof myClass; - ~~~~~~~ -!!! error TS4081: Exported type alias 'MyClass' has or is using private name 'myClass'. - } - ~ -!!! error TS1128: Declaration or statement expected. - \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmit_invalidReference.js b/tests/baselines/reference/declarationEmit_invalidReference.js deleted file mode 100644 index d6ef9f48e53..00000000000 --- a/tests/baselines/reference/declarationEmit_invalidReference.js +++ /dev/null @@ -1,11 +0,0 @@ -//// [declarationEmit_invalidReference.ts] -/// -var x = 0; - -//// [declarationEmit_invalidReference.js] -/// -var x = 0; - - -//// [declarationEmit_invalidReference.d.ts] -declare var x: number; diff --git a/tests/baselines/reference/declarationEmit_invalidReference.symbols b/tests/baselines/reference/declarationEmit_invalidReference.symbols deleted file mode 100644 index b23bf697661..00000000000 --- a/tests/baselines/reference/declarationEmit_invalidReference.symbols +++ /dev/null @@ -1,5 +0,0 @@ -=== tests/cases/compiler/declarationEmit_invalidReference.ts === -/// -var x = 0; ->x : Symbol(x, Decl(declarationEmit_invalidReference.ts, 1, 3)) - diff --git a/tests/baselines/reference/declarationEmit_invalidReference.types b/tests/baselines/reference/declarationEmit_invalidReference.types deleted file mode 100644 index 942f2088fc0..00000000000 --- a/tests/baselines/reference/declarationEmit_invalidReference.types +++ /dev/null @@ -1,6 +0,0 @@ -=== tests/cases/compiler/declarationEmit_invalidReference.ts === -/// -var x = 0; ->x : number ->0 : 0 - diff --git a/tests/baselines/reference/declarationEmit_invalidReference2.errors.txt b/tests/baselines/reference/declarationEmit_invalidReference2.errors.txt deleted file mode 100644 index 9d480419022..00000000000 --- a/tests/baselines/reference/declarationEmit_invalidReference2.errors.txt +++ /dev/null @@ -1,8 +0,0 @@ -tests/cases/compiler/declarationEmit_invalidReference2.ts(1,1): error TS6053: File 'tests/cases/compiler/invalid.ts' not found. - - -==== tests/cases/compiler/declarationEmit_invalidReference2.ts (1 errors) ==== - /// - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS6053: File 'tests/cases/compiler/invalid.ts' not found. - var x = 0; \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmit_invalidReference2.js b/tests/baselines/reference/declarationEmit_invalidReference2.js deleted file mode 100644 index 78fb232cca7..00000000000 --- a/tests/baselines/reference/declarationEmit_invalidReference2.js +++ /dev/null @@ -1,11 +0,0 @@ -//// [declarationEmit_invalidReference2.ts] -/// -var x = 0; - -//// [declarationEmit_invalidReference2.js] -/// -var x = 0; - - -//// [declarationEmit_invalidReference2.d.ts] -declare var x: number; diff --git a/tests/baselines/reference/declarationEmit_nameConflicts2.symbols b/tests/baselines/reference/declarationEmit_nameConflicts2.symbols deleted file mode 100644 index 801ad3e7cfc..00000000000 --- a/tests/baselines/reference/declarationEmit_nameConflicts2.symbols +++ /dev/null @@ -1,68 +0,0 @@ -=== tests/cases/compiler/declarationEmit_nameConflicts2.ts === -module X.Y.base { ->X : Symbol(X, Decl(declarationEmit_nameConflicts2.ts, 0, 0), Decl(declarationEmit_nameConflicts2.ts, 7, 1)) ->Y : Symbol(Y, Decl(declarationEmit_nameConflicts2.ts, 0, 9), Decl(declarationEmit_nameConflicts2.ts, 9, 9)) ->base : Symbol(base, Decl(declarationEmit_nameConflicts2.ts, 0, 11), Decl(declarationEmit_nameConflicts2.ts, 9, 11)) - - export function f() { } ->f : Symbol(f, Decl(declarationEmit_nameConflicts2.ts, 0, 17)) - - export class C { } ->C : Symbol(C, Decl(declarationEmit_nameConflicts2.ts, 1, 27)) - - export module M { ->M : Symbol(M, Decl(declarationEmit_nameConflicts2.ts, 2, 22)) - - export var v; ->v : Symbol(v, Decl(declarationEmit_nameConflicts2.ts, 4, 18)) - } - export enum E { } ->E : Symbol(E, Decl(declarationEmit_nameConflicts2.ts, 5, 5)) -} - -module X.Y.base.Z { ->X : Symbol(X, Decl(declarationEmit_nameConflicts2.ts, 0, 0), Decl(declarationEmit_nameConflicts2.ts, 7, 1)) ->Y : Symbol(Y, Decl(declarationEmit_nameConflicts2.ts, 0, 9), Decl(declarationEmit_nameConflicts2.ts, 9, 9)) ->base : Symbol(base, Decl(declarationEmit_nameConflicts2.ts, 0, 11), Decl(declarationEmit_nameConflicts2.ts, 9, 11)) ->Z : Symbol(Z, Decl(declarationEmit_nameConflicts2.ts, 9, 16)) - - export var f = X.Y.base.f; // Should be base.f ->f : Symbol(f, Decl(declarationEmit_nameConflicts2.ts, 10, 14)) ->X.Y.base.f : Symbol(f, Decl(declarationEmit_nameConflicts2.ts, 0, 17)) ->X.Y.base : Symbol(base, Decl(declarationEmit_nameConflicts2.ts, 0, 11), Decl(declarationEmit_nameConflicts2.ts, 9, 11)) ->X.Y : Symbol(Y, Decl(declarationEmit_nameConflicts2.ts, 0, 9), Decl(declarationEmit_nameConflicts2.ts, 9, 9)) ->X : Symbol(X, Decl(declarationEmit_nameConflicts2.ts, 0, 0), Decl(declarationEmit_nameConflicts2.ts, 7, 1)) ->Y : Symbol(Y, Decl(declarationEmit_nameConflicts2.ts, 0, 9), Decl(declarationEmit_nameConflicts2.ts, 9, 9)) ->base : Symbol(base, Decl(declarationEmit_nameConflicts2.ts, 0, 11), Decl(declarationEmit_nameConflicts2.ts, 9, 11)) ->f : Symbol(f, Decl(declarationEmit_nameConflicts2.ts, 0, 17)) - - export var C = X.Y.base.C; // Should be base.C ->C : Symbol(C, Decl(declarationEmit_nameConflicts2.ts, 11, 14)) ->X.Y.base.C : Symbol(C, Decl(declarationEmit_nameConflicts2.ts, 1, 27)) ->X.Y.base : Symbol(base, Decl(declarationEmit_nameConflicts2.ts, 0, 11), Decl(declarationEmit_nameConflicts2.ts, 9, 11)) ->X.Y : Symbol(Y, Decl(declarationEmit_nameConflicts2.ts, 0, 9), Decl(declarationEmit_nameConflicts2.ts, 9, 9)) ->X : Symbol(X, Decl(declarationEmit_nameConflicts2.ts, 0, 0), Decl(declarationEmit_nameConflicts2.ts, 7, 1)) ->Y : Symbol(Y, Decl(declarationEmit_nameConflicts2.ts, 0, 9), Decl(declarationEmit_nameConflicts2.ts, 9, 9)) ->base : Symbol(base, Decl(declarationEmit_nameConflicts2.ts, 0, 11), Decl(declarationEmit_nameConflicts2.ts, 9, 11)) ->C : Symbol(C, Decl(declarationEmit_nameConflicts2.ts, 1, 27)) - - export var M = X.Y.base.M; // Should be base.M ->M : Symbol(M, Decl(declarationEmit_nameConflicts2.ts, 12, 14)) ->X.Y.base.M : Symbol(M, Decl(declarationEmit_nameConflicts2.ts, 2, 22)) ->X.Y.base : Symbol(base, Decl(declarationEmit_nameConflicts2.ts, 0, 11), Decl(declarationEmit_nameConflicts2.ts, 9, 11)) ->X.Y : Symbol(Y, Decl(declarationEmit_nameConflicts2.ts, 0, 9), Decl(declarationEmit_nameConflicts2.ts, 9, 9)) ->X : Symbol(X, Decl(declarationEmit_nameConflicts2.ts, 0, 0), Decl(declarationEmit_nameConflicts2.ts, 7, 1)) ->Y : Symbol(Y, Decl(declarationEmit_nameConflicts2.ts, 0, 9), Decl(declarationEmit_nameConflicts2.ts, 9, 9)) ->base : Symbol(base, Decl(declarationEmit_nameConflicts2.ts, 0, 11), Decl(declarationEmit_nameConflicts2.ts, 9, 11)) ->M : Symbol(M, Decl(declarationEmit_nameConflicts2.ts, 2, 22)) - - export var E = X.Y.base.E; // Should be base.E ->E : Symbol(E, Decl(declarationEmit_nameConflicts2.ts, 13, 14)) ->X.Y.base.E : Symbol(E, Decl(declarationEmit_nameConflicts2.ts, 5, 5)) ->X.Y.base : Symbol(base, Decl(declarationEmit_nameConflicts2.ts, 0, 11), Decl(declarationEmit_nameConflicts2.ts, 9, 11)) ->X.Y : Symbol(Y, Decl(declarationEmit_nameConflicts2.ts, 0, 9), Decl(declarationEmit_nameConflicts2.ts, 9, 9)) ->X : Symbol(X, Decl(declarationEmit_nameConflicts2.ts, 0, 0), Decl(declarationEmit_nameConflicts2.ts, 7, 1)) ->Y : Symbol(Y, Decl(declarationEmit_nameConflicts2.ts, 0, 9), Decl(declarationEmit_nameConflicts2.ts, 9, 9)) ->base : Symbol(base, Decl(declarationEmit_nameConflicts2.ts, 0, 11), Decl(declarationEmit_nameConflicts2.ts, 9, 11)) ->E : Symbol(E, Decl(declarationEmit_nameConflicts2.ts, 5, 5)) -} diff --git a/tests/baselines/reference/declarationEmit_nameConflicts3.symbols b/tests/baselines/reference/declarationEmit_nameConflicts3.symbols deleted file mode 100644 index e72c4ec9cee..00000000000 --- a/tests/baselines/reference/declarationEmit_nameConflicts3.symbols +++ /dev/null @@ -1,76 +0,0 @@ -=== tests/cases/compiler/declarationEmit_nameConflicts3.ts === -module M { ->M : Symbol(M, Decl(declarationEmit_nameConflicts3.ts, 0, 0), Decl(declarationEmit_nameConflicts3.ts, 11, 1)) - - export interface D { } ->D : Symbol(D, Decl(declarationEmit_nameConflicts3.ts, 0, 10), Decl(declarationEmit_nameConflicts3.ts, 1, 26)) - - export module D { ->D : Symbol(D, Decl(declarationEmit_nameConflicts3.ts, 0, 10), Decl(declarationEmit_nameConflicts3.ts, 1, 26)) - - export function f() { } ->f : Symbol(f, Decl(declarationEmit_nameConflicts3.ts, 2, 21)) - } - export module C { ->C : Symbol(C, Decl(declarationEmit_nameConflicts3.ts, 4, 5)) - - export function f() { } ->f : Symbol(f, Decl(declarationEmit_nameConflicts3.ts, 5, 21)) - } - export module E { ->E : Symbol(E, Decl(declarationEmit_nameConflicts3.ts, 7, 5)) - - export function f() { } ->f : Symbol(f, Decl(declarationEmit_nameConflicts3.ts, 8, 21)) - } -} - -module M.P { ->M : Symbol(M, Decl(declarationEmit_nameConflicts3.ts, 0, 0), Decl(declarationEmit_nameConflicts3.ts, 11, 1)) ->P : Symbol(P, Decl(declarationEmit_nameConflicts3.ts, 13, 9)) - - export class C { ->C : Symbol(C, Decl(declarationEmit_nameConflicts3.ts, 13, 12)) - - static f() { } ->f : Symbol(C.f, Decl(declarationEmit_nameConflicts3.ts, 14, 20)) - } - export class E extends C { } ->E : Symbol(E, Decl(declarationEmit_nameConflicts3.ts, 16, 5)) ->C : Symbol(C, Decl(declarationEmit_nameConflicts3.ts, 13, 12)) - - export enum D { ->D : Symbol(D, Decl(declarationEmit_nameConflicts3.ts, 17, 32)) - - f ->f : Symbol(D.f, Decl(declarationEmit_nameConflicts3.ts, 18, 19)) - } - export var v: M.D; // ok ->v : Symbol(v, Decl(declarationEmit_nameConflicts3.ts, 21, 14)) ->M : Symbol(M, Decl(declarationEmit_nameConflicts3.ts, 0, 0), Decl(declarationEmit_nameConflicts3.ts, 11, 1)) ->D : Symbol(D, Decl(declarationEmit_nameConflicts3.ts, 0, 10), Decl(declarationEmit_nameConflicts3.ts, 1, 26)) - - export var w = M.D.f; // error, should be typeof M.D.f ->w : Symbol(w, Decl(declarationEmit_nameConflicts3.ts, 22, 14)) ->M.D.f : Symbol(M.D.f, Decl(declarationEmit_nameConflicts3.ts, 2, 21)) ->M.D : Symbol(D, Decl(declarationEmit_nameConflicts3.ts, 0, 10), Decl(declarationEmit_nameConflicts3.ts, 1, 26)) ->M : Symbol(M, Decl(declarationEmit_nameConflicts3.ts, 0, 0), Decl(declarationEmit_nameConflicts3.ts, 11, 1)) ->D : Symbol(D, Decl(declarationEmit_nameConflicts3.ts, 0, 10), Decl(declarationEmit_nameConflicts3.ts, 1, 26)) ->f : Symbol(M.D.f, Decl(declarationEmit_nameConflicts3.ts, 2, 21)) - - export var x = M.C.f; // error, should be typeof M.C.f ->x : Symbol(x, Decl(declarationEmit_nameConflicts3.ts, 23, 14), Decl(declarationEmit_nameConflicts3.ts, 24, 14)) ->M.C.f : Symbol(C.f, Decl(declarationEmit_nameConflicts3.ts, 5, 21)) ->M.C : Symbol(C, Decl(declarationEmit_nameConflicts3.ts, 4, 5)) ->M : Symbol(M, Decl(declarationEmit_nameConflicts3.ts, 0, 0), Decl(declarationEmit_nameConflicts3.ts, 11, 1)) ->C : Symbol(C, Decl(declarationEmit_nameConflicts3.ts, 4, 5)) ->f : Symbol(C.f, Decl(declarationEmit_nameConflicts3.ts, 5, 21)) - - export var x = M.E.f; // error, should be typeof M.E.f ->x : Symbol(x, Decl(declarationEmit_nameConflicts3.ts, 23, 14), Decl(declarationEmit_nameConflicts3.ts, 24, 14)) ->M.E.f : Symbol(E.f, Decl(declarationEmit_nameConflicts3.ts, 8, 21)) ->M.E : Symbol(E, Decl(declarationEmit_nameConflicts3.ts, 7, 5)) ->M : Symbol(M, Decl(declarationEmit_nameConflicts3.ts, 0, 0), Decl(declarationEmit_nameConflicts3.ts, 11, 1)) ->E : Symbol(E, Decl(declarationEmit_nameConflicts3.ts, 7, 5)) ->f : Symbol(E.f, Decl(declarationEmit_nameConflicts3.ts, 8, 21)) -} diff --git a/tests/baselines/reference/declarationEmit_nameConflictsWithAlias.symbols b/tests/baselines/reference/declarationEmit_nameConflictsWithAlias.symbols deleted file mode 100644 index 26c8875a236..00000000000 --- a/tests/baselines/reference/declarationEmit_nameConflictsWithAlias.symbols +++ /dev/null @@ -1,21 +0,0 @@ -=== tests/cases/compiler/declarationEmit_nameConflictsWithAlias.ts === -export module C { export interface I { } } ->C : Symbol(C, Decl(declarationEmit_nameConflictsWithAlias.ts, 0, 0)) ->I : Symbol(I, Decl(declarationEmit_nameConflictsWithAlias.ts, 0, 17)) - -export import v = C; ->v : Symbol(v, Decl(declarationEmit_nameConflictsWithAlias.ts, 0, 42)) ->C : Symbol(C, Decl(declarationEmit_nameConflictsWithAlias.ts, 0, 0)) - -export module M { ->M : Symbol(M, Decl(declarationEmit_nameConflictsWithAlias.ts, 1, 20)) - - export module C { export interface I { } } ->C : Symbol(C, Decl(declarationEmit_nameConflictsWithAlias.ts, 2, 17)) ->I : Symbol(I, Decl(declarationEmit_nameConflictsWithAlias.ts, 3, 21)) - - export var w: v.I; // Gets emitted as C.I, which is the wrong interface ->w : Symbol(w, Decl(declarationEmit_nameConflictsWithAlias.ts, 4, 14)) ->v : Symbol(v, Decl(declarationEmit_nameConflictsWithAlias.ts, 0, 42)) ->I : Symbol(v.I, Decl(declarationEmit_nameConflictsWithAlias.ts, 0, 17)) -} diff --git a/tests/baselines/reference/declarationEmit_protectedMembers.symbols b/tests/baselines/reference/declarationEmit_protectedMembers.symbols deleted file mode 100644 index ee9f5ce199d..00000000000 --- a/tests/baselines/reference/declarationEmit_protectedMembers.symbols +++ /dev/null @@ -1,114 +0,0 @@ -=== tests/cases/compiler/declarationEmit_protectedMembers.ts === - -// Class with protected members -class C1 { ->C1 : Symbol(C1, Decl(declarationEmit_protectedMembers.ts, 0, 0)) - - protected x: number; ->x : Symbol(C1.x, Decl(declarationEmit_protectedMembers.ts, 2, 10)) - - protected f() { ->f : Symbol(C1.f, Decl(declarationEmit_protectedMembers.ts, 3, 24)) - - return this.x; ->this.x : Symbol(C1.x, Decl(declarationEmit_protectedMembers.ts, 2, 10)) ->this : Symbol(C1, Decl(declarationEmit_protectedMembers.ts, 0, 0)) ->x : Symbol(C1.x, Decl(declarationEmit_protectedMembers.ts, 2, 10)) - } - - protected set accessor(a: number) { } ->accessor : Symbol(C1.accessor, Decl(declarationEmit_protectedMembers.ts, 7, 5), Decl(declarationEmit_protectedMembers.ts, 9, 41)) ->a : Symbol(a, Decl(declarationEmit_protectedMembers.ts, 9, 27)) - - protected get accessor() { return 0; } ->accessor : Symbol(C1.accessor, Decl(declarationEmit_protectedMembers.ts, 7, 5), Decl(declarationEmit_protectedMembers.ts, 9, 41)) - - protected static sx: number; ->sx : Symbol(C1.sx, Decl(declarationEmit_protectedMembers.ts, 10, 42)) - - protected static sf() { ->sf : Symbol(C1.sf, Decl(declarationEmit_protectedMembers.ts, 12, 32)) - - return this.sx; ->this.sx : Symbol(C1.sx, Decl(declarationEmit_protectedMembers.ts, 10, 42)) ->this : Symbol(C1, Decl(declarationEmit_protectedMembers.ts, 0, 0)) ->sx : Symbol(C1.sx, Decl(declarationEmit_protectedMembers.ts, 10, 42)) - } - - protected static set staticSetter(a: number) { } ->staticSetter : Symbol(C1.staticSetter, Decl(declarationEmit_protectedMembers.ts, 16, 5)) ->a : Symbol(a, Decl(declarationEmit_protectedMembers.ts, 18, 38)) - - protected static get staticGetter() { return 0; } ->staticGetter : Symbol(C1.staticGetter, Decl(declarationEmit_protectedMembers.ts, 18, 52)) -} - -// Derived class overriding protected members -class C2 extends C1 { ->C2 : Symbol(C2, Decl(declarationEmit_protectedMembers.ts, 20, 1)) ->C1 : Symbol(C1, Decl(declarationEmit_protectedMembers.ts, 0, 0)) - - protected f() { ->f : Symbol(C2.f, Decl(declarationEmit_protectedMembers.ts, 23, 21)) - - return super.f() + this.x; ->super.f : Symbol(C1.f, Decl(declarationEmit_protectedMembers.ts, 3, 24)) ->super : Symbol(C1, Decl(declarationEmit_protectedMembers.ts, 0, 0)) ->f : Symbol(C1.f, Decl(declarationEmit_protectedMembers.ts, 3, 24)) ->this.x : Symbol(C1.x, Decl(declarationEmit_protectedMembers.ts, 2, 10)) ->this : Symbol(C2, Decl(declarationEmit_protectedMembers.ts, 20, 1)) ->x : Symbol(C1.x, Decl(declarationEmit_protectedMembers.ts, 2, 10)) - } - protected static sf() { ->sf : Symbol(C2.sf, Decl(declarationEmit_protectedMembers.ts, 26, 5)) - - return super.sf() + this.sx; ->super.sf : Symbol(C1.sf, Decl(declarationEmit_protectedMembers.ts, 12, 32)) ->super : Symbol(C1, Decl(declarationEmit_protectedMembers.ts, 0, 0)) ->sf : Symbol(C1.sf, Decl(declarationEmit_protectedMembers.ts, 12, 32)) ->this.sx : Symbol(C1.sx, Decl(declarationEmit_protectedMembers.ts, 10, 42)) ->this : Symbol(C2, Decl(declarationEmit_protectedMembers.ts, 20, 1)) ->sx : Symbol(C1.sx, Decl(declarationEmit_protectedMembers.ts, 10, 42)) - } -} - -// Derived class making protected members public -class C3 extends C2 { ->C3 : Symbol(C3, Decl(declarationEmit_protectedMembers.ts, 30, 1)) ->C2 : Symbol(C2, Decl(declarationEmit_protectedMembers.ts, 20, 1)) - - x: number; ->x : Symbol(C3.x, Decl(declarationEmit_protectedMembers.ts, 33, 21)) - - static sx: number; ->sx : Symbol(C3.sx, Decl(declarationEmit_protectedMembers.ts, 34, 14)) - - f() { ->f : Symbol(C3.f, Decl(declarationEmit_protectedMembers.ts, 35, 22)) - - return super.f(); ->super.f : Symbol(C2.f, Decl(declarationEmit_protectedMembers.ts, 23, 21)) ->super : Symbol(C2, Decl(declarationEmit_protectedMembers.ts, 20, 1)) ->f : Symbol(C2.f, Decl(declarationEmit_protectedMembers.ts, 23, 21)) - } - static sf() { ->sf : Symbol(C3.sf, Decl(declarationEmit_protectedMembers.ts, 38, 5)) - - return super.sf(); ->super.sf : Symbol(C2.sf, Decl(declarationEmit_protectedMembers.ts, 26, 5)) ->super : Symbol(C2, Decl(declarationEmit_protectedMembers.ts, 20, 1)) ->sf : Symbol(C2.sf, Decl(declarationEmit_protectedMembers.ts, 26, 5)) - } - - static get staticGetter() { return 1; } ->staticGetter : Symbol(C3.staticGetter, Decl(declarationEmit_protectedMembers.ts, 41, 5)) -} - -// Protected properties in constructors -class C4 { ->C4 : Symbol(C4, Decl(declarationEmit_protectedMembers.ts, 44, 1)) - - constructor(protected a: number, protected b) { } ->a : Symbol(C4.a, Decl(declarationEmit_protectedMembers.ts, 48, 16)) ->b : Symbol(C4.b, Decl(declarationEmit_protectedMembers.ts, 48, 36)) -} diff --git a/tests/baselines/reference/declarationEmit_readonly.symbols b/tests/baselines/reference/declarationEmit_readonly.symbols deleted file mode 100644 index eadb7dc3ddf..00000000000 --- a/tests/baselines/reference/declarationEmit_readonly.symbols +++ /dev/null @@ -1,8 +0,0 @@ -=== tests/cases/conformance/classes/constructorDeclarations/constructorParameters/declarationEmit_readonly.ts === - -class C { ->C : Symbol(C, Decl(declarationEmit_readonly.ts, 0, 0)) - - constructor(readonly x: number) {} ->x : Symbol(C.x, Decl(declarationEmit_readonly.ts, 2, 16)) -} diff --git a/tests/cases/conformance/classes/constructorDeclarations/constructorParameters/declarationEmit_readonly.ts b/tests/cases/conformance/classes/constructorDeclarations/constructorParameters/declarationEmitReadonly.ts similarity index 100% rename from tests/cases/conformance/classes/constructorDeclarations/constructorParameters/declarationEmit_readonly.ts rename to tests/cases/conformance/classes/constructorDeclarations/constructorParameters/declarationEmitReadonly.ts From e2ee3c5c152c1f1facba341f551c1550a7cdab71 Mon Sep 17 00:00:00 2001 From: Gabe Moothart Date: Thu, 15 Sep 2016 10:33:06 -0700 Subject: [PATCH 36/46] Removed constructor typings which can't be used Also corrected some parameter names. --- src/lib/es2015.collection.d.ts | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/lib/es2015.collection.d.ts b/src/lib/es2015.collection.d.ts index 9b0a484ce36..4cdb2d187a5 100644 --- a/src/lib/es2015.collection.d.ts +++ b/src/lib/es2015.collection.d.ts @@ -1,7 +1,7 @@ interface Map { clear(): void; delete(key: K): boolean; - forEach(callbackfn: (value: V, index: K, map: Map) => void, thisArg?: any): void; + forEach(callbackfn: (value: V, key: K, map: Map) => void, thisArg?: any): void; get(key: K): V | undefined; has(key: K): boolean; set(key: K, value?: V): this; @@ -17,19 +17,13 @@ declare var Map: MapConstructor; interface ReadonlyMap { forEach( - callbackfn: (value: V, index: K, map: ReadonlyMap) => void, + callbackfn: (value: V, key: K, map: ReadonlyMap) => void, thisArg?: any): void; get(key: K): V|undefined; has(key: K): boolean; readonly size: number; } -interface ReadonlyMapConstructor { - new(entries?: [K, V][]): ReadonlyMap; - readonly prototype: ReadonlyMap; -} -declare var ReadonlyMap: ReadonlyMapConstructor; - interface WeakMap { delete(key: K): boolean; get(key: K): V | undefined; @@ -48,7 +42,7 @@ interface Set { add(value: T): this; clear(): void; delete(value: T): boolean; - forEach(callbackfn: (value: T, index: T, set: Set) => void, thisArg?: any): void; + forEach(callbackfn: (value: T, value2: T, set: Set) => void, thisArg?: any): void; has(value: T): boolean; readonly size: number; } @@ -61,18 +55,12 @@ interface SetConstructor { declare var Set: SetConstructor; interface ReadonlySet { - forEach(callbackfn: (value: T, index: T, set: ReadonlySet) => void, thisArg?: any): + forEach(callbackfn: (value: T, value2: T, set: ReadonlySet) => void, thisArg?: any): void; has(value: T): boolean; readonly size: number; } -interface ReadonlySetConstructor { - new(values?: T[]): ReadonlySet; - readonly prototype: ReadonlySet; -} -declare var ReadonlySet: ReadonlySetConstructor; - interface WeakSet { add(value: T): this; delete(value: T): boolean; From a9d4b3016ab02ca7fedeb884f9fdc36c7b695d39 Mon Sep 17 00:00:00 2001 From: Gabe Moothart Date: Thu, 15 Sep 2016 10:47:19 -0700 Subject: [PATCH 37/46] indenting --- src/lib/es2015.collection.d.ts | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/lib/es2015.collection.d.ts b/src/lib/es2015.collection.d.ts index 4cdb2d187a5..6a2c43cd050 100644 --- a/src/lib/es2015.collection.d.ts +++ b/src/lib/es2015.collection.d.ts @@ -16,12 +16,10 @@ interface MapConstructor { declare var Map: MapConstructor; interface ReadonlyMap { - forEach( - callbackfn: (value: V, key: K, map: ReadonlyMap) => void, - thisArg?: any): void; - get(key: K): V|undefined; - has(key: K): boolean; - readonly size: number; + forEach(callbackfn: (value: V, key: K, map: ReadonlyMap) => void, thisArg?: any): void; + get(key: K): V|undefined; + has(key: K): boolean; + readonly size: number; } interface WeakMap { @@ -55,10 +53,9 @@ interface SetConstructor { declare var Set: SetConstructor; interface ReadonlySet { - forEach(callbackfn: (value: T, value2: T, set: ReadonlySet) => void, thisArg?: any): - void; - has(value: T): boolean; - readonly size: number; + forEach(callbackfn: (value: T, value2: T, set: ReadonlySet) => void, thisArg?: any): void; + has(value: T): boolean; + readonly size: number; } interface WeakSet { From a4864d086e7e5f3cec69103b102ed56709b14eaa Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Fri, 16 Sep 2016 09:15:46 -0700 Subject: [PATCH 38/46] Add tests --- .../compiler/declarationEmitInferedTypeAlias1.ts | 13 +++++++++++++ .../compiler/declarationEmitInferedTypeAlias2.ts | 16 ++++++++++++++++ .../compiler/declarationEmitInferedTypeAlias3.ts | 13 +++++++++++++ .../compiler/declarationEmitInferedTypeAlias4.ts | 7 +++++++ .../compiler/declarationEmitInferedTypeAlias5.ts | 12 ++++++++++++ .../compiler/declarationEmitInferedTypeAlias6.ts | 13 +++++++++++++ .../compiler/declarationEmitInferedTypeAlias7.ts | 10 ++++++++++ .../compiler/declarationEmitInferedTypeAlias8.ts | 8 ++++++++ .../compiler/declarationEmitInferedTypeAlias9.ts | 8 ++++++++ 9 files changed, 100 insertions(+) create mode 100644 tests/cases/compiler/declarationEmitInferedTypeAlias1.ts create mode 100644 tests/cases/compiler/declarationEmitInferedTypeAlias2.ts create mode 100644 tests/cases/compiler/declarationEmitInferedTypeAlias3.ts create mode 100644 tests/cases/compiler/declarationEmitInferedTypeAlias4.ts create mode 100644 tests/cases/compiler/declarationEmitInferedTypeAlias5.ts create mode 100644 tests/cases/compiler/declarationEmitInferedTypeAlias6.ts create mode 100644 tests/cases/compiler/declarationEmitInferedTypeAlias7.ts create mode 100644 tests/cases/compiler/declarationEmitInferedTypeAlias8.ts create mode 100644 tests/cases/compiler/declarationEmitInferedTypeAlias9.ts diff --git a/tests/cases/compiler/declarationEmitInferedTypeAlias1.ts b/tests/cases/compiler/declarationEmitInferedTypeAlias1.ts new file mode 100644 index 00000000000..2e30797e515 --- /dev/null +++ b/tests/cases/compiler/declarationEmitInferedTypeAlias1.ts @@ -0,0 +1,13 @@ +// @declaration: true +// @skipDefaultLibCheck: true + +// @Filename: 0.ts +{ + type Data = string | boolean; + let obj: Data = true; +} +export { } + +// @Filename: 1.ts +let v = "str" || true; +export { v } \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmitInferedTypeAlias2.ts b/tests/cases/compiler/declarationEmitInferedTypeAlias2.ts new file mode 100644 index 00000000000..2a4e4e73b8d --- /dev/null +++ b/tests/cases/compiler/declarationEmitInferedTypeAlias2.ts @@ -0,0 +1,16 @@ +// @declaration: true +// @skipDefaultLibCheck: true + +// @Filename: 0.ts +{ + type Data = string | boolean; + let obj: Data = true; +} +export { } + +// @Filename: 1.ts +let v = "str" || true; +function bar () { + return v; +} +export { v, bar } \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmitInferedTypeAlias3.ts b/tests/cases/compiler/declarationEmitInferedTypeAlias3.ts new file mode 100644 index 00000000000..c7ba5168655 --- /dev/null +++ b/tests/cases/compiler/declarationEmitInferedTypeAlias3.ts @@ -0,0 +1,13 @@ +// @declaration: true +// @skipDefaultLibCheck: true + +// @Filename: 0.ts +{ + type Data = string | boolean; + let obj: Data = true; +} +export { } + +// @Filename: 1.ts +var x = "hi" || 5; +export default x; \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmitInferedTypeAlias4.ts b/tests/cases/compiler/declarationEmitInferedTypeAlias4.ts new file mode 100644 index 00000000000..d9c6b75912b --- /dev/null +++ b/tests/cases/compiler/declarationEmitInferedTypeAlias4.ts @@ -0,0 +1,7 @@ +// @declaration: true + +function f
() { + type Foo = T | { x: Foo }; + var x: Foo; + return x; +} \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmitInferedTypeAlias5.ts b/tests/cases/compiler/declarationEmitInferedTypeAlias5.ts new file mode 100644 index 00000000000..787847aecb0 --- /dev/null +++ b/tests/cases/compiler/declarationEmitInferedTypeAlias5.ts @@ -0,0 +1,12 @@ +// @declaration: true +// @skipDefaultLibCheck: true + +// @Filename: 0.ts +export type Data = string | boolean; +let obj: Data = true; + +// @Filename: 1.ts +import * as Z from "./0" +//let v2: Z.Data; +let v = "str" || true; +export { v } \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmitInferedTypeAlias6.ts b/tests/cases/compiler/declarationEmitInferedTypeAlias6.ts new file mode 100644 index 00000000000..2e30797e515 --- /dev/null +++ b/tests/cases/compiler/declarationEmitInferedTypeAlias6.ts @@ -0,0 +1,13 @@ +// @declaration: true +// @skipDefaultLibCheck: true + +// @Filename: 0.ts +{ + type Data = string | boolean; + let obj: Data = true; +} +export { } + +// @Filename: 1.ts +let v = "str" || true; +export { v } \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmitInferedTypeAlias7.ts b/tests/cases/compiler/declarationEmitInferedTypeAlias7.ts new file mode 100644 index 00000000000..690814f3667 --- /dev/null +++ b/tests/cases/compiler/declarationEmitInferedTypeAlias7.ts @@ -0,0 +1,10 @@ +// @declaration: true +// @skipDefaultLibCheck: true + +// @Filename: 0.ts +export type Data = string | boolean; +let obj: Data = true; + +// @Filename: 1.ts +let v = "str" || true; +export { v } \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmitInferedTypeAlias8.ts b/tests/cases/compiler/declarationEmitInferedTypeAlias8.ts new file mode 100644 index 00000000000..20c5e5da2fb --- /dev/null +++ b/tests/cases/compiler/declarationEmitInferedTypeAlias8.ts @@ -0,0 +1,8 @@ +// @declaration: true + +type Foo = T | { x: Foo }; +var x: Foo; + +function returnSomeGlobalValue() { + return x; +} \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmitInferedTypeAlias9.ts b/tests/cases/compiler/declarationEmitInferedTypeAlias9.ts new file mode 100644 index 00000000000..f346cf27e1c --- /dev/null +++ b/tests/cases/compiler/declarationEmitInferedTypeAlias9.ts @@ -0,0 +1,8 @@ +// @declaration: true + +type Foo = T | { x: Foo }; +var x: Foo; + +export function returnSomeGlobalValue() { + return x; +} \ No newline at end of file From e8810812e09634c255c58a3f17c3e81933e052f8 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Fri, 16 Sep 2016 09:16:55 -0700 Subject: [PATCH 39/46] Serialize type alias when type alias symbol is not accessible --- src/compiler/checker.ts | 36 ++++++++++++++++++++---------- src/compiler/declarationEmitter.ts | 2 +- src/compiler/types.ts | 2 +- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8b1b70b0fa1..22668d7b47c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1758,7 +1758,15 @@ namespace ts { return false; } - function isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessibilityResult { + /** + * Check if the given symbol in given enclosing declaration is accessible and mark all associated alias to be visible if requested + * + * @param symbol a Symbol to check if accessible + * @param enclosingDeclaration a Node containing the symbol + * @param meaning a SymbolFlags to check if such meaning of the symbol is accessible + * @param shouldComputeAliasToMarkVisible a boolean value to indicate whether to return aliases to be mark visible in case the symbol is accessible + */ + function isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, shouldComputeAliasesToMakeVisible: boolean): SymbolAccessibilityResult { if (symbol && enclosingDeclaration && !(symbol.flags & SymbolFlags.TypeParameter)) { const initialSymbol = symbol; let meaningToLook = meaning; @@ -1766,7 +1774,7 @@ namespace ts { // Symbol is accessible if it by itself is accessible const accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaningToLook, /*useOnlyExternalAliasing*/ false); if (accessibleSymbolChain) { - const hasAccessibleDeclarations = hasVisibleDeclarations(accessibleSymbolChain[0]); + const hasAccessibleDeclarations = hasVisibleDeclarations(accessibleSymbolChain[0], shouldComputeAliasesToMakeVisible); if (!hasAccessibleDeclarations) { return { accessibility: SymbolAccessibility.NotAccessible, @@ -1830,7 +1838,7 @@ namespace ts { return isAmbientModule(declaration) || (declaration.kind === SyntaxKind.SourceFile && isExternalOrCommonJsModule(declaration)); } - function hasVisibleDeclarations(symbol: Symbol): SymbolVisibilityResult { + function hasVisibleDeclarations(symbol: Symbol, shouldComputeAliasToMarkVisible: boolean): SymbolVisibilityResult { let aliasesToMakeVisible: AnyImportSyntax[]; if (forEach(symbol.declarations, declaration => !getIsDeclarationVisible(declaration))) { return undefined; @@ -1846,14 +1854,16 @@ namespace ts { if (anyImportSyntax && !(getModifierFlags(anyImportSyntax) & ModifierFlags.Export) && // import clause without export isDeclarationVisible(anyImportSyntax.parent)) { - getNodeLinks(declaration).isVisible = true; - if (aliasesToMakeVisible) { - if (!contains(aliasesToMakeVisible, anyImportSyntax)) { - aliasesToMakeVisible.push(anyImportSyntax); + if (shouldComputeAliasToMarkVisible) { + getNodeLinks(declaration).isVisible = true; + if (aliasesToMakeVisible) { + if (!contains(aliasesToMakeVisible, anyImportSyntax)) { + aliasesToMakeVisible.push(anyImportSyntax); + } + } + else { + aliasesToMakeVisible = [anyImportSyntax]; } - } - else { - aliasesToMakeVisible = [anyImportSyntax]; } return true; } @@ -1888,7 +1898,7 @@ namespace ts { const symbol = resolveName(enclosingDeclaration, (firstIdentifier).text, meaning, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined); // Verify if the symbol is accessible - return (symbol && hasVisibleDeclarations(symbol)) || { + return (symbol && hasVisibleDeclarations(symbol, /*shouldComputeAliasToMarkVisible*/ true)) || { accessibility: SymbolAccessibility.NotAccessible, errorSymbolName: getTextOfNode(firstIdentifier), errorNode: firstIdentifier @@ -2163,7 +2173,9 @@ namespace ts { // The specified symbol flags need to be reinterpreted as type flags buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags); } - else if (!(flags & TypeFormatFlags.InTypeAlias) && type.flags & (TypeFlags.Anonymous | TypeFlags.UnionOrIntersection) && type.aliasSymbol) { + else if (!(flags & TypeFormatFlags.InTypeAlias) && type.flags & (TypeFlags.Anonymous | TypeFlags.UnionOrIntersection) && type.aliasSymbol && + isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) { + // Only write out inferred type with its corresponding type-alias if type-alias is visible const typeArguments = type.aliasTypeArguments; writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, nextFlags); } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 68e488295e7..a015ad79b97 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -306,7 +306,7 @@ namespace ts { } function trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags) { - handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning)); + handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ true)); recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForSymbol(symbol, meaning)); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 82844980ca7..0c2a3dbd773 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2138,7 +2138,7 @@ namespace ts { writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; writeBaseConstructorTypeOfClass(node: ClassLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; - isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessibilityResult; + isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult; isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult; // Returns the constant value this property access resolves to, or 'undefined' for a non-constant getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number; From e60e72ee7312e37cc92b0c9d909b8e6031b9a118 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Fri, 16 Sep 2016 09:25:56 -0700 Subject: [PATCH 40/46] Update baselines --- .../controlFlowBinaryOrExpression.types | 12 ++--- .../declarationEmitInferedTypeAlias1.js | 30 ++++++++++++ .../declarationEmitInferedTypeAlias1.symbols | 19 ++++++++ .../declarationEmitInferedTypeAlias1.types | 23 ++++++++++ .../declarationEmitInferedTypeAlias2.js | 38 +++++++++++++++ .../declarationEmitInferedTypeAlias2.symbols | 26 +++++++++++ .../declarationEmitInferedTypeAlias2.types | 30 ++++++++++++ .../declarationEmitInferedTypeAlias3.js | 31 +++++++++++++ .../declarationEmitInferedTypeAlias3.symbols | 19 ++++++++ .../declarationEmitInferedTypeAlias3.types | 23 ++++++++++ .../declarationEmitInferedTypeAlias4.js | 19 ++++++++ .../declarationEmitInferedTypeAlias4.symbols | 22 +++++++++ .../declarationEmitInferedTypeAlias4.types | 22 +++++++++ .../declarationEmitInferedTypeAlias5.js | 29 ++++++++++++ .../declarationEmitInferedTypeAlias5.symbols | 20 ++++++++ .../declarationEmitInferedTypeAlias5.types | 24 ++++++++++ .../declarationEmitInferedTypeAlias6.js | 30 ++++++++++++ .../declarationEmitInferedTypeAlias6.symbols | 19 ++++++++ .../declarationEmitInferedTypeAlias6.types | 23 ++++++++++ .../declarationEmitInferedTypeAlias7.js | 25 ++++++++++ .../declarationEmitInferedTypeAlias7.symbols | 16 +++++++ .../declarationEmitInferedTypeAlias7.types | 20 ++++++++ .../declarationEmitInferedTypeAlias8.js | 22 +++++++++ .../declarationEmitInferedTypeAlias8.symbols | 20 ++++++++ .../declarationEmitInferedTypeAlias8.types | 20 ++++++++ .../declarationEmitInferedTypeAlias9.js | 22 +++++++++ .../declarationEmitInferedTypeAlias9.symbols | 20 ++++++++ .../declarationEmitInferedTypeAlias9.types | 20 ++++++++ .../reference/genericTypeAliases.types | 46 +++++++++---------- ...unusedLocalsAndParametersTypeAliases.types | 32 ++++++------- 30 files changed, 677 insertions(+), 45 deletions(-) create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias1.js create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias1.symbols create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias1.types create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias2.js create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias2.symbols create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias2.types create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias3.js create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias3.symbols create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias3.types create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias4.js create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias4.symbols create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias4.types create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias5.js create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias5.symbols create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias5.types create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias6.js create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias6.symbols create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias6.types create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias7.js create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias7.symbols create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias7.types create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias8.js create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias8.symbols create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias8.types create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias9.js create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias9.symbols create mode 100644 tests/baselines/reference/declarationEmitInferedTypeAlias9.types diff --git a/tests/baselines/reference/controlFlowBinaryOrExpression.types b/tests/baselines/reference/controlFlowBinaryOrExpression.types index 166718b9266..3634a322396 100644 --- a/tests/baselines/reference/controlFlowBinaryOrExpression.types +++ b/tests/baselines/reference/controlFlowBinaryOrExpression.types @@ -62,21 +62,21 @@ declare function isHTMLCollection(sourceObj: any): sourceObj is HTMLCollection; >HTMLCollection : HTMLCollection type EventTargetLike = {a: string} | HTMLCollection | NodeList; ->EventTargetLike : EventTargetLike +>EventTargetLike : NodeList | HTMLCollection | { a: string; } >a : string >HTMLCollection : HTMLCollection >NodeList : NodeList var sourceObj: EventTargetLike = undefined; ->sourceObj : EventTargetLike ->EventTargetLike : EventTargetLike +>sourceObj : NodeList | HTMLCollection | { a: string; } +>EventTargetLike : NodeList | HTMLCollection | { a: string; } >undefined : any >undefined : undefined if (isNodeList(sourceObj)) { >isNodeList(sourceObj) : boolean >isNodeList : (sourceObj: any) => sourceObj is NodeList ->sourceObj : EventTargetLike +>sourceObj : NodeList | HTMLCollection | { a: string; } sourceObj.length; >sourceObj.length : number @@ -87,7 +87,7 @@ if (isNodeList(sourceObj)) { if (isHTMLCollection(sourceObj)) { >isHTMLCollection(sourceObj) : boolean >isHTMLCollection : (sourceObj: any) => sourceObj is HTMLCollection ->sourceObj : EventTargetLike +>sourceObj : NodeList | HTMLCollection | { a: string; } sourceObj.length; >sourceObj.length : number @@ -99,7 +99,7 @@ if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { >isNodeList(sourceObj) || isHTMLCollection(sourceObj) : boolean >isNodeList(sourceObj) : boolean >isNodeList : (sourceObj: any) => sourceObj is NodeList ->sourceObj : EventTargetLike +>sourceObj : NodeList | HTMLCollection | { a: string; } >isHTMLCollection(sourceObj) : boolean >isHTMLCollection : (sourceObj: any) => sourceObj is HTMLCollection >sourceObj : HTMLCollection | { a: string; } diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias1.js b/tests/baselines/reference/declarationEmitInferedTypeAlias1.js new file mode 100644 index 00000000000..05ce74e3bad --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias1.js @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/declarationEmitInferedTypeAlias1.ts] //// + +//// [0.ts] + +{ + type Data = string | boolean; + let obj: Data = true; +} +export { } + +//// [1.ts] +let v = "str" || true; +export { v } + +//// [0.js] +"use strict"; +{ + var obj = true; +} +//// [1.js] +"use strict"; +var v = "str" || true; +exports.v = v; + + +//// [0.d.ts] +export { }; +//// [1.d.ts] +declare let v: string | boolean; +export { v }; diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias1.symbols b/tests/baselines/reference/declarationEmitInferedTypeAlias1.symbols new file mode 100644 index 00000000000..94599418c5d --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias1.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/0.ts === + +{ + type Data = string | boolean; +>Data : Symbol(Data, Decl(0.ts, 1, 1)) + + let obj: Data = true; +>obj : Symbol(obj, Decl(0.ts, 3, 7)) +>Data : Symbol(Data, Decl(0.ts, 1, 1)) +} +export { } + +=== tests/cases/compiler/1.ts === +let v = "str" || true; +>v : Symbol(v, Decl(1.ts, 0, 3)) + +export { v } +>v : Symbol(v, Decl(1.ts, 1, 8)) + diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias1.types b/tests/baselines/reference/declarationEmitInferedTypeAlias1.types new file mode 100644 index 00000000000..922eb9ccf44 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias1.types @@ -0,0 +1,23 @@ +=== tests/cases/compiler/0.ts === + +{ + type Data = string | boolean; +>Data : string | boolean + + let obj: Data = true; +>obj : string | boolean +>Data : string | boolean +>true : true +} +export { } + +=== tests/cases/compiler/1.ts === +let v = "str" || true; +>v : string | boolean +>"str" || true : true | "str" +>"str" : "str" +>true : true + +export { v } +>v : string | boolean + diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias2.js b/tests/baselines/reference/declarationEmitInferedTypeAlias2.js new file mode 100644 index 00000000000..307a9b82d67 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias2.js @@ -0,0 +1,38 @@ +//// [tests/cases/compiler/declarationEmitInferedTypeAlias2.ts] //// + +//// [0.ts] + +{ + type Data = string | boolean; + let obj: Data = true; +} +export { } + +//// [1.ts] +let v = "str" || true; +function bar () { + return v; +} +export { v, bar } + +//// [0.js] +"use strict"; +{ + var obj = true; +} +//// [1.js] +"use strict"; +var v = "str" || true; +exports.v = v; +function bar() { + return v; +} +exports.bar = bar; + + +//// [0.d.ts] +export { }; +//// [1.d.ts] +declare let v: string | boolean; +declare function bar(): string | boolean; +export { v, bar }; diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias2.symbols b/tests/baselines/reference/declarationEmitInferedTypeAlias2.symbols new file mode 100644 index 00000000000..c8027397869 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias2.symbols @@ -0,0 +1,26 @@ +=== tests/cases/compiler/0.ts === + +{ + type Data = string | boolean; +>Data : Symbol(Data, Decl(0.ts, 1, 1)) + + let obj: Data = true; +>obj : Symbol(obj, Decl(0.ts, 3, 7)) +>Data : Symbol(Data, Decl(0.ts, 1, 1)) +} +export { } + +=== tests/cases/compiler/1.ts === +let v = "str" || true; +>v : Symbol(v, Decl(1.ts, 0, 3)) + +function bar () { +>bar : Symbol(bar, Decl(1.ts, 0, 22)) + + return v; +>v : Symbol(v, Decl(1.ts, 0, 3)) +} +export { v, bar } +>v : Symbol(v, Decl(1.ts, 4, 8)) +>bar : Symbol(bar, Decl(1.ts, 4, 11)) + diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias2.types b/tests/baselines/reference/declarationEmitInferedTypeAlias2.types new file mode 100644 index 00000000000..6a9ace4eb86 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias2.types @@ -0,0 +1,30 @@ +=== tests/cases/compiler/0.ts === + +{ + type Data = string | boolean; +>Data : string | boolean + + let obj: Data = true; +>obj : string | boolean +>Data : string | boolean +>true : true +} +export { } + +=== tests/cases/compiler/1.ts === +let v = "str" || true; +>v : string | boolean +>"str" || true : true | "str" +>"str" : "str" +>true : true + +function bar () { +>bar : () => string | boolean + + return v; +>v : string | boolean +} +export { v, bar } +>v : string | boolean +>bar : () => string | boolean + diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias3.js b/tests/baselines/reference/declarationEmitInferedTypeAlias3.js new file mode 100644 index 00000000000..c99e5c429dd --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias3.js @@ -0,0 +1,31 @@ +//// [tests/cases/compiler/declarationEmitInferedTypeAlias3.ts] //// + +//// [0.ts] + +{ + type Data = string | boolean; + let obj: Data = true; +} +export { } + +//// [1.ts] +var x = "hi" || 5; +export default x; + +//// [0.js] +"use strict"; +{ + var obj = true; +} +//// [1.js] +"use strict"; +var x = "hi" || 5; +exports.__esModule = true; +exports["default"] = x; + + +//// [0.d.ts] +export { }; +//// [1.d.ts] +declare var x: string | number; +export default x; diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias3.symbols b/tests/baselines/reference/declarationEmitInferedTypeAlias3.symbols new file mode 100644 index 00000000000..8a9f7b35d18 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias3.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/0.ts === + +{ + type Data = string | boolean; +>Data : Symbol(Data, Decl(0.ts, 1, 1)) + + let obj: Data = true; +>obj : Symbol(obj, Decl(0.ts, 3, 7)) +>Data : Symbol(Data, Decl(0.ts, 1, 1)) +} +export { } + +=== tests/cases/compiler/1.ts === +var x = "hi" || 5; +>x : Symbol(x, Decl(1.ts, 0, 3)) + +export default x; +>x : Symbol(x, Decl(1.ts, 0, 3)) + diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias3.types b/tests/baselines/reference/declarationEmitInferedTypeAlias3.types new file mode 100644 index 00000000000..565a484a094 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias3.types @@ -0,0 +1,23 @@ +=== tests/cases/compiler/0.ts === + +{ + type Data = string | boolean; +>Data : string | boolean + + let obj: Data = true; +>obj : string | boolean +>Data : string | boolean +>true : true +} +export { } + +=== tests/cases/compiler/1.ts === +var x = "hi" || 5; +>x : string | number +>"hi" || 5 : "hi" | 5 +>"hi" : "hi" +>5 : 5 + +export default x; +>x : string | number + diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias4.js b/tests/baselines/reference/declarationEmitInferedTypeAlias4.js new file mode 100644 index 00000000000..8d7ef72012c --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias4.js @@ -0,0 +1,19 @@ +//// [declarationEmitInferedTypeAlias4.ts] + +function f() { + type Foo = T | { x: Foo }; + var x: Foo; + return x; +} + +//// [declarationEmitInferedTypeAlias4.js] +function f() { + var x; + return x; +} + + +//// [declarationEmitInferedTypeAlias4.d.ts] +declare function f(): A[] | { + x: A[] | any; +}; diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias4.symbols b/tests/baselines/reference/declarationEmitInferedTypeAlias4.symbols new file mode 100644 index 00000000000..f522eca7d0b --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias4.symbols @@ -0,0 +1,22 @@ +=== tests/cases/compiler/declarationEmitInferedTypeAlias4.ts === + +function f() { +>f : Symbol(f, Decl(declarationEmitInferedTypeAlias4.ts, 0, 0)) +>A : Symbol(A, Decl(declarationEmitInferedTypeAlias4.ts, 1, 11)) + + type Foo = T | { x: Foo }; +>Foo : Symbol(Foo, Decl(declarationEmitInferedTypeAlias4.ts, 1, 17)) +>T : Symbol(T, Decl(declarationEmitInferedTypeAlias4.ts, 2, 13)) +>T : Symbol(T, Decl(declarationEmitInferedTypeAlias4.ts, 2, 13)) +>x : Symbol(x, Decl(declarationEmitInferedTypeAlias4.ts, 2, 23)) +>Foo : Symbol(Foo, Decl(declarationEmitInferedTypeAlias4.ts, 1, 17)) +>T : Symbol(T, Decl(declarationEmitInferedTypeAlias4.ts, 2, 13)) + + var x: Foo; +>x : Symbol(x, Decl(declarationEmitInferedTypeAlias4.ts, 3, 7)) +>Foo : Symbol(Foo, Decl(declarationEmitInferedTypeAlias4.ts, 1, 17)) +>A : Symbol(A, Decl(declarationEmitInferedTypeAlias4.ts, 1, 11)) + + return x; +>x : Symbol(x, Decl(declarationEmitInferedTypeAlias4.ts, 3, 7)) +} diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias4.types b/tests/baselines/reference/declarationEmitInferedTypeAlias4.types new file mode 100644 index 00000000000..f4cc0789f45 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias4.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/declarationEmitInferedTypeAlias4.ts === + +function f() { +>f : () => A[] | { x: A[] | any; } +>A : A + + type Foo = T | { x: Foo }; +>Foo : T | { x: T | any; } +>T : T +>T : T +>x : T | { x: T | any; } +>Foo : T | { x: T | any; } +>T : T + + var x: Foo; +>x : A[] | { x: A[] | any; } +>Foo : T | { x: T | any; } +>A : A + + return x; +>x : A[] | { x: A[] | any; } +} diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias5.js b/tests/baselines/reference/declarationEmitInferedTypeAlias5.js new file mode 100644 index 00000000000..79d28d3d181 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias5.js @@ -0,0 +1,29 @@ +//// [tests/cases/compiler/declarationEmitInferedTypeAlias5.ts] //// + +//// [0.ts] + +export type Data = string | boolean; +let obj: Data = true; + +//// [1.ts] +import * as Z from "./0" +//let v2: Z.Data; +let v = "str" || true; +export { v } + +//// [0.js] +"use strict"; +var obj = true; +//// [1.js] +"use strict"; +//let v2: Z.Data; +var v = "str" || true; +exports.v = v; + + +//// [0.d.ts] +export declare type Data = string | boolean; +//// [1.d.ts] +import * as Z from "./0"; +declare let v: Z.Data; +export { v }; diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias5.symbols b/tests/baselines/reference/declarationEmitInferedTypeAlias5.symbols new file mode 100644 index 00000000000..6c06697cfdc --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias5.symbols @@ -0,0 +1,20 @@ +=== tests/cases/compiler/0.ts === + +export type Data = string | boolean; +>Data : Symbol(Data, Decl(0.ts, 0, 0)) + +let obj: Data = true; +>obj : Symbol(obj, Decl(0.ts, 2, 3)) +>Data : Symbol(Data, Decl(0.ts, 0, 0)) + +=== tests/cases/compiler/1.ts === +import * as Z from "./0" +>Z : Symbol(Z, Decl(1.ts, 0, 6)) + +//let v2: Z.Data; +let v = "str" || true; +>v : Symbol(v, Decl(1.ts, 2, 3)) + +export { v } +>v : Symbol(v, Decl(1.ts, 3, 8)) + diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias5.types b/tests/baselines/reference/declarationEmitInferedTypeAlias5.types new file mode 100644 index 00000000000..21e6b415d2e --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias5.types @@ -0,0 +1,24 @@ +=== tests/cases/compiler/0.ts === + +export type Data = string | boolean; +>Data : Data + +let obj: Data = true; +>obj : Data +>Data : Data +>true : true + +=== tests/cases/compiler/1.ts === +import * as Z from "./0" +>Z : typeof Z + +//let v2: Z.Data; +let v = "str" || true; +>v : Z.Data +>"str" || true : true | "str" +>"str" : "str" +>true : true + +export { v } +>v : Z.Data + diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias6.js b/tests/baselines/reference/declarationEmitInferedTypeAlias6.js new file mode 100644 index 00000000000..924f73d0ed9 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias6.js @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/declarationEmitInferedTypeAlias6.ts] //// + +//// [0.ts] + +{ + type Data = string | boolean; + let obj: Data = true; +} +export { } + +//// [1.ts] +let v = "str" || true; +export { v } + +//// [0.js] +"use strict"; +{ + var obj = true; +} +//// [1.js] +"use strict"; +var v = "str" || true; +exports.v = v; + + +//// [0.d.ts] +export { }; +//// [1.d.ts] +declare let v: string | boolean; +export { v }; diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias6.symbols b/tests/baselines/reference/declarationEmitInferedTypeAlias6.symbols new file mode 100644 index 00000000000..94599418c5d --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias6.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/0.ts === + +{ + type Data = string | boolean; +>Data : Symbol(Data, Decl(0.ts, 1, 1)) + + let obj: Data = true; +>obj : Symbol(obj, Decl(0.ts, 3, 7)) +>Data : Symbol(Data, Decl(0.ts, 1, 1)) +} +export { } + +=== tests/cases/compiler/1.ts === +let v = "str" || true; +>v : Symbol(v, Decl(1.ts, 0, 3)) + +export { v } +>v : Symbol(v, Decl(1.ts, 1, 8)) + diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias6.types b/tests/baselines/reference/declarationEmitInferedTypeAlias6.types new file mode 100644 index 00000000000..922eb9ccf44 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias6.types @@ -0,0 +1,23 @@ +=== tests/cases/compiler/0.ts === + +{ + type Data = string | boolean; +>Data : string | boolean + + let obj: Data = true; +>obj : string | boolean +>Data : string | boolean +>true : true +} +export { } + +=== tests/cases/compiler/1.ts === +let v = "str" || true; +>v : string | boolean +>"str" || true : true | "str" +>"str" : "str" +>true : true + +export { v } +>v : string | boolean + diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias7.js b/tests/baselines/reference/declarationEmitInferedTypeAlias7.js new file mode 100644 index 00000000000..2fba057fc91 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias7.js @@ -0,0 +1,25 @@ +//// [tests/cases/compiler/declarationEmitInferedTypeAlias7.ts] //// + +//// [0.ts] + +export type Data = string | boolean; +let obj: Data = true; + +//// [1.ts] +let v = "str" || true; +export { v } + +//// [0.js] +"use strict"; +var obj = true; +//// [1.js] +"use strict"; +var v = "str" || true; +exports.v = v; + + +//// [0.d.ts] +export declare type Data = string | boolean; +//// [1.d.ts] +declare let v: string | boolean; +export { v }; diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias7.symbols b/tests/baselines/reference/declarationEmitInferedTypeAlias7.symbols new file mode 100644 index 00000000000..8923fd72692 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias7.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/0.ts === + +export type Data = string | boolean; +>Data : Symbol(Data, Decl(0.ts, 0, 0)) + +let obj: Data = true; +>obj : Symbol(obj, Decl(0.ts, 2, 3)) +>Data : Symbol(Data, Decl(0.ts, 0, 0)) + +=== tests/cases/compiler/1.ts === +let v = "str" || true; +>v : Symbol(v, Decl(1.ts, 0, 3)) + +export { v } +>v : Symbol(v, Decl(1.ts, 1, 8)) + diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias7.types b/tests/baselines/reference/declarationEmitInferedTypeAlias7.types new file mode 100644 index 00000000000..f4bcaaf5105 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias7.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/0.ts === + +export type Data = string | boolean; +>Data : Data + +let obj: Data = true; +>obj : Data +>Data : Data +>true : true + +=== tests/cases/compiler/1.ts === +let v = "str" || true; +>v : string | boolean +>"str" || true : true | "str" +>"str" : "str" +>true : true + +export { v } +>v : string | boolean + diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias8.js b/tests/baselines/reference/declarationEmitInferedTypeAlias8.js new file mode 100644 index 00000000000..54a8ba37af1 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias8.js @@ -0,0 +1,22 @@ +//// [declarationEmitInferedTypeAlias8.ts] + +type Foo = T | { x: Foo }; +var x: Foo; + +function returnSomeGlobalValue() { + return x; +} + +//// [declarationEmitInferedTypeAlias8.js] +var x; +function returnSomeGlobalValue() { + return x; +} + + +//// [declarationEmitInferedTypeAlias8.d.ts] +declare type Foo = T | { + x: Foo; +}; +declare var x: Foo; +declare function returnSomeGlobalValue(): Foo; diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias8.symbols b/tests/baselines/reference/declarationEmitInferedTypeAlias8.symbols new file mode 100644 index 00000000000..9a0c0974e79 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias8.symbols @@ -0,0 +1,20 @@ +=== tests/cases/compiler/declarationEmitInferedTypeAlias8.ts === + +type Foo = T | { x: Foo }; +>Foo : Symbol(Foo, Decl(declarationEmitInferedTypeAlias8.ts, 0, 0)) +>T : Symbol(T, Decl(declarationEmitInferedTypeAlias8.ts, 1, 9)) +>T : Symbol(T, Decl(declarationEmitInferedTypeAlias8.ts, 1, 9)) +>x : Symbol(x, Decl(declarationEmitInferedTypeAlias8.ts, 1, 19)) +>Foo : Symbol(Foo, Decl(declarationEmitInferedTypeAlias8.ts, 0, 0)) +>T : Symbol(T, Decl(declarationEmitInferedTypeAlias8.ts, 1, 9)) + +var x: Foo; +>x : Symbol(x, Decl(declarationEmitInferedTypeAlias8.ts, 2, 3)) +>Foo : Symbol(Foo, Decl(declarationEmitInferedTypeAlias8.ts, 0, 0)) + +function returnSomeGlobalValue() { +>returnSomeGlobalValue : Symbol(returnSomeGlobalValue, Decl(declarationEmitInferedTypeAlias8.ts, 2, 21)) + + return x; +>x : Symbol(x, Decl(declarationEmitInferedTypeAlias8.ts, 2, 3)) +} diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias8.types b/tests/baselines/reference/declarationEmitInferedTypeAlias8.types new file mode 100644 index 00000000000..9fc0aaf7016 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias8.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/declarationEmitInferedTypeAlias8.ts === + +type Foo = T | { x: Foo }; +>Foo : Foo +>T : T +>T : T +>x : Foo +>Foo : Foo +>T : T + +var x: Foo; +>x : Foo +>Foo : Foo + +function returnSomeGlobalValue() { +>returnSomeGlobalValue : () => Foo + + return x; +>x : Foo +} diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias9.js b/tests/baselines/reference/declarationEmitInferedTypeAlias9.js new file mode 100644 index 00000000000..667acdff49c --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias9.js @@ -0,0 +1,22 @@ +//// [declarationEmitInferedTypeAlias9.ts] + +type Foo = T | { x: Foo }; +var x: Foo; + +export function returnSomeGlobalValue() { + return x; +} + +//// [declarationEmitInferedTypeAlias9.js] +"use strict"; +var x; +function returnSomeGlobalValue() { + return x; +} +exports.returnSomeGlobalValue = returnSomeGlobalValue; + + +//// [declarationEmitInferedTypeAlias9.d.ts] +export declare function returnSomeGlobalValue(): number[] | { + x: number[] | any; +}; diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias9.symbols b/tests/baselines/reference/declarationEmitInferedTypeAlias9.symbols new file mode 100644 index 00000000000..5057ef22c0b --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias9.symbols @@ -0,0 +1,20 @@ +=== tests/cases/compiler/declarationEmitInferedTypeAlias9.ts === + +type Foo = T | { x: Foo }; +>Foo : Symbol(Foo, Decl(declarationEmitInferedTypeAlias9.ts, 0, 0)) +>T : Symbol(T, Decl(declarationEmitInferedTypeAlias9.ts, 1, 9)) +>T : Symbol(T, Decl(declarationEmitInferedTypeAlias9.ts, 1, 9)) +>x : Symbol(x, Decl(declarationEmitInferedTypeAlias9.ts, 1, 19)) +>Foo : Symbol(Foo, Decl(declarationEmitInferedTypeAlias9.ts, 0, 0)) +>T : Symbol(T, Decl(declarationEmitInferedTypeAlias9.ts, 1, 9)) + +var x: Foo; +>x : Symbol(x, Decl(declarationEmitInferedTypeAlias9.ts, 2, 3)) +>Foo : Symbol(Foo, Decl(declarationEmitInferedTypeAlias9.ts, 0, 0)) + +export function returnSomeGlobalValue() { +>returnSomeGlobalValue : Symbol(returnSomeGlobalValue, Decl(declarationEmitInferedTypeAlias9.ts, 2, 21)) + + return x; +>x : Symbol(x, Decl(declarationEmitInferedTypeAlias9.ts, 2, 3)) +} diff --git a/tests/baselines/reference/declarationEmitInferedTypeAlias9.types b/tests/baselines/reference/declarationEmitInferedTypeAlias9.types new file mode 100644 index 00000000000..d4f61bf927a --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferedTypeAlias9.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/declarationEmitInferedTypeAlias9.ts === + +type Foo = T | { x: Foo }; +>Foo : T | { x: T | any; } +>T : T +>T : T +>x : T | { x: T | any; } +>Foo : T | { x: T | any; } +>T : T + +var x: Foo; +>x : number[] | { x: number[] | any; } +>Foo : T | { x: T | any; } + +export function returnSomeGlobalValue() { +>returnSomeGlobalValue : () => number[] | { x: number[] | any; } + + return x; +>x : number[] | { x: number[] | any; } +} diff --git a/tests/baselines/reference/genericTypeAliases.types b/tests/baselines/reference/genericTypeAliases.types index 1cabaa8caa0..b4c75841245 100644 --- a/tests/baselines/reference/genericTypeAliases.types +++ b/tests/baselines/reference/genericTypeAliases.types @@ -215,60 +215,60 @@ p.tag = "test"; >"test" : "test" function f() { ->f : () => Foo +>f : () => A[] | { x: A[] | any; } >A : A type Foo = T | { x: Foo }; ->Foo : Foo +>Foo : T | { x: T | any; } >T : T >T : T ->x : Foo ->Foo : Foo +>x : T | { x: T | any; } +>Foo : T | { x: T | any; } >T : T var x: Foo; ->x : Foo ->Foo : Foo +>x : A[] | { x: A[] | any; } +>Foo : T | { x: T | any; } >A : A return x; ->x : Foo +>x : A[] | { x: A[] | any; } } function g() { ->g : () => Bar +>g : () => B[] | { x: B[] | any; } >B : B type Bar = U | { x: Bar }; ->Bar : Bar +>Bar : U | { x: U | any; } >U : U >U : U ->x : Bar ->Bar : Bar +>x : U | { x: U | any; } +>Bar : U | { x: U | any; } >U : U var x: Bar; ->x : Bar ->Bar : Bar +>x : B[] | { x: B[] | any; } +>Bar : U | { x: U | any; } >B : B return x; ->x : Bar +>x : B[] | { x: B[] | any; } } // Deeply instantiated generics var a = f(); ->a : Foo ->f() : Foo ->f : () => Foo +>a : string[] | { x: string[] | any; } +>f() : string[] | { x: string[] | any; } +>f : () => A[] | { x: A[] | any; } var b = g(); ->b : Bar ->g() : Bar ->g : () => Bar +>b : string[] | { x: string[] | any; } +>g() : string[] | { x: string[] | any; } +>g : () => B[] | { x: B[] | any; } a = b; ->a = b : Bar ->a : Foo ->b : Bar +>a = b : string[] | { x: string[] | any; } +>a : string[] | { x: string[] | any; } +>b : string[] | { x: string[] | any; } diff --git a/tests/baselines/reference/unusedLocalsAndParametersTypeAliases.types b/tests/baselines/reference/unusedLocalsAndParametersTypeAliases.types index 6090d300056..e927b011e53 100644 --- a/tests/baselines/reference/unusedLocalsAndParametersTypeAliases.types +++ b/tests/baselines/reference/unusedLocalsAndParametersTypeAliases.types @@ -2,14 +2,14 @@ // used in a declaration type handler1 = () => void; ->handler1 : handler1 +>handler1 : () => void export interface I1 { >I1 : I1 getHandler: handler1; ->getHandler : handler1 ->handler1 : handler1 +>getHandler : () => void +>handler1 : () => void } // exported @@ -18,12 +18,12 @@ export type handler2 = () => void; // used in extends clause type handler3 = () => void; ->handler3 : handler3 +>handler3 : () => void export interface I3 { >I3 : I3 >T : T ->handler3 : handler3 +>handler3 : () => void getHandler: T; >getHandler : T @@ -32,32 +32,32 @@ export interface I3 { // used in another type alias declaration type handler4 = () => void; ->handler4 : handler4 +>handler4 : () => void type handler5 = handler4 | (()=>number); ->handler5 : handler5 ->handler4 : handler4 +>handler5 : (() => void) | (() => number) +>handler4 : () => void var x: handler5; ->x : handler5 ->handler5 : handler5 +>x : (() => void) | (() => number) +>handler5 : (() => void) | (() => number) x(); >x() : number | void ->x : handler5 +>x : (() => void) | (() => number) // used as type argument type handler6 = () => void; ->handler6 : handler6 +>handler6 : () => void var y: Array; ->y : handler6[] +>y : (() => void)[] >Array : T[] ->handler6 : handler6 +>handler6 : () => void y[0](); >y[0]() : void ->y[0] : handler6 ->y : handler6[] +>y[0] : () => void +>y : (() => void)[] >0 : 0 From f137c92deba74b129308a241415627b90a6583cc Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Fri, 16 Sep 2016 14:08:03 -0700 Subject: [PATCH 41/46] Address PR --- src/compiler/checker.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 22668d7b47c..2e1d8806c17 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1762,9 +1762,9 @@ namespace ts { * Check if the given symbol in given enclosing declaration is accessible and mark all associated alias to be visible if requested * * @param symbol a Symbol to check if accessible - * @param enclosingDeclaration a Node containing the symbol + * @param enclosingDeclaration a Node containing reference to the symbol * @param meaning a SymbolFlags to check if such meaning of the symbol is accessible - * @param shouldComputeAliasToMarkVisible a boolean value to indicate whether to return aliases to be mark visible in case the symbol is accessible + * @param shouldComputeAliasToMakeVisible a boolean value to indicate whether to return aliases to be mark visible in case the symbol is accessible */ function isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, shouldComputeAliasesToMakeVisible: boolean): SymbolAccessibilityResult { if (symbol && enclosingDeclaration && !(symbol.flags & SymbolFlags.TypeParameter)) { @@ -1838,7 +1838,7 @@ namespace ts { return isAmbientModule(declaration) || (declaration.kind === SyntaxKind.SourceFile && isExternalOrCommonJsModule(declaration)); } - function hasVisibleDeclarations(symbol: Symbol, shouldComputeAliasToMarkVisible: boolean): SymbolVisibilityResult { + function hasVisibleDeclarations(symbol: Symbol, shouldComputeAliasToMakeVisible: boolean): SymbolVisibilityResult { let aliasesToMakeVisible: AnyImportSyntax[]; if (forEach(symbol.declarations, declaration => !getIsDeclarationVisible(declaration))) { return undefined; @@ -1854,7 +1854,10 @@ namespace ts { if (anyImportSyntax && !(getModifierFlags(anyImportSyntax) & ModifierFlags.Export) && // import clause without export isDeclarationVisible(anyImportSyntax.parent)) { - if (shouldComputeAliasToMarkVisible) { + // In function "buildTypeDisplay" where we decide whether to write type-alias or serialize types, + // we want to just check if type- alias is accessible or not but we don't care about emitting those alias at that time + // since we will do the emitting later in trackSymbol. + if (shouldComputeAliasToMakeVisible) { getNodeLinks(declaration).isVisible = true; if (aliasesToMakeVisible) { if (!contains(aliasesToMakeVisible, anyImportSyntax)) { @@ -1898,7 +1901,7 @@ namespace ts { const symbol = resolveName(enclosingDeclaration, (firstIdentifier).text, meaning, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined); // Verify if the symbol is accessible - return (symbol && hasVisibleDeclarations(symbol, /*shouldComputeAliasToMarkVisible*/ true)) || { + return (symbol && hasVisibleDeclarations(symbol, /*shouldComputeAliasToMakeVisible*/ true)) || { accessibility: SymbolAccessibility.NotAccessible, errorSymbolName: getTextOfNode(firstIdentifier), errorNode: firstIdentifier From 0b5c8cee374e308fdf42ccafe1fedd471f1143a3 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Fri, 16 Sep 2016 14:39:21 -0700 Subject: [PATCH 42/46] Fix build break: difference result from treating things as literal type --- .../reference/commentOnDecoratedClassDeclaration.types | 4 ++-- .../reference/commentOnExportEnumDeclaration.types | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/baselines/reference/commentOnDecoratedClassDeclaration.types b/tests/baselines/reference/commentOnDecoratedClassDeclaration.types index f4850a0b7b7..170eb674453 100644 --- a/tests/baselines/reference/commentOnDecoratedClassDeclaration.types +++ b/tests/baselines/reference/commentOnDecoratedClassDeclaration.types @@ -9,7 +9,7 @@ declare function decorator(x: string): any; @decorator("hello") >decorator("hello") : any >decorator : (x: string) => any ->"hello" : string +>"hello" : "hello" class Remote { } >Remote : Remote @@ -21,7 +21,7 @@ class Remote { } @decorator("hi") >decorator("hi") : any >decorator : (x: string) => any ->"hi" : string +>"hi" : "hi" class AnotherRomote { >AnotherRomote : AnotherRomote diff --git a/tests/baselines/reference/commentOnExportEnumDeclaration.types b/tests/baselines/reference/commentOnExportEnumDeclaration.types index 522e1175540..c9f9338bbe2 100644 --- a/tests/baselines/reference/commentOnExportEnumDeclaration.types +++ b/tests/baselines/reference/commentOnExportEnumDeclaration.types @@ -6,7 +6,7 @@ export enum Color { >Color : Color r, g, b ->r : Color ->g : Color ->b : Color +>r : Color.r +>g : Color.g +>b : Color.b } From b193426c7b12ce73331aea2019b718f22f06dc87 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Fri, 16 Sep 2016 15:17:52 -0700 Subject: [PATCH 43/46] Address PR: Update comment --- src/compiler/transformers/ts.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 1912370998b..4de60322e93 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2891,7 +2891,7 @@ namespace ts { // })(world = hi.world || (hi.world = {})); // })(hi = hello.hi || (hello.hi = {})); // })(hello || (hello = {})); - // so if the block is a transformed module declaration, turn off the comment emit + // We only want to emit comment on the namespace which contains block body itself, not the containing namespaces. if (body.kind !== SyntaxKind.ModuleBlock) { setNodeEmitFlags(block, block.emitFlags | NodeEmitFlags.NoComments); } From fc4a5df6321285576c2992a95ff12471df3f9770 Mon Sep 17 00:00:00 2001 From: Justin Johansson Date: Sat, 17 Sep 2016 12:00:35 +0930 Subject: [PATCH 44/46] Fix Reflect has method signature(s) per issue #10949 initial report --- src/lib/es2015.reflect.d.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib/es2015.reflect.d.ts b/src/lib/es2015.reflect.d.ts index eda8d352263..2dc92c3bddb 100644 --- a/src/lib/es2015.reflect.d.ts +++ b/src/lib/es2015.reflect.d.ts @@ -6,8 +6,7 @@ declare namespace Reflect { function get(target: any, propertyKey: PropertyKey, receiver?: any): any; function getOwnPropertyDescriptor(target: any, propertyKey: PropertyKey): PropertyDescriptor; function getPrototypeOf(target: any): any; - function has(target: any, propertyKey: string): boolean; - function has(target: any, propertyKey: symbol): boolean; + function has(target: any, propertyKey: PropertyKey): boolean; function isExtensible(target: any): boolean; function ownKeys(target: any): Array; function preventExtensions(target: any): boolean; From e6610c5d54d753644d2bfabd32b67fb5c40d4add Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Mon, 19 Sep 2016 11:33:05 -0700 Subject: [PATCH 45/46] Handle msising tags for JsDoc nodes --- src/compiler/types.ts | 2 +- src/services/navigationBar.ts | 14 ++++++-------- .../navigationBarJsDocCommentWithNoTags.ts | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 tests/cases/fourslash/navigationBarJsDocCommentWithNoTags.ts diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b1b672d015b..e4bc9a29d5b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1604,7 +1604,7 @@ namespace ts { // @kind(SyntaxKind.JSDocComment) export interface JSDoc extends Node { - tags: NodeArray; + tags: NodeArray | undefined; comment: string | undefined; } diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index c2a5b745d3a..5c8c47e9666 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -218,15 +218,13 @@ namespace ts.NavigationBar { break; default: - if (node.jsDocComments) { - for (const jsDocComment of node.jsDocComments) { - for (const tag of jsDocComment.tags) { - if (tag.kind === SyntaxKind.JSDocTypedefTag) { - addLeafNode(tag); - } + forEach(node.jsDocComments, jsDocComment => { + forEach(jsDocComment.tags, tag => { + if (tag.kind === SyntaxKind.JSDocTypedefTag) { + addLeafNode(tag); } - } - } + }); + }); forEachChild(node, addChildrenRecursively); } diff --git a/tests/cases/fourslash/navigationBarJsDocCommentWithNoTags.ts b/tests/cases/fourslash/navigationBarJsDocCommentWithNoTags.ts new file mode 100644 index 00000000000..8746f135e4d --- /dev/null +++ b/tests/cases/fourslash/navigationBarJsDocCommentWithNoTags.ts @@ -0,0 +1,18 @@ +/// + +/////** Test */ +////export const Test = {} + +verify.navigationBar([ + { + "text": "\"navigationBarJsDocCommentWithNoTags\"", + "kind": "module", + "childItems": [ + { + "text": "Test", + "kind": "const", + "kindModifiers": "export" + } + ] + } +]); From af5148d4f35533df55e61f87f0c0419b97a64a48 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 19 Sep 2016 11:51:01 -0700 Subject: [PATCH 46/46] Add back getSourceFile and mark it as deprecated --- src/harness/harnessLanguageService.ts | 3 +++ src/server/client.ts | 4 ++++ src/services/services.ts | 5 +++++ src/services/types.ts | 6 ++++++ 4 files changed, 18 insertions(+) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index f96676747e4..a67f68eb1a9 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -492,6 +492,9 @@ namespace Harness.LanguageService { getNonBoundSourceFile(fileName: string): ts.SourceFile { throw new Error("SourceFile can not be marshaled across the shim layer."); } + getSourceFile(fileName: string): ts.SourceFile { + throw new Error("SourceFile can not be marshaled across the shim layer."); + } dispose(): void { this.shim.dispose({}); } } diff --git a/src/server/client.ts b/src/server/client.ts index 7268c3c9573..5032056c2f3 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -678,6 +678,10 @@ namespace ts.server { throw new Error("SourceFile objects are not serializable through the server protocol."); } + getSourceFile(fileName: string): SourceFile { + throw new Error("SourceFile objects are not serializable through the server protocol."); + } + cleanupSemanticCache(): void { throw new Error("cleanupSemanticCache is not available through the server layer."); } diff --git a/src/services/services.ts b/src/services/services.ts index 67843c1ce50..ad071723083 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1401,6 +1401,10 @@ namespace ts { return syntaxTreeCache.getCurrentSourceFile(fileName); } + function getSourceFile(fileName: string): SourceFile { + return getNonBoundSourceFile(fileName); + } + function getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); @@ -1812,6 +1816,7 @@ namespace ts { isValidBraceCompletionAtPosition, getEmitOutput, getNonBoundSourceFile, + getSourceFile, getProgram }; } diff --git a/src/services/types.ts b/src/services/types.ts index 7bd325482e6..e8c411cc1c8 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -240,6 +240,12 @@ namespace ts { /* @internal */ getNonBoundSourceFile(fileName: string): SourceFile; + /** + * @internal + * @deprecated Use ts.createSourceFile instead. + */ + getSourceFile(fileName: string): SourceFile; + dispose(): void; }