From b4c15982ff1caceedc496e6fbdee276a793de554 Mon Sep 17 00:00:00 2001 From: Herrington Darkholme Date: Wed, 18 Jan 2017 14:57:20 +0800 Subject: [PATCH 01/41] fix #13556: enable rest/spread on `object` --- src/compiler/checker.ts | 4 ++-- .../nonPrimitiveAccessProperty.errors.txt | 8 +++++++- .../reference/nonPrimitiveAccessProperty.js | 14 ++++++++++++++ tests/baselines/reference/objectSpread.js | 4 ++++ tests/baselines/reference/objectSpread.symbols | 4 ++++ tests/baselines/reference/objectSpread.types | 7 +++++++ .../reference/objectSpreadNegative.errors.txt | 14 +++++++++++--- tests/baselines/reference/objectSpreadNegative.js | 9 +++++++++ .../nonPrimitive/nonPrimitiveAccessProperty.ts | 3 +++ .../cases/conformance/types/spread/objectSpread.ts | 2 ++ .../types/spread/objectSpreadNegative.ts | 5 +++++ 11 files changed, 68 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 963d2e77c1b..97ca01bc086 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1,4 +1,4 @@ -/// +/// /// /* @internal */ @@ -11784,7 +11784,7 @@ namespace ts { } function isValidSpreadType(type: Type): boolean { - return !!(type.flags & (TypeFlags.Any | TypeFlags.Null | TypeFlags.Undefined) || + return !!(type.flags & (TypeFlags.Any | TypeFlags.Null | TypeFlags.Undefined | TypeFlags.NonPrimitive) || type.flags & TypeFlags.Object && !isGenericMappedType(type) || type.flags & TypeFlags.UnionOrIntersection && !forEach((type).types, t => !isValidSpreadType(t))); } diff --git a/tests/baselines/reference/nonPrimitiveAccessProperty.errors.txt b/tests/baselines/reference/nonPrimitiveAccessProperty.errors.txt index 8ef94c64448..0a6dfa66b86 100644 --- a/tests/baselines/reference/nonPrimitiveAccessProperty.errors.txt +++ b/tests/baselines/reference/nonPrimitiveAccessProperty.errors.txt @@ -1,10 +1,16 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts(3,3): error TS2339: Property 'nonExist' does not exist on type 'object'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts(5,7): error TS2459: Type 'object' has no property 'destructuring' and no string index signature. -==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts (1 errors) ==== +==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts (2 errors) ==== var a: object; a.toString(); a.nonExist(); // error ~~~~~~~~ !!! error TS2339: Property 'nonExist' does not exist on type 'object'. + + var { destructuring } = a; // error + ~~~~~~~~~~~~~ +!!! error TS2459: Type 'object' has no property 'destructuring' and no string index signature. + var { ...rest } = a; // ok \ No newline at end of file diff --git a/tests/baselines/reference/nonPrimitiveAccessProperty.js b/tests/baselines/reference/nonPrimitiveAccessProperty.js index a71b2aba865..abfe2605e32 100644 --- a/tests/baselines/reference/nonPrimitiveAccessProperty.js +++ b/tests/baselines/reference/nonPrimitiveAccessProperty.js @@ -2,9 +2,23 @@ var a: object; a.toString(); a.nonExist(); // error + +var { destructuring } = a; // error +var { ...rest } = a; // ok //// [nonPrimitiveAccessProperty.js] +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; var a; a.toString(); a.nonExist(); // error +var destructuring = a.destructuring; // error +var rest = __rest(a, []); // ok diff --git a/tests/baselines/reference/objectSpread.js b/tests/baselines/reference/objectSpread.js index 4305e17ab31..259b86628a5 100644 --- a/tests/baselines/reference/objectSpread.js +++ b/tests/baselines/reference/objectSpread.js @@ -78,6 +78,8 @@ let computedAfter: { a: number, b: string, "at the end": number } = // shortcut syntax let a = 12; let shortCutted: { a: number, b: string } = { ...o, a } +// non primitive +let spreadNonPrimitve = { ...{}} @@ -148,4 +150,6 @@ var computedAfter = __assign({}, o, (_c = { b: 'yeah' }, _c['at the end'] = 14, // shortcut syntax var a = 12; var shortCutted = __assign({}, o, { a: a }); +// non primitive +var spreadNonPrimitve = __assign({}, {}); var _a, _b, _c; diff --git a/tests/baselines/reference/objectSpread.symbols b/tests/baselines/reference/objectSpread.symbols index 35c10faa9c0..69c9ed34341 100644 --- a/tests/baselines/reference/objectSpread.symbols +++ b/tests/baselines/reference/objectSpread.symbols @@ -316,4 +316,8 @@ let shortCutted: { a: number, b: string } = { ...o, a } >o : Symbol(o, Decl(objectSpread.ts, 0, 3)) >a : Symbol(a, Decl(objectSpread.ts, 78, 51)) +// non primitive +let spreadNonPrimitve = { ...{}} +>spreadNonPrimitve : Symbol(spreadNonPrimitve, Decl(objectSpread.ts, 80, 3)) + diff --git a/tests/baselines/reference/objectSpread.types b/tests/baselines/reference/objectSpread.types index a571bd0bb63..8a8df1a497f 100644 --- a/tests/baselines/reference/objectSpread.types +++ b/tests/baselines/reference/objectSpread.types @@ -407,4 +407,11 @@ let shortCutted: { a: number, b: string } = { ...o, a } >o : { a: number; b: string; } >a : number +// non primitive +let spreadNonPrimitve = { ...{}} +>spreadNonPrimitve : { constructor: Function; toString(): string; toLocaleString(): string; valueOf(): Object; hasOwnProperty(v: string): boolean; isPrototypeOf(v: Object): boolean; propertyIsEnumerable(v: string): boolean; } +>{ ...{}} : { constructor: Function; toString(): string; toLocaleString(): string; valueOf(): Object; hasOwnProperty(v: string): boolean; isPrototypeOf(v: Object): boolean; propertyIsEnumerable(v: string): boolean; } +>{} : object +>{} : {} + diff --git a/tests/baselines/reference/objectSpreadNegative.errors.txt b/tests/baselines/reference/objectSpreadNegative.errors.txt index 17f07bc06a2..2b0960996ff 100644 --- a/tests/baselines/reference/objectSpreadNegative.errors.txt +++ b/tests/baselines/reference/objectSpreadNegative.errors.txt @@ -14,11 +14,12 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(37,19): error TS269 tests/cases/conformance/types/spread/objectSpreadNegative.ts(42,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures. tests/cases/conformance/types/spread/objectSpreadNegative.ts(46,12): error TS2339: Property 'b' does not exist on type '{}'. tests/cases/conformance/types/spread/objectSpreadNegative.ts(52,9): error TS2339: Property 'm' does not exist on type '{ p: number; }'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(56,14): error TS2698: Spread types may only be created from object types. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(59,14): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(57,11): error TS2339: Property 'a' does not exist on type '{ constructor: Function; toString(): string; toLocaleString(): string; valueOf(): Object; hasOwnProperty(v: string): boolean; isPrototypeOf(v: Object): boolean; propertyIsEnumerable(v: string): boolean; }'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(61,14): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(64,14): error TS2698: Spread types may only be created from object types. -==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (15 errors) ==== +==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (16 errors) ==== let o = { a: 1, b: 'no' } /// private propagates @@ -101,6 +102,13 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(59,14): error TS269 ~ !!! error TS2339: Property 'm' does not exist on type '{ p: number; }'. + // non primitive + let obj: object = { a: 123 }; + let spreadObj = { ...obj }; + spreadObj.a; // error 'a' is not in {} + ~ +!!! error TS2339: Property 'a' does not exist on type '{ constructor: Function; toString(): string; toLocaleString(): string; valueOf(): Object; hasOwnProperty(v: string): boolean; isPrototypeOf(v: Object): boolean; propertyIsEnumerable(v: string): boolean; }'. + // generics function f(t: T, u: U) { return { ...t, ...u, id: 'id' }; diff --git a/tests/baselines/reference/objectSpreadNegative.js b/tests/baselines/reference/objectSpreadNegative.js index dff84355370..fd834b6ef9c 100644 --- a/tests/baselines/reference/objectSpreadNegative.js +++ b/tests/baselines/reference/objectSpreadNegative.js @@ -52,6 +52,11 @@ let c: C = new C() let spreadC = { ...c } spreadC.m(); // error 'm' is not in '{ ... c }' +// non primitive +let obj: object = { a: 123 }; +let spreadObj = { ...obj }; +spreadObj.a; // error 'a' is not in {} + // generics function f(t: T, u: U) { return { ...t, ...u, id: 'id' }; @@ -132,6 +137,10 @@ var C = (function () { var c = new C(); var spreadC = __assign({}, c); spreadC.m(); // error 'm' is not in '{ ... c }' +// non primitive +var obj = { a: 123 }; +var spreadObj = __assign({}, obj); +spreadObj.a; // error 'a' is not in {} // generics function f(t, u) { return __assign({}, t, u, { id: 'id' }); diff --git a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts index 2febbb1e2ca..cf902c12e65 100644 --- a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts +++ b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts @@ -1,3 +1,6 @@ var a: object; a.toString(); a.nonExist(); // error + +var { destructuring } = a; // error +var { ...rest } = a; // ok diff --git a/tests/cases/conformance/types/spread/objectSpread.ts b/tests/cases/conformance/types/spread/objectSpread.ts index ebf2bdb2ade..c4562e6f196 100644 --- a/tests/cases/conformance/types/spread/objectSpread.ts +++ b/tests/cases/conformance/types/spread/objectSpread.ts @@ -78,4 +78,6 @@ let computedAfter: { a: number, b: string, "at the end": number } = // shortcut syntax let a = 12; let shortCutted: { a: number, b: string } = { ...o, a } +// non primitive +let spreadNonPrimitve = { ...{}} diff --git a/tests/cases/conformance/types/spread/objectSpreadNegative.ts b/tests/cases/conformance/types/spread/objectSpreadNegative.ts index 6d1e0dde429..c3b42b31aa9 100644 --- a/tests/cases/conformance/types/spread/objectSpreadNegative.ts +++ b/tests/cases/conformance/types/spread/objectSpreadNegative.ts @@ -52,6 +52,11 @@ let c: C = new C() let spreadC = { ...c } spreadC.m(); // error 'm' is not in '{ ... c }' +// non primitive +let obj: object = { a: 123 }; +let spreadObj = { ...obj }; +spreadObj.a; // error 'a' is not in {} + // generics function f(t: T, u: U) { return { ...t, ...u, id: 'id' }; From 2d232c21a2ab611b551af967459ac6e25431f9e8 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 17 Jan 2017 10:29:54 -0800 Subject: [PATCH 02/41] Support find-all-references for type keywords --- src/harness/fourslash.ts | 6 +- src/services/documentHighlights.ts | 18 +- src/services/findAllReferences.ts | 191 ++++++++++-------- src/services/services.ts | 31 ++- src/services/types.ts | 2 +- src/services/utilities.ts | 22 +- tests/cases/fourslash/findAllRefsPrimitive.ts | 33 +++ tests/cases/fourslash/fourslash.ts | 1 + tests/cases/fourslash/getOccurrencesOfAny.ts | 12 -- tests/cases/fourslash/localGetReferences.ts | 6 +- 10 files changed, 191 insertions(+), 131 deletions(-) create mode 100644 tests/cases/fourslash/findAllRefsPrimitive.ts delete mode 100644 tests/cases/fourslash/getOccurrencesOfAny.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 1afb6de2cf2..6e9ab502e52 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1668,7 +1668,7 @@ namespace FourSlash { this.goToPosition(len); } - private goToRangeStart({fileName, start}: Range) { + public goToRangeStart({fileName, start}: Range) { this.openFile(fileName); this.goToPosition(start); } @@ -3082,6 +3082,10 @@ namespace FourSlashInterface { this.state.goToMarker(name); } + public rangeStart(range: FourSlash.Range) { + this.state.goToRangeStart(range); + } + public bof() { this.state.goToBOF(); } diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index 79fa0236bc5..778a007ded5 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -17,25 +17,11 @@ namespace ts.DocumentHighlights { } function getSemanticDocumentHighlights(node: Node, typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFilesToSearch: SourceFile[]): DocumentHighlights[] { - if (node.kind === SyntaxKind.Identifier || - node.kind === SyntaxKind.ThisKeyword || - node.kind === SyntaxKind.ThisType || - node.kind === SyntaxKind.SuperKeyword || - node.kind === SyntaxKind.StringLiteral || - isLiteralNameOfPropertyDeclarationOrIndexAccess(node)) { - - const referencedSymbols = FindAllReferences.getReferencedSymbolsForNode(typeChecker, cancellationToken, node, sourceFilesToSearch, /*findInStrings*/ false, /*findInComments*/ false, /*implementations*/false); - return convertReferencedSymbols(referencedSymbols); - } - - return undefined; + const referencedSymbols = FindAllReferences.getReferencedSymbolsForNode(typeChecker, cancellationToken, node, sourceFilesToSearch, /*findInStrings*/false, /*findInComments*/false, /*implementations*/false); + return referencedSymbols && convertReferencedSymbols(referencedSymbols); } function convertReferencedSymbols(referencedSymbols: ReferencedSymbol[]): DocumentHighlights[] { - if (!referencedSymbols) { - return undefined; - } - const fileNameToDocumentHighlights = createMap(); const result: DocumentHighlights[] = []; for (const referencedSymbol of referencedSymbols) { diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 090357a56b2..68eb684fe25 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1,29 +1,16 @@ /* @internal */ namespace ts.FindAllReferences { - export function findReferencedSymbols(typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFiles: SourceFile[], sourceFile: SourceFile, position: number, findInStrings: boolean, findInComments: boolean): ReferencedSymbol[] { + export function findReferencedSymbols(typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFiles: SourceFile[], sourceFile: SourceFile, position: number, findInStrings: boolean, findInComments: boolean): ReferencedSymbol[] | undefined { const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); - if (node === sourceFile) { - return undefined; - } - - switch (node.kind) { - case SyntaxKind.NumericLiteral: - if (!isLiteralNameOfPropertyDeclarationOrIndexAccess(node)) { - break; - } - // Fallthrough - case SyntaxKind.Identifier: - case SyntaxKind.ThisKeyword: - // case SyntaxKind.SuperKeyword: TODO:GH#9268 - case SyntaxKind.ConstructorKeyword: - case SyntaxKind.StringLiteral: - return getReferencedSymbolsForNode(typeChecker, cancellationToken, node, sourceFiles, findInStrings, findInComments, /*implementations*/false); - } - return undefined; + return getReferencedSymbolsForNode(typeChecker, cancellationToken, node, sourceFiles, findInStrings, findInComments, /*implementations*/false); } - export function getReferencedSymbolsForNode(typeChecker: TypeChecker, cancellationToken: CancellationToken, node: Node, sourceFiles: SourceFile[], findInStrings: boolean, findInComments: boolean, implementations: boolean): ReferencedSymbol[] { + export function getReferencedSymbolsForNode(typeChecker: TypeChecker, cancellationToken: CancellationToken, node: Node, sourceFiles: SourceFile[], findInStrings: boolean, findInComments: boolean, implementations: boolean): ReferencedSymbol[] | undefined { if (!implementations) { + if (isTypeKeyword(node.kind)) { + return getAllReferencesForKeyword(sourceFiles, node.kind, cancellationToken); + } + // Labels if (isLabelName(node)) { if (isJumpStatementTarget(node)) { @@ -68,8 +55,6 @@ namespace ts.FindAllReferences { return undefined; } - let result: ReferencedSymbol[]; - // Compute the meaning from the location and the symbol it references const searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), declarations); @@ -84,6 +69,7 @@ namespace ts.FindAllReferences { // Maps from a symbol ID to the ReferencedSymbol entry in 'result'. const symbolToIndex: number[] = []; + let result: ReferencedSymbol[]; if (scope) { result = []; getReferencesInNode(scope, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex, implementations, typeChecker, cancellationToken); @@ -92,10 +78,7 @@ namespace ts.FindAllReferences { const internedName = getInternedName(symbol, node); for (const sourceFile of sourceFiles) { cancellationToken.throwIfCancellationRequested(); - - const nameTable = getNameTable(sourceFile); - - if (nameTable.get(internedName) !== undefined) { + if (sourceFileHasName(sourceFile, internedName)) { result = result || []; getReferencesInNode(sourceFile, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex, implementations, typeChecker, cancellationToken); } @@ -105,9 +88,13 @@ namespace ts.FindAllReferences { return result; } + function sourceFileHasName(sourceFile: SourceFile, name: string): boolean { + return getNameTable(sourceFile).get(name) !== undefined; + } + function getDefinition(symbol: Symbol, node: Node, typeChecker: TypeChecker): ReferencedSymbolDefinitionInfo { - const info = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, node.getSourceFile(), getContainerNode(node), node); - const name = map(info.displayParts, p => p.text).join(""); + const { displayParts, symbolKind } = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, node.getSourceFile(), getContainerNode(node), node); + const name = displayParts.map(p => p.text).join(""); const declarations = symbol.declarations; if (!declarations || declarations.length === 0) { return undefined; @@ -117,10 +104,10 @@ namespace ts.FindAllReferences { containerKind: "", containerName: "", name, - kind: info.symbolKind, + kind: symbolKind, fileName: declarations[0].getSourceFile().fileName, textSpan: createTextSpan(declarations[0].getStart(), 0), - displayParts: info.displayParts + displayParts }; } @@ -351,6 +338,45 @@ namespace ts.FindAllReferences { } } + function getAllReferencesForKeyword(sourceFiles: SourceFile[], keywordKind: ts.SyntaxKind, cancellationToken: CancellationToken): ReferencedSymbol[] { + const name = tokenToString(keywordKind); + const definition: ReferencedSymbolDefinitionInfo = { + containerKind: "", + containerName: "", + fileName: "", + kind: ScriptElementKind.keyword, + name, + textSpan: createTextSpan(0, 1), + displayParts: [{ text: name, kind: ScriptElementKind.keyword }] + } + + const references: ReferenceEntry[] = []; + for (const sourceFile of sourceFiles) { + cancellationToken.throwIfCancellationRequested(); + if (sourceFileHasName(sourceFile, name)) { + addReferencesForKeywordInFile(sourceFile, keywordKind, name, cancellationToken, references); + } + } + + return [{ definition, references }]; + } + + function addReferencesForKeywordInFile(sourceFile: SourceFile, kind: SyntaxKind, searchText: string, cancellationToken: CancellationToken, references: Push): void { + const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, sourceFile.getStart(), sourceFile.getEnd(), cancellationToken); + for (const position of possiblePositions) { + cancellationToken.throwIfCancellationRequested(); + const referenceLocation = getTouchingPropertyName(sourceFile, position); + if (referenceLocation.kind === kind) { + references.push({ + textSpan: createTextSpanFromNode(referenceLocation), + fileName: sourceFile.fileName, + isWriteAccess: false, + isDefinition: false, + }); + } + } + } + /** 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 @@ -375,67 +401,64 @@ namespace ts.FindAllReferences { const parents = getParentSymbolsOfPropertyAccess(); const inheritsFromCache: Map = createMap(); + // Build the set of symbols to search for, initially it has only the current symbol + const searchSymbols = populateSearchSymbolSet(searchSymbol, searchLocation, typeChecker, implementations); - if (possiblePositions.length) { - // Build the set of symbols to search for, initially it has only the current symbol - const searchSymbols = populateSearchSymbolSet(searchSymbol, searchLocation, typeChecker, implementations); + for (const position of possiblePositions) { + cancellationToken.throwIfCancellationRequested(); - forEach(possiblePositions, position => { - cancellationToken.throwIfCancellationRequested(); + const referenceLocation = getTouchingPropertyName(sourceFile, position); + 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 (!implementations && ((findInStrings && isInString(sourceFile, position)) || + (findInComments && isInNonReferenceComment(sourceFile, position)))) { - const referenceLocation = getTouchingPropertyName(sourceFile, position); - 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 (!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 - // 'Rename' won't care (as they ignore the definitions), and features like - // 'FindReferences' will just filter out these results. - result.push({ - definition: undefined, - references: [{ - fileName: sourceFile.fileName, - textSpan: createTextSpan(position, searchText.length), - isWriteAccess: false, - isDefinition: false - }] - }); - } - return; + // In the case where we're looking inside comments/strings, we don't have + // an actual definition. So just use 'undefined' here. Features like + // 'Rename' won't care (as they ignore the definitions), and features like + // 'FindReferences' will just filter out these results. + result.push({ + definition: undefined, + references: [{ + fileName: sourceFile.fileName, + textSpan: createTextSpan(position, searchText.length), + isWriteAccess: false, + isDefinition: false + }] + }); } + continue; + } - if (!(getMeaningFromLocation(referenceLocation) & searchMeaning)) { - return; + if (!(getMeaningFromLocation(referenceLocation) & searchMeaning)) { + continue; + } + + const referenceSymbol = typeChecker.getSymbolAtLocation(referenceLocation); + if (referenceSymbol) { + const referenceSymbolDeclaration = referenceSymbol.valueDeclaration; + const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); + const relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation, + /*searchLocationIsConstructor*/ searchLocation.kind === SyntaxKind.ConstructorKeyword, parents, inheritsFromCache, typeChecker); + + if (relatedSymbol) { + addReferenceToRelatedSymbol(referenceLocation, relatedSymbol); } - - const referenceSymbol = typeChecker.getSymbolAtLocation(referenceLocation); - if (referenceSymbol) { - const referenceSymbolDeclaration = referenceSymbol.valueDeclaration; - const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); - const relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation, - /*searchLocationIsConstructor*/ searchLocation.kind === SyntaxKind.ConstructorKeyword, parents, inheritsFromCache, typeChecker); - - if (relatedSymbol) { - 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 - * an identifier is declared, the language service should return the position of the variable declaration as well as - * the position in short-hand property assignment excluding property accessing. However, if we do findAllReference at the - * 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) { - addReferenceToRelatedSymbol(referenceSymbolDeclaration.name, shorthandValueSymbol); - } - else if (searchLocation.kind === SyntaxKind.ConstructorKeyword) { - findAdditionalConstructorReferences(referenceSymbol, referenceLocation); - } + /* 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 + * an identifier is declared, the language service should return the position of the variable declaration as well as + * the position in short-hand property assignment excluding property accessing. However, if we do findAllReference at the + * 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) { + addReferenceToRelatedSymbol(referenceSymbolDeclaration.name, shorthandValueSymbol); } - }); + else if (searchLocation.kind === SyntaxKind.ConstructorKeyword) { + findAdditionalConstructorReferences(referenceSymbol, referenceLocation); + } + } } return; diff --git a/src/services/services.ts b/src/services/services.ts index 26374eccbfd..20204165328 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1959,11 +1959,9 @@ namespace ts { function walk(node: Node) { switch (node.kind) { - case SyntaxKind.Identifier: { - const text = (node).text; - nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1); + case SyntaxKind.Identifier: + setNameTable((node).text, node); break; - } case SyntaxKind.StringLiteral: case SyntaxKind.NumericLiteral: // We want to store any numbers/strings if they were a name that could be @@ -1974,20 +1972,31 @@ namespace ts { node.parent.kind === SyntaxKind.ExternalModuleReference || isArgumentOfElementAccessExpression(node) || isLiteralComputedPropertyDeclarationName(node)) { - - const text = (node).text; - nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1); + setNameTable((node).text, node); } break; - default: + case SyntaxKind.TypeOperator: + setNameTable(tokenToString((node as ts.TypeOperatorNode).operator), node); forEachChild(node, walk); - if (node.jsDoc) { - for (const jsDoc of node.jsDoc) { - forEachChild(jsDoc, walk); + break; + default: + if (isTypeKeyword(node.kind)) { + setNameTable(tokenToString(node.kind), node); + } + else { + forEachChild(node, walk); + if (node.jsDoc) { + for (const jsDoc of node.jsDoc) { + forEachChild(jsDoc, walk); + } } } } } + + function setNameTable(text: string, node: ts.Node): void { + nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1); + } } function isArgumentOfElementAccessExpression(node: Node) { diff --git a/src/services/types.ts b/src/services/types.ts index 88ffe2950ce..42f2a7992bd 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -495,7 +495,7 @@ namespace ts { export interface SymbolDisplayPart { text: string; - kind: string; + kind: string; // A ScriptElementKind } export interface QuickInfo { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index def7ab8e4bd..dd337238da3 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -71,7 +71,10 @@ namespace ts { } export function getMeaningFromLocation(node: Node): SemanticMeaning { - if (node.parent.kind === SyntaxKind.ExportAssignment) { + if (node.kind === SyntaxKind.SourceFile) { + return SemanticMeaning.Value; + } + else if (node.parent.kind === SyntaxKind.ExportAssignment) { return SemanticMeaning.Value | SemanticMeaning.Type | SemanticMeaning.Namespace; } else if (isInRightSideOfImport(node)) { @@ -1116,6 +1119,23 @@ namespace ts { export function createTextSpanFromNode(node: Node, sourceFile?: SourceFile): TextSpan { return createTextSpanFromBounds(node.getStart(sourceFile), node.getEnd()); } + + export function isTypeKeyword(kind: SyntaxKind): boolean { + switch (kind) { + case SyntaxKind.AnyKeyword: + case SyntaxKind.BooleanKeyword: + case SyntaxKind.NeverKeyword: + case SyntaxKind.NumberKeyword: + case SyntaxKind.KeyOfKeyword: + case SyntaxKind.ObjectKeyword: + case SyntaxKind.StringKeyword: + case SyntaxKind.SymbolKeyword: + case SyntaxKind.VoidKeyword: + return true; + default: + return false; + } + } } // Display-part writer helpers diff --git a/tests/cases/fourslash/findAllRefsPrimitive.ts b/tests/cases/fourslash/findAllRefsPrimitive.ts new file mode 100644 index 00000000000..9bd3d62eabb --- /dev/null +++ b/tests/cases/fourslash/findAllRefsPrimitive.ts @@ -0,0 +1,33 @@ +// @noLib: true + +/// + +// @Filename: a.ts +////const x: [|any|] = 0; +////const any = 2; +////const y: [|any|] = any; + +////function f(b: [|boolean|]): [|boolean|]; + +////type T = [|never|]; type U = [|never|]; + +////function n(x: [|number|]): [|number|]; + +////function o(x: [|object|]): [|object|]; + +////function s(x: [|string|]): [|string|]; + +////function sy(s: [|symbol|]): [|symbol|]; + +////function v(v: [|void|]): [|void|]; + +////function k(x: [|keyof|] Date): [|keyof|] Date; + +// @Filename: b.ts +// const z: [|any|] = 0; + +verify.rangesWithSameTextReferenceEachOther(); +verify.rangesWithSameTextAreDocumentHighlights(); + +goTo.rangeStart(test.ranges()[0]); +verify.renameInfoFailed(); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index ed09fcd2c92..d0293585a4e 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -118,6 +118,7 @@ declare namespace FourSlashInterface { } class goTo { marker(name?: string): void; + rangeStart(range: Range): void; bof(): void; eof(): void; implementation(): void; diff --git a/tests/cases/fourslash/getOccurrencesOfAny.ts b/tests/cases/fourslash/getOccurrencesOfAny.ts deleted file mode 100644 index c28dd83b422..00000000000 --- a/tests/cases/fourslash/getOccurrencesOfAny.ts +++ /dev/null @@ -1,12 +0,0 @@ -/// - -////var obj1: { -//// (bar: any): any; -//// new (bar: any): any; -//// [bar: any]: any; -//// bar: any; -//// foob(bar: any): an/**/y; -////}; - -goTo.marker(); -verify.occurrencesAtPositionCount(0); diff --git a/tests/cases/fourslash/localGetReferences.ts b/tests/cases/fourslash/localGetReferences.ts index fa9e59cabcf..d8e64be1ada 100644 --- a/tests/cases/fourslash/localGetReferences.ts +++ b/tests/cases/fourslash/localGetReferences.ts @@ -3,7 +3,7 @@ // @Filename: localGetReferences_1.ts ////// Comment Refence Test: g/*1*/lobalVar ////// References to a variable declared in global. -////var [|globalVar|]: n/*2*/umber = 2; +////var [|globalVar|]: number = 2; //// ////class fooCls { //// // References to static variable declared in a class. @@ -189,10 +189,6 @@ goTo.marker("1"); verify.referencesAre([]); -// References to type. -goTo.marker("2"); -verify.referencesAre([]); - // References to unresolved symbol. goTo.marker("3"); verify.referencesAre([]); From 9665f2501158d8c765d27bd315dcace9b59d1758 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Wed, 18 Jan 2017 13:55:31 -0800 Subject: [PATCH 03/41] Simplify fourslash tests by adding some helpers --- src/harness/fourslash.ts | 72 +++++++++++++++++-- ...tIdentifierDefinitionLocations_Generics.ts | 6 +- ...stAtIdentifierDefinitionLocations_catch.ts | 6 +- ...AtIdentifierDefinitionLocations_classes.ts | 5 +- ...tifierDefinitionLocations_destructuring.ts | 5 +- ...entifierDefinitionLocations_enumMembers.ts | 6 +- ...ntifierDefinitionLocations_enumMembers2.ts | 5 +- ...stAtIdentifierDefinitionLocations_enums.ts | 5 +- ...IdentifierDefinitionLocations_functions.ts | 6 +- ...ierDefinitionLocations_interfaceMembers.ts | 5 +- ...erDefinitionLocations_interfaceMembers2.ts | 5 +- ...erDefinitionLocations_interfaceMembers3.ts | 5 +- ...dentifierDefinitionLocations_interfaces.ts | 6 +- ...dentifierDefinitionLocations_parameters.ts | 6 +- ...dentifierDefinitionLocations_properties.ts | 3 +- ...fierDefinitionLocations_varDeclarations.ts | 5 +- .../completionListAtInvalidLocations.ts | 5 +- ...stBuilderLocations_VariableDeclarations.ts | 9 +-- ...mpletionListBuilderLocations_parameters.ts | 4 +- ...mpletionListBuilderLocations_properties.ts | 5 +- .../completionListInIndexSignature01.ts | 5 +- .../completionListInIndexSignature02.ts | 5 +- .../completionListInObjectLiteral4.ts | 6 +- .../completionListInStringLiterals1.ts | 6 +- .../completionListInStringLiterals2.ts | 6 +- .../completionListInTemplateLiteralParts1.ts | 6 +- ...ionListInTemplateLiteralPartsNegatives1.ts | 6 +- ...ionListNewIdentifierFunctionDeclaration.ts | 3 +- ...ionListNewIdentifierVariableDeclaration.ts | 5 +- .../docCommentTemplateInSingleLineComment.ts | 7 +- ...ommentTemplateInsideFunctionDeclaration.ts | 5 +- .../fourslash/docCommentTemplateRegex.ts | 5 +- tests/cases/fourslash/fourslash.ts | 7 +- .../fourslash/getOccurrencesAbstract01.ts | 11 +-- .../fourslash/getOccurrencesAbstract02.ts | 11 +-- ...etOccurrencesClassExpressionConstructor.ts | 9 +-- .../getOccurrencesClassExpressionPrivate.ts | 9 +-- .../getOccurrencesClassExpressionPublic.ts | 9 +-- .../getOccurrencesClassExpressionStatic.ts | 11 +-- ...getOccurrencesClassExpressionStaticThis.ts | 9 +-- .../getOccurrencesClassExpressionThis.ts | 9 +-- .../cases/fourslash/getOccurrencesConst02.ts | 5 +- .../cases/fourslash/getOccurrencesConst03.ts | 5 +- .../fourslash/getOccurrencesConstructor.ts | 12 +--- .../fourslash/getOccurrencesConstructor2.ts | 12 +--- .../cases/fourslash/getOccurrencesDeclare1.ts | 9 +-- .../cases/fourslash/getOccurrencesDeclare2.ts | 9 +-- .../cases/fourslash/getOccurrencesDeclare3.ts | 9 +-- .../cases/fourslash/getOccurrencesExport1.ts | 9 +-- .../cases/fourslash/getOccurrencesExport2.ts | 9 +-- .../cases/fourslash/getOccurrencesExport3.ts | 9 +-- tests/cases/fourslash/getOccurrencesIfElse.ts | 12 +--- .../cases/fourslash/getOccurrencesIfElse2.ts | 9 +-- .../cases/fourslash/getOccurrencesIfElse3.ts | 9 +-- .../fourslash/getOccurrencesIfElseBroken.ts | 8 +-- .../fourslash/getOccurrencesIsWriteAccess.ts | 8 +-- .../getOccurrencesLoopBreakContinue.ts | 15 ++-- .../getOccurrencesLoopBreakContinue2.ts | 15 ++-- .../getOccurrencesLoopBreakContinue3.ts | 15 ++-- .../getOccurrencesLoopBreakContinue4.ts | 15 ++-- .../getOccurrencesLoopBreakContinue5.ts | 15 ++-- .../getOccurrencesLoopBreakContinue6.ts | 8 +-- ...etOccurrencesLoopBreakContinueNegatives.ts | 8 +-- .../getOccurrencesModifiersNegatives1.ts | 6 +- .../getOccurrencesOfAnonymousFunction.ts | 10 +-- .../cases/fourslash/getOccurrencesPrivate1.ts | 9 +-- .../cases/fourslash/getOccurrencesPrivate2.ts | 9 +-- ...etOccurrencesPropertyInAliasedInterface.ts | 8 +-- .../fourslash/getOccurrencesProtected1.ts | 9 +-- .../fourslash/getOccurrencesProtected2.ts | 9 +-- .../cases/fourslash/getOccurrencesPublic1.ts | 9 +-- .../cases/fourslash/getOccurrencesPublic2.ts | 9 +-- tests/cases/fourslash/getOccurrencesReturn.ts | 12 +--- .../cases/fourslash/getOccurrencesReturn2.ts | 12 +--- .../cases/fourslash/getOccurrencesReturn3.ts | 8 +-- .../fourslash/getOccurrencesReturnBroken.ts | 10 +-- .../fourslash/getOccurrencesSetAndGet.ts | 10 +-- .../fourslash/getOccurrencesSetAndGet2.ts | 10 +-- .../fourslash/getOccurrencesSetAndGet3.ts | 10 +-- .../cases/fourslash/getOccurrencesStatic1.ts | 9 +-- .../getOccurrencesStringLiteralTypes.ts | 9 +-- .../fourslash/getOccurrencesStringLiterals.ts | 6 +- tests/cases/fourslash/getOccurrencesSuper.ts | 14 ++-- tests/cases/fourslash/getOccurrencesSuper2.ts | 14 ++-- tests/cases/fourslash/getOccurrencesSuper3.ts | 2 +- .../fourslash/getOccurrencesSuperNegatives.ts | 6 +- .../getOccurrencesSwitchCaseDefault.ts | 10 +-- .../getOccurrencesSwitchCaseDefault2.ts | 10 +-- .../getOccurrencesSwitchCaseDefault3.ts | 9 +-- .../getOccurrencesSwitchCaseDefault4.ts | 15 +--- tests/cases/fourslash/getOccurrencesThis.ts | 14 ++-- tests/cases/fourslash/getOccurrencesThis2.ts | 14 ++-- tests/cases/fourslash/getOccurrencesThis3.ts | 14 ++-- tests/cases/fourslash/getOccurrencesThis4.ts | 14 ++-- tests/cases/fourslash/getOccurrencesThis5.ts | 14 ++-- .../fourslash/getOccurrencesThisNegatives2.ts | 8 +-- tests/cases/fourslash/getOccurrencesThrow.ts | 16 ++--- tests/cases/fourslash/getOccurrencesThrow2.ts | 16 ++--- tests/cases/fourslash/getOccurrencesThrow3.ts | 16 ++--- tests/cases/fourslash/getOccurrencesThrow4.ts | 16 ++--- tests/cases/fourslash/getOccurrencesThrow5.ts | 16 ++--- tests/cases/fourslash/getOccurrencesThrow6.ts | 13 +--- tests/cases/fourslash/getOccurrencesThrow7.ts | 11 +-- tests/cases/fourslash/getOccurrencesThrow8.ts | 11 +-- .../fourslash/quickInfoInvalidLocations.ts | 10 +-- .../fourslash/referencesForIndexProperty2.ts | 4 +- tests/cases/fourslash/referencesInComment.ts | 4 +- tests/cases/fourslash/renameAlias.ts | 6 +- tests/cases/fourslash/renameAlias2.ts | 6 +- tests/cases/fourslash/renameAlias3.ts | 6 +- .../fourslash/renameAliasExternalModule.ts | 7 +- .../fourslash/renameAliasExternalModule2.ts | 7 +- .../fourslash/renameAliasExternalModule3.ts | 7 +- .../renameContextuallyTypedProperties.ts | 7 +- .../renameContextuallyTypedProperties2.ts | 7 +- tests/cases/fourslash/renameDefaultImport.ts | 23 +++--- .../renameDefaultImportDifferentName.ts | 24 +++---- .../renameDestructuringAssignment.ts | 16 ++--- .../renameDestructuringAssignmentInFor2.ts | 26 +++---- .../renameDestructuringAssignmentInForOf2.ts | 26 +++---- ...ucturingAssignmentNestedInArrayLiteral2.ts | 20 +++--- ...nameDestructuringAssignmentNestedInFor2.ts | 13 ++-- ...meDestructuringAssignmentNestedInForOf2.ts | 14 ++-- .../renameDestructuringClassProperty.ts | 14 ++-- .../renameDestructuringDeclarationInFor.ts | 26 +++---- .../renameDestructuringDeclarationInForOf.ts | 24 +++---- .../renameDestructuringFunctionParameter.ts | 11 ++- ...renameDestructuringNestedBindingElement.ts | 14 ++-- .../fourslash/renameForDefaultExport01.ts | 7 +- .../fourslash/renameForDefaultExport02.ts | 7 +- .../fourslash/renameForDefaultExport03.ts | 7 +- .../cases/fourslash/renameImportAndExport.ts | 6 +- .../fourslash/renameImportAndShorthand.ts | 6 +- .../renameImportNamespaceAndShorthand.ts | 6 +- .../fourslash/renameImportOfExportEquals.ts | 6 +- tests/cases/fourslash/renameImportRequire.ts | 12 ++-- .../fourslash/renameInheritedProperties1.ts | 7 +- .../fourslash/renameInheritedProperties2.ts | 7 +- .../fourslash/renameInheritedProperties3.ts | 7 +- .../fourslash/renameInheritedProperties4.ts | 7 +- .../fourslash/renameInheritedProperties5.ts | 8 +-- .../fourslash/renameInheritedProperties6.ts | 7 +- .../fourslash/renameInheritedProperties7.ts | 11 +-- .../fourslash/renameInheritedProperties8.ts | 11 +-- .../renameLocationsForClassExpression01.ts | 8 +-- .../renameLocationsForFunctionExpression01.ts | 7 +- .../renameLocationsForFunctionExpression02.ts | 9 +-- ...enameObjectBindingElementPropertyName01.ts | 5 +- tests/cases/fourslash/renameObjectSpread.ts | 6 +- .../fourslash/renameObjectSpreadAssignment.ts | 10 +-- .../renameParameterPropertyDeclaration1.ts | 7 +- .../renameParameterPropertyDeclaration2.ts | 7 +- .../renameParameterPropertyDeclaration3.ts | 7 +- .../renameParameterPropertyDeclaration4.ts | 7 +- .../renameParameterPropertyDeclaration5.ts | 7 +- tests/cases/fourslash/renameRest.ts | 8 +-- .../fourslash/renameStingPropertyNames.ts | 7 +- .../fourslash/renameStringLiteralTypes.ts | 6 +- tests/cases/fourslash/renameThis.ts | 4 +- .../cases/fourslash/renameUMDModuleAlias1.ts | 6 +- tests/cases/fourslash/server/occurrences01.ts | 11 +-- tests/cases/fourslash/server/occurrences02.ts | 11 +-- .../signatureHelpTaggedTemplates1.ts | 6 +- .../signatureHelpTaggedTemplates2.ts | 6 +- .../signatureHelpTaggedTemplates3.ts | 6 +- .../signatureHelpTaggedTemplates4.ts | 6 +- .../signatureHelpTaggedTemplates5.ts | 6 +- .../signatureHelpTaggedTemplates6.ts | 6 +- .../signatureHelpTaggedTemplates7.ts | 6 +- ...signatureHelpTaggedTemplatesIncomplete1.ts | 8 +-- ...signatureHelpTaggedTemplatesIncomplete2.ts | 6 +- ...signatureHelpTaggedTemplatesIncomplete3.ts | 6 +- ...signatureHelpTaggedTemplatesIncomplete4.ts | 6 +- ...signatureHelpTaggedTemplatesIncomplete5.ts | 6 +- ...signatureHelpTaggedTemplatesIncomplete6.ts | 6 +- ...signatureHelpTaggedTemplatesIncomplete7.ts | 6 +- ...signatureHelpTaggedTemplatesIncomplete8.ts | 6 +- ...signatureHelpTaggedTemplatesIncomplete9.ts | 6 +- .../signatureHelpTaggedTemplatesNegatives1.ts | 7 +- .../signatureHelpTaggedTemplatesNegatives2.ts | 7 +- .../signatureHelpTaggedTemplatesNegatives3.ts | 7 +- .../signatureHelpTaggedTemplatesNegatives4.ts | 7 +- .../signatureHelpTaggedTemplatesNegatives5.ts | 7 +- .../signatureHelpTaggedTemplatesNested1.ts | 6 +- .../signatureHelpTaggedTemplatesNested2.ts | 6 +- ...eHelpTaggedTemplatesWithOverloadedTags1.ts | 6 +- ...eHelpTaggedTemplatesWithOverloadedTags2.ts | 6 +- ...eHelpTaggedTemplatesWithOverloadedTags3.ts | 6 +- ...eHelpTaggedTemplatesWithOverloadedTags4.ts | 6 +- ...eHelpTaggedTemplatesWithOverloadedTags5.ts | 6 +- ...eHelpTaggedTemplatesWithOverloadedTags6.ts | 6 +- ...eHelpTaggedTemplatesWithOverloadedTags7.ts | 6 +- ...eHelpTaggedTemplatesWithOverloadedTags8.ts | 6 +- ...eHelpTaggedTemplatesWithOverloadedTags9.ts | 8 +-- .../completionListGenericConstraintsNames.ts | 9 ++- 195 files changed, 482 insertions(+), 1301 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 1afb6de2cf2..721647df0cd 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -372,8 +372,8 @@ namespace FourSlash { } // Entry points from fourslash.ts - public goToMarker(name = "") { - const marker = this.getMarkerByName(name); + public goToMarker(name: string | Marker = "") { + const marker = typeof name === "string" ? this.getMarkerByName(name) : name; if (this.activeFile.fileName !== marker.fileName) { this.openFile(marker.fileName); } @@ -382,10 +382,37 @@ namespace FourSlash { if (marker.position === -1 || marker.position > content.length) { throw new Error(`Marker "${name}" has been invalidated by unrecoverable edits to the file.`); } - this.lastKnownMarker = name; + const mName = typeof name === "string" ? name : this.markerName(marker); + this.lastKnownMarker = mName; this.goToPosition(marker.position); } + public goToEachMarker(action: () => void) { + const markers = this.getMarkers(); + assert(markers.length); + for (const marker of markers) { + this.goToMarker(marker); + action(); + } + } + + public goToEachRange(action: () => void) { + const ranges = this.getRanges(); + assert(ranges.length); + for (const range of ranges) { + this.goToRangeStart(range); + action(); + } + } + + private markerName(m: Marker): string { + return ts.forEachEntry(this.testData.markerPositions, (marker, name) => { + if (marker === m) { + return name; + } + })!; + } + public goToPosition(pos: number) { this.currentCaretPosition = pos; } @@ -1668,7 +1695,7 @@ namespace FourSlash { this.goToPosition(len); } - private goToRangeStart({fileName, start}: Range) { + public goToRangeStart({fileName, start}: Range) { this.openFile(fileName); this.goToPosition(start); } @@ -2365,6 +2392,21 @@ namespace FourSlash { return this.languageService.getDocumentHighlights(this.activeFile.fileName, this.currentCaretPosition, filesToSearch); } + public verifyRangesAreOccurrences(isWriteAccess?: boolean) { + const ranges = this.getRanges(); + for (const r of ranges) { + this.goToRangeStart(r); + this.verifyOccurrencesAtPositionListCount(ranges.length); + for (const range of ranges) { + this.verifyOccurrencesAtPositionListContains(range.fileName, range.start, range.end, isWriteAccess); + } + } + } + + public verifyRangesAreRenameLocations(findInStrings: boolean, findInComments: boolean) { + this.goToEachRange(() => this.verifyRenameLocations(findInStrings, findInComments)); + } + public verifyRangesWithSameTextAreDocumentHighlights() { this.rangesByText().forEach(ranges => this.verifyRangesAreDocumentHighlights(ranges)); } @@ -3078,10 +3120,22 @@ namespace FourSlashInterface { // Moves the caret to the specified marker, // or the anonymous marker ('/**/') if no name // is given - public marker(name?: string) { + public marker(name?: string | FourSlash.Marker) { this.state.goToMarker(name); } + public eachMarker(action: () => void) { + this.state.goToEachMarker(action); + } + + public rangeStart(range: FourSlash.Range) { + this.state.goToRangeStart(range); + } + + public eachRange(action: () => void) { + this.state.goToEachRange(action); + } + public bof() { this.state.goToBOF(); } @@ -3432,6 +3486,14 @@ namespace FourSlashInterface { this.state.verifyOccurrencesAtPositionListCount(expectedCount); } + public rangesAreOccurrences(isWriteAccess?: boolean) { + this.state.verifyRangesAreOccurrences(isWriteAccess); + } + + public rangesAreRenameLocations(findInStrings = false, findInComments = false) { + this.state.verifyRangesAreRenameLocations(findInStrings, findInComments); + } + public rangesAreDocumentHighlights(ranges?: FourSlash.Range[]) { this.state.verifyRangesAreDocumentHighlights(ranges); } diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_Generics.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_Generics.ts index 0e92a3ae995..784fc8c499c 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_Generics.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_Generics.ts @@ -11,8 +11,4 @@ ////function A { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_catch.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_catch.ts index bdf13c1d97f..bfbfa1bb160 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_catch.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_catch.ts @@ -6,8 +6,4 @@ //// try {} catch(a/*catchVariable2*/ - -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_classes.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_classes.ts index 60a108cf1e6..5d96c565719 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_classes.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_classes.ts @@ -6,7 +6,4 @@ ////class a/*className2*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_destructuring.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_destructuring.ts index 7f8ef32e1ad..d2ecdf29426 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_destructuring.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_destructuring.ts @@ -16,7 +16,4 @@ //// function func2({ a, b/*parameter2*/ -test.markers().forEach(m => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enumMembers.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enumMembers.ts index 6c0472be546..f0818108301 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enumMembers.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enumMembers.ts @@ -4,8 +4,4 @@ ////enum a { /*enumValueName1*/ - -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enumMembers2.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enumMembers2.ts index ee2f3e71032..11aa276bb5a 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enumMembers2.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enumMembers2.ts @@ -3,7 +3,4 @@ ////var aa = 1; ////enum a { foo, /*enumValueName3*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enums.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enums.ts index 183f8a22c63..c740218e27e 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enums.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enums.ts @@ -8,7 +8,4 @@ ////var x = 0; enum /*enumName4*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_functions.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_functions.ts index 24231174727..2f55f9527bc 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_functions.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_functions.ts @@ -6,8 +6,4 @@ ////function a/*functionName2*/ - -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers.ts index 266b0b78c9c..9998f38c255 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers.ts @@ -4,7 +4,4 @@ ////interface a { /*interfaceValue1*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers2.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers2.ts index 82a30325948..234e41bfb71 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers2.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers2.ts @@ -4,7 +4,4 @@ ////interface a { f/*interfaceValue2*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers3.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers3.ts index ed640dd3f1a..f0a596ef8b1 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers3.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers3.ts @@ -4,7 +4,4 @@ ////interface a { f; /*interfaceValue3*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaces.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaces.ts index ec2732fe2fe..d4be268eb7d 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaces.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaces.ts @@ -6,8 +6,4 @@ ////interface a/*interfaceName2*/ - -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_parameters.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_parameters.ts index 10293c41a64..474859129db 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_parameters.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_parameters.ts @@ -22,8 +22,4 @@ ////class bar10{ constructor(...a/*constructorParamter6*/ - -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_properties.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_properties.ts index 58fdc1d2342..3ba0df0c31d 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_properties.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_properties.ts @@ -30,8 +30,7 @@ //// private a/*property7*/ ////} -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); +goTo.eachMarker(() => { verify.not.completionListIsEmpty(); verify.completionListAllowsNewIdentifier(); }); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_varDeclarations.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_varDeclarations.ts index 2e85364ce3c..9a2c9ba664a 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_varDeclarations.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_varDeclarations.ts @@ -11,7 +11,4 @@ ////var a2, a/*varName4*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtInvalidLocations.ts b/tests/cases/fourslash/completionListAtInvalidLocations.ts index 6e4b4056a7d..0660f0e183b 100644 --- a/tests/cases/fourslash/completionListAtInvalidLocations.ts +++ b/tests/cases/fourslash/completionListAtInvalidLocations.ts @@ -25,7 +25,4 @@ ////foo; ////var v10 = /reg/*inRegExp1*/ex/; -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListBuilderLocations_VariableDeclarations.ts b/tests/cases/fourslash/completionListBuilderLocations_VariableDeclarations.ts index d069b9a722e..2562b840995 100644 --- a/tests/cases/fourslash/completionListBuilderLocations_VariableDeclarations.ts +++ b/tests/cases/fourslash/completionListBuilderLocations_VariableDeclarations.ts @@ -11,7 +11,7 @@ //// var y : any = "", x = (a/*var5*/ ////class C{} -////var y = new C( +////var y = new C( //// class C{} //// var y = new C(0, /*var7*/ @@ -26,9 +26,4 @@ ////var y = 10; y=/*var12*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListAllowsNewIdentifier(); -}); - - +goTo.eachMarker(() => verify.completionListAllowsNewIdentifier()); diff --git a/tests/cases/fourslash/completionListBuilderLocations_parameters.ts b/tests/cases/fourslash/completionListBuilderLocations_parameters.ts index 12dba953d3d..607ca0d9819 100644 --- a/tests/cases/fourslash/completionListBuilderLocations_parameters.ts +++ b/tests/cases/fourslash/completionListBuilderLocations_parameters.ts @@ -14,9 +14,7 @@ ////class bar7{ constructor(private a, /*constructorParamter6*/ - -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); +goTo.eachMarker(() => { verify.not.completionListIsEmpty(); verify.completionListAllowsNewIdentifier(); }); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListBuilderLocations_properties.ts b/tests/cases/fourslash/completionListBuilderLocations_properties.ts index 287ffd6746b..806d8c1de4f 100644 --- a/tests/cases/fourslash/completionListBuilderLocations_properties.ts +++ b/tests/cases/fourslash/completionListBuilderLocations_properties.ts @@ -10,7 +10,4 @@ //// public static a/*property2*/ ////} -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListInIndexSignature01.ts b/tests/cases/fourslash/completionListInIndexSignature01.ts index 2db28505b3e..aaf97fee1a5 100644 --- a/tests/cases/fourslash/completionListInIndexSignature01.ts +++ b/tests/cases/fourslash/completionListInIndexSignature01.ts @@ -14,7 +14,4 @@ //// [x/*5*/yz: number]: boolean; //// [/*6*/ -for (let marker of test.markers()) { - goTo.position(marker.position); - verify.completionListAllowsNewIdentifier(); -} \ No newline at end of file +goTo.eachMarker(() => verify.completionListAllowsNewIdentifier()); diff --git a/tests/cases/fourslash/completionListInIndexSignature02.ts b/tests/cases/fourslash/completionListInIndexSignature02.ts index d3b65dc7759..ce1f8b38e24 100644 --- a/tests/cases/fourslash/completionListInIndexSignature02.ts +++ b/tests/cases/fourslash/completionListInIndexSignature02.ts @@ -13,7 +13,4 @@ ////type T = { //// [xyz: /*5*/ -for (let marker of test.markers()) { - goTo.position(marker.position); - verify.not.completionListAllowsNewIdentifier(); -} \ No newline at end of file +goTo.eachMarker(() => verify.not.completionListAllowsNewIdentifier()); diff --git a/tests/cases/fourslash/completionListInObjectLiteral4.ts b/tests/cases/fourslash/completionListInObjectLiteral4.ts index c00462c8255..3094b4db6ad 100644 --- a/tests/cases/fourslash/completionListInObjectLiteral4.ts +++ b/tests/cases/fourslash/completionListInObjectLiteral4.ts @@ -20,9 +20,7 @@ ////funcE({ /*E*/ }); ////funcF({ /*F*/ }); - -for (const marker of test.markers()) { - goTo.position(marker.position); +goTo.eachMarker(() => { verify.completionListContains("hello"); verify.completionListContains("world"); -} +}); diff --git a/tests/cases/fourslash/completionListInStringLiterals1.ts b/tests/cases/fourslash/completionListInStringLiterals1.ts index e394e8dfe7c..aabcc82eba5 100644 --- a/tests/cases/fourslash/completionListInStringLiterals1.ts +++ b/tests/cases/fourslash/completionListInStringLiterals1.ts @@ -3,8 +3,4 @@ ////"/*1*/ /*2*/\/*3*/ //// /*4*/ \\/*5*/ -test.markers().forEach(marker => { - goTo.position(marker.position); - - verify.completionListIsEmpty() -}); \ No newline at end of file +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListInStringLiterals2.ts b/tests/cases/fourslash/completionListInStringLiterals2.ts index 10cb05a4f91..4ffd5eb8a9b 100644 --- a/tests/cases/fourslash/completionListInStringLiterals2.ts +++ b/tests/cases/fourslash/completionListInStringLiterals2.ts @@ -4,8 +4,4 @@ //// /*4*/ \\\/*5*/ //// /*6*/ -test.markers().forEach(marker => { - goTo.position(marker.position); - - verify.completionListIsEmpty() -}); \ No newline at end of file +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListInTemplateLiteralParts1.ts b/tests/cases/fourslash/completionListInTemplateLiteralParts1.ts index 0166546f63e..9de7b6a6a5b 100644 --- a/tests/cases/fourslash/completionListInTemplateLiteralParts1.ts +++ b/tests/cases/fourslash/completionListInTemplateLiteralParts1.ts @@ -4,8 +4,4 @@ //// /////*6*/`asdasd${/*7*/ 2 + 1.1 /*8*/} 12312 { -test.markers().forEach(marker => { - goTo.position(marker.position); - - verify.completionListItemsCountIsGreaterThan(0) -}); \ No newline at end of file +goTo.eachMarker(() => verify.completionListItemsCountIsGreaterThan(0)); diff --git a/tests/cases/fourslash/completionListInTemplateLiteralPartsNegatives1.ts b/tests/cases/fourslash/completionListInTemplateLiteralPartsNegatives1.ts index ac64a41fb56..30af0678e7d 100644 --- a/tests/cases/fourslash/completionListInTemplateLiteralPartsNegatives1.ts +++ b/tests/cases/fourslash/completionListInTemplateLiteralPartsNegatives1.ts @@ -4,8 +4,4 @@ //// ////`asdasd$/*7*/{ 2 + 1.1 }/*8*/ 12312 /*9*/{/*10*/ -test.markers().forEach(marker => { - goTo.position(marker.position); - - verify.completionListIsEmpty() -}); \ No newline at end of file +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListNewIdentifierFunctionDeclaration.ts b/tests/cases/fourslash/completionListNewIdentifierFunctionDeclaration.ts index 8a9a5bfb9ed..1f8b24d1cf1 100644 --- a/tests/cases/fourslash/completionListNewIdentifierFunctionDeclaration.ts +++ b/tests/cases/fourslash/completionListNewIdentifierFunctionDeclaration.ts @@ -2,8 +2,7 @@ ////function F(pref: (a/*1*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); +goTo.eachMarker(() => { verify.not.completionListIsEmpty(); verify.completionListAllowsNewIdentifier(); }); diff --git a/tests/cases/fourslash/completionListNewIdentifierVariableDeclaration.ts b/tests/cases/fourslash/completionListNewIdentifierVariableDeclaration.ts index 534011b7ee1..a4126ebe8be 100644 --- a/tests/cases/fourslash/completionListNewIdentifierVariableDeclaration.ts +++ b/tests/cases/fourslash/completionListNewIdentifierVariableDeclaration.ts @@ -4,8 +4,7 @@ ////var y : (s:string, list/*2*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); +goTo.eachMarker(() => { verify.not.completionListIsEmpty(); verify.completionListAllowsNewIdentifier(); -}); \ No newline at end of file +}); diff --git a/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts b/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts index 52925870a66..65e9c17014e 100644 --- a/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts +++ b/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts @@ -3,12 +3,9 @@ // @Filename: justAComment.ts //// // We want to check off-by-one errors in assessing the end of the comment, so we check twice, //// // first with a trailing space and then without. -//// // /*0*/ +//// // /*0*/ //// // /*1*/ //// // We also want to check EOF handling at the end of a comment //// // /*2*/ -test.markers().forEach((marker) => { - goTo.position(marker.position); - verify.noDocCommentTemplate(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.noDocCommentTemplate()); diff --git a/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts b/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts index 9c803301526..dd58a1bfd5f 100644 --- a/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts +++ b/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts @@ -3,7 +3,4 @@ // @Filename: functionDecl.ts ////f/*0*/unction /*1*/foo/*2*/(/*3*/) /*4*/{ /*5*/} -test.markers().forEach((marker) => { - goTo.position(marker.position); - verify.noDocCommentTemplate(); -}); +goTo.eachMarker(() => verify.noDocCommentTemplate()); diff --git a/tests/cases/fourslash/docCommentTemplateRegex.ts b/tests/cases/fourslash/docCommentTemplateRegex.ts index 0bf50f5e85a..62d200dee10 100644 --- a/tests/cases/fourslash/docCommentTemplateRegex.ts +++ b/tests/cases/fourslash/docCommentTemplateRegex.ts @@ -3,7 +3,4 @@ // @Filename: regex.ts ////var regex = /*0*///*1*/asdf/*2*/ /*3*///*4*/; -test.markers().forEach((marker) => { - goTo.position(marker.position); - verify.noDocCommentTemplate(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.noDocCommentTemplate()); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index ed09fcd2c92..6685bbc19c0 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -117,7 +117,10 @@ declare namespace FourSlashInterface { markerByName(s: string): Marker; } class goTo { - marker(name?: string): void; + marker(name?: string | Marker): void; + eachMarker(action: () => void): void; + rangeStart(range: Range): void; + eachRange(action: () => void): void; bof(): void; eof(): void; implementation(): void; @@ -191,6 +194,8 @@ declare namespace FourSlashInterface { * `start` should be included in `references`. */ referencesOf(start: Range, references: Range[]): void; + rangesAreOccurrences(isWriteAccess?: boolean): void; + rangesAreRenameLocations(findInStrings?: boolean, findInComments?: boolean): void; /** * Performs `referencesOf` for every range on the whole set. * If `ranges` is omitted, this is `test.ranges()`. diff --git a/tests/cases/fourslash/getOccurrencesAbstract01.ts b/tests/cases/fourslash/getOccurrencesAbstract01.ts index 3e48ba4841a..b2ccc815e05 100644 --- a/tests/cases/fourslash/getOccurrencesAbstract01.ts +++ b/tests/cases/fourslash/getOccurrencesAbstract01.ts @@ -12,13 +12,4 @@ //// abstract bar(): void; ////} -const ranges = test.ranges(); - -for (let r of ranges) { - goTo.position(r.start); - verify.occurrencesAtPositionCount(ranges.length); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); \ No newline at end of file diff --git a/tests/cases/fourslash/getOccurrencesAbstract02.ts b/tests/cases/fourslash/getOccurrencesAbstract02.ts index 8daafdbdc8e..1decdaaf69c 100644 --- a/tests/cases/fourslash/getOccurrencesAbstract02.ts +++ b/tests/cases/fourslash/getOccurrencesAbstract02.ts @@ -11,16 +11,7 @@ //// abstract bar(): void; ////} -const ranges = test.ranges(); - -for (let r of ranges) { - goTo.position(r.start); - verify.occurrencesAtPositionCount(ranges.length); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); goTo.marker("1"); verify.occurrencesAtPositionCount(0); diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionConstructor.ts b/tests/cases/fourslash/getOccurrencesClassExpressionConstructor.ts index 5fa778ef8cd..d092c1dfd92 100644 --- a/tests/cases/fourslash/getOccurrencesClassExpressionConstructor.ts +++ b/tests/cases/fourslash/getOccurrencesClassExpressionConstructor.ts @@ -13,11 +13,4 @@ //// } ////} -const ranges = test.ranges(); -for (let r of ranges) { - goTo.position(r.start); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionPrivate.ts b/tests/cases/fourslash/getOccurrencesClassExpressionPrivate.ts index b008ec237b8..2bc18d2eb25 100644 --- a/tests/cases/fourslash/getOccurrencesClassExpressionPrivate.ts +++ b/tests/cases/fourslash/getOccurrencesClassExpressionPrivate.ts @@ -17,11 +17,4 @@ //// public test2() {} ////} -const ranges = test.ranges(); -for (let r of ranges) { - goTo.position(r.start); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionPublic.ts b/tests/cases/fourslash/getOccurrencesClassExpressionPublic.ts index 3070fd4f6ca..c54dbd289e0 100644 --- a/tests/cases/fourslash/getOccurrencesClassExpressionPublic.ts +++ b/tests/cases/fourslash/getOccurrencesClassExpressionPublic.ts @@ -17,11 +17,4 @@ //// public test2() {} ////} -const ranges = test.ranges(); -for (let r of ranges) { - goTo.position(r.start); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionStatic.ts b/tests/cases/fourslash/getOccurrencesClassExpressionStatic.ts index 567c0c4eccd..d4851ad86ef 100644 --- a/tests/cases/fourslash/getOccurrencesClassExpressionStatic.ts +++ b/tests/cases/fourslash/getOccurrencesClassExpressionStatic.ts @@ -1,7 +1,7 @@ /// ////let A = class Foo { -//// public static foo; +//// public [|static|] foo; //// [|static|] a; //// constructor(public y: string, private x: string) { //// } @@ -19,11 +19,4 @@ //// public static test2() {} ////} -const ranges = test.ranges(); -for (let r of ranges) { - goTo.position(r.start); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionStaticThis.ts b/tests/cases/fourslash/getOccurrencesClassExpressionStaticThis.ts index 5444ab9acdd..53c1a69bead 100644 --- a/tests/cases/fourslash/getOccurrencesClassExpressionStaticThis.ts +++ b/tests/cases/fourslash/getOccurrencesClassExpressionStaticThis.ts @@ -46,11 +46,4 @@ //// } ////} -const ranges = test.ranges(); -for (let r of ranges) { - goTo.position(r.start); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionThis.ts b/tests/cases/fourslash/getOccurrencesClassExpressionThis.ts index ed8f8cb1d0e..d1331e54a43 100644 --- a/tests/cases/fourslash/getOccurrencesClassExpressionThis.ts +++ b/tests/cases/fourslash/getOccurrencesClassExpressionThis.ts @@ -44,11 +44,4 @@ //// } ////} -const ranges = test.ranges(); -for (let r of ranges) { - goTo.position(r.start); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesConst02.ts b/tests/cases/fourslash/getOccurrencesConst02.ts index 0dc96fcca6c..57d75f88e22 100644 --- a/tests/cases/fourslash/getOccurrencesConst02.ts +++ b/tests/cases/fourslash/getOccurrencesConst02.ts @@ -10,7 +10,4 @@ ////declare [|const|] enum E { ////} -test.ranges().forEach(range => { - goTo.position(range.start); - verify.occurrencesAtPositionCount(0); -}); \ No newline at end of file +goTo.eachRange(() => verify.occurrencesAtPositionCount(0)); diff --git a/tests/cases/fourslash/getOccurrencesConst03.ts b/tests/cases/fourslash/getOccurrencesConst03.ts index 404ff655044..a86481ed72a 100644 --- a/tests/cases/fourslash/getOccurrencesConst03.ts +++ b/tests/cases/fourslash/getOccurrencesConst03.ts @@ -10,7 +10,4 @@ ////export [|const|] enum E { ////} -test.ranges().forEach(range => { - goTo.position(range.start); - verify.occurrencesAtPositionCount(0); -}); \ No newline at end of file +goTo.eachRange(() => verify.occurrencesAtPositionCount(0)); \ No newline at end of file diff --git a/tests/cases/fourslash/getOccurrencesConstructor.ts b/tests/cases/fourslash/getOccurrencesConstructor.ts index 0a6b84a5770..41d72c533a3 100644 --- a/tests/cases/fourslash/getOccurrencesConstructor.ts +++ b/tests/cases/fourslash/getOccurrencesConstructor.ts @@ -18,15 +18,9 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesConstructor2.ts b/tests/cases/fourslash/getOccurrencesConstructor2.ts index 049c25b7f52..b34ffa4a190 100644 --- a/tests/cases/fourslash/getOccurrencesConstructor2.ts +++ b/tests/cases/fourslash/getOccurrencesConstructor2.ts @@ -18,15 +18,9 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesDeclare1.ts b/tests/cases/fourslash/getOccurrencesDeclare1.ts index 4207a92b5a6..96114d3fc9d 100644 --- a/tests/cases/fourslash/getOccurrencesDeclare1.ts +++ b/tests/cases/fourslash/getOccurrencesDeclare1.ts @@ -53,11 +53,4 @@ //// [|declare|] function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesDeclare2.ts b/tests/cases/fourslash/getOccurrencesDeclare2.ts index 3d719e5d035..78028d94996 100644 --- a/tests/cases/fourslash/getOccurrencesDeclare2.ts +++ b/tests/cases/fourslash/getOccurrencesDeclare2.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesDeclare3.ts b/tests/cases/fourslash/getOccurrencesDeclare3.ts index 2dee0af4b14..8c1bf7e9658 100644 --- a/tests/cases/fourslash/getOccurrencesDeclare3.ts +++ b/tests/cases/fourslash/getOccurrencesDeclare3.ts @@ -61,11 +61,4 @@ ////[|declare|] module dm { } ////export class EC { } -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesExport1.ts b/tests/cases/fourslash/getOccurrencesExport1.ts index bc82e8a1bea..71202a820a7 100644 --- a/tests/cases/fourslash/getOccurrencesExport1.ts +++ b/tests/cases/fourslash/getOccurrencesExport1.ts @@ -53,11 +53,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesExport2.ts b/tests/cases/fourslash/getOccurrencesExport2.ts index a8e43e744b9..442642d77ec 100644 --- a/tests/cases/fourslash/getOccurrencesExport2.ts +++ b/tests/cases/fourslash/getOccurrencesExport2.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesExport3.ts b/tests/cases/fourslash/getOccurrencesExport3.ts index 215cbf8f48a..04ee55bb1e6 100644 --- a/tests/cases/fourslash/getOccurrencesExport3.ts +++ b/tests/cases/fourslash/getOccurrencesExport3.ts @@ -61,11 +61,4 @@ ////declare module dm { } ////[|export|] class EC { } -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesIfElse.ts b/tests/cases/fourslash/getOccurrencesIfElse.ts index 96c70d404ab..9251a59d130 100644 --- a/tests/cases/fourslash/getOccurrencesIfElse.ts +++ b/tests/cases/fourslash/getOccurrencesIfElse.ts @@ -22,15 +22,9 @@ ////} ////[|else|] { } -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesIfElse2.ts b/tests/cases/fourslash/getOccurrencesIfElse2.ts index 012e7a96efd..df77687aac6 100644 --- a/tests/cases/fourslash/getOccurrencesIfElse2.ts +++ b/tests/cases/fourslash/getOccurrencesIfElse2.ts @@ -22,11 +22,4 @@ ////} ////else { } - -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); \ No newline at end of file +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesIfElse3.ts b/tests/cases/fourslash/getOccurrencesIfElse3.ts index b0ca3615648..aec1a6911af 100644 --- a/tests/cases/fourslash/getOccurrencesIfElse3.ts +++ b/tests/cases/fourslash/getOccurrencesIfElse3.ts @@ -22,11 +22,4 @@ ////} ////else { } - -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); \ No newline at end of file +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesIfElseBroken.ts b/tests/cases/fourslash/getOccurrencesIfElseBroken.ts index a9e1e94f42d..c5460b3e634 100644 --- a/tests/cases/fourslash/getOccurrencesIfElseBroken.ts +++ b/tests/cases/fourslash/getOccurrencesIfElseBroken.ts @@ -12,13 +12,7 @@ // It would be nice if in the future, // We could include that last 'else'. -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); verify.occurrencesAtPositionCount(2); \ No newline at end of file diff --git a/tests/cases/fourslash/getOccurrencesIsWriteAccess.ts b/tests/cases/fourslash/getOccurrencesIsWriteAccess.ts index 1ba4c39041c..e31b199217f 100644 --- a/tests/cases/fourslash/getOccurrencesIsWriteAccess.ts +++ b/tests/cases/fourslash/getOccurrencesIsWriteAccess.ts @@ -18,10 +18,8 @@ ////[|{| "isWriteAccess": true |}x|] += 1; ////[|{| "isWriteAccess": true |}x|] <<= 1; +goTo.rangeStart(test.ranges()[0]); -var firstRange = test.ranges()[0]; -goTo.position(firstRange.start, firstRange.fileName); - -test.ranges().forEach((range) => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, range.marker.data.isWriteAccess); -}); +} diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinue.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinue.ts index 81aaaed5c58..88621cd4cf4 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinue.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinue.ts @@ -46,7 +46,7 @@ //// default: //// continue; //// } -//// +//// //// // these cross function boundaries //// break label1; //// continue label1; @@ -63,17 +63,10 @@ //// ////label7: while (true) continue label5; -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); verify.occurrencesAtPositionCount(test.ranges().length); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinue2.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinue2.ts index 51d4d89b657..225346f8077 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinue2.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinue2.ts @@ -46,7 +46,7 @@ //// default: //// continue; //// } -//// +//// //// // these cross function boundaries //// break label1; //// continue label1; @@ -63,17 +63,10 @@ //// ////label7: while (true) continue label5; -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); verify.occurrencesAtPositionCount(test.ranges().length); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinue3.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinue3.ts index 8777c912afd..c1aeef315f9 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinue3.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinue3.ts @@ -46,7 +46,7 @@ //// default: //// continue; //// } -//// +//// //// // these cross function boundaries //// break label1; //// continue label1; @@ -63,16 +63,9 @@ //// ////label7: while (true) continue label5; -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinue4.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinue4.ts index 1bca62ba013..b183b2b3fde 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinue4.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinue4.ts @@ -46,7 +46,7 @@ //// default: //// [|continue|]; //// } -//// +//// //// // these cross function boundaries //// break label1; //// continue label1; @@ -63,17 +63,10 @@ //// ////label7: while (true) continue label5; -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); verify.occurrencesAtPositionCount(test.ranges().length); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinue5.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinue5.ts index f4e62c554e4..3353d6c96dc 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinue5.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinue5.ts @@ -46,7 +46,7 @@ //// default: //// continue; //// } -//// +//// //// // these cross function boundaries //// break label1; //// continue label1; @@ -63,17 +63,10 @@ //// ////label7: while (true) continue label5; -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); verify.occurrencesAtPositionCount(test.ranges().length); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinue6.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinue6.ts index 0127245dd50..957f8c4af01 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinue6.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinue6.ts @@ -46,7 +46,7 @@ //// default: //// continue; //// } -//// +//// //// // these cross function boundaries //// br/*5*/eak label1; //// co/*6*/ntinue label1; @@ -63,8 +63,4 @@ //// ////label7: while (true) co/*10*/ntinue label5; -test.markers().forEach(m => { - goTo.position(m.position); - - verify.occurrencesAtPositionCount(0); -}); +goTo.eachMarker(() => verify.occurrencesAtPositionCount(0)); diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinueNegatives.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinueNegatives.ts index 0127245dd50..957f8c4af01 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinueNegatives.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinueNegatives.ts @@ -46,7 +46,7 @@ //// default: //// continue; //// } -//// +//// //// // these cross function boundaries //// br/*5*/eak label1; //// co/*6*/ntinue label1; @@ -63,8 +63,4 @@ //// ////label7: while (true) co/*10*/ntinue label5; -test.markers().forEach(m => { - goTo.position(m.position); - - verify.occurrencesAtPositionCount(0); -}); +goTo.eachMarker(() => verify.occurrencesAtPositionCount(0)); diff --git a/tests/cases/fourslash/getOccurrencesModifiersNegatives1.ts b/tests/cases/fourslash/getOccurrencesModifiersNegatives1.ts index 51d5907a5d6..836d87fa9be 100644 --- a/tests/cases/fourslash/getOccurrencesModifiersNegatives1.ts +++ b/tests/cases/fourslash/getOccurrencesModifiersNegatives1.ts @@ -34,8 +34,4 @@ ////[|public|] [|static|] [|protected|] [|private|] f; ////[|protected|] [|static|] [|public|] g; - -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(0); -}); +goTo.eachRange(() => verify.occurrencesAtPositionCount(0)); diff --git a/tests/cases/fourslash/getOccurrencesOfAnonymousFunction.ts b/tests/cases/fourslash/getOccurrencesOfAnonymousFunction.ts index 96354df6b05..8ce60b21306 100644 --- a/tests/cases/fourslash/getOccurrencesOfAnonymousFunction.ts +++ b/tests/cases/fourslash/getOccurrencesOfAnonymousFunction.ts @@ -5,12 +5,4 @@ //// return 0; ////}) - -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(2); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range); - }); -}); \ No newline at end of file +verify.rangesAreOccurrences(); diff --git a/tests/cases/fourslash/getOccurrencesPrivate1.ts b/tests/cases/fourslash/getOccurrencesPrivate1.ts index 991ed3ea31c..bb601451507 100644 --- a/tests/cases/fourslash/getOccurrencesPrivate1.ts +++ b/tests/cases/fourslash/getOccurrencesPrivate1.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesPrivate2.ts b/tests/cases/fourslash/getOccurrencesPrivate2.ts index 19397443af5..914db1a15a9 100644 --- a/tests/cases/fourslash/getOccurrencesPrivate2.ts +++ b/tests/cases/fourslash/getOccurrencesPrivate2.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesPropertyInAliasedInterface.ts b/tests/cases/fourslash/getOccurrencesPropertyInAliasedInterface.ts index 87ec260601b..3a9078cfc63 100644 --- a/tests/cases/fourslash/getOccurrencesPropertyInAliasedInterface.ts +++ b/tests/cases/fourslash/getOccurrencesPropertyInAliasedInterface.ts @@ -15,11 +15,5 @@ ////} //// ////(new C()).[|abc|]; -test.ranges().forEach(r => { - goTo.position(r.start); - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range); - }); - verify.occurrencesAtPositionCount(test.ranges().length); -}); \ No newline at end of file +verify.rangesAreOccurrences(); diff --git a/tests/cases/fourslash/getOccurrencesProtected1.ts b/tests/cases/fourslash/getOccurrencesProtected1.ts index af9e3302968..b5b3442ec00 100644 --- a/tests/cases/fourslash/getOccurrencesProtected1.ts +++ b/tests/cases/fourslash/getOccurrencesProtected1.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesProtected2.ts b/tests/cases/fourslash/getOccurrencesProtected2.ts index 666736eee16..365d78dc9f6 100644 --- a/tests/cases/fourslash/getOccurrencesProtected2.ts +++ b/tests/cases/fourslash/getOccurrencesProtected2.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesPublic1.ts b/tests/cases/fourslash/getOccurrencesPublic1.ts index a451a70c1cb..1ecc816dac5 100644 --- a/tests/cases/fourslash/getOccurrencesPublic1.ts +++ b/tests/cases/fourslash/getOccurrencesPublic1.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesPublic2.ts b/tests/cases/fourslash/getOccurrencesPublic2.ts index b4887e18e80..6d5b4e53c0e 100644 --- a/tests/cases/fourslash/getOccurrencesPublic2.ts +++ b/tests/cases/fourslash/getOccurrencesPublic2.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesReturn.ts b/tests/cases/fourslash/getOccurrencesReturn.ts index 613e1645fb5..44b3679ba2e 100644 --- a/tests/cases/fourslash/getOccurrencesReturn.ts +++ b/tests/cases/fourslash/getOccurrencesReturn.ts @@ -19,15 +19,9 @@ //// [|return|] true; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesReturn2.ts b/tests/cases/fourslash/getOccurrencesReturn2.ts index 15a062433fe..750648838a2 100644 --- a/tests/cases/fourslash/getOccurrencesReturn2.ts +++ b/tests/cases/fourslash/getOccurrencesReturn2.ts @@ -19,15 +19,9 @@ //// return true; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesReturn3.ts b/tests/cases/fourslash/getOccurrencesReturn3.ts index 030d700ef6e..ee739efef39 100644 --- a/tests/cases/fourslash/getOccurrencesReturn3.ts +++ b/tests/cases/fourslash/getOccurrencesReturn3.ts @@ -19,10 +19,4 @@ //// return true; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); \ No newline at end of file +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesReturnBroken.ts b/tests/cases/fourslash/getOccurrencesReturnBroken.ts index 2327a62d12c..c8d7fad0635 100644 --- a/tests/cases/fourslash/getOccurrencesReturnBroken.ts +++ b/tests/cases/fourslash/getOccurrencesReturnBroken.ts @@ -26,17 +26,11 @@ //// r/*4*/eturn 8675309; ////} -// Note: For this test, these 'return's get highlighted as a result of a parse recovery +// Note: For this test, these 'return's get highlighted as a result of a parse recovery // where if an arrow function starts with a statement, we try to parse a body // as if it was missing curly braces. If the behavior changes in the future, // a change to this test is very much welcome. -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); for (var i = 1; i <= test.markers().length; i++) { goTo.marker("" + i); diff --git a/tests/cases/fourslash/getOccurrencesSetAndGet.ts b/tests/cases/fourslash/getOccurrencesSetAndGet.ts index ddeaf8f26ff..2d28328800c 100644 --- a/tests/cases/fourslash/getOccurrencesSetAndGet.ts +++ b/tests/cases/fourslash/getOccurrencesSetAndGet.ts @@ -23,12 +23,4 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesSetAndGet2.ts b/tests/cases/fourslash/getOccurrencesSetAndGet2.ts index 3e05f511efc..541efc80509 100644 --- a/tests/cases/fourslash/getOccurrencesSetAndGet2.ts +++ b/tests/cases/fourslash/getOccurrencesSetAndGet2.ts @@ -23,12 +23,4 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesSetAndGet3.ts b/tests/cases/fourslash/getOccurrencesSetAndGet3.ts index 777a62db6a5..32c4d72c1a5 100644 --- a/tests/cases/fourslash/getOccurrencesSetAndGet3.ts +++ b/tests/cases/fourslash/getOccurrencesSetAndGet3.ts @@ -23,12 +23,4 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesStatic1.ts b/tests/cases/fourslash/getOccurrencesStatic1.ts index 8be9862d5ec..d853f16017d 100644 --- a/tests/cases/fourslash/getOccurrencesStatic1.ts +++ b/tests/cases/fourslash/getOccurrencesStatic1.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesStringLiteralTypes.ts b/tests/cases/fourslash/getOccurrencesStringLiteralTypes.ts index 56af87497d5..a115ee82211 100644 --- a/tests/cases/fourslash/getOccurrencesStringLiteralTypes.ts +++ b/tests/cases/fourslash/getOccurrencesStringLiteralTypes.ts @@ -3,11 +3,4 @@ ////function foo(a: "[|option 1|]") { } ////foo("[|option 1|]"); -const ranges = test.ranges(); -for (let r of ranges) { - goTo.position(r.start); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesStringLiterals.ts b/tests/cases/fourslash/getOccurrencesStringLiterals.ts index 827828acd24..cf17481e0eb 100644 --- a/tests/cases/fourslash/getOccurrencesStringLiterals.ts +++ b/tests/cases/fourslash/getOccurrencesStringLiterals.ts @@ -3,8 +3,4 @@ ////var x = "[|string|]"; ////function f(a = "[|initial value|]") { } -const ranges = test.ranges(); -for (let r of ranges) { - goTo.position(r.start); - verify.occurrencesAtPositionCount(1); -} +goTo.eachRange(() => verify.occurrencesAtPositionCount(1)); diff --git a/tests/cases/fourslash/getOccurrencesSuper.ts b/tests/cases/fourslash/getOccurrencesSuper.ts index f53d9aca62e..6f5c51715f3 100644 --- a/tests/cases/fourslash/getOccurrencesSuper.ts +++ b/tests/cases/fourslash/getOccurrencesSuper.ts @@ -27,7 +27,7 @@ //// //// public method3() { //// var x = () => [|super|].superMethod(); -//// +//// //// // Bad but still gets highlighted //// function f() { //// [|super|].superMethod(); @@ -50,15 +50,9 @@ //// static super = 20; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} \ No newline at end of file diff --git a/tests/cases/fourslash/getOccurrencesSuper2.ts b/tests/cases/fourslash/getOccurrencesSuper2.ts index 1392170ae18..2da702acbc6 100644 --- a/tests/cases/fourslash/getOccurrencesSuper2.ts +++ b/tests/cases/fourslash/getOccurrencesSuper2.ts @@ -27,7 +27,7 @@ //// //// public method3() { //// var x = () => super.superMethod(); -//// +//// //// // Bad but still gets highlighted //// function f() { //// super.superMethod(); @@ -50,15 +50,9 @@ //// static super = 20; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} \ No newline at end of file diff --git a/tests/cases/fourslash/getOccurrencesSuper3.ts b/tests/cases/fourslash/getOccurrencesSuper3.ts index bceac02a392..88275975004 100644 --- a/tests/cases/fourslash/getOccurrencesSuper3.ts +++ b/tests/cases/fourslash/getOccurrencesSuper3.ts @@ -14,7 +14,7 @@ ////} function checkRange(r: FourSlashInterface.Range, expectedOccurences: FourSlashInterface.Range[]): void { - goTo.position(r.start); + goTo.rangeStart(r); if (expectedOccurences.length) { for (const expected of expectedOccurences) { verify.occurrencesAtPositionContains(expected); diff --git a/tests/cases/fourslash/getOccurrencesSuperNegatives.ts b/tests/cases/fourslash/getOccurrencesSuperNegatives.ts index 8c76da33c12..e2bb248efc4 100644 --- a/tests/cases/fourslash/getOccurrencesSuperNegatives.ts +++ b/tests/cases/fourslash/getOccurrencesSuperNegatives.ts @@ -20,8 +20,4 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - verify.occurrencesAtPositionCount(0); -}); +goTo.eachRange(() => verify.occurrencesAtPositionCount(0)); diff --git a/tests/cases/fourslash/getOccurrencesSwitchCaseDefault.ts b/tests/cases/fourslash/getOccurrencesSwitchCaseDefault.ts index f32ff0e8f82..34f9ebcd112 100644 --- a/tests/cases/fourslash/getOccurrencesSwitchCaseDefault.ts +++ b/tests/cases/fourslash/getOccurrencesSwitchCaseDefault.ts @@ -18,12 +18,4 @@ //// [|case|] 16: ////} - -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesSwitchCaseDefault2.ts b/tests/cases/fourslash/getOccurrencesSwitchCaseDefault2.ts index dd4577faa1f..1f265f079f8 100644 --- a/tests/cases/fourslash/getOccurrencesSwitchCaseDefault2.ts +++ b/tests/cases/fourslash/getOccurrencesSwitchCaseDefault2.ts @@ -18,12 +18,4 @@ //// case 16: ////} - -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesSwitchCaseDefault3.ts b/tests/cases/fourslash/getOccurrencesSwitchCaseDefault3.ts index 24330ca1912..887e17c2b29 100644 --- a/tests/cases/fourslash/getOccurrencesSwitchCaseDefault3.ts +++ b/tests/cases/fourslash/getOccurrencesSwitchCaseDefault3.ts @@ -16,11 +16,4 @@ //// [|break|]; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesSwitchCaseDefault4.ts b/tests/cases/fourslash/getOccurrencesSwitchCaseDefault4.ts index 039009746dd..38b3fbfc7dd 100644 --- a/tests/cases/fourslash/getOccurrencesSwitchCaseDefault4.ts +++ b/tests/cases/fourslash/getOccurrencesSwitchCaseDefault4.ts @@ -10,16 +10,5 @@ //// contin/*2*/ue foo; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); - -test.markers().forEach(m => { - goTo.position(m.position); - verify.occurrencesAtPositionCount(0); -}); \ No newline at end of file +verify.rangesAreOccurrences(false); +goTo.eachMarker(() => verify.occurrencesAtPositionCount(0)); diff --git a/tests/cases/fourslash/getOccurrencesThis.ts b/tests/cases/fourslash/getOccurrencesThis.ts index e4b059b9cf9..156fde2c4ac 100644 --- a/tests/cases/fourslash/getOccurrencesThis.ts +++ b/tests/cases/fourslash/getOccurrencesThis.ts @@ -89,7 +89,7 @@ //// } //// //// public static staticB = this.staticMethod1; -//// +//// //// public static staticMethod1() { //// this; //// this; @@ -140,15 +140,9 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesThis2.ts b/tests/cases/fourslash/getOccurrencesThis2.ts index 3df30369e3e..9a40eb39fb0 100644 --- a/tests/cases/fourslash/getOccurrencesThis2.ts +++ b/tests/cases/fourslash/getOccurrencesThis2.ts @@ -89,7 +89,7 @@ //// } //// //// public static staticB = this.staticMethod1; -//// +//// //// public static staticMethod1() { //// this; //// this; @@ -140,15 +140,9 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesThis3.ts b/tests/cases/fourslash/getOccurrencesThis3.ts index 7ee18a31286..66c80241e4a 100644 --- a/tests/cases/fourslash/getOccurrencesThis3.ts +++ b/tests/cases/fourslash/getOccurrencesThis3.ts @@ -89,7 +89,7 @@ //// } //// //// public static staticB = this.staticMethod1; -//// +//// //// public static staticMethod1() { //// this; //// this; @@ -140,15 +140,9 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesThis4.ts b/tests/cases/fourslash/getOccurrencesThis4.ts index 75a9383f88e..42ddd7984a8 100644 --- a/tests/cases/fourslash/getOccurrencesThis4.ts +++ b/tests/cases/fourslash/getOccurrencesThis4.ts @@ -89,7 +89,7 @@ //// } //// //// public static staticB = this.staticMethod1; -//// +//// //// public static staticMethod1() { //// this; //// this; @@ -140,15 +140,9 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesThis5.ts b/tests/cases/fourslash/getOccurrencesThis5.ts index 86ce16b16be..845e8342fa5 100644 --- a/tests/cases/fourslash/getOccurrencesThis5.ts +++ b/tests/cases/fourslash/getOccurrencesThis5.ts @@ -89,7 +89,7 @@ //// } //// //// public static staticB = [|this|].staticMethod1; -//// +//// //// public static staticMethod1() { //// [|this|]; //// [|this|]; @@ -140,15 +140,9 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesThisNegatives2.ts b/tests/cases/fourslash/getOccurrencesThisNegatives2.ts index 0a8b5860feb..3f840e8311a 100644 --- a/tests/cases/fourslash/getOccurrencesThisNegatives2.ts +++ b/tests/cases/fourslash/getOccurrencesThisNegatives2.ts @@ -89,7 +89,7 @@ //// } //// //// public static staticB = this.staticMethod1; -//// +//// //// public static staticMethod1() { //// this; //// this; @@ -140,8 +140,4 @@ //// } ////} - -test.markers().forEach(m => { - goTo.position(m.position, m.fileName) - verify.occurrencesAtPositionCount(0); -}); +goTo.eachMarker(() => verify.occurrencesAtPositionCount(0)); diff --git a/tests/cases/fourslash/getOccurrencesThrow.ts b/tests/cases/fourslash/getOccurrencesThrow.ts index 19f10dbfb9f..db80e3c51a0 100644 --- a/tests/cases/fourslash/getOccurrencesThrow.ts +++ b/tests/cases/fourslash/getOccurrencesThrow.ts @@ -3,7 +3,7 @@ ////function f(a: number) { //// try { //// throw "Hello"; -//// +//// //// try { //// throw 10; //// } @@ -42,17 +42,9 @@ //// [|throw|] false; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); +} diff --git a/tests/cases/fourslash/getOccurrencesThrow2.ts b/tests/cases/fourslash/getOccurrencesThrow2.ts index 9bd2f82e638..21425990e2f 100644 --- a/tests/cases/fourslash/getOccurrencesThrow2.ts +++ b/tests/cases/fourslash/getOccurrencesThrow2.ts @@ -3,7 +3,7 @@ ////function f(a: number) { //// try { //// throw "Hello"; -//// +//// //// try { //// [|t/**/hrow|] 10; //// } @@ -42,17 +42,9 @@ //// throw false; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); +} diff --git a/tests/cases/fourslash/getOccurrencesThrow3.ts b/tests/cases/fourslash/getOccurrencesThrow3.ts index 359b783df07..d601123f7bd 100644 --- a/tests/cases/fourslash/getOccurrencesThrow3.ts +++ b/tests/cases/fourslash/getOccurrencesThrow3.ts @@ -3,7 +3,7 @@ ////function f(a: number) { //// try { //// [|throw|] "Hello"; -//// +//// //// try { //// throw 10; //// } @@ -42,17 +42,9 @@ //// throw false; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); +} diff --git a/tests/cases/fourslash/getOccurrencesThrow4.ts b/tests/cases/fourslash/getOccurrencesThrow4.ts index ab2375907ee..c348685b4ed 100644 --- a/tests/cases/fourslash/getOccurrencesThrow4.ts +++ b/tests/cases/fourslash/getOccurrencesThrow4.ts @@ -3,7 +3,7 @@ ////function f(a: number) { //// try { //// throw "Hello"; -//// +//// //// try { //// throw 10; //// } @@ -42,17 +42,9 @@ //// throw false; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); +} diff --git a/tests/cases/fourslash/getOccurrencesThrow5.ts b/tests/cases/fourslash/getOccurrencesThrow5.ts index 9ba28191752..b4b51b677bc 100644 --- a/tests/cases/fourslash/getOccurrencesThrow5.ts +++ b/tests/cases/fourslash/getOccurrencesThrow5.ts @@ -3,7 +3,7 @@ ////function f(a: number) { //// try { //// throw "Hello"; -//// +//// //// try { //// throw 10; //// } @@ -42,17 +42,9 @@ //// throw false; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); +} diff --git a/tests/cases/fourslash/getOccurrencesThrow6.ts b/tests/cases/fourslash/getOccurrencesThrow6.ts index 8b58347ed8a..21509659cd8 100644 --- a/tests/cases/fourslash/getOccurrencesThrow6.ts +++ b/tests/cases/fourslash/getOccurrencesThrow6.ts @@ -14,15 +14,4 @@ //// [|throw|] 300; ////} - - -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); - +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesThrow7.ts b/tests/cases/fourslash/getOccurrencesThrow7.ts index 48ab981d762..7a35daeb775 100644 --- a/tests/cases/fourslash/getOccurrencesThrow7.ts +++ b/tests/cases/fourslash/getOccurrencesThrow7.ts @@ -19,13 +19,4 @@ //// ////[|throw|] 10; -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); - +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesThrow8.ts b/tests/cases/fourslash/getOccurrencesThrow8.ts index cc527720dc4..0e57520d492 100644 --- a/tests/cases/fourslash/getOccurrencesThrow8.ts +++ b/tests/cases/fourslash/getOccurrencesThrow8.ts @@ -19,13 +19,4 @@ //// ////throw 10; -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); - +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/quickInfoInvalidLocations.ts b/tests/cases/fourslash/quickInfoInvalidLocations.ts index 81845e27672..c70be23f387 100644 --- a/tests/cases/fourslash/quickInfoInvalidLocations.ts +++ b/tests/cases/fourslash/quickInfoInvalidLocations.ts @@ -27,13 +27,13 @@ //// ////mod/*invlaid10*/ule m1 { //// va/*invlaid11*/r varibale = 0; -//// +//// //// func/*invlaid12*/tion foo(arg1: number) { //// ret/*invlaid13*/urn string; //// } //// //// class foo { -//// +//// //// } //// //// var object = { @@ -44,9 +44,5 @@ //// }; ////} - -test.markers().forEach((marker) => { - goTo.position(marker.position, marker.fileName); - verify.not.quickInfoExists(); -}); +goTo.eachMarker(() => verify.not.quickInfoExists()); diff --git a/tests/cases/fourslash/referencesForIndexProperty2.ts b/tests/cases/fourslash/referencesForIndexProperty2.ts index 0aa099c9622..35c9d7cdd64 100644 --- a/tests/cases/fourslash/referencesForIndexProperty2.ts +++ b/tests/cases/fourslash/referencesForIndexProperty2.ts @@ -5,6 +5,4 @@ ////var a; ////a["[|blah|]"]; -goTo.position(test.ranges()[0].start, test.ranges()[0].fileName); -verify.referencesAre(test.ranges()); - +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/referencesInComment.ts b/tests/cases/fourslash/referencesInComment.ts index c53a2e6d9b3..eabf74d2f23 100644 --- a/tests/cases/fourslash/referencesInComment.ts +++ b/tests/cases/fourslash/referencesInComment.ts @@ -5,6 +5,4 @@ ////class foo { } ////var bar = 0; -for (const marker of test.markers()) { - verify.referencesAre([]); -} +goTo.eachMarker(() => verify.referencesAre([])); diff --git a/tests/cases/fourslash/renameAlias.ts b/tests/cases/fourslash/renameAlias.ts index e0408af656f..3869b1522b5 100644 --- a/tests/cases/fourslash/renameAlias.ts +++ b/tests/cases/fourslash/renameAlias.ts @@ -4,8 +4,4 @@ ////import [|M|] = SomeModule; ////import C = [|M|].SomeClass; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameAlias2.ts b/tests/cases/fourslash/renameAlias2.ts index da1bcf8248d..f97121f5f7d 100644 --- a/tests/cases/fourslash/renameAlias2.ts +++ b/tests/cases/fourslash/renameAlias2.ts @@ -4,8 +4,4 @@ ////import M = [|SomeModule|]; ////import C = M.SomeClass; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); \ No newline at end of file diff --git a/tests/cases/fourslash/renameAlias3.ts b/tests/cases/fourslash/renameAlias3.ts index 9172f052abb..af3bafef115 100644 --- a/tests/cases/fourslash/renameAlias3.ts +++ b/tests/cases/fourslash/renameAlias3.ts @@ -4,8 +4,4 @@ ////import M = SomeModule; ////import C = M.[|SomeClass|]; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameAliasExternalModule.ts b/tests/cases/fourslash/renameAliasExternalModule.ts index 54277fd6e64..49cc6396717 100644 --- a/tests/cases/fourslash/renameAliasExternalModule.ts +++ b/tests/cases/fourslash/renameAliasExternalModule.ts @@ -8,9 +8,4 @@ ////import [|M|] = require("./a"); ////import C = [|M|].SomeClass; -let ranges = test.ranges() -for (let range of ranges) { - goTo.file(range.fileName); - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameAliasExternalModule2.ts b/tests/cases/fourslash/renameAliasExternalModule2.ts index 2d9d07efb68..35916295a8e 100644 --- a/tests/cases/fourslash/renameAliasExternalModule2.ts +++ b/tests/cases/fourslash/renameAliasExternalModule2.ts @@ -8,9 +8,4 @@ ////import M = require("./a"); ////import C = M.SomeClass; -let ranges = test.ranges() -for (let range of ranges) { - goTo.file(range.fileName); - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameAliasExternalModule3.ts b/tests/cases/fourslash/renameAliasExternalModule3.ts index acff9371c77..53b28e7983e 100644 --- a/tests/cases/fourslash/renameAliasExternalModule3.ts +++ b/tests/cases/fourslash/renameAliasExternalModule3.ts @@ -8,9 +8,4 @@ ////import M = require("./a"); ////import C = M.[|SomeClass|]; -let ranges = test.ranges() -for (let range of ranges) { - goTo.file(range.fileName); - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameContextuallyTypedProperties.ts b/tests/cases/fourslash/renameContextuallyTypedProperties.ts index 4feed49256f..4ce3c2b0738 100644 --- a/tests/cases/fourslash/renameContextuallyTypedProperties.ts +++ b/tests/cases/fourslash/renameContextuallyTypedProperties.ts @@ -55,9 +55,4 @@ //// set ["prop2"](v) { } ////}; -let ranges = test.ranges() -for (let range of ranges) { - goTo.file(range.fileName); - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameContextuallyTypedProperties2.ts b/tests/cases/fourslash/renameContextuallyTypedProperties2.ts index 1887c7751a5..01e638395a0 100644 --- a/tests/cases/fourslash/renameContextuallyTypedProperties2.ts +++ b/tests/cases/fourslash/renameContextuallyTypedProperties2.ts @@ -55,9 +55,4 @@ //// set ["[|prop2|]"](v) { } ////}; -let ranges = test.ranges() -for (let range of ranges) { - goTo.file(range.fileName); - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDefaultImport.ts b/tests/cases/fourslash/renameDefaultImport.ts index fd9534e65f7..8d9b65d78d6 100644 --- a/tests/cases/fourslash/renameDefaultImport.ts +++ b/tests/cases/fourslash/renameDefaultImport.ts @@ -1,19 +1,14 @@ /// -// @Filename: B.ts -////export default class [|B|] { -//// test() { -//// } -////} +// @Filename: B.ts +////export default class [|B|] { +//// test() { +//// } +////} -// @Filename: A.ts -////import [|B|] from "./B"; -////let b = new [|B|](); +// @Filename: A.ts +////import [|B|] from "./B"; +////let b = new [|B|](); ////b.test(); -let ranges = test.ranges() -for (let range of ranges) { - goTo.file(range.fileName); - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDefaultImportDifferentName.ts b/tests/cases/fourslash/renameDefaultImportDifferentName.ts index 5965f1a63e9..aec699aadda 100644 --- a/tests/cases/fourslash/renameDefaultImportDifferentName.ts +++ b/tests/cases/fourslash/renameDefaultImportDifferentName.ts @@ -1,23 +1,17 @@ /// -// @Filename: B.ts -////export default class /*1*/C { -//// test() { -//// } -////} +// @Filename: B.ts +////export default class /*1*/C { +//// test() { +//// } +////} -// @Filename: A.ts -////import [|B|] from "./B"; -////let b = new [|B|](); +// @Filename: A.ts +////import [|B|] from "./B"; +////let b = new [|B|](); ////b.test(); -goTo.file("B.ts"); goTo.marker("1"); verify.occurrencesAtPositionCount(1); -goTo.file("A.ts"); -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringAssignment.ts b/tests/cases/fourslash/renameDestructuringAssignment.ts index b7b18f661d2..89a44a3a9d9 100644 --- a/tests/cases/fourslash/renameDestructuringAssignment.ts +++ b/tests/cases/fourslash/renameDestructuringAssignment.ts @@ -1,14 +1,10 @@ /// -////interface I { -//// [|x|]: number; -////} -////var a: I; -////var x; +////interface I { +//// [|x|]: number; +////} +////var a: I; +////var x; ////({ [|x|]: x } = a); -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringAssignmentInFor2.ts b/tests/cases/fourslash/renameDestructuringAssignmentInFor2.ts index ca75e42394b..4d79b47a267 100644 --- a/tests/cases/fourslash/renameDestructuringAssignmentInFor2.ts +++ b/tests/cases/fourslash/renameDestructuringAssignmentInFor2.ts @@ -1,20 +1,16 @@ /// -////interface I { -//// property1: number; -//// property2: string; -////} -////var elems: I[]; -//// -////var p2: number, [|property1|]: number; -////for ({ [|property1|] } = elems[0]; p2 < 100; p2++) { -//// p2 = [|property1|]++; +////interface I { +//// property1: number; +//// property2: string; ////} -////for ({ property1: p2 } = elems[0]; p2 < 100; p2++) { +////var elems: I[]; +//// +////var p2: number, [|property1|]: number; +////for ({ [|property1|] } = elems[0]; p2 < 100; p2++) { +//// p2 = [|property1|]++; +////} +////for ({ property1: p2 } = elems[0]; p2 < 100; p2++) { ////} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringAssignmentInForOf2.ts b/tests/cases/fourslash/renameDestructuringAssignmentInForOf2.ts index 401b6776d2e..9987a17d36e 100644 --- a/tests/cases/fourslash/renameDestructuringAssignmentInForOf2.ts +++ b/tests/cases/fourslash/renameDestructuringAssignmentInForOf2.ts @@ -1,20 +1,16 @@ /// -////interface I { -//// property1: number; -//// property2: string; -////} -////var elems: I[]; -//// -////var [|property1|]: number, p2: number; -////for ({ [|property1|] } of elems) { -//// [|property1|]++; +////interface I { +//// property1: number; +//// property2: string; ////} -////for ({ property1: p2 } of elems) { +////var elems: I[]; +//// +////var [|property1|]: number, p2: number; +////for ({ [|property1|] } of elems) { +//// [|property1|]++; +////} +////for ({ property1: p2 } of elems) { ////} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringAssignmentNestedInArrayLiteral2.ts b/tests/cases/fourslash/renameDestructuringAssignmentNestedInArrayLiteral2.ts index c4db2de512f..e45ae3349a4 100644 --- a/tests/cases/fourslash/renameDestructuringAssignmentNestedInArrayLiteral2.ts +++ b/tests/cases/fourslash/renameDestructuringAssignmentNestedInArrayLiteral2.ts @@ -1,15 +1,11 @@ /// -////interface I { -//// property1: number; -//// property2: string; -////} -////var elems: I[], p1: number, [|property1|]: number; -////[{ property1: p1 }] = elems; -////[{ [|property1|] }] = elems; +////interface I { +//// property1: number; +//// property2: string; +////} +////var elems: I[], p1: number, [|property1|]: number; +////[{ property1: p1 }] = elems; +////[{ [|property1|] }] = elems; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringAssignmentNestedInFor2.ts b/tests/cases/fourslash/renameDestructuringAssignmentNestedInFor2.ts index 89dc899c5bf..2ec7d906ad1 100644 --- a/tests/cases/fourslash/renameDestructuringAssignmentNestedInFor2.ts +++ b/tests/cases/fourslash/renameDestructuringAssignmentNestedInFor2.ts @@ -1,5 +1,5 @@ -/// - +/// + ////interface MultiRobot { //// name: string; //// skills: { @@ -14,10 +14,5 @@ ////for ({ skills: { [|primary|], secondary } } = multiRobot, i = 0; i < 1; i++) { //// console.log([|primary|]); ////} - -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} - + +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringAssignmentNestedInForOf2.ts b/tests/cases/fourslash/renameDestructuringAssignmentNestedInForOf2.ts index b684e6b6a81..5364cffebb9 100644 --- a/tests/cases/fourslash/renameDestructuringAssignmentNestedInForOf2.ts +++ b/tests/cases/fourslash/renameDestructuringAssignmentNestedInForOf2.ts @@ -1,5 +1,5 @@ -/// - +/// + ////interface MultiRobot { //// name: string; //// skills: { @@ -14,10 +14,6 @@ ////for ({ skills: { [|primary|], secondary } } of multiRobots) { //// console.log([|primary|]); ////} - - -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} + + +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringClassProperty.ts b/tests/cases/fourslash/renameDestructuringClassProperty.ts index acc58f999c4..11261a4df78 100644 --- a/tests/cases/fourslash/renameDestructuringClassProperty.ts +++ b/tests/cases/fourslash/renameDestructuringClassProperty.ts @@ -1,5 +1,5 @@ -/// - +/// + ////class A { //// [|foo|]: string; ////} @@ -14,10 +14,6 @@ //// let { [|foo|] } = a; //// [|foo|] = "newString"; //// } -////} - -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +////} + +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringDeclarationInFor.ts b/tests/cases/fourslash/renameDestructuringDeclarationInFor.ts index 0edf9085092..0338433ae72 100644 --- a/tests/cases/fourslash/renameDestructuringDeclarationInFor.ts +++ b/tests/cases/fourslash/renameDestructuringDeclarationInFor.ts @@ -1,20 +1,16 @@ /// -////interface I { -//// [|property1|]: number; -//// property2: string; -////} -////var elems: I[]; -//// -////var p2: number, property1: number; -////for (let { [|property1|]: p2 } = elems[0]; p2 < 100; p2++) { +////interface I { +//// [|property1|]: number; +//// property2: string; ////} -////for (let { [|property1|] } = elems[0]; p2 < 100; p2++) { -//// [|property1|] = p2; +////var elems: I[]; +//// +////var p2: number, property1: number; +////for (let { [|property1|]: p2 } = elems[0]; p2 < 100; p2++) { +////} +////for (let { [|property1|] } = elems[0]; p2 < 100; p2++) { +//// [|property1|] = p2; ////} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringDeclarationInForOf.ts b/tests/cases/fourslash/renameDestructuringDeclarationInForOf.ts index 1c2b04b7ab5..fcd55a5bc20 100644 --- a/tests/cases/fourslash/renameDestructuringDeclarationInForOf.ts +++ b/tests/cases/fourslash/renameDestructuringDeclarationInForOf.ts @@ -1,19 +1,15 @@ /// -////interface I { -//// [|property1|]: number; -//// property2: string; -////} -////var elems: I[]; -//// -////for (let { [|property1|] } of elems) { -//// [|property1|]++; +////interface I { +//// [|property1|]: number; +//// property2: string; ////} -////for (let { [|property1|]: p2 } of elems) { +////var elems: I[]; +//// +////for (let { [|property1|] } of elems) { +//// [|property1|]++; +////} +////for (let { [|property1|]: p2 } of elems) { ////} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringFunctionParameter.ts b/tests/cases/fourslash/renameDestructuringFunctionParameter.ts index d1df0f58275..4abbabc3723 100644 --- a/tests/cases/fourslash/renameDestructuringFunctionParameter.ts +++ b/tests/cases/fourslash/renameDestructuringFunctionParameter.ts @@ -1,10 +1,7 @@ /// -////function f({[|a|]}: {[|a|]}) { -//// f({[|a|]}); +////function f({[|a|]}: {[|a|]}) { +//// f({[|a|]}); ////} -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} + +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringNestedBindingElement.ts b/tests/cases/fourslash/renameDestructuringNestedBindingElement.ts index 1c4254b14ae..7557744ecee 100644 --- a/tests/cases/fourslash/renameDestructuringNestedBindingElement.ts +++ b/tests/cases/fourslash/renameDestructuringNestedBindingElement.ts @@ -1,5 +1,5 @@ -/// - +/// + ////interface MultiRobot { //// name: string; //// skills: { @@ -13,10 +13,6 @@ ////} ////for (let { skills: {[|primary|], secondary } } of multiRobots) { //// console.log([|primary|]); -////} - -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +////} + +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameForDefaultExport01.ts b/tests/cases/fourslash/renameForDefaultExport01.ts index 809c127a727..96f0d6e54e8 100644 --- a/tests/cases/fourslash/renameForDefaultExport01.ts +++ b/tests/cases/fourslash/renameForDefaultExport01.ts @@ -10,9 +10,4 @@ //// ////var y = new /*3*/[|DefaultExportedClass|]; -let markers = test.markers() -for (let marker of markers) { - goTo.position(marker.position); - - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true); -} \ No newline at end of file +goTo.eachMarker(() => verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true)); \ No newline at end of file diff --git a/tests/cases/fourslash/renameForDefaultExport02.ts b/tests/cases/fourslash/renameForDefaultExport02.ts index ddf4b224023..471b10e32b2 100644 --- a/tests/cases/fourslash/renameForDefaultExport02.ts +++ b/tests/cases/fourslash/renameForDefaultExport02.ts @@ -11,9 +11,4 @@ //// ////var y = /*4*/[|DefaultExportedFunction|](); -let markers = test.markers() -for (let marker of markers) { - goTo.position(marker.position); - - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true); -} \ No newline at end of file +goTo.eachMarker(() => verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true)); \ No newline at end of file diff --git a/tests/cases/fourslash/renameForDefaultExport03.ts b/tests/cases/fourslash/renameForDefaultExport03.ts index 6f82d96fe5e..1da6ff20b0b 100644 --- a/tests/cases/fourslash/renameForDefaultExport03.ts +++ b/tests/cases/fourslash/renameForDefaultExport03.ts @@ -17,9 +17,4 @@ //// var local = 100; ////} -let markers = test.markers() -for (let marker of markers) { - goTo.position(marker.position); - - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true); -} \ No newline at end of file +goTo.eachMarker(() => verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true)); \ No newline at end of file diff --git a/tests/cases/fourslash/renameImportAndExport.ts b/tests/cases/fourslash/renameImportAndExport.ts index 495e15c1e7e..fe8bce4b208 100644 --- a/tests/cases/fourslash/renameImportAndExport.ts +++ b/tests/cases/fourslash/renameImportAndExport.ts @@ -3,8 +3,4 @@ ////import [|a|] from "module"; ////export { [|a|] }; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameImportAndShorthand.ts b/tests/cases/fourslash/renameImportAndShorthand.ts index bc4746aebdd..4836d8c14fe 100644 --- a/tests/cases/fourslash/renameImportAndShorthand.ts +++ b/tests/cases/fourslash/renameImportAndShorthand.ts @@ -3,8 +3,4 @@ ////import [|foo|] from 'bar'; ////const bar = { [|foo|] }; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameImportNamespaceAndShorthand.ts b/tests/cases/fourslash/renameImportNamespaceAndShorthand.ts index a6b06c11408..21cdc0fa820 100644 --- a/tests/cases/fourslash/renameImportNamespaceAndShorthand.ts +++ b/tests/cases/fourslash/renameImportNamespaceAndShorthand.ts @@ -3,8 +3,4 @@ ////import * as [|foo|] from 'bar'; ////const bar = { [|foo|] }; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameImportOfExportEquals.ts b/tests/cases/fourslash/renameImportOfExportEquals.ts index 9d71ee907c8..192acefd6fd 100644 --- a/tests/cases/fourslash/renameImportOfExportEquals.ts +++ b/tests/cases/fourslash/renameImportOfExportEquals.ts @@ -11,8 +11,4 @@ //// export { [|N|] }; // Renaming N here would rename ////} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameImportRequire.ts b/tests/cases/fourslash/renameImportRequire.ts index c26cc80b616..8a9aeebc328 100644 --- a/tests/cases/fourslash/renameImportRequire.ts +++ b/tests/cases/fourslash/renameImportRequire.ts @@ -1,12 +1,8 @@ /// -////import [|e|] = require("mod4"); -////[|e|]; -////a = { [|e|] }; +////import [|e|] = require("mod4"); +////[|e|]; +////a = { [|e|] }; ////export { [|e|] }; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameInheritedProperties1.ts b/tests/cases/fourslash/renameInheritedProperties1.ts index 4698fe3d97b..b42335277a9 100644 --- a/tests/cases/fourslash/renameInheritedProperties1.ts +++ b/tests/cases/fourslash/renameInheritedProperties1.ts @@ -7,9 +7,4 @@ //// var v: class1; //// v.[|propName|]; -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (const range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameInheritedProperties2.ts b/tests/cases/fourslash/renameInheritedProperties2.ts index ed99ec3e013..bcc4c5fc323 100644 --- a/tests/cases/fourslash/renameInheritedProperties2.ts +++ b/tests/cases/fourslash/renameInheritedProperties2.ts @@ -7,9 +7,4 @@ //// var v: class1; //// v.[|doStuff|](); -let ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameInheritedProperties3.ts b/tests/cases/fourslash/renameInheritedProperties3.ts index 17e7785fbc7..f1ec547d6ed 100644 --- a/tests/cases/fourslash/renameInheritedProperties3.ts +++ b/tests/cases/fourslash/renameInheritedProperties3.ts @@ -7,9 +7,4 @@ //// var v: interface1; //// v.[|propName|]; -let ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameInheritedProperties4.ts b/tests/cases/fourslash/renameInheritedProperties4.ts index ea2f7c40fbf..42d9acfdb53 100644 --- a/tests/cases/fourslash/renameInheritedProperties4.ts +++ b/tests/cases/fourslash/renameInheritedProperties4.ts @@ -7,9 +7,4 @@ //// var v: interface1; //// v.[|doStuff|](); -let ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameInheritedProperties5.ts b/tests/cases/fourslash/renameInheritedProperties5.ts index 45058827747..e153742d4ed 100644 --- a/tests/cases/fourslash/renameInheritedProperties5.ts +++ b/tests/cases/fourslash/renameInheritedProperties5.ts @@ -9,9 +9,5 @@ //// var d: D; //// d.[|propD|]; -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (const range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); + diff --git a/tests/cases/fourslash/renameInheritedProperties6.ts b/tests/cases/fourslash/renameInheritedProperties6.ts index 6bdd32ce3e0..59318334cb0 100644 --- a/tests/cases/fourslash/renameInheritedProperties6.ts +++ b/tests/cases/fourslash/renameInheritedProperties6.ts @@ -9,9 +9,4 @@ //// var d: D; //// d.[|propC|]; -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (const range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameInheritedProperties7.ts b/tests/cases/fourslash/renameInheritedProperties7.ts index a2f8c5a2b51..bc0521458f8 100644 --- a/tests/cases/fourslash/renameInheritedProperties7.ts +++ b/tests/cases/fourslash/renameInheritedProperties7.ts @@ -3,17 +3,12 @@ //// class C extends D { //// [|prop1|]: string; //// } -//// +//// //// class D extends C { //// prop1: string; //// } -//// +//// //// var c: C; //// c.[|prop1|]; -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (const range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameInheritedProperties8.ts b/tests/cases/fourslash/renameInheritedProperties8.ts index 119e1a477aa..7cde300bf0b 100644 --- a/tests/cases/fourslash/renameInheritedProperties8.ts +++ b/tests/cases/fourslash/renameInheritedProperties8.ts @@ -3,17 +3,12 @@ //// class C implements D { //// [|prop1|]: string; //// } -//// +//// //// interface D extends C { //// [|prop1|]: string; //// } -//// +//// //// var c: C; //// c.[|prop1|]; -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (const range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameLocationsForClassExpression01.ts b/tests/cases/fourslash/renameLocationsForClassExpression01.ts index b95040085c9..b0f2f509500 100644 --- a/tests/cases/fourslash/renameLocationsForClassExpression01.ts +++ b/tests/cases/fourslash/renameLocationsForClassExpression01.ts @@ -11,7 +11,7 @@ //// static doItStatically() { //// return [|Foo|].y; //// } -////} +////} //// ////var y = class { //// getSomeName() { @@ -20,8 +20,4 @@ ////} ////var z = class Foo {} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameLocationsForFunctionExpression01.ts b/tests/cases/fourslash/renameLocationsForFunctionExpression01.ts index e884783d960..1e02e3f5284 100644 --- a/tests/cases/fourslash/renameLocationsForFunctionExpression01.ts +++ b/tests/cases/fourslash/renameLocationsForFunctionExpression01.ts @@ -4,9 +4,4 @@ //// [|f|]([|f|], g); ////} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameLocationsForFunctionExpression02.ts b/tests/cases/fourslash/renameLocationsForFunctionExpression02.ts index 8186611cb64..a258bcd803d 100644 --- a/tests/cases/fourslash/renameLocationsForFunctionExpression02.ts +++ b/tests/cases/fourslash/renameLocationsForFunctionExpression02.ts @@ -1,7 +1,7 @@ /// ////function f() { -//// +//// ////} ////var x = function [|f|](g: any, h: any) { //// @@ -10,9 +10,4 @@ //// let foo = () => [|f|]([|f|], g); ////} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts b/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts index 535dbd3d5a3..4ae87f19db5 100644 --- a/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts +++ b/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts @@ -8,7 +8,4 @@ ////var foo: I; ////var { [|property1|]: prop1 } = foo; -for (let range of test.ranges()) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameObjectSpread.ts b/tests/cases/fourslash/renameObjectSpread.ts index eba148c0e39..f56c22dd42f 100644 --- a/tests/cases/fourslash/renameObjectSpread.ts +++ b/tests/cases/fourslash/renameObjectSpread.ts @@ -10,11 +10,11 @@ const ranges = test.ranges(); verify.assertHasRanges(ranges); // A1 unions with A2, so rename A1.a and a12.a -goTo.position(ranges[0].start); +goTo.rangeStart(ranges[0]); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[0], ranges[2]]); // A1 unions with A2, so rename A2.a and a12.a -goTo.position(ranges[1].start); +goTo.rangeStart(ranges[1]); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[1], ranges[2]]); // a12.a unions A1.a and A2.a, so rename A1.a, A2.a and a12.a -goTo.position(ranges[2].start); +goTo.rangeStart(ranges[2]); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[0], ranges[1], ranges[2]]); diff --git a/tests/cases/fourslash/renameObjectSpreadAssignment.ts b/tests/cases/fourslash/renameObjectSpreadAssignment.ts index 9cf0b6ebf81..2ddebb6e18b 100644 --- a/tests/cases/fourslash/renameObjectSpreadAssignment.ts +++ b/tests/cases/fourslash/renameObjectSpreadAssignment.ts @@ -5,16 +5,18 @@ ////let [|a1|]: A1; ////let [|a2|]: A2; ////let a12 = { ...[|a1|], ...[|a2|] }; + const ranges = test.ranges(); verify.assertHasRanges(ranges); + // rename a1 -goTo.position(ranges[0].start); +goTo.rangeStart(ranges[0]); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[0], ranges[2]]); -goTo.position(ranges[2].start); +goTo.rangeStart(ranges[2]); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[0], ranges[2]]); // rename a2 -goTo.position(ranges[1].start); +goTo.rangeStart(ranges[1]); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[1], ranges[3]]); -goTo.position(ranges[3].start); +goTo.rangeStart(ranges[3]); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[1], ranges[3]]); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts index 42bfbf63a47..14f8a240bfb 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts @@ -7,9 +7,4 @@ //// } //// } -let ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts index e7ef9d1c1a2..ce31ad6c9c5 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts @@ -7,9 +7,4 @@ //// } //// } -let ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts index 9446e2aeb75..6291eff2605 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts @@ -7,9 +7,4 @@ //// } //// } -let ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts index 7fb4b8c757d..ca201d28b2c 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts @@ -6,9 +6,4 @@ //// } //// } -let ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts index b7c47a4c0d7..f989e7c3fd9 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts @@ -6,9 +6,4 @@ //// } //// } -let ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameRest.ts b/tests/cases/fourslash/renameRest.ts index a5cc2c38683..60fc1bbb227 100644 --- a/tests/cases/fourslash/renameRest.ts +++ b/tests/cases/fourslash/renameRest.ts @@ -7,9 +7,5 @@ ////let t: Gen; ////var { x, ...rest } = t; ////rest.[|parent|]; -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -goTo.position(ranges[0].start); -verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, ranges); -goTo.position(ranges[1].start); -verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, ranges); + +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameStingPropertyNames.ts b/tests/cases/fourslash/renameStingPropertyNames.ts index a948220efad..13863b043e7 100644 --- a/tests/cases/fourslash/renameStingPropertyNames.ts +++ b/tests/cases/fourslash/renameStingPropertyNames.ts @@ -12,9 +12,4 @@ ////o['[|prop|]']; ////o.[|prop|]; - -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameStringLiteralTypes.ts b/tests/cases/fourslash/renameStringLiteralTypes.ts index f9df83371c1..d0e7368f25d 100644 --- a/tests/cases/fourslash/renameStringLiteralTypes.ts +++ b/tests/cases/fourslash/renameStringLiteralTypes.ts @@ -11,8 +11,4 @@ //// ////animate({ deltaX: 100, deltaY: 100, easing: "[|ease-in-out|]" }); -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameThis.ts b/tests/cases/fourslash/renameThis.ts index f567cace70d..c4e5d932261 100644 --- a/tests/cases/fourslash/renameThis.ts +++ b/tests/cases/fourslash/renameThis.ts @@ -8,7 +8,7 @@ let [r0, r1, r2, r3] = test.ranges() for (let range of [r0, r1]) { - goTo.position(range.start); + goTo.rangeStart(range); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [r0, r1]); } @@ -17,6 +17,6 @@ goTo.marker(); verify.renameInfoFailed("You cannot rename this element."); for (let range of [r2, r3]) { - goTo.position(range.start); + goTo.rangeStart(range); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [r2, r3]); } diff --git a/tests/cases/fourslash/renameUMDModuleAlias1.ts b/tests/cases/fourslash/renameUMDModuleAlias1.ts index 94aabcdbde5..c44e459b008 100644 --- a/tests/cases/fourslash/renameUMDModuleAlias1.ts +++ b/tests/cases/fourslash/renameUMDModuleAlias1.ts @@ -10,8 +10,4 @@ //// /// //// [|myLib|].doThing(); -const ranges = test.ranges() -for (const range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/server/occurrences01.ts b/tests/cases/fourslash/server/occurrences01.ts index db2fa64f38d..f6e39d55b91 100644 --- a/tests/cases/fourslash/server/occurrences01.ts +++ b/tests/cases/fourslash/server/occurrences01.ts @@ -10,13 +10,4 @@ //// continue foo; ////} -let ranges = test.ranges(); - -for (let r of ranges) { - goTo.position(r.start); - verify.occurrencesAtPositionCount(ranges.length); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, /*isWriteAccess*/ false); - } -} \ No newline at end of file +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/server/occurrences02.ts b/tests/cases/fourslash/server/occurrences02.ts index e0d39cb92fd..4cf8f1bcac3 100644 --- a/tests/cases/fourslash/server/occurrences02.ts +++ b/tests/cases/fourslash/server/occurrences02.ts @@ -4,13 +4,4 @@ //// [|f|]([|f|]); ////} -let ranges = test.ranges(); - -for (let r of ranges) { - goTo.position(r.start); - verify.occurrencesAtPositionCount(ranges.length); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range); - } -} \ No newline at end of file +verify.rangesAreOccurrences(); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates1.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates1.ts index 39644ba8c24..87c9262f893 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplates1.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates1.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f `/*1*/ qwe/*2*/rty /*3*/$/*4*/{ 123 }/*5*/ as/*6*/df /*7*/$/*8*/{ 41234 }/*9*/ zxc/*10*/vb /*11*/$/*12*/{ g ` ` }/*13*/ /*14*/ /*15*/` -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(4); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates2.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates2.ts index 123a6cc4c2c..ef306a22934 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplates2.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates2.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f `/*1*/ qwe/*2*/rty /*3*/$/*4*/{ 123 }/*5*/ as/*6*/df /*7*/$/*8*/{ 41234 }/*9*/ zxc/*10*/vb /*11*/$/*12*/{ g ` ` }/*13*/ /*14*/ /*15*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(4); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates3.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates3.ts index f203468ca04..7859fd6f457 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplates3.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates3.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` qwerty ${/*1*/ /*2*/123/*3*/ /*4*/} asdf ${ 41234 } zxcvb ${ g ` ` } ` -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(4); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates4.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates4.ts index 13ee47a3309..4c8ce2cd917 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplates4.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates4.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` qwerty ${ 123 } asdf ${/*1*/ /*2*/ /*3*/41/*4*/234/*5*/ /*6*/} zxcvb ${ g ` ` } ` -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(4); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates5.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates5.ts index 7cd2affd675..03ef244e719 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplates5.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates5.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` qwerty ${ 123 } asdf ${ 41234 } zxcvb ${/*1*/ /*2*/g/*3*/ /*4*/` `/*5*/ /*6*/} ` -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(4); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates6.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates6.ts index 7671666bb54..67ab1199be8 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplates6.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates6.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` qwerty ${ 123 } asdf ${ 41234 } zxcvb ${ g `/*1*/ /*2*/ /*3*/` } ` -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(1); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates7.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates7.ts index 35bed336f39..cd17ddd1027 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplates7.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates7.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f `/*1*/ /*2*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(1); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete1.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete1.ts index 1da96ea5c1b..2995c6cdcd8 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete1.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete1.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// -//// f `/*1*/ /*2*/${ - -test.markers().forEach(m => { - goTo.position(m.position); +//// +//// f `/*1*/ /*2*/${ +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(2); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete2.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete2.ts index 68ff7202f01..d1ceebfb1b0 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete2.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete2.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` ${/*1*/ /*2*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(2); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete3.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete3.ts index 8165da7f67b..211fa66f594 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete3.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete3.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` ${ }/*1*/ /*2*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(2); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete4.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete4.ts index 8c970b60c77..79432077ce9 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete4.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete4.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` ${ } ${/*1*/ /*2*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete5.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete5.ts index f93da36ce5c..18ffdbe3bf0 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete5.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete5.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` ${ } ${ }/*1*/ /*2*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete6.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete6.ts index 10d81eb80f4..fdd6f22554d 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete6.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete6.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` ${ 123 } ${/*1*/ } ` -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete7.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete7.ts index a8afe2d9c6d..9bc4a535564 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete7.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete7.ts @@ -2,15 +2,13 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` ${ 123 } /*1*/${ } /*2*/\/*3*/ //// /*4*/\\/*5*/ //// /*6*/\\\/*7*/ //// /*8*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete8.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete8.ts index 86455a65ccd..05ab05c3e6c 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete8.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete8.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f `/*1*/\/*2*/`/*3*/ /*4*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(1); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete9.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete9.ts index de42a33b397..597ec928bb9 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete9.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete9.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f `/*1*/ \\\/*2*/`/*3*/ /*4*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(1); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives1.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives1.ts index c61f1a871e4..10f9f81fa61 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives1.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives1.ts @@ -2,10 +2,7 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// /*1*/f/*2*/ /*3*/` qwerty ${ 123 } asdf ${ 41234 } zxcvb ${ g ` ` } `/*4*/ -test.markers().forEach(m => { - goTo.position(m.position); - verify.not.signatureHelpPresent(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.not.signatureHelpPresent()); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives2.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives2.ts index e7a5078dcd0..da21fda631c 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives2.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives2.ts @@ -2,10 +2,7 @@ //// function foo(strs, ...rest) { //// } -//// +//// //// /*1*/fo/*2*/o /*3*/`abcd${0 + 1}abcd{1 + 1}`/*4*/ /*5*/ -test.markers().forEach(m => { - goTo.position(m.position); - verify.not.signatureHelpPresent(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.not.signatureHelpPresent()); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives3.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives3.ts index c84b92fee4f..9ccbe927a57 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives3.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives3.ts @@ -2,10 +2,7 @@ //// function foo(strs, ...rest) { //// } -//// +//// //// /*1*/fo/*2*/o /*3*/`abcd${0 + 1}abcd{1 + 1}abcd`/*4*/ /*5*/ -test.markers().forEach(m => { - goTo.position(m.position); - verify.not.signatureHelpPresent(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.not.signatureHelpPresent()); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives4.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives4.ts index 338a8dc65ca..825afd265ab 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives4.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives4.ts @@ -2,10 +2,7 @@ //// function foo(strs, ...rest) { //// } -//// +//// //// /*1*/fo/*2*/o /*3*/``/*4*/ /*5*/ -test.markers().forEach(m => { - goTo.position(m.position); - verify.not.signatureHelpPresent(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.not.signatureHelpPresent()); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives5.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives5.ts index 02383df9267..5b14b627f6a 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives5.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives5.ts @@ -2,10 +2,7 @@ //// function foo(strs, ...rest) { //// } -//// +//// //// /*1*/fo/*2*/o /*3*/`abcd`/*4*/ -test.markers().forEach(m => { - goTo.position(m.position); - verify.not.signatureHelpPresent(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.not.signatureHelpPresent()); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesNested1.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesNested1.ts index a3c9f7ccce4..313e55bf517 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesNested1.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesNested1.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f `a ${ g `/*1*/alpha/*2*/ ${/*3*/ 12/*4*/3 /*5*/} beta /*6*/${ /*7*/456 /*8*/} gamma/*9*/` } b ${ g `/*10*/txt/*11*/` } c ${ g `/*12*/aleph /*13*/$/*14*/{ 12/*15*/3 } beit/*16*/` } d`; -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.currentSignatureParameterCountIs(4); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesNested2.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesNested2.ts index d72fa74d985..aa04e425998 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesNested2.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesNested2.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f `/*1*/a $/*2*/{ /*3*/g /*4*/`alpha ${ 123 } beta ${ 456 } gamma`/*5*/ }/*6*/ b $/*7*/{ /*8*/g /*9*/`txt`/*10*/ } /*11*/c ${ /*12*/g /*13*/`aleph ${ 123 } beit`/*14*/ } d/*15*/`; -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.currentSignatureParameterCountIs(4); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags1.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags1.ts index 6850b1bc54f..54aee5887b8 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags1.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags1.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// +//// //// f `/*1*/ /*2*/$/*3*/{ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(2); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags2.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags2.ts index 8466c6b05f2..9cbd20a49d2 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags2.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags2.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// +//// //// f `${/*1*/ /*2*/ /*3*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(2); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags3.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags3.ts index b919afc7703..a9b91dbf438 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags3.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags3.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: TemplateStringsArray, p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: TemplateStringsArray, p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// +//// //// f `${/*1*/ "s/*2*/tring" /*3*/ } ${ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags4.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags4.ts index a1072366a98..96ff7c4683a 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags4.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags4.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// +//// //// f `${/*1*/ 123.456/*2*/ /*3*/ } ${ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags5.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags5.ts index 2646e70b39c..52a1e3f74be 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags5.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags5.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// +//// //// f `${ } ${/*1*/ /*2*/ /*3*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags6.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags6.ts index 62410a5fda3..b34df14e926 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags6.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags6.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// +//// //// f `${ } ${/*1*/ /*2*/ /*3*/} -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags7.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags7.ts index 5f706b8c0fa..26a80e36f6f 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags7.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags7.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: TemplateStringsArray, p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: TemplateStringsArray, p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// +//// //// f `${ } ${/*1*/ fa/*2*/lse /*3*/} -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags8.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags8.ts index 8000f15d3c6..6b9daa60dcc 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags8.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags8.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// +//// //// f `${ undefined } ${ undefined } ${/*1*/ 10/*2*/./*3*/01 /*4*/} ` -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(4); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags9.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags9.ts index aee06c1df53..cbcc55a2f22 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags9.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags9.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// -//// f `${/*1*/ /*2*/ /*3*/} ${ - -test.markers().forEach(m => { - goTo.position(m.position); +//// +//// f `${/*1*/ /*2*/ /*3*/} ${ +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash_old/completionListGenericConstraintsNames.ts b/tests/cases/fourslash_old/completionListGenericConstraintsNames.ts index 3e60456f389..92d288dcb2a 100644 --- a/tests/cases/fourslash_old/completionListGenericConstraintsNames.ts +++ b/tests/cases/fourslash_old/completionListGenericConstraintsNames.ts @@ -17,9 +17,8 @@ //// } ////} - test.markers().forEach((marker) => { - goTo.position(marker.position, marker.fileName); - verify.memberListContains("T"); - verify.memberListContains("U"); - verify.memberListContains("M"); +goTo.eachMarker(() => { + verify.memberListContains("T"); + verify.memberListContains("U"); + verify.memberListContains("M"); }); From a6c5306479d1ca150657967f77fa2a195db4b793 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 19 Jan 2017 13:58:09 -0800 Subject: [PATCH 04/41] Allow object intersection types as class/interface base types --- src/compiler/checker.ts | 53 ++++++++++++++++++++++++++-------------- src/compiler/types.ts | 7 ++++-- src/services/services.ts | 2 +- src/services/types.ts | 2 +- 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 756a2b2d3b1..9cc5fb111cd 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3732,11 +3732,16 @@ namespace ts { return getObjectFlags(type) & ObjectFlags.Reference ? (type).target : type; } - function hasBaseType(type: InterfaceType, checkBase: InterfaceType) { + function hasBaseType(type: BaseType, checkBase: BaseType) { return check(type); - function check(type: InterfaceType): boolean { - const target = getTargetType(type); - return target === checkBase || forEach(getBaseTypes(target), check); + function check(type: BaseType): boolean { + if (getObjectFlags(type) & (ObjectFlags.ClassOrInterface | ObjectFlags.Reference)) { + const target = getTargetType(type); + return target === checkBase || forEach(getBaseTypes(target), check); + } + else if (type.flags & TypeFlags.Intersection) { + return forEach((type).types, check); + } } } @@ -3862,7 +3867,7 @@ namespace ts { return type.resolvedBaseConstructorType; } - function getBaseTypes(type: InterfaceType): ObjectType[] { + function getBaseTypes(type: InterfaceType): BaseType[] { if (!type.resolvedBaseTypes) { if (type.objectFlags & ObjectFlags.Tuple) { type.resolvedBaseTypes = [createArrayType(getUnionType(type.typeParameters))]; @@ -3922,11 +3927,11 @@ namespace ts { if (baseType === unknownType) { return; } - if (!(getObjectFlags(getTargetType(baseType)) & ObjectFlags.ClassOrInterface)) { + if (!isValidBaseType(baseType)) { error(baseTypeNode.expression, Diagnostics.Base_constructor_return_type_0_is_not_a_class_or_interface_type, typeToString(baseType)); return; } - if (type === baseType || hasBaseType(baseType, type)) { + if (type === baseType || hasBaseType(baseType, type)) { error(valueDecl, Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType)); return; @@ -3951,6 +3956,13 @@ namespace ts { return true; } + // A valid base type is any non-generic object type or intersection of non-generic + // object types. + function isValidBaseType(type: Type): boolean { + return type.flags & TypeFlags.Object && !isGenericMappedType(type) || + type.flags & TypeFlags.Intersection && !forEach((type).types, t => !isValidBaseType(t)); + } + function resolveBaseTypesOfInterface(type: InterfaceType): void { type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray; for (const declaration of type.symbol.declarations) { @@ -3958,8 +3970,8 @@ namespace ts { for (const node of getInterfaceBaseTypeNodes(declaration)) { const baseType = getTypeFromTypeNode(node); if (baseType !== unknownType) { - if (getObjectFlags(getTargetType(baseType)) & ObjectFlags.ClassOrInterface) { - if (type !== baseType && !hasBaseType(baseType, type)) { + if (isValidBaseType(baseType)) { + if (type !== baseType && !hasBaseType(baseType, type)) { if (type.resolvedBaseTypes === emptyArray) { type.resolvedBaseTypes = [baseType]; } @@ -4317,6 +4329,9 @@ namespace ts { return createTypeReference((type).target, concatenate((type).typeArguments, [thisArgument || (type).target.thisType])); } + if (type.flags & TypeFlags.Intersection) { + return getIntersectionType(map((type).types, t => getTypeWithThisArgument(t, thisArgument))); + } return type; } @@ -4350,8 +4365,8 @@ namespace ts { } const thisArgument = lastOrUndefined(typeArguments); for (const baseType of baseTypes) { - const instantiatedBaseType = thisArgument ? getTypeWithThisArgument(instantiateType(baseType, mapper), thisArgument) : baseType; - addInheritedMembers(members, getPropertiesOfObjectType(instantiatedBaseType)); + const instantiatedBaseType = thisArgument ? getTypeWithThisArgument(instantiateType(baseType, mapper), thisArgument) : baseType; + addInheritedMembers(members, getPropertiesOfType(instantiatedBaseType)); callSignatures = concatenate(callSignatures, getSignaturesOfType(instantiatedBaseType, SignatureKind.Call)); constructSignatures = concatenate(constructSignatures, getSignaturesOfType(instantiatedBaseType, SignatureKind.Construct)); stringIndexInfo = stringIndexInfo || getIndexInfoOfType(instantiatedBaseType, IndexKind.String); @@ -18216,16 +18231,18 @@ namespace ts { return; } + const propDeclaration = prop.valueDeclaration; + // index is numeric and property name is not valid numeric literal - if (indexKind === IndexKind.Number && !isNumericName(prop.valueDeclaration.name)) { + if (indexKind === IndexKind.Number && propDeclaration && !isNumericName(propDeclaration.name)) { return; } // perform property check if property or indexer is declared in 'type' // this allows to rule out cases when both property and indexer are inherited from the base class let errorNode: Node; - if (prop.valueDeclaration.name.kind === SyntaxKind.ComputedPropertyName || prop.parent === containingType.symbol) { - errorNode = prop.valueDeclaration; + if (propDeclaration && propDeclaration.name.kind === SyntaxKind.ComputedPropertyName || prop.parent === containingType.symbol) { + errorNode = propDeclaration; } else if (indexDeclaration) { errorNode = indexDeclaration; @@ -18364,7 +18381,7 @@ namespace ts { checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node, Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1); - if (baseType.symbol.valueDeclaration && + if (baseType.symbol && baseType.symbol.valueDeclaration && !isInAmbientContext(baseType.symbol.valueDeclaration) && baseType.symbol.valueDeclaration.kind === SyntaxKind.ClassDeclaration) { if (!isBlockScopedNameDeclaredBeforeUse(baseType.symbol.valueDeclaration, node)) { @@ -18437,7 +18454,7 @@ namespace ts { return forEach(symbol.declarations, d => isClassLike(d) ? d : undefined); } - function checkKindsOfPropertyMemberOverrides(type: InterfaceType, baseType: ObjectType): void { + function checkKindsOfPropertyMemberOverrides(type: InterfaceType, baseType: BaseType): void { // TypeScript 1.0 spec (April 2014): 8.2.3 // A derived class inherits all members from its base class it doesn't override. @@ -18454,7 +18471,7 @@ namespace ts { // derived class instance member variables and accessors, but not by other kinds of members. // NOTE: assignability is checked in checkClassDeclaration - const baseProperties = getPropertiesOfObjectType(baseType); + const baseProperties = getPropertiesOfType(baseType); for (const baseProperty of baseProperties) { const base = getTargetSymbol(baseProperty); @@ -18578,7 +18595,7 @@ namespace ts { let ok = true; for (const base of baseTypes) { - const properties = getPropertiesOfObjectType(getTypeWithThisArgument(base, type.thisType)); + const properties = getPropertiesOfType(getTypeWithThisArgument(base, type.thisType)); for (const prop of properties) { const existing = seen.get(prop.name); if (!existing) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 51347c8d3df..b834d73300a 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2358,7 +2358,7 @@ getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo; getSignaturesOfType(type: Type, kind: SignatureKind): Signature[]; getIndexTypeOfType(type: Type, kind: IndexKind): Type; - getBaseTypes(type: InterfaceType): ObjectType[]; + getBaseTypes(type: InterfaceType): BaseType[]; getReturnTypeOfSignature(signature: Signature): Type; /** * Gets the type of a parameter at a given position in a signature. @@ -2910,9 +2910,12 @@ /* @internal */ resolvedBaseConstructorType?: Type; // Resolved base constructor type of class /* @internal */ - resolvedBaseTypes: ObjectType[]; // Resolved base types + resolvedBaseTypes: BaseType[]; // Resolved base types } + // Object type or intersection of object types + export type BaseType = ObjectType | IntersectionType; + export interface InterfaceTypeWithDeclaredMembers extends InterfaceType { declaredProperties: Symbol[]; // Declared members declaredCallSignatures: Signature[]; // Declared call signatures diff --git a/src/services/services.ts b/src/services/services.ts index 26374eccbfd..04cb233557f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -379,7 +379,7 @@ namespace ts { getNumberIndexType(): Type { return this.checker.getIndexTypeOfType(this, IndexKind.Number); } - getBaseTypes(): ObjectType[] { + getBaseTypes(): BaseType[] { return this.flags & TypeFlags.Object && this.objectFlags & (ObjectFlags.Class | ObjectFlags.Interface) ? this.checker.getBaseTypes(this) : undefined; diff --git a/src/services/types.ts b/src/services/types.ts index 88ffe2950ce..f410eb5b401 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -33,7 +33,7 @@ namespace ts { getConstructSignatures(): Signature[]; getStringIndexType(): Type; getNumberIndexType(): Type; - getBaseTypes(): ObjectType[]; + getBaseTypes(): BaseType[]; getNonNullableType(): Type; } From d22b963b0bd4984597e003ca4267e1dca6f44183 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 19 Jan 2017 13:51:34 -0800 Subject: [PATCH 05/41] Add test for decorator referencing alias named Event --- .../reference/metadataOfEventAlias.js | 38 +++++++++++++++++++ .../reference/metadataOfEventAlias.symbols | 23 +++++++++++ .../reference/metadataOfEventAlias.types | 23 +++++++++++ tests/cases/compiler/metadataOfEventAlias.ts | 14 +++++++ 4 files changed, 98 insertions(+) create mode 100644 tests/baselines/reference/metadataOfEventAlias.js create mode 100644 tests/baselines/reference/metadataOfEventAlias.symbols create mode 100644 tests/baselines/reference/metadataOfEventAlias.types create mode 100644 tests/cases/compiler/metadataOfEventAlias.ts diff --git a/tests/baselines/reference/metadataOfEventAlias.js b/tests/baselines/reference/metadataOfEventAlias.js new file mode 100644 index 00000000000..a79a2daa5d9 --- /dev/null +++ b/tests/baselines/reference/metadataOfEventAlias.js @@ -0,0 +1,38 @@ +//// [tests/cases/compiler/metadataOfEventAlias.ts] //// + +//// [event.ts] + +export interface Event { title: string }; + +//// [test.ts] +import { Event } from './event'; +function Input(target: any, key: string): void { } +export class SomeClass { + @Input event: Event; +} + +//// [event.js] +"use strict"; +; +//// [test.js] +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +function Input(target, key) { } +var SomeClass = (function () { + function SomeClass() { + } + return SomeClass; +}()); +__decorate([ + Input, + __metadata("design:type", event_1.Event) +], SomeClass.prototype, "event", void 0); +exports.SomeClass = SomeClass; diff --git a/tests/baselines/reference/metadataOfEventAlias.symbols b/tests/baselines/reference/metadataOfEventAlias.symbols new file mode 100644 index 00000000000..441714e63e6 --- /dev/null +++ b/tests/baselines/reference/metadataOfEventAlias.symbols @@ -0,0 +1,23 @@ +=== tests/cases/compiler/event.ts === + +export interface Event { title: string }; +>Event : Symbol(Event, Decl(event.ts, 0, 0)) +>title : Symbol(Event.title, Decl(event.ts, 1, 24)) + +=== tests/cases/compiler/test.ts === +import { Event } from './event'; +>Event : Symbol(Event, Decl(test.ts, 0, 8)) + +function Input(target: any, key: string): void { } +>Input : Symbol(Input, Decl(test.ts, 0, 32)) +>target : Symbol(target, Decl(test.ts, 1, 15)) +>key : Symbol(key, Decl(test.ts, 1, 27)) + +export class SomeClass { +>SomeClass : Symbol(SomeClass, Decl(test.ts, 1, 50)) + + @Input event: Event; +>Input : Symbol(Input, Decl(test.ts, 0, 32)) +>event : Symbol(SomeClass.event, Decl(test.ts, 2, 24)) +>Event : Symbol(Event, Decl(test.ts, 0, 8)) +} diff --git a/tests/baselines/reference/metadataOfEventAlias.types b/tests/baselines/reference/metadataOfEventAlias.types new file mode 100644 index 00000000000..b644552f9c2 --- /dev/null +++ b/tests/baselines/reference/metadataOfEventAlias.types @@ -0,0 +1,23 @@ +=== tests/cases/compiler/event.ts === + +export interface Event { title: string }; +>Event : Event +>title : string + +=== tests/cases/compiler/test.ts === +import { Event } from './event'; +>Event : any + +function Input(target: any, key: string): void { } +>Input : (target: any, key: string) => void +>target : any +>key : string + +export class SomeClass { +>SomeClass : SomeClass + + @Input event: Event; +>Input : (target: any, key: string) => void +>event : Event +>Event : Event +} diff --git a/tests/cases/compiler/metadataOfEventAlias.ts b/tests/cases/compiler/metadataOfEventAlias.ts new file mode 100644 index 00000000000..c62e1480c89 --- /dev/null +++ b/tests/cases/compiler/metadataOfEventAlias.ts @@ -0,0 +1,14 @@ +// @experimentalDecorators: true +// @emitDecoratorMetadata: true +// @target: es5 +// @includeBuiltFile: lib.d.ts + +// @filename: event.ts +export interface Event { title: string }; + +// @filename: test.ts +import { Event } from './event'; +function Input(target: any, key: string): void { } +export class SomeClass { + @Input event: Event; +} \ No newline at end of file From 679a7ec04f544d05104cc11ba3e6f99da6ac98b2 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 19 Jan 2017 14:27:53 -0800 Subject: [PATCH 06/41] Use the value symbol for decorator purpose only if it is same as typesymbol Fixes #13155 --- src/compiler/checker.ts | 21 +++++++++++-------- .../reference/metadataOfEventAlias.js | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 756a2b2d3b1..ad0a8dbaebb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20518,18 +20518,21 @@ namespace ts { function getTypeReferenceSerializationKind(typeName: EntityName, location?: Node): TypeReferenceSerializationKind { // Resolve the symbol as a value to ensure the type can be reached at runtime during emit. const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location); - const globalPromiseSymbol = tryGetGlobalPromiseConstructorSymbol(); - if (globalPromiseSymbol && valueSymbol === globalPromiseSymbol) { - return TypeReferenceSerializationKind.Promise; - } - - const constructorType = valueSymbol ? getTypeOfSymbol(valueSymbol) : undefined; - if (constructorType && isConstructorType(constructorType)) { - return TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue; - } // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer. const typeSymbol = resolveEntityName(typeName, SymbolFlags.Type, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location); + if (valueSymbol && valueSymbol === typeSymbol) { + const globalPromiseSymbol = tryGetGlobalPromiseConstructorSymbol(); + if (globalPromiseSymbol && valueSymbol === globalPromiseSymbol) { + return TypeReferenceSerializationKind.Promise; + } + + const constructorType = getTypeOfSymbol(valueSymbol); + if (constructorType && isConstructorType(constructorType)) { + return TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue; + } + } + // We might not be able to resolve type symbol so use unknown type in that case (eg error case) if (!typeSymbol) { return TypeReferenceSerializationKind.ObjectType; diff --git a/tests/baselines/reference/metadataOfEventAlias.js b/tests/baselines/reference/metadataOfEventAlias.js index a79a2daa5d9..8a22a90bc2e 100644 --- a/tests/baselines/reference/metadataOfEventAlias.js +++ b/tests/baselines/reference/metadataOfEventAlias.js @@ -33,6 +33,6 @@ var SomeClass = (function () { }()); __decorate([ Input, - __metadata("design:type", event_1.Event) + __metadata("design:type", Object) ], SomeClass.prototype, "event", void 0); exports.SomeClass = SomeClass; From 1c2f7f866bd19d8ebbf3a4fe35b096bf512efba2 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 19 Jan 2017 14:30:53 -0800 Subject: [PATCH 07/41] Improve efficiency of union/intersection resolved property caching --- src/compiler/checker.ts | 40 +++++++++++++++++++--------------------- src/compiler/types.ts | 4 +++- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9cc5fb111cd..1ca1cd9cf74 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4754,28 +4754,26 @@ namespace ts { } function getPropertiesOfUnionOrIntersectionType(type: UnionOrIntersectionType): Symbol[] { - for (const current of type.types) { - for (const prop of getPropertiesOfType(current)) { - getUnionOrIntersectionProperty(type, prop.name); - } - // The properties of a union type are those that are present in all constituent types, so - // we only need to check the properties of the first type - if (type.flags & TypeFlags.Union) { - break; - } - } - const props = type.resolvedProperties; - if (props) { - const result: Symbol[] = []; - props.forEach(prop => { - // We need to filter out partial properties in union types - if (!(prop.flags & SymbolFlags.SyntheticProperty && (prop).isPartial)) { - result.push(prop); + if (!type.resolvedProperties) { + const members = createMap(); + for (const current of type.types) { + for (const prop of getPropertiesOfType(current)) { + if (!members.has(prop.name)) { + const combinedProp = getPropertyOfUnionOrIntersectionType(type, prop.name); + if (combinedProp) { + members.set(prop.name, combinedProp); + } + } } - }); - return result; + // The properties of a union type are those that are present in all constituent types, so + // we only need to check the properties of the first type + if (type.flags & TypeFlags.Union) { + break; + } + } + type.resolvedProperties = getNamedMembers(members); } - return emptyArray; + return type.resolvedProperties; } function getPropertiesOfType(type: Type): Symbol[] { @@ -4943,7 +4941,7 @@ namespace ts { // these partial properties when identifying discriminant properties, but otherwise they are filtered out // and do not appear to be present in the union type. function getUnionOrIntersectionProperty(type: UnionOrIntersectionType, name: string): Symbol { - const properties = type.resolvedProperties || (type.resolvedProperties = createMap()); + const properties = type.propertyCache || (type.propertyCache = createMap()); let property = properties.get(name); if (!property) { property = createUnionOrIntersectionProperty(type, name); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b834d73300a..65cd4031613 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2948,7 +2948,9 @@ export interface UnionOrIntersectionType extends Type { types: Type[]; // Constituent types /* @internal */ - resolvedProperties: SymbolTable; // Cache of resolved properties + propertyCache: SymbolTable; // Cache of resolved properties + /* @internal */ + resolvedProperties: Symbol[]; /* @internal */ resolvedIndexType: IndexType; /* @internal */ From c51e2867f50de63db151310da03b829d667becc9 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 19 Jan 2017 14:47:26 -0800 Subject: [PATCH 08/41] Allow object intersection types in class implements clauses --- src/compiler/checker.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1ca1cd9cf74..450fcfe1da4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18411,8 +18411,7 @@ namespace ts { if (produceDiagnostics) { const t = getTypeFromTypeNode(typeRefNode); if (t !== unknownType) { - const declaredType = getObjectFlags(t) & ObjectFlags.Reference ? (t).target : t; - if (getObjectFlags(declaredType) & ObjectFlags.ClassOrInterface) { + if (isValidBaseType(t)) { checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(t, type.thisType), node.name || node, Diagnostics.Class_0_incorrectly_implements_interface_1); } else { From f9a65e436c67b1da2e0a80274e1fba5a9afc6d61 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 19 Jan 2017 14:47:38 -0800 Subject: [PATCH 09/41] Accept new baselines --- .../reference/typeAliasesForObjectTypes.errors.txt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/baselines/reference/typeAliasesForObjectTypes.errors.txt b/tests/baselines/reference/typeAliasesForObjectTypes.errors.txt index d5bc01f93ba..b4ae5978049 100644 --- a/tests/baselines/reference/typeAliasesForObjectTypes.errors.txt +++ b/tests/baselines/reference/typeAliasesForObjectTypes.errors.txt @@ -1,19 +1,13 @@ -tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(4,22): error TS2312: An interface may only extend a class or another interface. -tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(5,21): error TS2422: A class may only implement another class or interface. tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(10,6): error TS2300: Duplicate identifier 'T2'. tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(11,6): error TS2300: Duplicate identifier 'T2'. -==== tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts (4 errors) ==== +==== tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts (2 errors) ==== type T1 = { x: string } // An interface can be named in an extends or implements clause, but a type alias for an object type literal cannot. interface I1 extends T1 { y: string } - ~~ -!!! error TS2312: An interface may only extend a class or another interface. class C1 implements T1 { - ~~ -!!! error TS2422: A class may only implement another class or interface. x: string; } From d11d03a06c189ffc744914e9c961c4875afea6bd Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 19 Jan 2017 17:36:16 -0800 Subject: [PATCH 10/41] Fix https://github.com/DefinitelyTyped/DefinitelyTyped/issues/14036: Remove assert. --- src/compiler/checker.ts | 1 - .../reference/mergedDeclarations7.errors.txt | 32 +++++++++++++++++++ .../reference/mergedDeclarations7.js | 28 ++++++++++++++++ tests/cases/compiler/mergedDeclarations7.ts | 21 ++++++++++++ 4 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/mergedDeclarations7.errors.txt create mode 100644 tests/baselines/reference/mergedDeclarations7.js create mode 100644 tests/cases/compiler/mergedDeclarations7.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 756a2b2d3b1..a376e091ca3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4172,7 +4172,6 @@ namespace ts { } function getDeclaredTypeOfSymbol(symbol: Symbol): Type { - Debug.assert((symbol.flags & SymbolFlags.Instantiated) === 0); if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { return getDeclaredTypeOfClassOrInterface(symbol); } diff --git a/tests/baselines/reference/mergedDeclarations7.errors.txt b/tests/baselines/reference/mergedDeclarations7.errors.txt new file mode 100644 index 00000000000..cd9b3a5e939 --- /dev/null +++ b/tests/baselines/reference/mergedDeclarations7.errors.txt @@ -0,0 +1,32 @@ +tests/cases/compiler/test.ts(4,5): error TS2322: Type 'PassportStatic' is not assignable to type 'Passport'. + Types of property 'use' are incompatible. + Type '() => PassportStatic' is not assignable to type '() => this'. + Type 'PassportStatic' is not assignable to type 'this'. + + +==== tests/cases/compiler/passport.d.ts (0 errors) ==== + declare module 'passport' { + namespace passport { + interface Passport { + use(): this; + } + + interface PassportStatic extends Passport { + Passport: {new(): Passport}; + } + } + + const passport: passport.PassportStatic; + export = passport; + } + +==== tests/cases/compiler/test.ts (1 errors) ==== + import * as passport from "passport"; + import { Passport } from "passport"; + + let p: Passport = passport.use(); + ~ +!!! error TS2322: Type 'PassportStatic' is not assignable to type 'Passport'. +!!! error TS2322: Types of property 'use' are incompatible. +!!! error TS2322: Type '() => PassportStatic' is not assignable to type '() => this'. +!!! error TS2322: Type 'PassportStatic' is not assignable to type 'this'. \ No newline at end of file diff --git a/tests/baselines/reference/mergedDeclarations7.js b/tests/baselines/reference/mergedDeclarations7.js new file mode 100644 index 00000000000..e3d1ddc6e0e --- /dev/null +++ b/tests/baselines/reference/mergedDeclarations7.js @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/mergedDeclarations7.ts] //// + +//// [passport.d.ts] +declare module 'passport' { + namespace passport { + interface Passport { + use(): this; + } + + interface PassportStatic extends Passport { + Passport: {new(): Passport}; + } + } + + const passport: passport.PassportStatic; + export = passport; +} + +//// [test.ts] +import * as passport from "passport"; +import { Passport } from "passport"; + +let p: Passport = passport.use(); + +//// [test.js] +"use strict"; +var passport = require("passport"); +var p = passport.use(); diff --git a/tests/cases/compiler/mergedDeclarations7.ts b/tests/cases/compiler/mergedDeclarations7.ts new file mode 100644 index 00000000000..fc0945f4419 --- /dev/null +++ b/tests/cases/compiler/mergedDeclarations7.ts @@ -0,0 +1,21 @@ +// @filename: passport.d.ts +declare module 'passport' { + namespace passport { + interface Passport { + use(): this; + } + + interface PassportStatic extends Passport { + Passport: {new(): Passport}; + } + } + + const passport: passport.PassportStatic; + export = passport; +} + +//@filename: test.ts +import * as passport from "passport"; +import { Passport } from "passport"; + +let p: Passport = passport.use(); \ No newline at end of file From 21c2c0e78607cab6fac463b8b227d63189f1306f Mon Sep 17 00:00:00 2001 From: falsandtru Date: Fri, 20 Jan 2017 23:05:45 +0900 Subject: [PATCH 11/41] Fix regressions --- src/lib/es2015.collection.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/es2015.collection.d.ts b/src/lib/es2015.collection.d.ts index 6a2c43cd050..75a11b5eb17 100644 --- a/src/lib/es2015.collection.d.ts +++ b/src/lib/es2015.collection.d.ts @@ -4,7 +4,7 @@ interface Map { 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; + set(key: K, value: V): this; readonly size: number; } @@ -26,7 +26,7 @@ interface WeakMap { delete(key: K): boolean; get(key: K): V | undefined; has(key: K): boolean; - set(key: K, value?: V): this; + set(key: K, value: V): this; } interface WeakMapConstructor { From a9af10b030d2167ad7612a98df28f4084e95a005 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 20 Jan 2017 06:16:08 -0800 Subject: [PATCH 12/41] Intersections as their own 'this' type --- src/compiler/checker.ts | 16 ++++++++++++---- src/compiler/core.ts | 4 ++++ src/compiler/types.ts | 5 ++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 450fcfe1da4..6de1b5aa624 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4326,10 +4326,13 @@ namespace ts { function getTypeWithThisArgument(type: Type, thisArgument?: Type): Type { if (getObjectFlags(type) & ObjectFlags.Reference) { - return createTypeReference((type).target, - concatenate((type).typeArguments, [thisArgument || (type).target.thisType])); + const target = (type).target; + const typeArguments = (type).typeArguments; + if (length(target.typeParameters) === length(typeArguments)) { + return createTypeReference(target, concatenate(typeArguments, [thisArgument || target.thisType])); + } } - if (type.flags & TypeFlags.Intersection) { + else if (type.flags & TypeFlags.Intersection) { return getIntersectionType(map((type).types, t => getTypeWithThisArgument(t, thisArgument))); } return type; @@ -4858,6 +4861,10 @@ namespace ts { } } + function getApparentTypeOfIntersectionType(type: IntersectionType) { + return type.resolvedIndexType || (type.resolvedApparentType = getTypeWithThisArgument(type, type)); + } + /** * For a type parameter, return the base constraint of the type parameter. For the string, number, * boolean, and symbol primitive types, return the corresponding object types. Otherwise return the @@ -4865,7 +4872,8 @@ namespace ts { */ function getApparentType(type: Type): Type { const t = type.flags & TypeFlags.TypeVariable ? getBaseConstraintOfType(type) || emptyObjectType : type; - return t.flags & TypeFlags.StringLike ? globalStringType : + return t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(type) : + t.flags & TypeFlags.StringLike ? globalStringType : t.flags & TypeFlags.NumberLike ? globalNumberType : t.flags & TypeFlags.BooleanLike ? globalBooleanType : t.flags & TypeFlags.ESSymbol ? getGlobalESSymbolType() : diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 654b1bc2912..47a6e2e70a8 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -202,6 +202,10 @@ namespace ts { GreaterThan = 1 } + export function length(array: any[]) { + return array ? array.length : 0; + } + /** * 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. diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 65cd4031613..6b5c670a9fa 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2961,7 +2961,10 @@ export interface UnionType extends UnionOrIntersectionType { } - export interface IntersectionType extends UnionOrIntersectionType { } + export interface IntersectionType extends UnionOrIntersectionType { + /* @internal */ + resolvedApparentType: Type; + } export type StructuredType = ObjectType | UnionType | IntersectionType; From 1267fd3030a588eb29dcf7ad0e4bb3c8887a59fb Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Fri, 20 Jan 2017 06:41:57 -0800 Subject: [PATCH 13/41] Don't use nameTable for type keywords, and don't handle keyof. --- src/services/findAllReferences.ts | 4 +--- src/services/services.ts | 17 ++++------------- src/services/utilities.ts | 3 +-- tests/cases/fourslash/findAllRefsPrimitive.ts | 2 -- 4 files changed, 6 insertions(+), 20 deletions(-) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 68eb684fe25..82a5da453b7 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -353,9 +353,7 @@ namespace ts.FindAllReferences { const references: ReferenceEntry[] = []; for (const sourceFile of sourceFiles) { cancellationToken.throwIfCancellationRequested(); - if (sourceFileHasName(sourceFile, name)) { - addReferencesForKeywordInFile(sourceFile, keywordKind, name, cancellationToken, references); - } + addReferencesForKeywordInFile(sourceFile, keywordKind, name, cancellationToken, references); } return [{ definition, references }]; diff --git a/src/services/services.ts b/src/services/services.ts index 20204165328..1fe2235a4ba 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1975,20 +1975,11 @@ namespace ts { setNameTable((node).text, node); } break; - case SyntaxKind.TypeOperator: - setNameTable(tokenToString((node as ts.TypeOperatorNode).operator), node); - forEachChild(node, walk); - break; default: - if (isTypeKeyword(node.kind)) { - setNameTable(tokenToString(node.kind), node); - } - else { - forEachChild(node, walk); - if (node.jsDoc) { - for (const jsDoc of node.jsDoc) { - forEachChild(jsDoc, walk); - } + forEachChild(node, walk); + if (node.jsDoc) { + for (const jsDoc of node.jsDoc) { + forEachChild(jsDoc, walk); } } } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index dd337238da3..a1680da69c3 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1,4 +1,4 @@ -// These utilities are common to multiple language service features. +// These utilities are common to multiple language service features. /* @internal */ namespace ts { export const scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); @@ -1126,7 +1126,6 @@ namespace ts { case SyntaxKind.BooleanKeyword: case SyntaxKind.NeverKeyword: case SyntaxKind.NumberKeyword: - case SyntaxKind.KeyOfKeyword: case SyntaxKind.ObjectKeyword: case SyntaxKind.StringKeyword: case SyntaxKind.SymbolKeyword: diff --git a/tests/cases/fourslash/findAllRefsPrimitive.ts b/tests/cases/fourslash/findAllRefsPrimitive.ts index 9bd3d62eabb..51c463843e1 100644 --- a/tests/cases/fourslash/findAllRefsPrimitive.ts +++ b/tests/cases/fourslash/findAllRefsPrimitive.ts @@ -21,8 +21,6 @@ ////function v(v: [|void|]): [|void|]; -////function k(x: [|keyof|] Date): [|keyof|] Date; - // @Filename: b.ts // const z: [|any|] = 0; From c16c7d56c0a4e9f7e11dd134cffcdbb1eef5916c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 20 Jan 2017 09:17:14 -0800 Subject: [PATCH 14/41] Allow base constructor types to be intersections --- src/compiler/checker.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6de1b5aa624..a5058bdf7f2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3810,7 +3810,7 @@ namespace ts { } function isConstructorType(type: Type): boolean { - return type.flags & TypeFlags.Object && getSignaturesOfType(type, SignatureKind.Construct).length > 0; + return isValidBaseType(type) && getSignaturesOfType(type, SignatureKind.Construct).length > 0; } function getBaseTypeNodeOfClass(type: InterfaceType): ExpressionWithTypeArguments { @@ -3849,7 +3849,7 @@ namespace ts { return unknownType; } const baseConstructorType = checkExpression(baseTypeNode.expression); - if (baseConstructorType.flags & TypeFlags.Object) { + if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection)) { // Resolving the members of a class requires us to resolve the base class of that class. // We force resolution here such that we catch circularities now. resolveStructuredTypeMembers(baseConstructorType); @@ -3890,7 +3890,7 @@ namespace ts { function resolveBaseTypesOfClass(type: InterfaceType): void { type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray; const baseConstructorType = getBaseConstructorTypeOfClass(type); - if (!(baseConstructorType.flags & TypeFlags.Object)) { + if (!(baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection))) { return; } const baseTypeNode = getBaseTypeNodeOfClass(type); @@ -4591,9 +4591,9 @@ namespace ts { constructSignatures = getDefaultConstructSignatures(classType); } const baseConstructorType = getBaseConstructorTypeOfClass(classType); - if (baseConstructorType.flags & TypeFlags.Object) { + if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection)) { members = createSymbolTable(getNamedMembers(members)); - addInheritedMembers(members, getPropertiesOfObjectType(baseConstructorType)); + addInheritedMembers(members, getPropertiesOfType(baseConstructorType)); } } const numberIndexInfo = symbol.flags & SymbolFlags.Enum ? enumNumberIndexInfo : undefined; From 1183129bda17ff969334b1f1a055d463f8028535 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 20 Jan 2017 10:17:11 -0800 Subject: [PATCH 15/41] getFirstToken returns jsdoc as single comment This is a bit odd, but it's the way that 2.0 and earlier behaved. 2.1 broke it. --- src/compiler/types.ts | 2 +- src/harness/unittests/jsDocParsing.ts | 14 ++++++++++++++ src/services/services.ts | 9 ++++++--- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 51347c8d3df..f0e20ecd4bf 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -421,7 +421,7 @@ LastBinaryOperator = CaretEqualsToken, FirstNode = QualifiedName, FirstJSDocNode = JSDocTypeExpression, - LastJSDocNode = JSDocLiteralType, + LastJSDocNode = JSDocNeverKeyword, FirstJSDocTagNode = JSDocComment, LastJSDocTagNode = JSDocNeverKeyword } diff --git a/src/harness/unittests/jsDocParsing.ts b/src/harness/unittests/jsDocParsing.ts index addd01b0e0a..3cafc9d49ae 100644 --- a/src/harness/unittests/jsDocParsing.ts +++ b/src/harness/unittests/jsDocParsing.ts @@ -288,5 +288,19 @@ namespace ts { */`); }); }); + describe("getFirstToken", () => { + it("gets jsdoc", () => { + const first = ts.createSourceFile("foo.ts", "/** comment */var a = true;", ts.ScriptTarget.ES5, /*setParentNodes*/ true); + assert.isDefined(first); + assert.equal(first.kind, 263); + }); + }); + describe("getLastToken", () => { + it("gets jsdoc", () => { + const last = ts.createSourceFile("foo.ts", "var a = true;/** comment */", ts.ScriptTarget.ES5, /*setParentNodes*/ true); + assert.isDefined(last); + assert.equal(last.kind, 263); + }); + }); }); } diff --git a/src/services/services.ts b/src/services/services.ts index 26374eccbfd..cdd789166bc 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -194,8 +194,9 @@ namespace ts { } const child = children[0]; - - return child.kind < SyntaxKind.FirstNode ? child : child.getFirstToken(sourceFile); + return child.kind < SyntaxKind.FirstNode || SyntaxKind.FirstJSDocNode <= child.kind && child.kind <= SyntaxKind.LastJSDocNode ? + child : + child.getFirstToken(sourceFile); } public getLastToken(sourceFile?: SourceFile): Node { @@ -206,7 +207,9 @@ namespace ts { return undefined; } - return child.kind < SyntaxKind.FirstNode ? child : child.getLastToken(sourceFile); + return child.kind < SyntaxKind.FirstNode || SyntaxKind.FirstJSDocNode <= child.kind && child.kind <= SyntaxKind.LastJSDocNode ? + child : + child.getLastToken(sourceFile); } } From 8886cefe58c4674589f8f96067effcbb3dc77aa8 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Fri, 20 Jan 2017 08:12:00 -0800 Subject: [PATCH 16/41] Clean up code for getting emitted files --- src/compiler/emitter.ts | 4 +- src/compiler/program.ts | 2 +- src/compiler/utilities.ts | 186 +++++------------- .../reference/noBundledEmitFromNodeModules.js | 20 ++ .../noBundledEmitFromNodeModules.symbols | 9 + .../noBundledEmitFromNodeModules.types | 9 + .../compiler/noBundledEmitFromNodeModules.ts | 10 + 7 files changed, 98 insertions(+), 142 deletions(-) create mode 100644 tests/baselines/reference/noBundledEmitFromNodeModules.js create mode 100644 tests/baselines/reference/noBundledEmitFromNodeModules.symbols create mode 100644 tests/baselines/reference/noBundledEmitFromNodeModules.types create mode 100644 tests/cases/compiler/noBundledEmitFromNodeModules.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 2ff342138c8..1c4662fa587 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -73,7 +73,7 @@ namespace ts { // Emit each output file performance.mark("beforePrint"); - forEachTransformedEmitFile(host, transformed, emitFile, emitOnlyDtsFiles); + forEachEmittedFile(host, transformed, emitFile, emitOnlyDtsFiles); performance.measure("printTime", "beforePrint"); // Clean up emit nodes on parse tree @@ -88,7 +88,7 @@ namespace ts { sourceMaps: sourceMapDataList }; - function emitFile(jsFilePath: string, sourceMapFilePath: string, declarationFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) { + function emitFile({ jsFilePath, sourceMapFilePath, declarationFilePath }: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean) { // Make sure not to write js file and source map file if any of them cannot be written if (!host.isEmitBlocked(jsFilePath) && !compilerOptions.noEmit) { if (!emitOnlyDtsFiles) { diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 324a21f229e..851e206d448 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -439,7 +439,7 @@ namespace ts { function getCommonSourceDirectory() { if (commonSourceDirectory === undefined) { - const emittedFiles = filterSourceFilesInDirectory(files, isSourceFileFromExternalLibrary); + const emittedFiles = filter(files, file => sourceFileMayBeEmitted(file, options, isSourceFileFromExternalLibrary)); if (options.rootDir && checkSourceFilesBelongToPath(emittedFiles, options.rootDir)) { // If a rootDir is specified and is valid use it as the commonSourceDirectory commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, currentDirectory); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 932e75d0345..f59d384e490 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2568,108 +2568,25 @@ namespace ts { * @param host An EmitHost. * @param targetSourceFile An optional target source file to emit. */ - export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFile) { + export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFile): SourceFile[] { const options = host.getCompilerOptions(); + const isSourceFileFromExternalLibrary = (file: SourceFile) => host.isSourceFileFromExternalLibrary(file); if (options.outFile || options.out) { const moduleKind = getEmitModuleKind(options); const moduleEmitEnabled = moduleKind === ModuleKind.AMD || moduleKind === ModuleKind.System; - const sourceFiles = getAllEmittableSourceFiles(); // Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified - return filter(sourceFiles, moduleEmitEnabled ? isNonDeclarationFile : isBundleEmitNonExternalModule); + return filter(host.getSourceFiles(), sourceFile => + (moduleEmitEnabled || !isExternalModule(sourceFile)) && sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary)); } else { - const sourceFiles = targetSourceFile === undefined ? getAllEmittableSourceFiles() : [targetSourceFile]; - return filterSourceFilesInDirectory(sourceFiles, file => host.isSourceFileFromExternalLibrary(file)); - } - - function getAllEmittableSourceFiles() { - return options.noEmitForJsFiles ? filter(host.getSourceFiles(), sourceFile => !isSourceFileJavaScript(sourceFile)) : host.getSourceFiles(); + const sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile]; + return filter(sourceFiles, sourceFile => sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary)); } } - /** Don't call this for `--outFile`, just for `--outDir` or plain emit. */ - export function filterSourceFilesInDirectory(sourceFiles: SourceFile[], isSourceFileFromExternalLibrary: (file: SourceFile) => boolean): SourceFile[] { - return filter(sourceFiles, file => shouldEmitInDirectory(file, isSourceFileFromExternalLibrary)); - } - - function isNonDeclarationFile(sourceFile: SourceFile) { - return !isDeclarationFile(sourceFile); - } - - /** - * Whether a file should be emitted in a non-`--outFile` case. - * Don't emit if source file is a declaration file, or was located under node_modules - */ - function shouldEmitInDirectory(sourceFile: SourceFile, isSourceFileFromExternalLibrary: (file: SourceFile) => boolean): boolean { - return isNonDeclarationFile(sourceFile) && !isSourceFileFromExternalLibrary(sourceFile); - } - - function isBundleEmitNonExternalModule(sourceFile: SourceFile) { - return isNonDeclarationFile(sourceFile) && !isExternalModule(sourceFile); - } - - /** - * Iterates over each source file to emit. The source files are expected to have been - * transformed for use by the pretty printer. - * - * Originally part of `forEachExpectedEmitFile`, this functionality was extracted to support - * transformations. - * - * @param host An EmitHost. - * @param sourceFiles The transformed source files to emit. - * @param action The action to execute. - */ - export function forEachTransformedEmitFile(host: EmitHost, sourceFiles: SourceFile[], - action: (jsFilePath: string, sourceMapFilePath: string, declarationFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) => void, - emitOnlyDtsFiles?: boolean) { - const options = host.getCompilerOptions(); - // Emit on each source file - if (options.outFile || options.out) { - onBundledEmit(sourceFiles); - } - else { - for (const sourceFile of sourceFiles) { - // Don't emit if source file is a declaration file, or was located under node_modules - if (!isDeclarationFile(sourceFile) && !host.isSourceFileFromExternalLibrary(sourceFile)) { - onSingleFileEmit(host, sourceFile); - } - } - } - - function onSingleFileEmit(host: EmitHost, sourceFile: SourceFile) { - // JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also. - // So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve. - // For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve - let extension = ".js"; - if (options.jsx === JsxEmit.Preserve) { - if (isSourceFileJavaScript(sourceFile)) { - if (fileExtensionIs(sourceFile.fileName, ".jsx")) { - extension = ".jsx"; - } - } - else if (sourceFile.languageVariant === LanguageVariant.JSX) { - // TypeScript source file preserving JSX syntax - extension = ".jsx"; - } - } - const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, extension); - const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); - const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (options.declaration || emitOnlyDtsFiles) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined; - action(jsFilePath, sourceMapFilePath, declarationFilePath, [sourceFile], /*isBundledEmit*/ false); - } - - function onBundledEmit(sourceFiles: SourceFile[]) { - if (sourceFiles.length) { - const jsFilePath = options.outFile || options.out; - const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); - const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined; - action(jsFilePath, sourceMapFilePath, declarationFilePath, sourceFiles, /*isBundledEmit*/ true); - } - } - } - - function getSourceMapFilePath(jsFilePath: string, options: CompilerOptions) { - return options.sourceMap ? jsFilePath + ".map" : undefined; + /** Don't call this for `--outFile`, just for `--outDir` or plain emit. `--outFile` needs additional checks. */ + export function sourceFileMayBeEmitted(sourceFile: SourceFile, options: CompilerOptions, isSourceFileFromExternalLibrary: (file: SourceFile) => boolean) { + return !(options.noEmitForJsFiles && isSourceFileJavaScript(sourceFile)) && !isDeclarationFile(sourceFile) && !isSourceFileFromExternalLibrary(sourceFile); } /** @@ -2685,64 +2602,55 @@ namespace ts { action: (emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean) => void, targetSourceFile?: SourceFile, emitOnlyDtsFiles?: boolean) { + forEachEmittedFile(host, getSourceFilesToEmit(host, targetSourceFile), action, emitOnlyDtsFiles); + } + + /** + * Iterates over each source file to emit. + */ + export function forEachEmittedFile(host: EmitHost, sourceFiles: SourceFile[], + action: (emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean) => void, + emitOnlyDtsFiles?: boolean) { const options = host.getCompilerOptions(); - // Emit on each source file if (options.outFile || options.out) { - onBundledEmit(host); + if (sourceFiles.length) { + const jsFilePath = options.outFile || options.out; + const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); + const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined; + action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFiles, /*isBundledEmit*/true, emitOnlyDtsFiles); + } } else { - const sourceFiles = targetSourceFile === undefined ? getSourceFilesToEmit(host) : [targetSourceFile]; for (const sourceFile of sourceFiles) { - if (shouldEmitInDirectory(sourceFile, file => host.isSourceFileFromExternalLibrary(file))) { - onSingleFileEmit(host, sourceFile); - } + const options = host.getCompilerOptions(); + const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options)); + const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); + const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined; + action({ jsFilePath, sourceMapFilePath, declarationFilePath }, [sourceFile], /*isBundledEmit*/false, emitOnlyDtsFiles); } } + } - function onSingleFileEmit(host: EmitHost, sourceFile: SourceFile) { - // JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also. - // So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve. - // For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve - let extension = ".js"; - if (options.jsx === JsxEmit.Preserve) { - if (isSourceFileJavaScript(sourceFile)) { - if (fileExtensionIs(sourceFile.fileName, ".jsx")) { - extension = ".jsx"; - } - } - else if (sourceFile.languageVariant === LanguageVariant.JSX) { - // TypeScript source file preserving JSX syntax - extension = ".jsx"; - } - } - const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, extension); - const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined; - const emitFileNames: EmitFileNames = { - jsFilePath, - sourceMapFilePath: getSourceMapFilePath(jsFilePath, options), - declarationFilePath - }; - action(emitFileNames, [sourceFile], /*isBundledEmit*/false, emitOnlyDtsFiles); - } + function getSourceMapFilePath(jsFilePath: string, options: CompilerOptions) { + return options.sourceMap ? jsFilePath + ".map" : undefined; + } - function onBundledEmit(host: EmitHost) { - // Can emit only sources that are not declaration file and are either non module code or module with - // --module or --target es6 specified. Files included by searching under node_modules are also not emitted. - const bundledSources = filter(getSourceFilesToEmit(host), - sourceFile => !isDeclarationFile(sourceFile) && - !host.isSourceFileFromExternalLibrary(sourceFile) && - (!isExternalModule(sourceFile) || - !!getEmitModuleKind(options))); - if (bundledSources.length) { - const jsFilePath = options.outFile || options.out; - const emitFileNames: EmitFileNames = { - jsFilePath, - sourceMapFilePath: getSourceMapFilePath(jsFilePath, options), - declarationFilePath: options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined - }; - action(emitFileNames, bundledSources, /*isBundledEmit*/true, emitOnlyDtsFiles); + // JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also. + // So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve. + // For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve + function getOutputExtension(sourceFile: SourceFile, options: CompilerOptions): string { + if (options.jsx === JsxEmit.Preserve) { + if (isSourceFileJavaScript(sourceFile)) { + if (fileExtensionIs(sourceFile.fileName, ".jsx")) { + return ".jsx"; + } + } + else if (sourceFile.languageVariant === LanguageVariant.JSX) { + // TypeScript source file preserving JSX syntax + return ".jsx"; } } + return ".js"; } export function getSourceFilePathInNewDir(sourceFile: SourceFile, host: EmitHost, newDirPath: string) { diff --git a/tests/baselines/reference/noBundledEmitFromNodeModules.js b/tests/baselines/reference/noBundledEmitFromNodeModules.js new file mode 100644 index 00000000000..67216a408af --- /dev/null +++ b/tests/baselines/reference/noBundledEmitFromNodeModules.js @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/noBundledEmitFromNodeModules.ts] //// + +//// [index.ts] + +export class C {} + +//// [a.ts] +import { C } from "projB"; + + +//// [out.js] +System.register("a", [], function (exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + return { + setters: [], + execute: function () { + } + }; +}); diff --git a/tests/baselines/reference/noBundledEmitFromNodeModules.symbols b/tests/baselines/reference/noBundledEmitFromNodeModules.symbols new file mode 100644 index 00000000000..a1f6c67e4b4 --- /dev/null +++ b/tests/baselines/reference/noBundledEmitFromNodeModules.symbols @@ -0,0 +1,9 @@ +=== /a.ts === +import { C } from "projB"; +>C : Symbol(C, Decl(a.ts, 0, 8)) + +=== /node_modules/projB/index.ts === + +export class C {} +>C : Symbol(C, Decl(index.ts, 0, 0)) + diff --git a/tests/baselines/reference/noBundledEmitFromNodeModules.types b/tests/baselines/reference/noBundledEmitFromNodeModules.types new file mode 100644 index 00000000000..a11bad24aaf --- /dev/null +++ b/tests/baselines/reference/noBundledEmitFromNodeModules.types @@ -0,0 +1,9 @@ +=== /a.ts === +import { C } from "projB"; +>C : typeof C + +=== /node_modules/projB/index.ts === + +export class C {} +>C : C + diff --git a/tests/cases/compiler/noBundledEmitFromNodeModules.ts b/tests/cases/compiler/noBundledEmitFromNodeModules.ts new file mode 100644 index 00000000000..66c71a58489 --- /dev/null +++ b/tests/cases/compiler/noBundledEmitFromNodeModules.ts @@ -0,0 +1,10 @@ +// @outFile: out.js +// @module: system +// @moduleResolution: node +// @noImplicitReferences: true + +// @fileName: /node_modules/projB/index.ts +export class C {} + +// @fileName: /a.ts +import { C } from "projB"; From 108d8cf584406824a569cc4b18428d5dc26cbdd1 Mon Sep 17 00:00:00 2001 From: Basarat Ali Syed Date: Sat, 21 Jan 2017 11:36:18 +1100 Subject: [PATCH 17/41] export the type `Log` that is used by exported functions closes https://github.com/Microsoft/TypeScript/issues/13559 --- src/services/completions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index d6d3a9ce060..5a08dbcb9c8 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1,6 +1,6 @@ /* @internal */ namespace ts.Completions { - type Log = (message: string) => void; + export type Log = (message: string) => void; export function getCompletionsAtPosition(host: LanguageServiceHost, typeChecker: TypeChecker, log: Log, compilerOptions: CompilerOptions, sourceFile: SourceFile, position: number): CompletionInfo | undefined { if (isInReferenceComment(sourceFile, position)) { From 4ee8213dde3a08b29d3add176cae92bdb20c5415 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Fri, 20 Jan 2017 19:59:26 -0800 Subject: [PATCH 18/41] do not capture 'arguments' when property name 'arguments' is met (#13600) do not capture 'arguments' when property name 'arguments' is met --- src/compiler/checker.ts | 3 +- src/compiler/transformers/es2015.ts | 2 +- .../reference/argumentsAsPropertyName.js | 29 ++++++++++ .../reference/argumentsAsPropertyName.symbols | 43 ++++++++++++++ .../reference/argumentsAsPropertyName.types | 57 +++++++++++++++++++ .../cases/compiler/argumentsAsPropertyName.ts | 15 +++++ 6 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/argumentsAsPropertyName.js create mode 100644 tests/baselines/reference/argumentsAsPropertyName.symbols create mode 100644 tests/baselines/reference/argumentsAsPropertyName.types create mode 100644 tests/cases/compiler/argumentsAsPropertyName.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a1ad9f0344d..5f80444c73e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20222,7 +20222,8 @@ namespace ts { if (!isGeneratedIdentifier(node)) { node = getParseTreeNode(node, isIdentifier); if (node) { - return getReferencedValueSymbol(node) === argumentsSymbol; + const isPropertyName = node.parent.kind === SyntaxKind.PropertyAccessExpression && (node.parent).name === node; + return !isPropertyName && getReferencedValueSymbol(node) === argumentsSymbol; } } diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index d0b9ef7455f..d1dab8eeb7a 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -585,7 +585,7 @@ namespace ts { if (isGeneratedIdentifier(node)) { return node; } - if (node.text !== "arguments" && !resolver.isArgumentsLocalBinding(node)) { + if (node.text !== "arguments" || !resolver.isArgumentsLocalBinding(node)) { return node; } return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = createUniqueName("arguments")); diff --git a/tests/baselines/reference/argumentsAsPropertyName.js b/tests/baselines/reference/argumentsAsPropertyName.js new file mode 100644 index 00000000000..a4197c0a1d2 --- /dev/null +++ b/tests/baselines/reference/argumentsAsPropertyName.js @@ -0,0 +1,29 @@ +//// [argumentsAsPropertyName.ts] +// target: es5 +type MyType = { + arguments: Array +} + +declare function use(s: any); + +function myFunction(myType: MyType) { + for (let i = 0; i < 10; i++) { + use(myType.arguments[i]); + // create closure so that tsc will turn loop body into function + const x = 5; + [1, 2, 3].forEach(function(j) { use(x); }) + } +} + +//// [argumentsAsPropertyName.js] +function myFunction(myType) { + var _loop_1 = function (i) { + use(myType.arguments[i]); + // create closure so that tsc will turn loop body into function + var x = 5; + [1, 2, 3].forEach(function (j) { use(x); }); + }; + for (var i = 0; i < 10; i++) { + _loop_1(i); + } +} diff --git a/tests/baselines/reference/argumentsAsPropertyName.symbols b/tests/baselines/reference/argumentsAsPropertyName.symbols new file mode 100644 index 00000000000..1e3e41abb6e --- /dev/null +++ b/tests/baselines/reference/argumentsAsPropertyName.symbols @@ -0,0 +1,43 @@ +=== tests/cases/compiler/argumentsAsPropertyName.ts === +// target: es5 +type MyType = { +>MyType : Symbol(MyType, Decl(argumentsAsPropertyName.ts, 0, 0)) + + arguments: Array +>arguments : Symbol(arguments, Decl(argumentsAsPropertyName.ts, 1, 15)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +} + +declare function use(s: any); +>use : Symbol(use, Decl(argumentsAsPropertyName.ts, 3, 1)) +>s : Symbol(s, Decl(argumentsAsPropertyName.ts, 5, 21)) + +function myFunction(myType: MyType) { +>myFunction : Symbol(myFunction, Decl(argumentsAsPropertyName.ts, 5, 29)) +>myType : Symbol(myType, Decl(argumentsAsPropertyName.ts, 7, 20)) +>MyType : Symbol(MyType, Decl(argumentsAsPropertyName.ts, 0, 0)) + + for (let i = 0; i < 10; i++) { +>i : Symbol(i, Decl(argumentsAsPropertyName.ts, 8, 12)) +>i : Symbol(i, Decl(argumentsAsPropertyName.ts, 8, 12)) +>i : Symbol(i, Decl(argumentsAsPropertyName.ts, 8, 12)) + + use(myType.arguments[i]); +>use : Symbol(use, Decl(argumentsAsPropertyName.ts, 3, 1)) +>myType.arguments : Symbol(arguments, Decl(argumentsAsPropertyName.ts, 1, 15)) +>myType : Symbol(myType, Decl(argumentsAsPropertyName.ts, 7, 20)) +>arguments : Symbol(arguments, Decl(argumentsAsPropertyName.ts, 1, 15)) +>i : Symbol(i, Decl(argumentsAsPropertyName.ts, 8, 12)) + + // create closure so that tsc will turn loop body into function + const x = 5; +>x : Symbol(x, Decl(argumentsAsPropertyName.ts, 11, 13)) + + [1, 2, 3].forEach(function(j) { use(x); }) +>[1, 2, 3].forEach : Symbol(Array.forEach, Decl(lib.d.ts, --, --)) +>forEach : Symbol(Array.forEach, Decl(lib.d.ts, --, --)) +>j : Symbol(j, Decl(argumentsAsPropertyName.ts, 12, 35)) +>use : Symbol(use, Decl(argumentsAsPropertyName.ts, 3, 1)) +>x : Symbol(x, Decl(argumentsAsPropertyName.ts, 11, 13)) + } +} diff --git a/tests/baselines/reference/argumentsAsPropertyName.types b/tests/baselines/reference/argumentsAsPropertyName.types new file mode 100644 index 00000000000..d0aaaa1cc72 --- /dev/null +++ b/tests/baselines/reference/argumentsAsPropertyName.types @@ -0,0 +1,57 @@ +=== tests/cases/compiler/argumentsAsPropertyName.ts === +// target: es5 +type MyType = { +>MyType : MyType + + arguments: Array +>arguments : string[] +>Array : T[] +} + +declare function use(s: any); +>use : (s: any) => any +>s : any + +function myFunction(myType: MyType) { +>myFunction : (myType: MyType) => void +>myType : MyType +>MyType : MyType + + for (let i = 0; i < 10; i++) { +>i : number +>0 : 0 +>i < 10 : boolean +>i : number +>10 : 10 +>i++ : number +>i : number + + use(myType.arguments[i]); +>use(myType.arguments[i]) : any +>use : (s: any) => any +>myType.arguments[i] : string +>myType.arguments : string[] +>myType : MyType +>arguments : string[] +>i : number + + // create closure so that tsc will turn loop body into function + const x = 5; +>x : 5 +>5 : 5 + + [1, 2, 3].forEach(function(j) { use(x); }) +>[1, 2, 3].forEach(function(j) { use(x); }) : void +>[1, 2, 3].forEach : (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void +>[1, 2, 3] : number[] +>1 : 1 +>2 : 2 +>3 : 3 +>forEach : (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void +>function(j) { use(x); } : (j: number) => void +>j : number +>use(x) : any +>use : (s: any) => any +>x : 5 + } +} diff --git a/tests/cases/compiler/argumentsAsPropertyName.ts b/tests/cases/compiler/argumentsAsPropertyName.ts new file mode 100644 index 00000000000..ffecdaa1301 --- /dev/null +++ b/tests/cases/compiler/argumentsAsPropertyName.ts @@ -0,0 +1,15 @@ +// target: es5 +type MyType = { + arguments: Array +} + +declare function use(s: any); + +function myFunction(myType: MyType) { + for (let i = 0; i < 10; i++) { + use(myType.arguments[i]); + // create closure so that tsc will turn loop body into function + const x = 5; + [1, 2, 3].forEach(function(j) { use(x); }) + } +} \ No newline at end of file From 7d773f18e09de59fc49090307b5980529fe97d0d Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Sat, 21 Jan 2017 17:07:37 +0100 Subject: [PATCH 19/41] Adds non-ambient context check --- src/compiler/checker.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5f80444c73e..2cac77bf576 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1,4 +1,4 @@ -/// +/// /// /* @internal */ @@ -18337,7 +18337,11 @@ namespace ts { const staticType = getTypeOfSymbol(symbol); checkTypeParameterListsIdentical(node, symbol); checkClassForDuplicateDeclarations(node); + + // Only check for reserved static identifiers on non-ambient context. + if (!isInAmbientContext(node)) { checkClassForStaticPropertyNameConflicts(node); + } const baseTypeNode = getClassExtendsHeritageClauseElement(node); if (baseTypeNode) { From 02af00fae7ce4ad63ffa9a566e6f46d48e7ca333 Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Sat, 21 Jan 2017 17:08:48 +0100 Subject: [PATCH 20/41] Fixes formatting --- src/compiler/checker.ts | 12 +- ...pertyNameConflictsInAmbientContext.symbols | 107 ++++++++++++++++++ 2 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/staticPropertyNameConflictsInAmbientContext.symbols diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2cac77bf576..383b92b7074 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1,4 +1,4 @@ -/// +/// /// /* @internal */ @@ -15722,12 +15722,12 @@ namespace ts { } } - /** + /** * Static members being set on a constructor function may conflict with built-in properties - * of Function. Esp. in ECMAScript 5 there are non-configurable and non-writable - * built-in properties. This check issues a transpile error when a class has a static + * of Function. Esp. in ECMAScript 5 there are non-configurable and non-writable + * built-in properties. This check issues a transpile error when a class has a static * member with the same name as a non-writable built-in property. - * + * * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.3 * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.5 * @see http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-function-constructor @@ -18340,7 +18340,7 @@ namespace ts { // Only check for reserved static identifiers on non-ambient context. if (!isInAmbientContext(node)) { - checkClassForStaticPropertyNameConflicts(node); + checkClassForStaticPropertyNameConflicts(node); } const baseTypeNode = getClassExtendsHeritageClauseElement(node); diff --git a/tests/baselines/reference/staticPropertyNameConflictsInAmbientContext.symbols b/tests/baselines/reference/staticPropertyNameConflictsInAmbientContext.symbols new file mode 100644 index 00000000000..46297eab86a --- /dev/null +++ b/tests/baselines/reference/staticPropertyNameConflictsInAmbientContext.symbols @@ -0,0 +1,107 @@ +=== tests/cases/conformance/classes/propertyMemberDeclarations/decl.d.ts === + +// name +declare class StaticName { +>StaticName : Symbol(StaticName, Decl(decl.d.ts, 0, 0)) + + static name: number; // ok +>name : Symbol(StaticName.name, Decl(decl.d.ts, 2, 26)) + + name: string; // ok +>name : Symbol(StaticName.name, Decl(decl.d.ts, 3, 24)) +} + +declare class StaticNameFn { +>StaticNameFn : Symbol(StaticNameFn, Decl(decl.d.ts, 5, 1)) + + static name(): string; // ok +>name : Symbol(StaticNameFn.name, Decl(decl.d.ts, 7, 28)) + + name(): string; // ok +>name : Symbol(StaticNameFn.name, Decl(decl.d.ts, 8, 26)) +} + +// length +declare class StaticLength { +>StaticLength : Symbol(StaticLength, Decl(decl.d.ts, 10, 1)) + + static length: number; // ok +>length : Symbol(StaticLength.length, Decl(decl.d.ts, 13, 28)) + + length: string; // ok +>length : Symbol(StaticLength.length, Decl(decl.d.ts, 14, 26)) +} + +declare class StaticLengthFn { +>StaticLengthFn : Symbol(StaticLengthFn, Decl(decl.d.ts, 16, 1)) + + static length(): number; // ok +>length : Symbol(StaticLengthFn.length, Decl(decl.d.ts, 18, 30)) + + length(): number; // ok +>length : Symbol(StaticLengthFn.length, Decl(decl.d.ts, 19, 28)) +} + +// prototype +declare class StaticPrototype { +>StaticPrototype : Symbol(StaticPrototype, Decl(decl.d.ts, 21, 1)) + + static prototype: number; // ok +>prototype : Symbol(StaticPrototype.prototype, Decl(decl.d.ts, 24, 31)) + + prototype: string; // ok +>prototype : Symbol(StaticPrototype.prototype, Decl(decl.d.ts, 25, 29)) +} + +declare class StaticPrototypeFn { +>StaticPrototypeFn : Symbol(StaticPrototypeFn, Decl(decl.d.ts, 27, 1)) + + static prototype: any; // ok +>prototype : Symbol(StaticPrototypeFn.prototype, Decl(decl.d.ts, 29, 33)) + + prototype(): any; // ok +>prototype : Symbol(StaticPrototypeFn.prototype, Decl(decl.d.ts, 30, 26)) +} + +// caller +declare class StaticCaller { +>StaticCaller : Symbol(StaticCaller, Decl(decl.d.ts, 32, 1)) + + static caller: number; // ok +>caller : Symbol(StaticCaller.caller, Decl(decl.d.ts, 35, 28)) + + caller: string; // ok +>caller : Symbol(StaticCaller.caller, Decl(decl.d.ts, 36, 26)) +} + +declare class StaticCallerFn { +>StaticCallerFn : Symbol(StaticCallerFn, Decl(decl.d.ts, 38, 1)) + + static caller(): any; // ok +>caller : Symbol(StaticCallerFn.caller, Decl(decl.d.ts, 40, 30)) + + caller(): any; // ok +>caller : Symbol(StaticCallerFn.caller, Decl(decl.d.ts, 41, 25)) +} + +// arguments +declare class StaticArguments { +>StaticArguments : Symbol(StaticArguments, Decl(decl.d.ts, 43, 1)) + + static arguments: number; // ok +>arguments : Symbol(StaticArguments.arguments, Decl(decl.d.ts, 46, 31)) + + arguments: string; // ok +>arguments : Symbol(StaticArguments.arguments, Decl(decl.d.ts, 47, 29)) +} + +declare class StaticArgumentsFn { +>StaticArgumentsFn : Symbol(StaticArgumentsFn, Decl(decl.d.ts, 49, 1)) + + static arguments(): any; // ok +>arguments : Symbol(StaticArgumentsFn.arguments, Decl(decl.d.ts, 51, 33)) + + arguments(): any; // ok +>arguments : Symbol(StaticArgumentsFn.arguments, Decl(decl.d.ts, 52, 28)) +} + From 1e5b7c5564eeae81b4ee750703cb9cd79ae8e47f Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Sat, 21 Jan 2017 17:09:09 +0100 Subject: [PATCH 21/41] Add tests --- ...icPropertyNameConflictsInAmbientContext.ts | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsInAmbientContext.ts diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsInAmbientContext.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsInAmbientContext.ts new file mode 100644 index 00000000000..198c923b0dd --- /dev/null +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsInAmbientContext.ts @@ -0,0 +1,56 @@ + +//@Filename: decl.d.ts +// name +declare class StaticName { + static name: number; // ok + name: string; // ok +} + +declare class StaticNameFn { + static name(): string; // ok + name(): string; // ok +} + +// length +declare class StaticLength { + static length: number; // ok + length: string; // ok +} + +declare class StaticLengthFn { + static length(): number; // ok + length(): number; // ok +} + +// prototype +declare class StaticPrototype { + static prototype: number; // ok + prototype: string; // ok +} + +declare class StaticPrototypeFn { + static prototype: any; // ok + prototype(): any; // ok +} + +// caller +declare class StaticCaller { + static caller: number; // ok + caller: string; // ok +} + +declare class StaticCallerFn { + static caller(): any; // ok + caller(): any; // ok +} + +// arguments +declare class StaticArguments { + static arguments: number; // ok + arguments: string; // ok +} + +declare class StaticArgumentsFn { + static arguments(): any; // ok + arguments(): any; // ok +} From 36f6e19d9eeb1f7da92e466dede07f800d8c14a9 Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Sat, 21 Jan 2017 17:09:26 +0100 Subject: [PATCH 22/41] Add reference baseline --- ...ropertyNameConflictsInAmbientContext.types | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 tests/baselines/reference/staticPropertyNameConflictsInAmbientContext.types diff --git a/tests/baselines/reference/staticPropertyNameConflictsInAmbientContext.types b/tests/baselines/reference/staticPropertyNameConflictsInAmbientContext.types new file mode 100644 index 00000000000..233bd8a46fc --- /dev/null +++ b/tests/baselines/reference/staticPropertyNameConflictsInAmbientContext.types @@ -0,0 +1,107 @@ +=== tests/cases/conformance/classes/propertyMemberDeclarations/decl.d.ts === + +// name +declare class StaticName { +>StaticName : StaticName + + static name: number; // ok +>name : number + + name: string; // ok +>name : string +} + +declare class StaticNameFn { +>StaticNameFn : StaticNameFn + + static name(): string; // ok +>name : () => string + + name(): string; // ok +>name : () => string +} + +// length +declare class StaticLength { +>StaticLength : StaticLength + + static length: number; // ok +>length : number + + length: string; // ok +>length : string +} + +declare class StaticLengthFn { +>StaticLengthFn : StaticLengthFn + + static length(): number; // ok +>length : () => number + + length(): number; // ok +>length : () => number +} + +// prototype +declare class StaticPrototype { +>StaticPrototype : StaticPrototype + + static prototype: number; // ok +>prototype : StaticPrototype + + prototype: string; // ok +>prototype : string +} + +declare class StaticPrototypeFn { +>StaticPrototypeFn : StaticPrototypeFn + + static prototype: any; // ok +>prototype : StaticPrototypeFn + + prototype(): any; // ok +>prototype : () => any +} + +// caller +declare class StaticCaller { +>StaticCaller : StaticCaller + + static caller: number; // ok +>caller : number + + caller: string; // ok +>caller : string +} + +declare class StaticCallerFn { +>StaticCallerFn : StaticCallerFn + + static caller(): any; // ok +>caller : () => any + + caller(): any; // ok +>caller : () => any +} + +// arguments +declare class StaticArguments { +>StaticArguments : StaticArguments + + static arguments: number; // ok +>arguments : number + + arguments: string; // ok +>arguments : string +} + +declare class StaticArgumentsFn { +>StaticArgumentsFn : StaticArgumentsFn + + static arguments(): any; // ok +>arguments : () => any + + arguments(): any; // ok +>arguments : () => any +} + From ad71da0a7f36fafa8e940c388fd503c60ae6afee Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 21 Jan 2017 13:06:54 -0800 Subject: [PATCH 23/41] Fix error reporting bug --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a5058bdf7f2..3242a30d381 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18240,14 +18240,14 @@ namespace ts { const propDeclaration = prop.valueDeclaration; // index is numeric and property name is not valid numeric literal - if (indexKind === IndexKind.Number && propDeclaration && !isNumericName(propDeclaration.name)) { + if (indexKind === IndexKind.Number && !(propDeclaration ? isNumericName(propDeclaration.name) : isNumericLiteralName(prop.name))) { return; } // perform property check if property or indexer is declared in 'type' // this allows to rule out cases when both property and indexer are inherited from the base class let errorNode: Node; - if (propDeclaration && propDeclaration.name.kind === SyntaxKind.ComputedPropertyName || prop.parent === containingType.symbol) { + if (propDeclaration && (propDeclaration.name.kind === SyntaxKind.ComputedPropertyName || prop.parent === containingType.symbol)) { errorNode = propDeclaration; } else if (indexDeclaration) { From 615784ad944a3e7ec392e6043c41028558aab5b4 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 21 Jan 2017 13:07:06 -0800 Subject: [PATCH 24/41] Add tests --- .../interfaceExtendsObjectIntersection.ts | 55 +++++++++++++++++++ ...nterfaceExtendsObjectIntersectionErrors.ts | 49 +++++++++++++++++ .../intersection/intersectionThisTypes.ts | 40 ++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersection.ts create mode 100644 tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts create mode 100644 tests/cases/conformance/types/intersection/intersectionThisTypes.ts diff --git a/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersection.ts b/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersection.ts new file mode 100644 index 00000000000..003976a2b27 --- /dev/null +++ b/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersection.ts @@ -0,0 +1,55 @@ +// @strictNullChecks: true + +type T1 = { a: number }; +type T2 = T1 & { b: number }; +type T3 = () => void; +type T4 = new () => { a: number }; +type T5 = number[]; +type T6 = [string, number]; +type T7 = { [P in 'a' | 'b' | 'c']: string }; + +interface I1 extends T1 { x: string } +interface I2 extends T2 { x: string } +interface I3 extends T3 { x: string } +interface I4 extends T4 { x: string } +interface I5 extends T5 { x: string } +interface I6 extends T6 { x: string } +interface I7 extends T7 { x: string } + +type Constructor = new () => T; +declare function Constructor(): Constructor; + +class C1 extends Constructor() { x: string } +class C2 extends Constructor() { x: string } +class C3 extends Constructor() { x: string } +class C4 extends Constructor() { x: string } +class C5 extends Constructor() { x: string } +class C6 extends Constructor() { x: string } +class C7 extends Constructor() { x: string } + +declare function fx(x: string): string; +declare class CX { a: number } +declare enum EX { A, B, C } +declare namespace NX { export const a = 1 } + +type T10 = typeof fx; +type T11 = typeof CX; +type T12 = typeof EX; +type T13 = typeof NX; + +interface I10 extends T10 { x: string } +interface I11 extends T11 { x: string } +interface I12 extends T12 { x: string } +interface I13 extends T13 { x: string } + +type Identifiable = { _id: string } & T; + +interface I20 extends Partial { x: string } +interface I21 extends Readonly { x: string } +interface I22 extends Identifiable { x: string } +interface I23 extends Identifiable { x: string } + +class C20 extends Constructor>() { x: string } +class C21 extends Constructor>() { x: string } +class C22 extends Constructor>() { x: string } +class C23 extends Constructor>() { x: string } diff --git a/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts b/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts new file mode 100644 index 00000000000..5a2a37fc227 --- /dev/null +++ b/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts @@ -0,0 +1,49 @@ +// @strictNullChecks: true + +type T1 = { a: number }; +type T2 = T1 & { b: number }; +type T3 = number[]; +type T4 = [string, number]; +type T5 = { [P in 'a' | 'b' | 'c']: string }; + +interface I1 extends T1 { a: string } +interface I2 extends T2 { b: string } +interface I3 extends T3 { length: string } +interface I4 extends T4 { 0: number } +interface I5 extends T5 { c: number } + +type Constructor = new () => T; +declare function Constructor(): Constructor; + +class C1 extends Constructor() { a: string } +class C2 extends Constructor() { b: string } +class C3 extends Constructor() { length: string } +class C4 extends Constructor() { 0: number } +class C5 extends Constructor() { c: number } + +declare class CX { static a: string } +declare enum EX { A, B, C } +declare namespace NX { export const a = "hello" } + +type TCX = typeof CX; +type TEX = typeof EX; +type TNX = typeof NX; + +interface I10 extends TCX { a: number } +interface I11 extends TEX { C: string } +interface I12 extends TNX { a: number } +interface I14 extends TCX { [x: string]: number } +interface I15 extends TEX { [x: string]: number } +interface I16 extends TNX { [x: string]: number } + +type Identifiable = { _id: string } & T; + +interface I20 extends Partial { a: string } +interface I21 extends Readonly { a: string } +interface I22 extends Identifiable { a: string } +interface I23 extends Identifiable { a: string } + +type U = { a: number } | { b: string }; + +interface I30 extends U { x: string } +interface I31 extends T { x: string } diff --git a/tests/cases/conformance/types/intersection/intersectionThisTypes.ts b/tests/cases/conformance/types/intersection/intersectionThisTypes.ts new file mode 100644 index 00000000000..8819148dc9e --- /dev/null +++ b/tests/cases/conformance/types/intersection/intersectionThisTypes.ts @@ -0,0 +1,40 @@ +interface Thing1 { + a: number; + self(): this; +} + +interface Thing2 { + b: number; + me(): this; +} + +type Thing3 = Thing1 & Thing2; +type Thing4 = Thing3 & string[]; + +function f1(t: Thing3) { + t = t.self(); + t = t.me().self().me(); +} + +interface Thing5 extends Thing4 { + c: string; +} + +function f2(t: Thing5) { + t = t.self(); + t = t.me().self().me(); +} + +interface Component { + extend(props: T): this & T; +} + +interface Label extends Component { + title: string; +} + +function test(label: Label) { + const extended = label.extend({ id: 67 }).extend({ tag: "hello" }); + extended.id; // Ok + extended.tag; // Ok +} From 3a34cb3088632f2361b7adafdb16fe802febcd8e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 21 Jan 2017 13:12:02 -0800 Subject: [PATCH 25/41] Accept new baselines --- .../interfaceExtendsObjectIntersection.js | 145 +++++++++++ ...interfaceExtendsObjectIntersection.symbols | 230 +++++++++++++++++ .../interfaceExtendsObjectIntersection.types | 242 ++++++++++++++++++ ...ExtendsObjectIntersectionErrors.errors.txt | 197 ++++++++++++++ ...nterfaceExtendsObjectIntersectionErrors.js | 97 +++++++ .../reference/intersectionThisTypes.js | 57 +++++ .../reference/intersectionThisTypes.symbols | 127 +++++++++ .../reference/intersectionThisTypes.types | 145 +++++++++++ 8 files changed, 1240 insertions(+) create mode 100644 tests/baselines/reference/interfaceExtendsObjectIntersection.js create mode 100644 tests/baselines/reference/interfaceExtendsObjectIntersection.symbols create mode 100644 tests/baselines/reference/interfaceExtendsObjectIntersection.types create mode 100644 tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt create mode 100644 tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.js create mode 100644 tests/baselines/reference/intersectionThisTypes.js create mode 100644 tests/baselines/reference/intersectionThisTypes.symbols create mode 100644 tests/baselines/reference/intersectionThisTypes.types diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersection.js b/tests/baselines/reference/interfaceExtendsObjectIntersection.js new file mode 100644 index 00000000000..a6fb62f5070 --- /dev/null +++ b/tests/baselines/reference/interfaceExtendsObjectIntersection.js @@ -0,0 +1,145 @@ +//// [interfaceExtendsObjectIntersection.ts] + +type T1 = { a: number }; +type T2 = T1 & { b: number }; +type T3 = () => void; +type T4 = new () => { a: number }; +type T5 = number[]; +type T6 = [string, number]; +type T7 = { [P in 'a' | 'b' | 'c']: string }; + +interface I1 extends T1 { x: string } +interface I2 extends T2 { x: string } +interface I3 extends T3 { x: string } +interface I4 extends T4 { x: string } +interface I5 extends T5 { x: string } +interface I6 extends T6 { x: string } +interface I7 extends T7 { x: string } + +type Constructor = new () => T; +declare function Constructor(): Constructor; + +class C1 extends Constructor() { x: string } +class C2 extends Constructor() { x: string } +class C3 extends Constructor() { x: string } +class C4 extends Constructor() { x: string } +class C5 extends Constructor() { x: string } +class C6 extends Constructor() { x: string } +class C7 extends Constructor() { x: string } + +declare function fx(x: string): string; +declare class CX { a: number } +declare enum EX { A, B, C } +declare namespace NX { export const a = 1 } + +type T10 = typeof fx; +type T11 = typeof CX; +type T12 = typeof EX; +type T13 = typeof NX; + +interface I10 extends T10 { x: string } +interface I11 extends T11 { x: string } +interface I12 extends T12 { x: string } +interface I13 extends T13 { x: string } + +type Identifiable = { _id: string } & T; + +interface I20 extends Partial { x: string } +interface I21 extends Readonly { x: string } +interface I22 extends Identifiable { x: string } +interface I23 extends Identifiable { x: string } + +class C20 extends Constructor>() { x: string } +class C21 extends Constructor>() { x: string } +class C22 extends Constructor>() { x: string } +class C23 extends Constructor>() { x: string } + + +//// [interfaceExtendsObjectIntersection.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var C1 = (function (_super) { + __extends(C1, _super); + function C1() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C1; +}(Constructor())); +var C2 = (function (_super) { + __extends(C2, _super); + function C2() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C2; +}(Constructor())); +var C3 = (function (_super) { + __extends(C3, _super); + function C3() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C3; +}(Constructor())); +var C4 = (function (_super) { + __extends(C4, _super); + function C4() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C4; +}(Constructor())); +var C5 = (function (_super) { + __extends(C5, _super); + function C5() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C5; +}(Constructor())); +var C6 = (function (_super) { + __extends(C6, _super); + function C6() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C6; +}(Constructor())); +var C7 = (function (_super) { + __extends(C7, _super); + function C7() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C7; +}(Constructor())); +var C20 = (function (_super) { + __extends(C20, _super); + function C20() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C20; +}(Constructor())); +var C21 = (function (_super) { + __extends(C21, _super); + function C21() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C21; +}(Constructor())); +var C22 = (function (_super) { + __extends(C22, _super); + function C22() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C22; +}(Constructor())); +var C23 = (function (_super) { + __extends(C23, _super); + function C23() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C23; +}(Constructor())); diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersection.symbols b/tests/baselines/reference/interfaceExtendsObjectIntersection.symbols new file mode 100644 index 00000000000..16c8c51cf47 --- /dev/null +++ b/tests/baselines/reference/interfaceExtendsObjectIntersection.symbols @@ -0,0 +1,230 @@ +=== tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersection.ts === + +type T1 = { a: number }; +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>a : Symbol(a, Decl(interfaceExtendsObjectIntersection.ts, 1, 11)) + +type T2 = T1 & { b: number }; +>T2 : Symbol(T2, Decl(interfaceExtendsObjectIntersection.ts, 1, 24)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>b : Symbol(b, Decl(interfaceExtendsObjectIntersection.ts, 2, 16)) + +type T3 = () => void; +>T3 : Symbol(T3, Decl(interfaceExtendsObjectIntersection.ts, 2, 29)) + +type T4 = new () => { a: number }; +>T4 : Symbol(T4, Decl(interfaceExtendsObjectIntersection.ts, 3, 21)) +>a : Symbol(a, Decl(interfaceExtendsObjectIntersection.ts, 4, 21)) + +type T5 = number[]; +>T5 : Symbol(T5, Decl(interfaceExtendsObjectIntersection.ts, 4, 34)) + +type T6 = [string, number]; +>T6 : Symbol(T6, Decl(interfaceExtendsObjectIntersection.ts, 5, 19)) + +type T7 = { [P in 'a' | 'b' | 'c']: string }; +>T7 : Symbol(T7, Decl(interfaceExtendsObjectIntersection.ts, 6, 27)) +>P : Symbol(P, Decl(interfaceExtendsObjectIntersection.ts, 7, 13)) + +interface I1 extends T1 { x: string } +>I1 : Symbol(I1, Decl(interfaceExtendsObjectIntersection.ts, 7, 45)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(I1.x, Decl(interfaceExtendsObjectIntersection.ts, 9, 25)) + +interface I2 extends T2 { x: string } +>I2 : Symbol(I2, Decl(interfaceExtendsObjectIntersection.ts, 9, 37)) +>T2 : Symbol(T2, Decl(interfaceExtendsObjectIntersection.ts, 1, 24)) +>x : Symbol(I2.x, Decl(interfaceExtendsObjectIntersection.ts, 10, 25)) + +interface I3 extends T3 { x: string } +>I3 : Symbol(I3, Decl(interfaceExtendsObjectIntersection.ts, 10, 37)) +>T3 : Symbol(T3, Decl(interfaceExtendsObjectIntersection.ts, 2, 29)) +>x : Symbol(I3.x, Decl(interfaceExtendsObjectIntersection.ts, 11, 25)) + +interface I4 extends T4 { x: string } +>I4 : Symbol(I4, Decl(interfaceExtendsObjectIntersection.ts, 11, 37)) +>T4 : Symbol(T4, Decl(interfaceExtendsObjectIntersection.ts, 3, 21)) +>x : Symbol(I4.x, Decl(interfaceExtendsObjectIntersection.ts, 12, 25)) + +interface I5 extends T5 { x: string } +>I5 : Symbol(I5, Decl(interfaceExtendsObjectIntersection.ts, 12, 37)) +>T5 : Symbol(T5, Decl(interfaceExtendsObjectIntersection.ts, 4, 34)) +>x : Symbol(I5.x, Decl(interfaceExtendsObjectIntersection.ts, 13, 25)) + +interface I6 extends T6 { x: string } +>I6 : Symbol(I6, Decl(interfaceExtendsObjectIntersection.ts, 13, 37)) +>T6 : Symbol(T6, Decl(interfaceExtendsObjectIntersection.ts, 5, 19)) +>x : Symbol(I6.x, Decl(interfaceExtendsObjectIntersection.ts, 14, 25)) + +interface I7 extends T7 { x: string } +>I7 : Symbol(I7, Decl(interfaceExtendsObjectIntersection.ts, 14, 37)) +>T7 : Symbol(T7, Decl(interfaceExtendsObjectIntersection.ts, 6, 27)) +>x : Symbol(I7.x, Decl(interfaceExtendsObjectIntersection.ts, 15, 25)) + +type Constructor = new () => T; +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 17, 17)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 17, 17)) + +declare function Constructor(): Constructor; +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 18, 29)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 18, 29)) + +class C1 extends Constructor() { x: string } +>C1 : Symbol(C1, Decl(interfaceExtendsObjectIntersection.ts, 18, 50)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I1 : Symbol(I1, Decl(interfaceExtendsObjectIntersection.ts, 7, 45)) +>x : Symbol(C1.x, Decl(interfaceExtendsObjectIntersection.ts, 20, 36)) + +class C2 extends Constructor() { x: string } +>C2 : Symbol(C2, Decl(interfaceExtendsObjectIntersection.ts, 20, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I2 : Symbol(I2, Decl(interfaceExtendsObjectIntersection.ts, 9, 37)) +>x : Symbol(C2.x, Decl(interfaceExtendsObjectIntersection.ts, 21, 36)) + +class C3 extends Constructor() { x: string } +>C3 : Symbol(C3, Decl(interfaceExtendsObjectIntersection.ts, 21, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I3 : Symbol(I3, Decl(interfaceExtendsObjectIntersection.ts, 10, 37)) +>x : Symbol(C3.x, Decl(interfaceExtendsObjectIntersection.ts, 22, 36)) + +class C4 extends Constructor() { x: string } +>C4 : Symbol(C4, Decl(interfaceExtendsObjectIntersection.ts, 22, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I4 : Symbol(I4, Decl(interfaceExtendsObjectIntersection.ts, 11, 37)) +>x : Symbol(C4.x, Decl(interfaceExtendsObjectIntersection.ts, 23, 36)) + +class C5 extends Constructor() { x: string } +>C5 : Symbol(C5, Decl(interfaceExtendsObjectIntersection.ts, 23, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I5 : Symbol(I5, Decl(interfaceExtendsObjectIntersection.ts, 12, 37)) +>x : Symbol(C5.x, Decl(interfaceExtendsObjectIntersection.ts, 24, 36)) + +class C6 extends Constructor() { x: string } +>C6 : Symbol(C6, Decl(interfaceExtendsObjectIntersection.ts, 24, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I6 : Symbol(I6, Decl(interfaceExtendsObjectIntersection.ts, 13, 37)) +>x : Symbol(C6.x, Decl(interfaceExtendsObjectIntersection.ts, 25, 36)) + +class C7 extends Constructor() { x: string } +>C7 : Symbol(C7, Decl(interfaceExtendsObjectIntersection.ts, 25, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I7 : Symbol(I7, Decl(interfaceExtendsObjectIntersection.ts, 14, 37)) +>x : Symbol(C7.x, Decl(interfaceExtendsObjectIntersection.ts, 26, 36)) + +declare function fx(x: string): string; +>fx : Symbol(fx, Decl(interfaceExtendsObjectIntersection.ts, 26, 48)) +>x : Symbol(x, Decl(interfaceExtendsObjectIntersection.ts, 28, 20)) + +declare class CX { a: number } +>CX : Symbol(CX, Decl(interfaceExtendsObjectIntersection.ts, 28, 39)) +>a : Symbol(CX.a, Decl(interfaceExtendsObjectIntersection.ts, 29, 18)) + +declare enum EX { A, B, C } +>EX : Symbol(EX, Decl(interfaceExtendsObjectIntersection.ts, 29, 30)) +>A : Symbol(EX.A, Decl(interfaceExtendsObjectIntersection.ts, 30, 17)) +>B : Symbol(EX.B, Decl(interfaceExtendsObjectIntersection.ts, 30, 20)) +>C : Symbol(EX.C, Decl(interfaceExtendsObjectIntersection.ts, 30, 23)) + +declare namespace NX { export const a = 1 } +>NX : Symbol(NX, Decl(interfaceExtendsObjectIntersection.ts, 30, 27)) +>a : Symbol(a, Decl(interfaceExtendsObjectIntersection.ts, 31, 35)) + +type T10 = typeof fx; +>T10 : Symbol(T10, Decl(interfaceExtendsObjectIntersection.ts, 31, 43)) +>fx : Symbol(fx, Decl(interfaceExtendsObjectIntersection.ts, 26, 48)) + +type T11 = typeof CX; +>T11 : Symbol(T11, Decl(interfaceExtendsObjectIntersection.ts, 33, 21)) +>CX : Symbol(CX, Decl(interfaceExtendsObjectIntersection.ts, 28, 39)) + +type T12 = typeof EX; +>T12 : Symbol(T12, Decl(interfaceExtendsObjectIntersection.ts, 34, 21)) +>EX : Symbol(EX, Decl(interfaceExtendsObjectIntersection.ts, 29, 30)) + +type T13 = typeof NX; +>T13 : Symbol(T13, Decl(interfaceExtendsObjectIntersection.ts, 35, 21)) +>NX : Symbol(NX, Decl(interfaceExtendsObjectIntersection.ts, 30, 27)) + +interface I10 extends T10 { x: string } +>I10 : Symbol(I10, Decl(interfaceExtendsObjectIntersection.ts, 36, 21)) +>T10 : Symbol(T10, Decl(interfaceExtendsObjectIntersection.ts, 31, 43)) +>x : Symbol(I10.x, Decl(interfaceExtendsObjectIntersection.ts, 38, 27)) + +interface I11 extends T11 { x: string } +>I11 : Symbol(I11, Decl(interfaceExtendsObjectIntersection.ts, 38, 39)) +>T11 : Symbol(T11, Decl(interfaceExtendsObjectIntersection.ts, 33, 21)) +>x : Symbol(I11.x, Decl(interfaceExtendsObjectIntersection.ts, 39, 27)) + +interface I12 extends T12 { x: string } +>I12 : Symbol(I12, Decl(interfaceExtendsObjectIntersection.ts, 39, 39)) +>T12 : Symbol(T12, Decl(interfaceExtendsObjectIntersection.ts, 34, 21)) +>x : Symbol(I12.x, Decl(interfaceExtendsObjectIntersection.ts, 40, 27)) + +interface I13 extends T13 { x: string } +>I13 : Symbol(I13, Decl(interfaceExtendsObjectIntersection.ts, 40, 39)) +>T13 : Symbol(T13, Decl(interfaceExtendsObjectIntersection.ts, 35, 21)) +>x : Symbol(I13.x, Decl(interfaceExtendsObjectIntersection.ts, 41, 27)) + +type Identifiable = { _id: string } & T; +>Identifiable : Symbol(Identifiable, Decl(interfaceExtendsObjectIntersection.ts, 41, 39)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 43, 18)) +>_id : Symbol(_id, Decl(interfaceExtendsObjectIntersection.ts, 43, 24)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 43, 18)) + +interface I20 extends Partial { x: string } +>I20 : Symbol(I20, Decl(interfaceExtendsObjectIntersection.ts, 43, 43)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(I20.x, Decl(interfaceExtendsObjectIntersection.ts, 45, 35)) + +interface I21 extends Readonly { x: string } +>I21 : Symbol(I21, Decl(interfaceExtendsObjectIntersection.ts, 45, 47)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(I21.x, Decl(interfaceExtendsObjectIntersection.ts, 46, 36)) + +interface I22 extends Identifiable { x: string } +>I22 : Symbol(I22, Decl(interfaceExtendsObjectIntersection.ts, 46, 48)) +>Identifiable : Symbol(Identifiable, Decl(interfaceExtendsObjectIntersection.ts, 41, 39)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(I22.x, Decl(interfaceExtendsObjectIntersection.ts, 47, 40)) + +interface I23 extends Identifiable { x: string } +>I23 : Symbol(I23, Decl(interfaceExtendsObjectIntersection.ts, 47, 52)) +>Identifiable : Symbol(Identifiable, Decl(interfaceExtendsObjectIntersection.ts, 41, 39)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>b : Symbol(b, Decl(interfaceExtendsObjectIntersection.ts, 48, 41)) +>x : Symbol(I23.x, Decl(interfaceExtendsObjectIntersection.ts, 48, 55)) + +class C20 extends Constructor>() { x: string } +>C20 : Symbol(C20, Decl(interfaceExtendsObjectIntersection.ts, 48, 67)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(C20.x, Decl(interfaceExtendsObjectIntersection.ts, 50, 46)) + +class C21 extends Constructor>() { x: string } +>C21 : Symbol(C21, Decl(interfaceExtendsObjectIntersection.ts, 50, 58)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(C21.x, Decl(interfaceExtendsObjectIntersection.ts, 51, 47)) + +class C22 extends Constructor>() { x: string } +>C22 : Symbol(C22, Decl(interfaceExtendsObjectIntersection.ts, 51, 59)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>Identifiable : Symbol(Identifiable, Decl(interfaceExtendsObjectIntersection.ts, 41, 39)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(C22.x, Decl(interfaceExtendsObjectIntersection.ts, 52, 51)) + +class C23 extends Constructor>() { x: string } +>C23 : Symbol(C23, Decl(interfaceExtendsObjectIntersection.ts, 52, 63)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>Identifiable : Symbol(Identifiable, Decl(interfaceExtendsObjectIntersection.ts, 41, 39)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>b : Symbol(b, Decl(interfaceExtendsObjectIntersection.ts, 53, 49)) +>x : Symbol(C23.x, Decl(interfaceExtendsObjectIntersection.ts, 53, 66)) + diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersection.types b/tests/baselines/reference/interfaceExtendsObjectIntersection.types new file mode 100644 index 00000000000..1ff550df7b4 --- /dev/null +++ b/tests/baselines/reference/interfaceExtendsObjectIntersection.types @@ -0,0 +1,242 @@ +=== tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersection.ts === + +type T1 = { a: number }; +>T1 : T1 +>a : number + +type T2 = T1 & { b: number }; +>T2 : T2 +>T1 : T1 +>b : number + +type T3 = () => void; +>T3 : T3 + +type T4 = new () => { a: number }; +>T4 : T4 +>a : number + +type T5 = number[]; +>T5 : number[] + +type T6 = [string, number]; +>T6 : [string, number] + +type T7 = { [P in 'a' | 'b' | 'c']: string }; +>T7 : T7 +>P : P + +interface I1 extends T1 { x: string } +>I1 : I1 +>T1 : T1 +>x : string + +interface I2 extends T2 { x: string } +>I2 : I2 +>T2 : T2 +>x : string + +interface I3 extends T3 { x: string } +>I3 : I3 +>T3 : T3 +>x : string + +interface I4 extends T4 { x: string } +>I4 : I4 +>T4 : T4 +>x : string + +interface I5 extends T5 { x: string } +>I5 : I5 +>T5 : number[] +>x : string + +interface I6 extends T6 { x: string } +>I6 : I6 +>T6 : [string, number] +>x : string + +interface I7 extends T7 { x: string } +>I7 : I7 +>T7 : T7 +>x : string + +type Constructor = new () => T; +>Constructor : Constructor +>T : T +>T : T + +declare function Constructor(): Constructor; +>Constructor : () => Constructor +>T : T +>Constructor : Constructor +>T : T + +class C1 extends Constructor() { x: string } +>C1 : C1 +>Constructor() : I1 +>Constructor : () => Constructor +>I1 : I1 +>x : string + +class C2 extends Constructor() { x: string } +>C2 : C2 +>Constructor() : I2 +>Constructor : () => Constructor +>I2 : I2 +>x : string + +class C3 extends Constructor() { x: string } +>C3 : C3 +>Constructor() : I3 +>Constructor : () => Constructor +>I3 : I3 +>x : string + +class C4 extends Constructor() { x: string } +>C4 : C4 +>Constructor() : I4 +>Constructor : () => Constructor +>I4 : I4 +>x : string + +class C5 extends Constructor() { x: string } +>C5 : C5 +>Constructor() : I5 +>Constructor : () => Constructor +>I5 : I5 +>x : string + +class C6 extends Constructor() { x: string } +>C6 : C6 +>Constructor() : I6 +>Constructor : () => Constructor +>I6 : I6 +>x : string + +class C7 extends Constructor() { x: string } +>C7 : C7 +>Constructor() : I7 +>Constructor : () => Constructor +>I7 : I7 +>x : string + +declare function fx(x: string): string; +>fx : (x: string) => string +>x : string + +declare class CX { a: number } +>CX : CX +>a : number + +declare enum EX { A, B, C } +>EX : EX +>A : EX +>B : EX +>C : EX + +declare namespace NX { export const a = 1 } +>NX : typeof NX +>a : 1 +>1 : 1 + +type T10 = typeof fx; +>T10 : (x: string) => string +>fx : (x: string) => string + +type T11 = typeof CX; +>T11 : typeof CX +>CX : typeof CX + +type T12 = typeof EX; +>T12 : typeof EX +>EX : typeof EX + +type T13 = typeof NX; +>T13 : typeof NX +>NX : typeof NX + +interface I10 extends T10 { x: string } +>I10 : I10 +>T10 : (x: string) => string +>x : string + +interface I11 extends T11 { x: string } +>I11 : I11 +>T11 : typeof CX +>x : string + +interface I12 extends T12 { x: string } +>I12 : I12 +>T12 : typeof EX +>x : string + +interface I13 extends T13 { x: string } +>I13 : I13 +>T13 : typeof NX +>x : string + +type Identifiable = { _id: string } & T; +>Identifiable : Identifiable +>T : T +>_id : string +>T : T + +interface I20 extends Partial { x: string } +>I20 : I20 +>Partial : Partial +>T1 : T1 +>x : string + +interface I21 extends Readonly { x: string } +>I21 : I21 +>Readonly : Readonly +>T1 : T1 +>x : string + +interface I22 extends Identifiable { x: string } +>I22 : I22 +>Identifiable : Identifiable +>T1 : T1 +>x : string + +interface I23 extends Identifiable { x: string } +>I23 : I23 +>Identifiable : Identifiable +>T1 : T1 +>b : number +>x : string + +class C20 extends Constructor>() { x: string } +>C20 : C20 +>Constructor>() : Partial +>Constructor : () => Constructor +>Partial : Partial +>T1 : T1 +>x : string + +class C21 extends Constructor>() { x: string } +>C21 : C21 +>Constructor>() : Readonly +>Constructor : () => Constructor +>Readonly : Readonly +>T1 : T1 +>x : string + +class C22 extends Constructor>() { x: string } +>C22 : C22 +>Constructor>() : Identifiable +>Constructor : () => Constructor +>Identifiable : Identifiable +>T1 : T1 +>x : string + +class C23 extends Constructor>() { x: string } +>C23 : C23 +>Constructor>() : Identifiable +>Constructor : () => Constructor +>Identifiable : Identifiable +>T1 : T1 +>b : number +>x : string + diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt new file mode 100644 index 00000000000..839474b3bdc --- /dev/null +++ b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt @@ -0,0 +1,197 @@ +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(8,11): error TS2430: Interface 'I1' incorrectly extends interface 'T1'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(9,11): error TS2430: Interface 'I2' incorrectly extends interface 'T2'. + Type 'I2' is not assignable to type '{ b: number; }'. + Types of property 'b' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(10,11): error TS2430: Interface 'I3' incorrectly extends interface 'number[]'. + Types of property 'length' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(11,11): error TS2430: Interface 'I4' incorrectly extends interface '[string, number]'. + Types of property '0' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(12,11): error TS2430: Interface 'I5' incorrectly extends interface 'T5'. + Types of property 'c' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(17,7): error TS2415: Class 'C1' incorrectly extends base class 'T1'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(18,7): error TS2415: Class 'C2' incorrectly extends base class 'T2'. + Type 'C2' is not assignable to type '{ b: number; }'. + Types of property 'b' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(19,7): error TS2415: Class 'C3' incorrectly extends base class 'number[]'. + Types of property 'length' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(20,7): error TS2415: Class 'C4' incorrectly extends base class '[string, number]'. + Types of property '0' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(21,7): error TS2415: Class 'C5' incorrectly extends base class 'T5'. + Types of property 'c' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(31,11): error TS2430: Interface 'I10' incorrectly extends interface 'typeof CX'. + Types of property 'a' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(32,11): error TS2430: Interface 'I11' incorrectly extends interface 'typeof EX'. + Types of property 'C' are incompatible. + Type 'string' is not assignable to type 'EX'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(33,11): error TS2430: Interface 'I12' incorrectly extends interface 'typeof NX'. + Types of property 'a' are incompatible. + Type 'number' is not assignable to type '"hello"'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(34,29): error TS2411: Property 'a' of type 'string' is not assignable to string index type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(34,29): error TS2411: Property 'prototype' of type 'CX' is not assignable to string index type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(35,29): error TS2413: Numeric index type 'string' is not assignable to string index type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(36,29): error TS2411: Property 'a' of type '"hello"' is not assignable to string index type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(40,11): error TS2430: Interface 'I20' incorrectly extends interface 'Partial'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number | undefined'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(41,11): error TS2430: Interface 'I21' incorrectly extends interface 'Readonly'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(42,11): error TS2430: Interface 'I22' incorrectly extends interface 'Identifiable'. + Type 'I22' is not assignable to type 'T1'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(43,11): error TS2430: Interface 'I23' incorrectly extends interface 'Identifiable'. + Type 'I23' is not assignable to type 'T1'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(47,23): error TS2312: An interface may only extend a class or another interface. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(48,26): error TS2312: An interface may only extend a class or another interface. + + +==== tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts (23 errors) ==== + + type T1 = { a: number }; + type T2 = T1 & { b: number }; + type T3 = number[]; + type T4 = [string, number]; + type T5 = { [P in 'a' | 'b' | 'c']: string }; + + interface I1 extends T1 { a: string } + ~~ +!!! error TS2430: Interface 'I1' incorrectly extends interface 'T1'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + interface I2 extends T2 { b: string } + ~~ +!!! error TS2430: Interface 'I2' incorrectly extends interface 'T2'. +!!! error TS2430: Type 'I2' is not assignable to type '{ b: number; }'. +!!! error TS2430: Types of property 'b' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + interface I3 extends T3 { length: string } + ~~ +!!! error TS2430: Interface 'I3' incorrectly extends interface 'number[]'. +!!! error TS2430: Types of property 'length' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + interface I4 extends T4 { 0: number } + ~~ +!!! error TS2430: Interface 'I4' incorrectly extends interface '[string, number]'. +!!! error TS2430: Types of property '0' are incompatible. +!!! error TS2430: Type 'number' is not assignable to type 'string'. + interface I5 extends T5 { c: number } + ~~ +!!! error TS2430: Interface 'I5' incorrectly extends interface 'T5'. +!!! error TS2430: Types of property 'c' are incompatible. +!!! error TS2430: Type 'number' is not assignable to type 'string'. + + type Constructor = new () => T; + declare function Constructor(): Constructor; + + class C1 extends Constructor() { a: string } + ~~ +!!! error TS2415: Class 'C1' incorrectly extends base class 'T1'. +!!! error TS2415: Types of property 'a' are incompatible. +!!! error TS2415: Type 'string' is not assignable to type 'number'. + class C2 extends Constructor() { b: string } + ~~ +!!! error TS2415: Class 'C2' incorrectly extends base class 'T2'. +!!! error TS2415: Type 'C2' is not assignable to type '{ b: number; }'. +!!! error TS2415: Types of property 'b' are incompatible. +!!! error TS2415: Type 'string' is not assignable to type 'number'. + class C3 extends Constructor() { length: string } + ~~ +!!! error TS2415: Class 'C3' incorrectly extends base class 'number[]'. +!!! error TS2415: Types of property 'length' are incompatible. +!!! error TS2415: Type 'string' is not assignable to type 'number'. + class C4 extends Constructor() { 0: number } + ~~ +!!! error TS2415: Class 'C4' incorrectly extends base class '[string, number]'. +!!! error TS2415: Types of property '0' are incompatible. +!!! error TS2415: Type 'number' is not assignable to type 'string'. + class C5 extends Constructor() { c: number } + ~~ +!!! error TS2415: Class 'C5' incorrectly extends base class 'T5'. +!!! error TS2415: Types of property 'c' are incompatible. +!!! error TS2415: Type 'number' is not assignable to type 'string'. + + declare class CX { static a: string } + declare enum EX { A, B, C } + declare namespace NX { export const a = "hello" } + + type TCX = typeof CX; + type TEX = typeof EX; + type TNX = typeof NX; + + interface I10 extends TCX { a: number } + ~~~ +!!! error TS2430: Interface 'I10' incorrectly extends interface 'typeof CX'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'number' is not assignable to type 'string'. + interface I11 extends TEX { C: string } + ~~~ +!!! error TS2430: Interface 'I11' incorrectly extends interface 'typeof EX'. +!!! error TS2430: Types of property 'C' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'EX'. + interface I12 extends TNX { a: number } + ~~~ +!!! error TS2430: Interface 'I12' incorrectly extends interface 'typeof NX'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'number' is not assignable to type '"hello"'. + interface I14 extends TCX { [x: string]: number } + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'a' of type 'string' is not assignable to string index type 'number'. + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'prototype' of type 'CX' is not assignable to string index type 'number'. + interface I15 extends TEX { [x: string]: number } + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2413: Numeric index type 'string' is not assignable to string index type 'number'. + interface I16 extends TNX { [x: string]: number } + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'a' of type '"hello"' is not assignable to string index type 'number'. + + type Identifiable = { _id: string } & T; + + interface I20 extends Partial { a: string } + ~~~ +!!! error TS2430: Interface 'I20' incorrectly extends interface 'Partial'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number | undefined'. + interface I21 extends Readonly { a: string } + ~~~ +!!! error TS2430: Interface 'I21' incorrectly extends interface 'Readonly'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + interface I22 extends Identifiable { a: string } + ~~~ +!!! error TS2430: Interface 'I22' incorrectly extends interface 'Identifiable'. +!!! error TS2430: Type 'I22' is not assignable to type 'T1'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + interface I23 extends Identifiable { a: string } + ~~~ +!!! error TS2430: Interface 'I23' incorrectly extends interface 'Identifiable'. +!!! error TS2430: Type 'I23' is not assignable to type 'T1'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + + type U = { a: number } | { b: string }; + + interface I30 extends U { x: string } + ~ +!!! error TS2312: An interface may only extend a class or another interface. + interface I31 extends T { x: string } + ~ +!!! error TS2312: An interface may only extend a class or another interface. + \ No newline at end of file diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.js b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.js new file mode 100644 index 00000000000..61f84b2f7fe --- /dev/null +++ b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.js @@ -0,0 +1,97 @@ +//// [interfaceExtendsObjectIntersectionErrors.ts] + +type T1 = { a: number }; +type T2 = T1 & { b: number }; +type T3 = number[]; +type T4 = [string, number]; +type T5 = { [P in 'a' | 'b' | 'c']: string }; + +interface I1 extends T1 { a: string } +interface I2 extends T2 { b: string } +interface I3 extends T3 { length: string } +interface I4 extends T4 { 0: number } +interface I5 extends T5 { c: number } + +type Constructor = new () => T; +declare function Constructor(): Constructor; + +class C1 extends Constructor() { a: string } +class C2 extends Constructor() { b: string } +class C3 extends Constructor() { length: string } +class C4 extends Constructor() { 0: number } +class C5 extends Constructor() { c: number } + +declare class CX { static a: string } +declare enum EX { A, B, C } +declare namespace NX { export const a = "hello" } + +type TCX = typeof CX; +type TEX = typeof EX; +type TNX = typeof NX; + +interface I10 extends TCX { a: number } +interface I11 extends TEX { C: string } +interface I12 extends TNX { a: number } +interface I14 extends TCX { [x: string]: number } +interface I15 extends TEX { [x: string]: number } +interface I16 extends TNX { [x: string]: number } + +type Identifiable = { _id: string } & T; + +interface I20 extends Partial { a: string } +interface I21 extends Readonly { a: string } +interface I22 extends Identifiable { a: string } +interface I23 extends Identifiable { a: string } + +type U = { a: number } | { b: string }; + +interface I30 extends U { x: string } +interface I31 extends T { x: string } + + +//// [interfaceExtendsObjectIntersectionErrors.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var C1 = (function (_super) { + __extends(C1, _super); + function C1() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C1; +}(Constructor())); +var C2 = (function (_super) { + __extends(C2, _super); + function C2() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C2; +}(Constructor())); +var C3 = (function (_super) { + __extends(C3, _super); + function C3() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C3; +}(Constructor())); +var C4 = (function (_super) { + __extends(C4, _super); + function C4() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C4; +}(Constructor())); +var C5 = (function (_super) { + __extends(C5, _super); + function C5() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C5; +}(Constructor())); diff --git a/tests/baselines/reference/intersectionThisTypes.js b/tests/baselines/reference/intersectionThisTypes.js new file mode 100644 index 00000000000..9c7be09eeb8 --- /dev/null +++ b/tests/baselines/reference/intersectionThisTypes.js @@ -0,0 +1,57 @@ +//// [intersectionThisTypes.ts] +interface Thing1 { + a: number; + self(): this; +} + +interface Thing2 { + b: number; + me(): this; +} + +type Thing3 = Thing1 & Thing2; +type Thing4 = Thing3 & string[]; + +function f1(t: Thing3) { + t = t.self(); + t = t.me().self().me(); +} + +interface Thing5 extends Thing4 { + c: string; +} + +function f2(t: Thing5) { + t = t.self(); + t = t.me().self().me(); +} + +interface Component { + extend(props: T): this & T; +} + +interface Label extends Component { + title: string; +} + +function test(label: Label) { + const extended = label.extend({ id: 67 }).extend({ tag: "hello" }); + extended.id; // Ok + extended.tag; // Ok +} + + +//// [intersectionThisTypes.js] +function f1(t) { + t = t.self(); + t = t.me().self().me(); +} +function f2(t) { + t = t.self(); + t = t.me().self().me(); +} +function test(label) { + var extended = label.extend({ id: 67 }).extend({ tag: "hello" }); + extended.id; // Ok + extended.tag; // Ok +} diff --git a/tests/baselines/reference/intersectionThisTypes.symbols b/tests/baselines/reference/intersectionThisTypes.symbols new file mode 100644 index 00000000000..8a8a6cd5496 --- /dev/null +++ b/tests/baselines/reference/intersectionThisTypes.symbols @@ -0,0 +1,127 @@ +=== tests/cases/conformance/types/intersection/intersectionThisTypes.ts === +interface Thing1 { +>Thing1 : Symbol(Thing1, Decl(intersectionThisTypes.ts, 0, 0)) + + a: number; +>a : Symbol(Thing1.a, Decl(intersectionThisTypes.ts, 0, 18)) + + self(): this; +>self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +} + +interface Thing2 { +>Thing2 : Symbol(Thing2, Decl(intersectionThisTypes.ts, 3, 1)) + + b: number; +>b : Symbol(Thing2.b, Decl(intersectionThisTypes.ts, 5, 18)) + + me(): this; +>me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +} + +type Thing3 = Thing1 & Thing2; +>Thing3 : Symbol(Thing3, Decl(intersectionThisTypes.ts, 8, 1)) +>Thing1 : Symbol(Thing1, Decl(intersectionThisTypes.ts, 0, 0)) +>Thing2 : Symbol(Thing2, Decl(intersectionThisTypes.ts, 3, 1)) + +type Thing4 = Thing3 & string[]; +>Thing4 : Symbol(Thing4, Decl(intersectionThisTypes.ts, 10, 30)) +>Thing3 : Symbol(Thing3, Decl(intersectionThisTypes.ts, 8, 1)) + +function f1(t: Thing3) { +>f1 : Symbol(f1, Decl(intersectionThisTypes.ts, 11, 32)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 13, 12)) +>Thing3 : Symbol(Thing3, Decl(intersectionThisTypes.ts, 8, 1)) + + t = t.self(); +>t : Symbol(t, Decl(intersectionThisTypes.ts, 13, 12)) +>t.self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 13, 12)) +>self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) + + t = t.me().self().me(); +>t : Symbol(t, Decl(intersectionThisTypes.ts, 13, 12)) +>t.me().self().me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>t.me().self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>t.me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 13, 12)) +>me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +} + +interface Thing5 extends Thing4 { +>Thing5 : Symbol(Thing5, Decl(intersectionThisTypes.ts, 16, 1)) +>Thing4 : Symbol(Thing4, Decl(intersectionThisTypes.ts, 10, 30)) + + c: string; +>c : Symbol(Thing5.c, Decl(intersectionThisTypes.ts, 18, 33)) +} + +function f2(t: Thing5) { +>f2 : Symbol(f2, Decl(intersectionThisTypes.ts, 20, 1)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 22, 12)) +>Thing5 : Symbol(Thing5, Decl(intersectionThisTypes.ts, 16, 1)) + + t = t.self(); +>t : Symbol(t, Decl(intersectionThisTypes.ts, 22, 12)) +>t.self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 22, 12)) +>self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) + + t = t.me().self().me(); +>t : Symbol(t, Decl(intersectionThisTypes.ts, 22, 12)) +>t.me().self().me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>t.me().self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>t.me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 22, 12)) +>me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +} + +interface Component { +>Component : Symbol(Component, Decl(intersectionThisTypes.ts, 25, 1)) + + extend(props: T): this & T; +>extend : Symbol(Component.extend, Decl(intersectionThisTypes.ts, 27, 21)) +>T : Symbol(T, Decl(intersectionThisTypes.ts, 28, 11)) +>props : Symbol(props, Decl(intersectionThisTypes.ts, 28, 14)) +>T : Symbol(T, Decl(intersectionThisTypes.ts, 28, 11)) +>T : Symbol(T, Decl(intersectionThisTypes.ts, 28, 11)) +} + +interface Label extends Component { +>Label : Symbol(Label, Decl(intersectionThisTypes.ts, 29, 1)) +>Component : Symbol(Component, Decl(intersectionThisTypes.ts, 25, 1)) + + title: string; +>title : Symbol(Label.title, Decl(intersectionThisTypes.ts, 31, 35)) +} + +function test(label: Label) { +>test : Symbol(test, Decl(intersectionThisTypes.ts, 33, 1)) +>label : Symbol(label, Decl(intersectionThisTypes.ts, 35, 14)) +>Label : Symbol(Label, Decl(intersectionThisTypes.ts, 29, 1)) + + const extended = label.extend({ id: 67 }).extend({ tag: "hello" }); +>extended : Symbol(extended, Decl(intersectionThisTypes.ts, 36, 9)) +>label.extend({ id: 67 }).extend : Symbol(Component.extend, Decl(intersectionThisTypes.ts, 27, 21)) +>label.extend : Symbol(Component.extend, Decl(intersectionThisTypes.ts, 27, 21)) +>label : Symbol(label, Decl(intersectionThisTypes.ts, 35, 14)) +>extend : Symbol(Component.extend, Decl(intersectionThisTypes.ts, 27, 21)) +>id : Symbol(id, Decl(intersectionThisTypes.ts, 36, 35)) +>extend : Symbol(Component.extend, Decl(intersectionThisTypes.ts, 27, 21)) +>tag : Symbol(tag, Decl(intersectionThisTypes.ts, 36, 54)) + + extended.id; // Ok +>extended.id : Symbol(id, Decl(intersectionThisTypes.ts, 36, 35)) +>extended : Symbol(extended, Decl(intersectionThisTypes.ts, 36, 9)) +>id : Symbol(id, Decl(intersectionThisTypes.ts, 36, 35)) + + extended.tag; // Ok +>extended.tag : Symbol(tag, Decl(intersectionThisTypes.ts, 36, 54)) +>extended : Symbol(extended, Decl(intersectionThisTypes.ts, 36, 9)) +>tag : Symbol(tag, Decl(intersectionThisTypes.ts, 36, 54)) +} + diff --git a/tests/baselines/reference/intersectionThisTypes.types b/tests/baselines/reference/intersectionThisTypes.types new file mode 100644 index 00000000000..285609cdfdc --- /dev/null +++ b/tests/baselines/reference/intersectionThisTypes.types @@ -0,0 +1,145 @@ +=== tests/cases/conformance/types/intersection/intersectionThisTypes.ts === +interface Thing1 { +>Thing1 : Thing1 + + a: number; +>a : number + + self(): this; +>self : () => this +} + +interface Thing2 { +>Thing2 : Thing2 + + b: number; +>b : number + + me(): this; +>me : () => this +} + +type Thing3 = Thing1 & Thing2; +>Thing3 : Thing3 +>Thing1 : Thing1 +>Thing2 : Thing2 + +type Thing4 = Thing3 & string[]; +>Thing4 : Thing4 +>Thing3 : Thing3 + +function f1(t: Thing3) { +>f1 : (t: Thing3) => void +>t : Thing3 +>Thing3 : Thing3 + + t = t.self(); +>t = t.self() : Thing3 +>t : Thing3 +>t.self() : Thing3 +>t.self : () => Thing3 +>t : Thing3 +>self : () => Thing3 + + t = t.me().self().me(); +>t = t.me().self().me() : Thing3 +>t : Thing3 +>t.me().self().me() : Thing3 +>t.me().self().me : () => Thing3 +>t.me().self() : Thing3 +>t.me().self : () => Thing3 +>t.me() : Thing3 +>t.me : () => Thing3 +>t : Thing3 +>me : () => Thing3 +>self : () => Thing3 +>me : () => Thing3 +} + +interface Thing5 extends Thing4 { +>Thing5 : Thing5 +>Thing4 : Thing4 + + c: string; +>c : string +} + +function f2(t: Thing5) { +>f2 : (t: Thing5) => void +>t : Thing5 +>Thing5 : Thing5 + + t = t.self(); +>t = t.self() : Thing5 +>t : Thing5 +>t.self() : Thing5 +>t.self : () => Thing5 +>t : Thing5 +>self : () => Thing5 + + t = t.me().self().me(); +>t = t.me().self().me() : Thing5 +>t : Thing5 +>t.me().self().me() : Thing5 +>t.me().self().me : () => Thing5 +>t.me().self() : Thing5 +>t.me().self : () => Thing5 +>t.me() : Thing5 +>t.me : () => Thing5 +>t : Thing5 +>me : () => Thing5 +>self : () => Thing5 +>me : () => Thing5 +} + +interface Component { +>Component : Component + + extend(props: T): this & T; +>extend : (props: T) => this & T +>T : T +>props : T +>T : T +>T : T +} + +interface Label extends Component { +>Label : Label +>Component : Component + + title: string; +>title : string +} + +function test(label: Label) { +>test : (label: Label) => void +>label : Label +>Label : Label + + const extended = label.extend({ id: 67 }).extend({ tag: "hello" }); +>extended : Label & { id: number; } & { tag: string; } +>label.extend({ id: 67 }).extend({ tag: "hello" }) : Label & { id: number; } & { tag: string; } +>label.extend({ id: 67 }).extend : (props: T) => Label & { id: number; } & T +>label.extend({ id: 67 }) : Label & { id: number; } +>label.extend : (props: T) => Label & T +>label : Label +>extend : (props: T) => Label & T +>{ id: 67 } : { id: number; } +>id : number +>67 : 67 +>extend : (props: T) => Label & { id: number; } & T +>{ tag: "hello" } : { tag: string; } +>tag : string +>"hello" : "hello" + + extended.id; // Ok +>extended.id : number +>extended : Label & { id: number; } & { tag: string; } +>id : number + + extended.tag; // Ok +>extended.tag : string +>extended : Label & { id: number; } & { tag: string; } +>tag : string +} + From 80e5f2f314b46e327567902a912b2d885e6a4e63 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 22 Jan 2017 11:53:18 -0800 Subject: [PATCH 26/41] Add regression test --- .../conformance/types/keyof/keyofAndIndexedAccess.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts index a4088e65df4..04c26fbe8f7 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts @@ -505,3 +505,15 @@ function updateIds2( // Repro from #13514 declare function head>(list: T): T[0]; + +// Repro from #13604 + +class A { + props: T & { foo: string }; +} + +class B extends A<{ x: number}> { + f(p: this["props"]) { + p.x; + } +} From 6d6b19fd23e7795da5e73c4fe72517d898536b22 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 22 Jan 2017 11:54:39 -0800 Subject: [PATCH 27/41] Fix typo in intersection apparent type --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 60d109d7600..bd8ff7568f3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4871,7 +4871,7 @@ namespace ts { */ function getApparentType(type: Type): Type { const t = type.flags & TypeFlags.TypeVariable ? getBaseConstraintOfType(type) || emptyObjectType : type; - return t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(type) : + return t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(t) : t.flags & TypeFlags.StringLike ? globalStringType : t.flags & TypeFlags.NumberLike ? globalNumberType : t.flags & TypeFlags.BooleanLike ? globalBooleanType : From f0e90c0d8bcc0009dca5e4ffcbcbb9b529779f03 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 22 Jan 2017 11:59:40 -0800 Subject: [PATCH 28/41] Accept new baselines --- .../reference/keyofAndIndexedAccess.js | 38 +++++++++++++++++++ .../reference/keyofAndIndexedAccess.symbols | 28 ++++++++++++++ .../reference/keyofAndIndexedAccess.types | 28 ++++++++++++++ 3 files changed, 94 insertions(+) diff --git a/tests/baselines/reference/keyofAndIndexedAccess.js b/tests/baselines/reference/keyofAndIndexedAccess.js index a86184c8ff0..e7df8bbd5a1 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.js +++ b/tests/baselines/reference/keyofAndIndexedAccess.js @@ -504,6 +504,18 @@ function updateIds2( // Repro from #13514 declare function head>(list: T): T[0]; + +// Repro from #13604 + +class A { + props: T & { foo: string }; +} + +class B extends A<{ x: number}> { + f(p: this["props"]) { + p.x; + } +} //// [keyofAndIndexedAccess.js] @@ -834,6 +846,22 @@ function updateIds2(obj, key, stringMap) { var x = obj[key]; stringMap[x]; // Should be OK. } +// Repro from #13604 +var A = (function () { + function A() { + } + return A; +}()); +var B = (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + B.prototype.f = function (p) { + p.x; + }; + return B; +}(A)); //// [keyofAndIndexedAccess.d.ts] @@ -1066,3 +1094,13 @@ declare function updateIds2>(list: T): T[0]; +declare class A { + props: T & { + foo: string; + }; +} +declare class B extends A<{ + x: number; +}> { + f(p: this["props"]): void; +} diff --git a/tests/baselines/reference/keyofAndIndexedAccess.symbols b/tests/baselines/reference/keyofAndIndexedAccess.symbols index 4c12c6554c9..01501cd719c 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccess.symbols @@ -1816,3 +1816,31 @@ declare function head>(list: T): T[0]; >T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 504, 22)) >T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 504, 22)) +// Repro from #13604 + +class A { +>A : Symbol(A, Decl(keyofAndIndexedAccess.ts, 504, 59)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 508, 8)) + + props: T & { foo: string }; +>props : Symbol(A.props, Decl(keyofAndIndexedAccess.ts, 508, 12)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 508, 8)) +>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 509, 13)) +} + +class B extends A<{ x: number}> { +>B : Symbol(B, Decl(keyofAndIndexedAccess.ts, 510, 1)) +>A : Symbol(A, Decl(keyofAndIndexedAccess.ts, 504, 59)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 512, 19)) + + f(p: this["props"]) { +>f : Symbol(B.f, Decl(keyofAndIndexedAccess.ts, 512, 33)) +>p : Symbol(p, Decl(keyofAndIndexedAccess.ts, 513, 3)) + + p.x; +>p.x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 512, 19)) +>p : Symbol(p, Decl(keyofAndIndexedAccess.ts, 513, 3)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 512, 19)) + } +} + diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 3919d768151..21c9d645ce4 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -2138,3 +2138,31 @@ declare function head>(list: T): T[0]; >T : T >T : T +// Repro from #13604 + +class A { +>A : A +>T : T + + props: T & { foo: string }; +>props : T & { foo: string; } +>T : T +>foo : string +} + +class B extends A<{ x: number}> { +>B : B +>A : A<{ x: number; }> +>x : number + + f(p: this["props"]) { +>f : (p: this["props"]) => void +>p : this["props"] + + p.x; +>p.x : number +>p : this["props"] +>x : number + } +} + From dd0ed44b9aaa7dcd24bb415a5a6a241cd2d6061f Mon Sep 17 00:00:00 2001 From: David Sheldrick Date: Mon, 23 Jan 2017 17:40:20 +0100 Subject: [PATCH 29/41] Add option to output .js files while preserving jsx This commit adds the ability to preserve jsx in source code, but also to output .js files rather than .jsx files. This is useful for react-native which does not support .jsx files. --- lib/protocol.d.ts | 5 +- src/compiler/commandLineParser.ts | 3 +- src/compiler/diagnosticMessages.json | 2 +- src/compiler/types.ts | 3 +- src/harness/unittests/commandLineParsing.ts | 2 +- .../convertCompilerOptionsFromJson.ts | 2 +- src/harness/unittests/matchFiles.ts | 54 ++++++++++++++++- src/server/protocol.ts | 9 +-- tests/cases/unittests/matchFiles.ts | 58 ++++++++++++++++++- 9 files changed, 125 insertions(+), 13 deletions(-) diff --git a/lib/protocol.d.ts b/lib/protocol.d.ts index d6c0246af34..66c2ef5c8db 100644 --- a/lib/protocol.d.ts +++ b/lib/protocol.d.ts @@ -1798,9 +1798,10 @@ declare namespace ts.server.protocol { namespace JsxEmit { type None = "None"; type Preserve = "Preserve"; + type PreserveWithJsExtension = "PreserveWithJsExtension"; type React = "React"; } - type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React; + type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React | JsxEmit.PreserveWithJsExtension; namespace ModuleKind { type None = "None"; type CommonJS = "CommonJS"; @@ -1880,4 +1881,4 @@ declare namespace ts { } import protocol = ts.server.protocol; export = protocol; -export as namespace protocol; \ No newline at end of file +export as namespace protocol; diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index b222df53630..7c69676d6f0 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -67,10 +67,11 @@ namespace ts { name: "jsx", type: createMapFromTemplate({ "preserve": JsxEmit.Preserve, + "preservewithjsextension": JsxEmit.PreserveWithJsExtension, "react": JsxEmit.React }), paramType: Diagnostics.KIND, - description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_or_react, + description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_preserveWithJsExtension_or_react, }, { name: "reactNamespace", diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 43bb7415c88..6646017e73d 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2713,7 +2713,7 @@ "category": "Message", "code": 6079 }, - "Specify JSX code generation: 'preserve' or 'react'": { + "Specify JSX code generation: 'preserve', 'preserveWithJsExtension', or 'react'": { "category": "Message", "code": 6080 }, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c16c199d3eb..9024b7c1b13 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3298,7 +3298,8 @@ export const enum JsxEmit { None = 0, Preserve = 1, - React = 2 + React = 2, + PreserveWithJsExtension = 3 } export const enum NewLineKind { diff --git a/src/harness/unittests/commandLineParsing.ts b/src/harness/unittests/commandLineParsing.ts index 8c691992043..34a096628f9 100644 --- a/src/harness/unittests/commandLineParsing.ts +++ b/src/harness/unittests/commandLineParsing.ts @@ -87,7 +87,7 @@ namespace ts { start: undefined, length: undefined, }, { - messageText: "Argument for '--jsx' option must be: 'preserve', 'react'", + messageText: "Argument for '--jsx' option must be: 'preserve', 'preservewithjsextension', 'react'", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, diff --git a/src/harness/unittests/convertCompilerOptionsFromJson.ts b/src/harness/unittests/convertCompilerOptionsFromJson.ts index f44dc259710..cbfa47180f3 100644 --- a/src/harness/unittests/convertCompilerOptionsFromJson.ts +++ b/src/harness/unittests/convertCompilerOptionsFromJson.ts @@ -94,7 +94,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--jsx' option must be: 'preserve', 'react'", + messageText: "Argument for '--jsx' option must be: 'preserve', 'preservewithjsextension', 'react'", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] diff --git a/src/harness/unittests/matchFiles.ts b/src/harness/unittests/matchFiles.ts index c562fcefe91..2b4bbfd4ee6 100644 --- a/src/harness/unittests/matchFiles.ts +++ b/src/harness/unittests/matchFiles.ts @@ -909,6 +909,31 @@ namespace ts { const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); assertParsed(actual, expected); }); + it("with jsx=preserveWithJsExtension, allowJs=false", () => { + const json = { + compilerOptions: { + jsx: "preserveWithJsExtension", + allowJs: false + } + }; + const expected: ts.ParsedCommandLine = { + options: { + jsx: ts.JsxEmit.PreserveWithJsExtension, + allowJs: false + }, + errors: [], + fileNames: [ + "c:/dev/a.ts", + "c:/dev/b.tsx", + "c:/dev/c.tsx", + ], + wildcardDirectories: { + "c:/dev": ts.WatchDirectoryFlags.Recursive + } + }; + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); + assertParsed(actual, expected); + }); it("with jsx=none, allowJs=true", () => { const json = { compilerOptions: { @@ -961,6 +986,33 @@ namespace ts { const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); assertParsed(actual, expected); }); + it("with jsx=preserveWithJsExtension, allowJs=true", () => { + const json = { + compilerOptions: { + jsx: "preserveWithJsExtension", + allowJs: true + } + }; + const expected: ts.ParsedCommandLine = { + options: { + jsx: ts.JsxEmit.PreserveWithJsExtension, + allowJs: true + }, + errors: [], + fileNames: [ + "c:/dev/a.ts", + "c:/dev/b.tsx", + "c:/dev/c.tsx", + "c:/dev/d.js", + "c:/dev/e.jsx", + ], + wildcardDirectories: { + "c:/dev": ts.WatchDirectoryFlags.Recursive + } + }; + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); + assertParsed(actual, expected); + }); it("exclude .min.js files using wildcards", () => { const json = { compilerOptions: { @@ -1306,4 +1358,4 @@ namespace ts { }); }); }); -} \ No newline at end of file +} diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 680b81dff99..b18c887126b 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -417,7 +417,7 @@ namespace ts.server.protocol { startOffset: number; /** - * Position (can be specified instead of line/offset pair) + * Position (can be specified instead of line/offset pair) */ /* @internal */ startPosition?: number; @@ -433,7 +433,7 @@ namespace ts.server.protocol { endOffset: number; /** - * Position (can be specified instead of line/offset pair) + * Position (can be specified instead of line/offset pair) */ /* @internal */ endPosition?: number; @@ -445,7 +445,7 @@ namespace ts.server.protocol { } /** - * Response for GetCodeFixes request. + * Response for GetCodeFixes request. */ export interface GetCodeFixesResponse extends Response { body?: CodeAction[]; @@ -2272,10 +2272,11 @@ namespace ts.server.protocol { export namespace JsxEmit { export type None = "None"; export type Preserve = "Preserve"; + export type PreserveWithJsExtension = "PreserveWithJsExtension"; export type React = "React"; } - export type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React; + export type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React | JsxEmit.PreserveWithJsExtension; export namespace ModuleKind { export type None = "None"; diff --git a/tests/cases/unittests/matchFiles.ts b/tests/cases/unittests/matchFiles.ts index 91be2de8747..ef982f5f2bb 100644 --- a/tests/cases/unittests/matchFiles.ts +++ b/tests/cases/unittests/matchFiles.ts @@ -898,6 +898,33 @@ namespace ts { assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories); assert.deepEqual(actual.errors, expected.errors); }); + it("with jsx=preserveWithJsExtension, allowJs=false", () => { + const json = { + compilerOptions: { + jsx: "preserveWithJsExtension", + allowJs: false + } + }; + const expected: ts.ParsedCommandLine = { + options: { + jsx: ts.JsxEmit.PreserveWithJsExtension, + allowJs: false + }, + errors: [], + fileNames: [ + "c:/dev/a.ts", + "c:/dev/b.tsx", + "c:/dev/c.tsx", + ], + wildcardDirectories: { + "c:/dev": ts.WatchDirectoryFlags.Recursive + } + }; + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); + assert.deepEqual(actual.fileNames, expected.fileNames); + assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories); + assert.deepEqual(actual.errors, expected.errors); + }); it("with jsx=none, allowJs=true", () => { const json = { compilerOptions: { @@ -954,6 +981,35 @@ namespace ts { assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories); assert.deepEqual(actual.errors, expected.errors); }); + it("with jsx=preserveWithJsExtension, allowJs=true", () => { + const json = { + compilerOptions: { + jsx: "preserveWithJsExtension", + allowJs: true + } + }; + const expected: ts.ParsedCommandLine = { + options: { + jsx: ts.JsxEmit.PreserveWithJsExtension, + allowJs: true + }, + errors: [], + fileNames: [ + "c:/dev/a.ts", + "c:/dev/b.tsx", + "c:/dev/c.tsx", + "c:/dev/d.js", + "c:/dev/e.jsx", + ], + wildcardDirectories: { + "c:/dev": ts.WatchDirectoryFlags.Recursive + } + }; + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); + assert.deepEqual(actual.fileNames, expected.fileNames); + assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories); + assert.deepEqual(actual.errors, expected.errors); + }); describe("with trailing recursive directory", () => { it("in includes", () => { const json = { @@ -1149,4 +1205,4 @@ namespace ts { }); }); }); -} \ No newline at end of file +} From 7879b22ea9b210934c50b8d87df418379dfcc435 Mon Sep 17 00:00:00 2001 From: David Sheldrick Date: Mon, 23 Jan 2017 19:30:24 +0100 Subject: [PATCH 30/41] Add test case for preserveWithJsExtension --- ...utTsxFile_PreserveWithJsExtension.baseline | 26 +++++++++++++++++++ ...itOutputTsxFile_PreserveWithJsExtension.ts | 22 ++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 tests/baselines/reference/getEmitOutputTsxFile_PreserveWithJsExtension.baseline create mode 100644 tests/cases/fourslash/getEmitOutputTsxFile_PreserveWithJsExtension.ts diff --git a/tests/baselines/reference/getEmitOutputTsxFile_PreserveWithJsExtension.baseline b/tests/baselines/reference/getEmitOutputTsxFile_PreserveWithJsExtension.baseline new file mode 100644 index 00000000000..88fb0f0daf6 --- /dev/null +++ b/tests/baselines/reference/getEmitOutputTsxFile_PreserveWithJsExtension.baseline @@ -0,0 +1,26 @@ +EmitSkipped: false +FileName : /tests/cases/fourslash/inputFile1.js.map +{"version":3,"file":"inputFile1.js","sourceRoot":"","sources":["inputFile1.ts"],"names":[],"mappings":"AAAA,kBAAkB;AACjB,IAAI,CAAC,GAAW,CAAC,CAAC;AAClB;IAAA;IAGA,CAAC;IAAD,UAAC;AAAD,CAAC,AAHD,IAGC"}FileName : /tests/cases/fourslash/inputFile1.js +// regular ts file +var t = 5; +var Bar = (function () { + function Bar() { + } + return Bar; +}()); +//# sourceMappingURL=inputFile1.js.mapFileName : /tests/cases/fourslash/inputFile1.d.ts +declare var t: number; +declare class Bar { + x: string; + y: number; +} + +EmitSkipped: false +FileName : /tests/cases/fourslash/inputFile2.js.map +{"version":3,"file":"inputFile2.js","sourceRoot":"","sources":["inputFile2.tsx"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG,QAAQ,CAAC;AACjB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,CAAC,CAAC,EAAG,CAAA"}FileName : /tests/cases/fourslash/inputFile2.js +var y = "my div"; +var x =
; +//# sourceMappingURL=inputFile2.js.mapFileName : /tests/cases/fourslash/inputFile2.d.ts +declare var y: string; +declare var x: any; + diff --git a/tests/cases/fourslash/getEmitOutputTsxFile_PreserveWithJsExtension.ts b/tests/cases/fourslash/getEmitOutputTsxFile_PreserveWithJsExtension.ts new file mode 100644 index 00000000000..a1e4ce2d984 --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputTsxFile_PreserveWithJsExtension.ts @@ -0,0 +1,22 @@ +/// + +// @BaselineFile: getEmitOutputTsxFile_PreserveWithJsExtension.baseline +// @declaration: true +// @sourceMap: true +// @jsx: preserveWithJsExtension + +// @Filename: inputFile1.ts +// @emitThisFile: true +////// regular ts file +//// var t: number = 5; +//// class Bar { +//// x : string; +//// y : number +//// } + +// @Filename: inputFile2.tsx +// @emitThisFile: true +//// var y = "my div"; +//// var x =
+ +verify.baselineGetEmitOutput(); From a32914f6872b9c5764d77f77ea85c7160ff9ae28 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Mon, 23 Jan 2017 11:14:29 -0800 Subject: [PATCH 31/41] Combine `forEachExpectedEmitFile` and `forEachEmittedFile` --- src/compiler/declarationEmitter.ts | 4 ++-- src/compiler/emitter.ts | 2 +- src/compiler/program.ts | 2 +- src/compiler/utilities.ts | 24 ++++++++---------------- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 2287de179e3..46df4fed689 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -32,7 +32,7 @@ namespace ts { export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, targetSourceFile: SourceFile): Diagnostic[] { const declarationDiagnostics = createDiagnosticCollection(); - forEachExpectedEmitFile(host, getDeclarationDiagnosticsFromFile, targetSourceFile); + forEachEmittedFile(host, getDeclarationDiagnosticsFromFile, targetSourceFile); return declarationDiagnostics.getDiagnostics(targetSourceFile ? targetSourceFile.fileName : undefined); function getDeclarationDiagnosticsFromFile({ declarationFilePath }: EmitFileNames, sources: SourceFile[], isBundledEmit: boolean) { @@ -1788,7 +1788,7 @@ namespace ts { } else { // Get the declaration file path - forEachExpectedEmitFile(host, getDeclFileName, referencedFile, emitOnlyDtsFiles); + forEachEmittedFile(host, getDeclFileName, referencedFile, emitOnlyDtsFiles); } if (declFileName) { diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 1c4662fa587..cc006a06637 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -73,7 +73,7 @@ namespace ts { // Emit each output file performance.mark("beforePrint"); - forEachEmittedFile(host, transformed, emitFile, emitOnlyDtsFiles); + forEachEmittedFile(host, emitFile, transformed, emitOnlyDtsFiles); performance.measure("printTime", "beforePrint"); // Clean up emit nodes on parse tree diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 851e206d448..650711afc79 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1707,7 +1707,7 @@ namespace ts { if (!options.noEmit && !options.suppressOutputPathCheck) { const emitHost = getEmitHost(); const emitFilesSeen = createFileMap(!host.useCaseSensitiveFileNames() ? key => key.toLocaleLowerCase() : undefined); - forEachExpectedEmitFile(emitHost, (emitFileNames) => { + forEachEmittedFile(emitHost, (emitFileNames) => { verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen); verifyEmitFilePath(emitFileNames.declarationFilePath, emitFilesSeen); }); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index f59d384e490..b7cc0f0de6d 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2590,27 +2590,20 @@ namespace ts { } /** - * Iterates over the source files that are expected to have an emit output. This function - * is used by the legacy emitter and the declaration emitter and should not be used by - * the tree transforming emitter. + * Iterates over the source files that are expected to have an emit output. * * @param host An EmitHost. * @param action The action to execute. - * @param targetSourceFile An optional target source file to emit. + * @param sourceFilesOrTargetSourceFile + * If an array, the full list of source files to emit. + * Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit. */ - export function forEachExpectedEmitFile(host: EmitHost, - action: (emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean) => void, - targetSourceFile?: SourceFile, + export function forEachEmittedFile( + host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean) => void, + sourceFilesOrTargetSourceFile?: SourceFile[] | SourceFile, emitOnlyDtsFiles?: boolean) { - forEachEmittedFile(host, getSourceFilesToEmit(host, targetSourceFile), action, emitOnlyDtsFiles); - } - /** - * Iterates over each source file to emit. - */ - export function forEachEmittedFile(host: EmitHost, sourceFiles: SourceFile[], - action: (emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean) => void, - emitOnlyDtsFiles?: boolean) { + const sourceFiles = isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile); const options = host.getCompilerOptions(); if (options.outFile || options.out) { if (sourceFiles.length) { @@ -2622,7 +2615,6 @@ namespace ts { } else { for (const sourceFile of sourceFiles) { - const options = host.getCompilerOptions(); const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options)); const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined; From 8d590d51916e6491191634097b8fb04f40d7d964 Mon Sep 17 00:00:00 2001 From: David Sheldrick Date: Mon, 23 Jan 2017 21:42:39 +0100 Subject: [PATCH 32/41] rename preserveWithJsExtension to react-native --- lib/protocol.d.ts | 4 ++-- src/compiler/commandLineParser.ts | 4 ++-- src/compiler/diagnosticMessages.json | 2 +- src/compiler/types.ts | 2 +- src/harness/unittests/commandLineParsing.ts | 2 +- .../unittests/convertCompilerOptionsFromJson.ts | 2 +- src/harness/unittests/matchFiles.ts | 12 ++++++------ src/server/protocol.ts | 4 ++-- ...ine => getEmitOutputTsxFile_ReactNative.baseline} | 0 ...ension.ts => getEmitOutputTsxFile_ReactNative.ts} | 4 ++-- tests/cases/unittests/matchFiles.ts | 12 ++++++------ 11 files changed, 24 insertions(+), 24 deletions(-) rename tests/baselines/reference/{getEmitOutputTsxFile_PreserveWithJsExtension.baseline => getEmitOutputTsxFile_ReactNative.baseline} (100%) rename tests/cases/fourslash/{getEmitOutputTsxFile_PreserveWithJsExtension.ts => getEmitOutputTsxFile_ReactNative.ts} (75%) diff --git a/lib/protocol.d.ts b/lib/protocol.d.ts index 66c2ef5c8db..cd46ebcd366 100644 --- a/lib/protocol.d.ts +++ b/lib/protocol.d.ts @@ -1798,10 +1798,10 @@ declare namespace ts.server.protocol { namespace JsxEmit { type None = "None"; type Preserve = "Preserve"; - type PreserveWithJsExtension = "PreserveWithJsExtension"; + type ReactNative = "ReactNative"; type React = "React"; } - type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React | JsxEmit.PreserveWithJsExtension; + type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React | JsxEmit.ReactNative; namespace ModuleKind { type None = "None"; type CommonJS = "CommonJS"; diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 7c69676d6f0..248726693c9 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -67,11 +67,11 @@ namespace ts { name: "jsx", type: createMapFromTemplate({ "preserve": JsxEmit.Preserve, - "preservewithjsextension": JsxEmit.PreserveWithJsExtension, + "react-native": JsxEmit.ReactNative, "react": JsxEmit.React }), paramType: Diagnostics.KIND, - description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_preserveWithJsExtension_or_react, + description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_react_native_or_react, }, { name: "reactNamespace", diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 6646017e73d..4278784e9ab 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2713,7 +2713,7 @@ "category": "Message", "code": 6079 }, - "Specify JSX code generation: 'preserve', 'preserveWithJsExtension', or 'react'": { + "Specify JSX code generation: 'preserve', 'react-native', or 'react'": { "category": "Message", "code": 6080 }, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 9024b7c1b13..6ac7d573eda 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3299,7 +3299,7 @@ None = 0, Preserve = 1, React = 2, - PreserveWithJsExtension = 3 + ReactNative = 3 } export const enum NewLineKind { diff --git a/src/harness/unittests/commandLineParsing.ts b/src/harness/unittests/commandLineParsing.ts index 34a096628f9..1895fe2d60e 100644 --- a/src/harness/unittests/commandLineParsing.ts +++ b/src/harness/unittests/commandLineParsing.ts @@ -87,7 +87,7 @@ namespace ts { start: undefined, length: undefined, }, { - messageText: "Argument for '--jsx' option must be: 'preserve', 'preservewithjsextension', 'react'", + messageText: "Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, diff --git a/src/harness/unittests/convertCompilerOptionsFromJson.ts b/src/harness/unittests/convertCompilerOptionsFromJson.ts index cbfa47180f3..4e442173883 100644 --- a/src/harness/unittests/convertCompilerOptionsFromJson.ts +++ b/src/harness/unittests/convertCompilerOptionsFromJson.ts @@ -94,7 +94,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--jsx' option must be: 'preserve', 'preservewithjsextension', 'react'", + messageText: "Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] diff --git a/src/harness/unittests/matchFiles.ts b/src/harness/unittests/matchFiles.ts index 2b4bbfd4ee6..38e5c6c4393 100644 --- a/src/harness/unittests/matchFiles.ts +++ b/src/harness/unittests/matchFiles.ts @@ -909,16 +909,16 @@ namespace ts { const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); assertParsed(actual, expected); }); - it("with jsx=preserveWithJsExtension, allowJs=false", () => { + it("with jsx=react-native, allowJs=false", () => { const json = { compilerOptions: { - jsx: "preserveWithJsExtension", + jsx: "react-native", allowJs: false } }; const expected: ts.ParsedCommandLine = { options: { - jsx: ts.JsxEmit.PreserveWithJsExtension, + jsx: ts.JsxEmit.ReactNative, allowJs: false }, errors: [], @@ -986,16 +986,16 @@ namespace ts { const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); assertParsed(actual, expected); }); - it("with jsx=preserveWithJsExtension, allowJs=true", () => { + it("with jsx=react-native, allowJs=true", () => { const json = { compilerOptions: { - jsx: "preserveWithJsExtension", + jsx: "react-native", allowJs: true } }; const expected: ts.ParsedCommandLine = { options: { - jsx: ts.JsxEmit.PreserveWithJsExtension, + jsx: ts.JsxEmit.ReactNative, allowJs: true }, errors: [], diff --git a/src/server/protocol.ts b/src/server/protocol.ts index b18c887126b..e3fe17362d7 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2272,11 +2272,11 @@ namespace ts.server.protocol { export namespace JsxEmit { export type None = "None"; export type Preserve = "Preserve"; - export type PreserveWithJsExtension = "PreserveWithJsExtension"; + export type ReactNative = "ReactNative"; export type React = "React"; } - export type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React | JsxEmit.PreserveWithJsExtension; + export type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React | JsxEmit.ReactNative; export namespace ModuleKind { export type None = "None"; diff --git a/tests/baselines/reference/getEmitOutputTsxFile_PreserveWithJsExtension.baseline b/tests/baselines/reference/getEmitOutputTsxFile_ReactNative.baseline similarity index 100% rename from tests/baselines/reference/getEmitOutputTsxFile_PreserveWithJsExtension.baseline rename to tests/baselines/reference/getEmitOutputTsxFile_ReactNative.baseline diff --git a/tests/cases/fourslash/getEmitOutputTsxFile_PreserveWithJsExtension.ts b/tests/cases/fourslash/getEmitOutputTsxFile_ReactNative.ts similarity index 75% rename from tests/cases/fourslash/getEmitOutputTsxFile_PreserveWithJsExtension.ts rename to tests/cases/fourslash/getEmitOutputTsxFile_ReactNative.ts index a1e4ce2d984..c2aac0e9d03 100644 --- a/tests/cases/fourslash/getEmitOutputTsxFile_PreserveWithJsExtension.ts +++ b/tests/cases/fourslash/getEmitOutputTsxFile_ReactNative.ts @@ -1,9 +1,9 @@ /// -// @BaselineFile: getEmitOutputTsxFile_PreserveWithJsExtension.baseline +// @BaselineFile: getEmitOutputTsxFile_ReactNative.baseline // @declaration: true // @sourceMap: true -// @jsx: preserveWithJsExtension +// @jsx: react-native // @Filename: inputFile1.ts // @emitThisFile: true diff --git a/tests/cases/unittests/matchFiles.ts b/tests/cases/unittests/matchFiles.ts index ef982f5f2bb..e3448136c08 100644 --- a/tests/cases/unittests/matchFiles.ts +++ b/tests/cases/unittests/matchFiles.ts @@ -898,16 +898,16 @@ namespace ts { assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories); assert.deepEqual(actual.errors, expected.errors); }); - it("with jsx=preserveWithJsExtension, allowJs=false", () => { + it("with jsx=react-native, allowJs=false", () => { const json = { compilerOptions: { - jsx: "preserveWithJsExtension", + jsx: "react-native", allowJs: false } }; const expected: ts.ParsedCommandLine = { options: { - jsx: ts.JsxEmit.PreserveWithJsExtension, + jsx: ts.JsxEmit.ReactNative, allowJs: false }, errors: [], @@ -981,16 +981,16 @@ namespace ts { assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories); assert.deepEqual(actual.errors, expected.errors); }); - it("with jsx=preserveWithJsExtension, allowJs=true", () => { + it("with jsx=react-native, allowJs=true", () => { const json = { compilerOptions: { - jsx: "preserveWithJsExtension", + jsx: "react-native", allowJs: true } }; const expected: ts.ParsedCommandLine = { options: { - jsx: ts.JsxEmit.PreserveWithJsExtension, + jsx: ts.JsxEmit.ReactNative, allowJs: true }, errors: [], From 7bf52ee1fde05154eb38042e63ac1ef95d0a415d Mon Sep 17 00:00:00 2001 From: David Sheldrick Date: Mon, 23 Jan 2017 22:08:39 +0100 Subject: [PATCH 33/41] add notifications and tests for jsx react-native es3 --- src/compiler/transformers/es5.ts | 4 ++-- tests/baselines/reference/es3-jsx-preserve.js | 11 +++++++++++ tests/baselines/reference/es3-jsx-preserve.symbols | 11 +++++++++++ tests/baselines/reference/es3-jsx-preserve.types | 13 +++++++++++++ tests/baselines/reference/es3-jsx-react-native.js | 11 +++++++++++ .../reference/es3-jsx-react-native.symbols | 11 +++++++++++ .../baselines/reference/es3-jsx-react-native.types | 13 +++++++++++++ tests/baselines/reference/es3-jsx-react.js | 11 +++++++++++ tests/baselines/reference/es3-jsx-react.symbols | 11 +++++++++++ tests/baselines/reference/es3-jsx-react.types | 13 +++++++++++++ tests/cases/compiler/es3-jsx-preserve.tsx | 9 +++++++++ tests/cases/compiler/es3-jsx-react-native.tsx | 9 +++++++++ tests/cases/compiler/es3-jsx-react.tsx | 9 +++++++++ 13 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/es3-jsx-preserve.js create mode 100644 tests/baselines/reference/es3-jsx-preserve.symbols create mode 100644 tests/baselines/reference/es3-jsx-preserve.types create mode 100644 tests/baselines/reference/es3-jsx-react-native.js create mode 100644 tests/baselines/reference/es3-jsx-react-native.symbols create mode 100644 tests/baselines/reference/es3-jsx-react-native.types create mode 100644 tests/baselines/reference/es3-jsx-react.js create mode 100644 tests/baselines/reference/es3-jsx-react.symbols create mode 100644 tests/baselines/reference/es3-jsx-react.types create mode 100644 tests/cases/compiler/es3-jsx-preserve.tsx create mode 100644 tests/cases/compiler/es3-jsx-react-native.tsx create mode 100644 tests/cases/compiler/es3-jsx-react.tsx diff --git a/src/compiler/transformers/es5.ts b/src/compiler/transformers/es5.ts index 6dd875965d9..972b9214f16 100644 --- a/src/compiler/transformers/es5.ts +++ b/src/compiler/transformers/es5.ts @@ -14,7 +14,7 @@ namespace ts { // enable emit notification only if using --jsx preserve let previousOnEmitNode: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void; let noSubstitution: boolean[]; - if (compilerOptions.jsx === JsxEmit.Preserve) { + if (compilerOptions.jsx === JsxEmit.Preserve || compilerOptions.jsx === JsxEmit.ReactNative) { previousOnEmitNode = context.onEmitNode; context.onEmitNode = onEmitNode; context.enableEmitNotification(SyntaxKind.JsxOpeningElement); @@ -116,4 +116,4 @@ namespace ts { return undefined; } } -} \ No newline at end of file +} diff --git a/tests/baselines/reference/es3-jsx-preserve.js b/tests/baselines/reference/es3-jsx-preserve.js new file mode 100644 index 00000000000..cb1ba2a887d --- /dev/null +++ b/tests/baselines/reference/es3-jsx-preserve.js @@ -0,0 +1,11 @@ +//// [es3-jsx-preserve.tsx] + +const React: any = null; + +const elem =
; + + + +//// [es3-jsx-preserve.jsx] +var React = null; +var elem =
; diff --git a/tests/baselines/reference/es3-jsx-preserve.symbols b/tests/baselines/reference/es3-jsx-preserve.symbols new file mode 100644 index 00000000000..61c9260223f --- /dev/null +++ b/tests/baselines/reference/es3-jsx-preserve.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/es3-jsx-preserve.tsx === + +const React: any = null; +>React : Symbol(React, Decl(es3-jsx-preserve.tsx, 1, 5)) + +const elem =
; +>elem : Symbol(elem, Decl(es3-jsx-preserve.tsx, 3, 5)) +>div : Symbol(unknown) +>div : Symbol(unknown) + + diff --git a/tests/baselines/reference/es3-jsx-preserve.types b/tests/baselines/reference/es3-jsx-preserve.types new file mode 100644 index 00000000000..b37fe8af567 --- /dev/null +++ b/tests/baselines/reference/es3-jsx-preserve.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/es3-jsx-preserve.tsx === + +const React: any = null; +>React : any +>null : null + +const elem =
; +>elem : any +>
: any +>div : any +>div : any + + diff --git a/tests/baselines/reference/es3-jsx-react-native.js b/tests/baselines/reference/es3-jsx-react-native.js new file mode 100644 index 00000000000..08e6e25502b --- /dev/null +++ b/tests/baselines/reference/es3-jsx-react-native.js @@ -0,0 +1,11 @@ +//// [es3-jsx-react-native.tsx] + +const React: any = null; + +const elem =
; + + + +//// [es3-jsx-react-native.js] +var React = null; +var elem =
; diff --git a/tests/baselines/reference/es3-jsx-react-native.symbols b/tests/baselines/reference/es3-jsx-react-native.symbols new file mode 100644 index 00000000000..e7f010bd2ea --- /dev/null +++ b/tests/baselines/reference/es3-jsx-react-native.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/es3-jsx-react-native.tsx === + +const React: any = null; +>React : Symbol(React, Decl(es3-jsx-react-native.tsx, 1, 5)) + +const elem =
; +>elem : Symbol(elem, Decl(es3-jsx-react-native.tsx, 3, 5)) +>div : Symbol(unknown) +>div : Symbol(unknown) + + diff --git a/tests/baselines/reference/es3-jsx-react-native.types b/tests/baselines/reference/es3-jsx-react-native.types new file mode 100644 index 00000000000..1bf199606f2 --- /dev/null +++ b/tests/baselines/reference/es3-jsx-react-native.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/es3-jsx-react-native.tsx === + +const React: any = null; +>React : any +>null : null + +const elem =
; +>elem : any +>
: any +>div : any +>div : any + + diff --git a/tests/baselines/reference/es3-jsx-react.js b/tests/baselines/reference/es3-jsx-react.js new file mode 100644 index 00000000000..861dde74c86 --- /dev/null +++ b/tests/baselines/reference/es3-jsx-react.js @@ -0,0 +1,11 @@ +//// [es3-jsx-react.tsx] + +const React: any = null; + +const elem =
; + + + +//// [es3-jsx-react.js] +var React = null; +var elem = React.createElement("div", null); diff --git a/tests/baselines/reference/es3-jsx-react.symbols b/tests/baselines/reference/es3-jsx-react.symbols new file mode 100644 index 00000000000..465cfab7ea9 --- /dev/null +++ b/tests/baselines/reference/es3-jsx-react.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/es3-jsx-react.tsx === + +const React: any = null; +>React : Symbol(React, Decl(es3-jsx-react.tsx, 1, 5)) + +const elem =
; +>elem : Symbol(elem, Decl(es3-jsx-react.tsx, 3, 5)) +>div : Symbol(unknown) +>div : Symbol(unknown) + + diff --git a/tests/baselines/reference/es3-jsx-react.types b/tests/baselines/reference/es3-jsx-react.types new file mode 100644 index 00000000000..b7734ffc1f0 --- /dev/null +++ b/tests/baselines/reference/es3-jsx-react.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/es3-jsx-react.tsx === + +const React: any = null; +>React : any +>null : null + +const elem =
; +>elem : any +>
: any +>div : any +>div : any + + diff --git a/tests/cases/compiler/es3-jsx-preserve.tsx b/tests/cases/compiler/es3-jsx-preserve.tsx new file mode 100644 index 00000000000..f6092e692b4 --- /dev/null +++ b/tests/cases/compiler/es3-jsx-preserve.tsx @@ -0,0 +1,9 @@ +// @target: ES3 +// @sourcemap: false +// @declaration: false +// @jsx: preserve + +const React: any = null; + +const elem =
; + diff --git a/tests/cases/compiler/es3-jsx-react-native.tsx b/tests/cases/compiler/es3-jsx-react-native.tsx new file mode 100644 index 00000000000..9ed0f9e003d --- /dev/null +++ b/tests/cases/compiler/es3-jsx-react-native.tsx @@ -0,0 +1,9 @@ +// @target: ES3 +// @sourcemap: false +// @declaration: false +// @jsx: react-native + +const React: any = null; + +const elem =
; + diff --git a/tests/cases/compiler/es3-jsx-react.tsx b/tests/cases/compiler/es3-jsx-react.tsx new file mode 100644 index 00000000000..d47aea9613f --- /dev/null +++ b/tests/cases/compiler/es3-jsx-react.tsx @@ -0,0 +1,9 @@ +// @target: ES3 +// @sourcemap: false +// @declaration: false +// @jsx: react + +const React: any = null; + +const elem =
; + From 6fda5a1b3a3018623e3b3d49ab9520a9af24510c Mon Sep 17 00:00:00 2001 From: David Sheldrick Date: Mon, 23 Jan 2017 22:14:51 +0100 Subject: [PATCH 34/41] Update comment about jsx react-native in es5.ts --- src/compiler/transformers/es5.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/transformers/es5.ts b/src/compiler/transformers/es5.ts index 972b9214f16..c3b011fe36d 100644 --- a/src/compiler/transformers/es5.ts +++ b/src/compiler/transformers/es5.ts @@ -11,7 +11,7 @@ namespace ts { export function transformES5(context: TransformationContext) { const compilerOptions = context.getCompilerOptions(); - // enable emit notification only if using --jsx preserve + // enable emit notification only if using --jsx preserve or react-native let previousOnEmitNode: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void; let noSubstitution: boolean[]; if (compilerOptions.jsx === JsxEmit.Preserve || compilerOptions.jsx === JsxEmit.ReactNative) { From da05ced2e5b8807af3698963515bc71da0997a0d Mon Sep 17 00:00:00 2001 From: falsandtru Date: Wed, 18 Jan 2017 12:05:25 +0900 Subject: [PATCH 35/41] Fix Symbol.valueOf method signature --- src/lib/es2015.symbol.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/es2015.symbol.d.ts b/src/lib/es2015.symbol.d.ts index cd7e45595f0..d7ea4fa0328 100644 --- a/src/lib/es2015.symbol.d.ts +++ b/src/lib/es2015.symbol.d.ts @@ -3,7 +3,7 @@ interface Symbol { toString(): string; /** Returns the primitive value of the specified object. */ - valueOf(): Object; + valueOf(): symbol; } interface SymbolConstructor { From 053b3cd893d00b63dda48085c744844128aaba43 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 23 Jan 2017 16:01:29 -0800 Subject: [PATCH 36/41] getFirstToken skips JSDoc Fixes #13519. This is a better fix than #13599. Also fixes broken tests associated with #13599. --- src/harness/unittests/jsDocParsing.ts | 13 +++++++++---- src/services/services.ts | 8 +++----- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/harness/unittests/jsDocParsing.ts b/src/harness/unittests/jsDocParsing.ts index 3cafc9d49ae..98c32c77778 100644 --- a/src/harness/unittests/jsDocParsing.ts +++ b/src/harness/unittests/jsDocParsing.ts @@ -290,16 +290,21 @@ namespace ts { }); describe("getFirstToken", () => { it("gets jsdoc", () => { - const first = ts.createSourceFile("foo.ts", "/** comment */var a = true;", ts.ScriptTarget.ES5, /*setParentNodes*/ true); + const root = ts.createSourceFile("foo.ts", "/** comment */var a = true;", ts.ScriptTarget.ES5, /*setParentNodes*/ true); + assert.isDefined(root); + assert.equal(root.kind, ts.SyntaxKind.SourceFile); + const first = root.getFirstToken(); assert.isDefined(first); - assert.equal(first.kind, 263); + assert.equal(first.kind, ts.SyntaxKind.VarKeyword); }); }); describe("getLastToken", () => { it("gets jsdoc", () => { - const last = ts.createSourceFile("foo.ts", "var a = true;/** comment */", ts.ScriptTarget.ES5, /*setParentNodes*/ true); + const root = ts.createSourceFile("foo.ts", "var a = true;/** comment */", ts.ScriptTarget.ES5, /*setParentNodes*/ true); + assert.isDefined(root); + const last = root.getLastToken(); assert.isDefined(last); - assert.equal(last.kind, 263); + assert.equal(last.kind, ts.SyntaxKind.EndOfFileToken); }); }); }); diff --git a/src/services/services.ts b/src/services/services.ts index cb38b1d500e..208e1031cd2 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -193,8 +193,8 @@ namespace ts { return undefined; } - const child = children[0]; - return child.kind < SyntaxKind.FirstNode || SyntaxKind.FirstJSDocNode <= child.kind && child.kind <= SyntaxKind.LastJSDocNode ? + const child = ts.find(children, kid => kid.kind < SyntaxKind.FirstJSDocNode || kid.kind > SyntaxKind.LastJSDocNode); + return child.kind < SyntaxKind.FirstNode ? child : child.getFirstToken(sourceFile); } @@ -207,9 +207,7 @@ namespace ts { return undefined; } - return child.kind < SyntaxKind.FirstNode || SyntaxKind.FirstJSDocNode <= child.kind && child.kind <= SyntaxKind.LastJSDocNode ? - child : - child.getLastToken(sourceFile); + return child.kind < SyntaxKind.FirstNode ? child : child.getLastToken(sourceFile); } } From 24bb21c55a1842393d523d8b4a26f5f230d24e10 Mon Sep 17 00:00:00 2001 From: Herrington Darkholme Date: Tue, 24 Jan 2017 11:24:30 +0800 Subject: [PATCH 37/41] address code review --- src/compiler/checker.ts | 11 +++++++---- tests/baselines/reference/objectSpread.js | 5 ++--- tests/baselines/reference/objectSpread.symbols | 5 ++--- tests/baselines/reference/objectSpread.types | 7 +++---- .../reference/objectSpreadNegative.errors.txt | 4 ++-- tests/cases/conformance/types/spread/objectSpread.ts | 3 +-- 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 97ca01bc086..1a1cea4633f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6291,6 +6291,9 @@ namespace ts { if (right.flags & TypeFlags.Union) { return mapType(right, t => getSpreadType(left, t)); } + if (right.flags & TypeFlags.NonPrimitive) { + return emptyObjectType; + } const members = createMap(); const skippedPrivateMembers = createMap(); @@ -15719,12 +15722,12 @@ namespace ts { } } - /** + /** * Static members being set on a constructor function may conflict with built-in properties - * of Function. Esp. in ECMAScript 5 there are non-configurable and non-writable - * built-in properties. This check issues a transpile error when a class has a static + * of Function. Esp. in ECMAScript 5 there are non-configurable and non-writable + * built-in properties. This check issues a transpile error when a class has a static * member with the same name as a non-writable built-in property. - * + * * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.3 * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.5 * @see http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-function-constructor diff --git a/tests/baselines/reference/objectSpread.js b/tests/baselines/reference/objectSpread.js index 259b86628a5..2bc3b9e11bd 100644 --- a/tests/baselines/reference/objectSpread.js +++ b/tests/baselines/reference/objectSpread.js @@ -79,8 +79,7 @@ let computedAfter: { a: number, b: string, "at the end": number } = let a = 12; let shortCutted: { a: number, b: string } = { ...o, a } // non primitive -let spreadNonPrimitve = { ...{}} - +let spreadNonPrimitive = { ...{}}; //// [objectSpread.js] @@ -151,5 +150,5 @@ var computedAfter = __assign({}, o, (_c = { b: 'yeah' }, _c['at the end'] = 14, var a = 12; var shortCutted = __assign({}, o, { a: a }); // non primitive -var spreadNonPrimitve = __assign({}, {}); +var spreadNonPrimitive = __assign({}, {}); var _a, _b, _c; diff --git a/tests/baselines/reference/objectSpread.symbols b/tests/baselines/reference/objectSpread.symbols index 69c9ed34341..1ec2520e166 100644 --- a/tests/baselines/reference/objectSpread.symbols +++ b/tests/baselines/reference/objectSpread.symbols @@ -317,7 +317,6 @@ let shortCutted: { a: number, b: string } = { ...o, a } >a : Symbol(a, Decl(objectSpread.ts, 78, 51)) // non primitive -let spreadNonPrimitve = { ...{}} ->spreadNonPrimitve : Symbol(spreadNonPrimitve, Decl(objectSpread.ts, 80, 3)) - +let spreadNonPrimitive = { ...{}}; +>spreadNonPrimitive : Symbol(spreadNonPrimitive, Decl(objectSpread.ts, 80, 3)) diff --git a/tests/baselines/reference/objectSpread.types b/tests/baselines/reference/objectSpread.types index 8a8df1a497f..950dab43465 100644 --- a/tests/baselines/reference/objectSpread.types +++ b/tests/baselines/reference/objectSpread.types @@ -408,10 +408,9 @@ let shortCutted: { a: number, b: string } = { ...o, a } >a : number // non primitive -let spreadNonPrimitve = { ...{}} ->spreadNonPrimitve : { constructor: Function; toString(): string; toLocaleString(): string; valueOf(): Object; hasOwnProperty(v: string): boolean; isPrototypeOf(v: Object): boolean; propertyIsEnumerable(v: string): boolean; } ->{ ...{}} : { constructor: Function; toString(): string; toLocaleString(): string; valueOf(): Object; hasOwnProperty(v: string): boolean; isPrototypeOf(v: Object): boolean; propertyIsEnumerable(v: string): boolean; } +let spreadNonPrimitive = { ...{}}; +>spreadNonPrimitive : {} +>{ ...{}} : {} >{} : object >{} : {} - diff --git a/tests/baselines/reference/objectSpreadNegative.errors.txt b/tests/baselines/reference/objectSpreadNegative.errors.txt index 2b0960996ff..d9106d651a3 100644 --- a/tests/baselines/reference/objectSpreadNegative.errors.txt +++ b/tests/baselines/reference/objectSpreadNegative.errors.txt @@ -14,7 +14,7 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(37,19): error TS269 tests/cases/conformance/types/spread/objectSpreadNegative.ts(42,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures. tests/cases/conformance/types/spread/objectSpreadNegative.ts(46,12): error TS2339: Property 'b' does not exist on type '{}'. tests/cases/conformance/types/spread/objectSpreadNegative.ts(52,9): error TS2339: Property 'm' does not exist on type '{ p: number; }'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(57,11): error TS2339: Property 'a' does not exist on type '{ constructor: Function; toString(): string; toLocaleString(): string; valueOf(): Object; hasOwnProperty(v: string): boolean; isPrototypeOf(v: Object): boolean; propertyIsEnumerable(v: string): boolean; }'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(57,11): error TS2339: Property 'a' does not exist on type '{}'. tests/cases/conformance/types/spread/objectSpreadNegative.ts(61,14): error TS2698: Spread types may only be created from object types. tests/cases/conformance/types/spread/objectSpreadNegative.ts(64,14): error TS2698: Spread types may only be created from object types. @@ -107,7 +107,7 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(64,14): error TS269 let spreadObj = { ...obj }; spreadObj.a; // error 'a' is not in {} ~ -!!! error TS2339: Property 'a' does not exist on type '{ constructor: Function; toString(): string; toLocaleString(): string; valueOf(): Object; hasOwnProperty(v: string): boolean; isPrototypeOf(v: Object): boolean; propertyIsEnumerable(v: string): boolean; }'. +!!! error TS2339: Property 'a' does not exist on type '{}'. // generics function f(t: T, u: U) { diff --git a/tests/cases/conformance/types/spread/objectSpread.ts b/tests/cases/conformance/types/spread/objectSpread.ts index c4562e6f196..59b93bdd9e4 100644 --- a/tests/cases/conformance/types/spread/objectSpread.ts +++ b/tests/cases/conformance/types/spread/objectSpread.ts @@ -79,5 +79,4 @@ let computedAfter: { a: number, b: string, "at the end": number } = let a = 12; let shortCutted: { a: number, b: string } = { ...o, a } // non primitive -let spreadNonPrimitve = { ...{}} - +let spreadNonPrimitive = { ...{}}; From ebb666a9c2e01a5ae1358252e0dde6a3e83f11f1 Mon Sep 17 00:00:00 2001 From: David Sheldrick Date: Tue, 24 Jan 2017 05:09:30 +0100 Subject: [PATCH 38/41] delete fourslash testcase for --jsx react-native --- .../getEmitOutputTsxFile_ReactNative.baseline | 26 ------------------- .../getEmitOutputTsxFile_ReactNative.ts | 22 ---------------- 2 files changed, 48 deletions(-) delete mode 100644 tests/baselines/reference/getEmitOutputTsxFile_ReactNative.baseline delete mode 100644 tests/cases/fourslash/getEmitOutputTsxFile_ReactNative.ts diff --git a/tests/baselines/reference/getEmitOutputTsxFile_ReactNative.baseline b/tests/baselines/reference/getEmitOutputTsxFile_ReactNative.baseline deleted file mode 100644 index 88fb0f0daf6..00000000000 --- a/tests/baselines/reference/getEmitOutputTsxFile_ReactNative.baseline +++ /dev/null @@ -1,26 +0,0 @@ -EmitSkipped: false -FileName : /tests/cases/fourslash/inputFile1.js.map -{"version":3,"file":"inputFile1.js","sourceRoot":"","sources":["inputFile1.ts"],"names":[],"mappings":"AAAA,kBAAkB;AACjB,IAAI,CAAC,GAAW,CAAC,CAAC;AAClB;IAAA;IAGA,CAAC;IAAD,UAAC;AAAD,CAAC,AAHD,IAGC"}FileName : /tests/cases/fourslash/inputFile1.js -// regular ts file -var t = 5; -var Bar = (function () { - function Bar() { - } - return Bar; -}()); -//# sourceMappingURL=inputFile1.js.mapFileName : /tests/cases/fourslash/inputFile1.d.ts -declare var t: number; -declare class Bar { - x: string; - y: number; -} - -EmitSkipped: false -FileName : /tests/cases/fourslash/inputFile2.js.map -{"version":3,"file":"inputFile2.js","sourceRoot":"","sources":["inputFile2.tsx"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG,QAAQ,CAAC;AACjB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,CAAC,CAAC,EAAG,CAAA"}FileName : /tests/cases/fourslash/inputFile2.js -var y = "my div"; -var x =
; -//# sourceMappingURL=inputFile2.js.mapFileName : /tests/cases/fourslash/inputFile2.d.ts -declare var y: string; -declare var x: any; - diff --git a/tests/cases/fourslash/getEmitOutputTsxFile_ReactNative.ts b/tests/cases/fourslash/getEmitOutputTsxFile_ReactNative.ts deleted file mode 100644 index c2aac0e9d03..00000000000 --- a/tests/cases/fourslash/getEmitOutputTsxFile_ReactNative.ts +++ /dev/null @@ -1,22 +0,0 @@ -/// - -// @BaselineFile: getEmitOutputTsxFile_ReactNative.baseline -// @declaration: true -// @sourceMap: true -// @jsx: react-native - -// @Filename: inputFile1.ts -// @emitThisFile: true -////// regular ts file -//// var t: number = 5; -//// class Bar { -//// x : string; -//// y : number -//// } - -// @Filename: inputFile2.tsx -// @emitThisFile: true -//// var y = "my div"; -//// var x =
- -verify.baselineGetEmitOutput(); From 0a4632fe79c0390db616812ee9a5d2dd1fc1cff6 Mon Sep 17 00:00:00 2001 From: David Sheldrick Date: Tue, 24 Jan 2017 07:16:15 +0100 Subject: [PATCH 39/41] revert change to lib/protocol.d.ts --- lib/protocol.d.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/protocol.d.ts b/lib/protocol.d.ts index cd46ebcd366..d6c0246af34 100644 --- a/lib/protocol.d.ts +++ b/lib/protocol.d.ts @@ -1798,10 +1798,9 @@ declare namespace ts.server.protocol { namespace JsxEmit { type None = "None"; type Preserve = "Preserve"; - type ReactNative = "ReactNative"; type React = "React"; } - type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React | JsxEmit.ReactNative; + type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React; namespace ModuleKind { type None = "None"; type CommonJS = "CommonJS"; @@ -1881,4 +1880,4 @@ declare namespace ts { } import protocol = ts.server.protocol; export = protocol; -export as namespace protocol; +export as namespace protocol; \ No newline at end of file From 0d21c241b2954a1ba8b23f98c6a3f083de22d3bd Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 24 Jan 2017 09:06:46 -0800 Subject: [PATCH 40/41] Support find-all-references on mapped types. * Need to put a 'mappedTypeOrigin' property in SymbolLinks --- src/compiler/checker.ts | 15 ++++++++++++--- src/compiler/types.ts | 1 + tests/cases/fourslash/findAllRefsForMappedType.ts | 9 +++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 tests/cases/fourslash/findAllRefsForMappedType.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bd8ff7568f3..878e7d47273 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4618,12 +4618,14 @@ namespace ts { const typeParameter = getTypeParameterFromMappedType(type); const constraintType = getConstraintTypeFromMappedType(type); const templateType = getTemplateTypeFromMappedType(type); - const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); + const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T' const templateReadonly = !!type.declaration.readonlyToken; const templateOptional = !!type.declaration.questionToken; if (type.declaration.typeParameter.constraint.kind === SyntaxKind.TypeOperator) { // We have a { [P in keyof T]: X } - forEachType(getLiteralTypeFromPropertyNames(modifiersType), addMemberForKeyType); + for (const propertySymbol of getPropertiesOfType(modifiersType)) { + addMemberForKeyType(getLiteralTypeFromPropertyName(propertySymbol), propertySymbol); + } if (getIndexInfoOfType(modifiersType, IndexKind.String)) { addMemberForKeyType(stringType); } @@ -4638,7 +4640,7 @@ namespace ts { } setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, undefined); - function addMemberForKeyType(t: Type) { + function addMemberForKeyType(t: Type, propertySymbol?: Symbol) { // Create a mapper from T to the current iteration type constituent. Then, if the // mapped type is itself an instantiated type, combine the iteration mapper with the // instantiation mapper. @@ -4654,6 +4656,9 @@ namespace ts { const prop = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | (isOptional ? SymbolFlags.Optional : 0), propName); prop.type = propType; prop.isReadonly = templateReadonly || modifiersProp && isReadonlySymbol(modifiersProp); + if (propertySymbol) { + prop.mappedTypeOrigin = propertySymbol; + } members.set(propName, prop); } else if (t.flags & TypeFlags.String) { @@ -20230,6 +20235,10 @@ namespace ts { const links = symbol as SymbolLinks; return [links.leftSpread, links.rightSpread]; } + if ((symbol as SymbolLinks).mappedTypeOrigin) { + return getRootSymbols((symbol as SymbolLinks).mappedTypeOrigin); + } + let target: Symbol; let next = symbol; while (next = getSymbolLinks(next).target) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6ac7d573eda..8b49af402cf 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2712,6 +2712,7 @@ containingType?: UnionOrIntersectionType; // Containing union or intersection type for synthetic property leftSpread?: Symbol; // Left source for synthetic spread property rightSpread?: Symbol; // Right source for synthetic spread property + mappedTypeOrigin?: Symbol; // For a property on a mapped type, points back to the orignal 'T' from 'keyof T'. hasNonUniformType?: boolean; // True if constituents have non-uniform types isPartial?: boolean; // True if syntheric property of union type occurs in some but not all constituents isDiscriminantProperty?: boolean; // True if discriminant synthetic property diff --git a/tests/cases/fourslash/findAllRefsForMappedType.ts b/tests/cases/fourslash/findAllRefsForMappedType.ts new file mode 100644 index 00000000000..620eae0815c --- /dev/null +++ b/tests/cases/fourslash/findAllRefsForMappedType.ts @@ -0,0 +1,9 @@ +/// + +////interface T { [|a|]: number }; +////type U { [K in keyof T]: string }; +////type V = { [K in keyof U]: boolean }; +////const u: U = { [|a|]: "" } +////const v: V = { [|a|]: true } + +verify.rangesReferenceEachOther(); From b48a2811f67b66a14cd4584999a7d7ab2e723b56 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 24 Jan 2017 13:03:16 -0800 Subject: [PATCH 41/41] Update baselines --- tests/baselines/reference/mappedTypes1.js | 2 +- tests/baselines/reference/mappedTypes1.types | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/baselines/reference/mappedTypes1.js b/tests/baselines/reference/mappedTypes1.js index 1998ad5ab6b..4dd8f172179 100644 --- a/tests/baselines/reference/mappedTypes1.js +++ b/tests/baselines/reference/mappedTypes1.js @@ -139,9 +139,9 @@ declare let x2: string; declare let x3: number; declare let x4: { toString: void; - valueOf: void; toFixed: void; toExponential: void; toPrecision: void; + valueOf: void; toLocaleString: void; }; diff --git a/tests/baselines/reference/mappedTypes1.types b/tests/baselines/reference/mappedTypes1.types index 35d13143bab..a9a7f53a899 100644 --- a/tests/baselines/reference/mappedTypes1.types +++ b/tests/baselines/reference/mappedTypes1.types @@ -165,7 +165,7 @@ let x3 = f3(); >f3 : () => { [P in keyof T1]: void; } let x4 = f4(); ->x4 : { toString: void; valueOf: void; toFixed: void; toExponential: void; toPrecision: void; toLocaleString: void; } ->f4() : { toString: void; valueOf: void; toFixed: void; toExponential: void; toPrecision: void; toLocaleString: void; } +>x4 : { toString: void; toFixed: void; toExponential: void; toPrecision: void; valueOf: void; toLocaleString: void; } +>f4() : { toString: void; toFixed: void; toExponential: void; toPrecision: void; valueOf: void; toLocaleString: void; } >f4 : () => { [P in keyof T1]: void; }