| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -413,9 +413,9 @@ namespace ts { | |||
| 413 | 413 | location = getParseTreeNode(location); | |
| 414 | 414 | return location ? getSymbolsInScope(location, meaning) : []; | |
| 415 | 415 | }, | |
| 416 | - getSymbolAtLocation: (node: Node) => { | ||
| 416 | + getSymbolAtLocation: node => { | ||
| 417 | 417 | node = getParseTreeNode(node); | |
| 418 | - return node && getSymbolAtLocation(node); | ||
| 418 | + return node ? getSymbolAtLocation(node) : undefined; | ||
| 419 | 419 | }, | |
| 420 | 420 | getShorthandAssignmentValueSymbol: node => { | |
| 421 | 421 | node = getParseTreeNode(node); | |
@@ -34249,7 +34249,7 @@ namespace ts { | |||
| 34249 | 34249 | if (constructorDeclaration && constructorDeclaration.kind === SyntaxKind.Constructor) { | |
| 34250 | 34250 | return (<ClassDeclaration>constructorDeclaration.parent).symbol; | |
| 34251 | 34251 | } | |
| 34252 | - break; | ||
| 34252 | + return undefined; | ||
| 34253 | 34253 | ||
| 34254 | 34254 | case SyntaxKind.StringLiteral: | |
| 34255 | 34255 | case SyntaxKind.NoSubstitutionTemplateLiteral: | |
@@ -34287,10 +34287,10 @@ namespace ts { | |||
| 34287 | 34287 | return isLiteralImportTypeNode(node) ? getSymbolAtLocation(node.argument.literal) : undefined; | |
| 34288 | 34288 | ||
| 34289 | 34289 | case SyntaxKind.ExportKeyword: | |
| 34290 | - if (isExportAssignment(node.parent)) { | ||
| 34291 | - return Debug.assertDefined(node.parent.symbol); | ||
| 34292 | - } | ||
| 34293 | - break; | ||
| 34290 | + return isExportAssignment(node.parent) ? Debug.assertDefined(node.parent.symbol) : undefined; | ||
| 34291 | + | ||
| 34292 | + default: | ||
| 34293 | + return undefined; | ||
| 34294 | 34294 | } | |
| 34295 | 34295 | } | |
| 34296 | 34296 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2288,7 +2288,7 @@ namespace FourSlash { | |||
| 2288 | 2288 | return result; | |
| 2289 | 2289 | } | |
| 2290 | 2290 | ||
| 2291 | - private rangeText({ fileName, pos, end }: Range): string { | ||
| 2291 | + public rangeText({ fileName, pos, end }: Range): string { | ||
| 2292 | 2292 | return this.getFileContent(fileName).slice(pos, end); | |
| 2293 | 2293 | } | |
| 2294 | 2294 | ||
@@ -3637,18 +3637,17 @@ namespace FourSlash { | |||
| 3637 | 3637 | const testData = parseTestData(absoluteBasePath, content, absoluteFileName); | |
| 3638 | 3638 | const state = new TestState(absoluteFileName, absoluteBasePath, testType, testData); | |
| 3639 | 3639 | const actualFileName = Harness.IO.resolvePath(fileName) || absoluteFileName; | |
| 3640 | - const output = ts.transpileModule(content, { reportDiagnostics: true, fileName: actualFileName, compilerOptions: { target: ts.ScriptTarget.ES2015, sourceMap: true } }); | ||
| 3640 | + const output = ts.transpileModule(content, { reportDiagnostics: true, fileName: actualFileName, compilerOptions: { target: ts.ScriptTarget.ES2015, inlineSourceMap: true } }); | ||
| 3641 | 3641 | if (output.diagnostics!.length > 0) { | |
| 3642 | 3642 | throw new Error(`Syntax error in ${absoluteBasePath}: ${output.diagnostics![0].messageText}`); | |
| 3643 | 3643 | } | |
| 3644 | - runCode(output, state, actualFileName); | ||
| 3644 | + runCode(output.outputText, state, actualFileName); | ||
| 3645 | 3645 | } | |
| 3646 | 3646 | ||
| 3647 | - function runCode(output: ts.TranspileOutput, state: TestState, fileName: string): void { | ||
| 3647 | + function runCode(code: string, state: TestState, fileName: string): void { | ||
| 3648 | 3648 | // Compile and execute the test | |
| 3649 | 3649 | const generatedFile = ts.changeExtension(fileName, ".js"); | |
| 3650 | - const mapFile = generatedFile + ".map"; | ||
| 3651 | - const wrappedCode = `(function(test, goTo, plugins, verify, edit, debug, format, cancellation, classification, completion, verifyOperationIsCancelled) {${output.outputText}\n//# sourceURL=${generatedFile}\n})`; | ||
| 3650 | + const wrappedCode = `(function(test, goTo, plugins, verify, edit, debug, format, cancellation, classification, completion, verifyOperationIsCancelled) {${code}\n//# sourceURL=${generatedFile}\n})`; | ||
| 3652 | 3651 | ||
| 3653 | 3652 | type SourceMapSupportModule = typeof import("source-map-support") & { | |
| 3654 | 3653 | // TODO(rbuckton): This is missing from the DT definitions and needs to be added. | |
@@ -3668,7 +3667,6 @@ namespace FourSlash { | |||
| 3668 | 3667 | sourceMapSupportModule?.install({ | |
| 3669 | 3668 | retrieveFile: path => { | |
| 3670 | 3669 | return path === generatedFile ? wrappedCode : | |
| 3671 | - path === mapFile ? output.sourceMapText! : | ||
| 3672 | 3670 | undefined!; | |
| 3673 | 3671 | } | |
| 3674 | 3672 | }); | |
@@ -3687,7 +3685,7 @@ namespace FourSlash { | |||
| 3687 | 3685 | f(test, goTo, plugins, verify, edit, debug, format, cancellation, FourSlashInterface.Classification, FourSlashInterface.Completion, verifyOperationIsCancelled); | |
| 3688 | 3686 | } | |
| 3689 | 3687 | catch (err) { | |
| 3690 | - // ensure we trigger 'source-map-support' while we still have the handler attached | ||
| 3688 | + // ensure 'source-map-support' is triggered while we still have the handler attached by accessing `error.stack`. | ||
| 3691 | 3689 | err.stack?.toString(); | |
| 3692 | 3690 | throw err; | |
| 3693 | 3691 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,6 +23,10 @@ namespace FourSlashInterface { | |||
| 23 | 23 | return this.state.getRanges(); | |
| 24 | 24 | } | |
| 25 | 25 | ||
| 26 | + public rangeText(range: FourSlash.Range): string { | ||
| 27 | + return this.state.rangeText(range); | ||
| 28 | + } | ||
| 29 | + | ||
| 26 | 30 | public spans(): ts.TextSpan[] { | |
| 27 | 31 | return this.ranges().map(r => ts.createTextSpan(r.pos, r.end - r.pos)); | |
| 28 | 32 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -88,6 +88,7 @@ namespace ts { | |||
| 88 | 88 | } | |
| 89 | 89 | ||
| 90 | 90 | export function getMeaningFromLocation(node: Node): SemanticMeaning { | |
| 91 | + node = getAdjustedReferenceLocation(node); | ||
| 91 | 92 | if (node.kind === SyntaxKind.SourceFile) { | |
| 92 | 93 | return SemanticMeaning.Value; | |
| 93 | 94 | } | |
@@ -114,24 +115,6 @@ namespace ts { | |||
| 114 | 115 | // This might be T["name"], which is actually referencing a property and not a type. So allow both meanings. | |
| 115 | 116 | return SemanticMeaning.Type | SemanticMeaning.Value; | |
| 116 | 117 | } | |
| 117 | - else if (isModifier(node) && contains(node.parent.modifiers, node)) { | ||
| 118 | - // on the modifier of a declaration | ||
| 119 | - return getMeaningFromDeclaration(node.parent); | ||
| 120 | - } | ||
| 121 | - else if (node.kind === SyntaxKind.ClassKeyword && isClassLike(node.parent) || | ||
| 122 | - node.kind === SyntaxKind.InterfaceKeyword && isInterfaceDeclaration(node.parent) || | ||
| 123 | - node.kind === SyntaxKind.TypeKeyword && isTypeAliasDeclaration(node.parent) || | ||
| 124 | - node.kind === SyntaxKind.EnumKeyword && isEnumDeclaration(node.parent) || | ||
| 125 | - node.kind === SyntaxKind.FunctionKeyword && isFunctionLikeDeclaration(node.parent) || | ||
| 126 | - node.kind === SyntaxKind.GetKeyword && isGetAccessorDeclaration(node.parent) || | ||
| 127 | - node.kind === SyntaxKind.SetKeyword && isSetAccessorDeclaration(node.parent) || | ||
| 128 | - (node.kind === SyntaxKind.NamespaceKeyword || node.kind === SyntaxKind.ModuleKeyword) && isModuleDeclaration(node.parent)) { | ||
| 129 | - // on the keyword of a declaration | ||
| 130 | - return getMeaningFromDeclaration(node.parent); | ||
| 131 | - } | ||
| 132 | - else if (node.kind === SyntaxKind.TypeKeyword && isImportClause(node.parent) && node.parent.isTypeOnly) { | ||
| 133 | - return getMeaningFromDeclaration(node.parent.parent); | ||
| 134 | - } | ||
| 135 | 118 | else { | |
| 136 | 119 | return SemanticMeaning.Value; | |
| 137 | 120 | } | |
@@ -986,8 +969,36 @@ namespace ts { | |||
| 986 | 969 | return location; | |
| 987 | 970 | } | |
| 988 | 971 | } | |
| 972 | + if (node.kind === SyntaxKind.ExtendsKeyword) { | ||
| 973 | + // ... <T /**/extends [|U|]> ... | ||
| 974 | + if (isTypeParameterDeclaration(parent) && parent.constraint && isTypeReferenceNode(parent.constraint)) { | ||
| 975 | + return parent.constraint.typeName; | ||
| 976 | + } | ||
| 977 | + // ... T /**/extends [|U|] ? ... | ||
| 978 | + if (isConditionalTypeNode(parent) && isTypeReferenceNode(parent.extendsType)) { | ||
| 979 | + return parent.extendsType.typeName; | ||
| 980 | + } | ||
| 981 | + } | ||
| 982 | + // ... T extends /**/infer [|U|] ? ... | ||
| 983 | + if (node.kind === SyntaxKind.InferKeyword && isInferTypeNode(parent)) { | ||
| 984 | + return parent.typeParameter.name; | ||
| 985 | + } | ||
| 986 | + // { [ [|K|] /**/in keyof T]: ... } | ||
| 987 | + if (node.kind === SyntaxKind.InKeyword && isTypeParameterDeclaration(parent) && isMappedTypeNode(parent.parent)) { | ||
| 988 | + return parent.name; | ||
| 989 | + } | ||
| 990 | + // /**/keyof [|T|] | ||
| 991 | + if (node.kind === SyntaxKind.KeyOfKeyword && isTypeOperatorNode(parent) && parent.operator === SyntaxKind.KeyOfKeyword && | ||
| 992 | + isTypeReferenceNode(parent.type)) { | ||
| 993 | + return parent.type.typeName; | ||
| 994 | + } | ||
| 995 | + // /**/readonly [|name|][] | ||
| 996 | + if (node.kind === SyntaxKind.ReadonlyKeyword && isTypeOperatorNode(parent) && parent.operator === SyntaxKind.ReadonlyKeyword && | ||
| 997 | + isArrayTypeNode(parent.type) && isTypeReferenceNode(parent.type.elementType)) { | ||
| 998 | + return parent.type.elementType.typeName; | ||
| 999 | + } | ||
| 989 | 1000 | if (!forRename) { | |
| 990 | - // /**/new [|name|](...) | ||
| 1001 | + // /**/new [|name|] | ||
| 991 | 1002 | // /**/void [|name|] | |
| 992 | 1003 | // /**/void obj.[|name|] | |
| 993 | 1004 | // /**/typeof [|name|] | |
@@ -1007,6 +1018,21 @@ namespace ts { | |||
| 1007 | 1018 | return skipOuterExpressions(parent.expression); | |
| 1008 | 1019 | } | |
| 1009 | 1020 | } | |
| 1021 | + // left /**/in [|name|] | ||
| 1022 | + // left /**/instanceof [|name|] | ||
| 1023 | + if ((node.kind === SyntaxKind.InKeyword || node.kind === SyntaxKind.InstanceOfKeyword) && isBinaryExpression(parent) && parent.operatorToken === node) { | ||
| 1024 | + return skipOuterExpressions(parent.right); | ||
| 1025 | + } | ||
| 1026 | + // left /**/as [|name|] | ||
| 1027 | + if (node.kind === SyntaxKind.AsKeyword && isAsExpression(parent) && isTypeReferenceNode(parent.type)) { | ||
| 1028 | + return parent.type.typeName; | ||
| 1029 | + } | ||
| 1030 | + // for (... /**/in [|name|]) | ||
| 1031 | + // for (... /**/of [|name|]) | ||
| 1032 | + if (node.kind === SyntaxKind.InKeyword && isForInStatement(parent) || | ||
| 1033 | + node.kind === SyntaxKind.OfKeyword && isForOfStatement(parent)) { | ||
| 1034 | + return skipOuterExpressions(parent.expression); | ||
| 1035 | + } | ||
| 1010 | 1036 | } | |
| 1011 | 1037 | return node; | |
| 1012 | 1038 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -181,6 +181,7 @@ declare namespace FourSlashInterface { | |||
| 181 | 181 | ranges(): Range[]; | |
| 182 | 182 | spans(): Array<{ start: number, length: number }>; | |
| 183 | 183 | rangesByText(): ts.Map<Range[]>; | |
| 184 | + rangeText(range: Range): string; | ||
| 184 | 185 | markerByName(s: string): Marker; | |
| 185 | 186 | symbolsInScope(range: Range): any[]; | |
| 186 | 187 | setTypesRegistry(map: { [key: string]: void }): void; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -71,7 +71,7 @@ const [ | |||
| 71 | 71 | ] = test.ranges(); | |
| 72 | 72 | verify.referenceGroups(classDecl1_classKeyword, [{ definition: "class C1", ranges: [classDecl1_name] }]); | |
| 73 | 73 | verify.referenceGroups(classDecl1_extendsKeyword, [{ definition: "class Base", ranges: [baseDecl_name, classDecl1_extendsName, interfaceDecl1_extendsName] }]); | |
| 74 | - verify.referenceGroups(classDecl1_implementsKeyword, [{ definition: "", ranges: [implemented1Decl_name, classDecl1_implementsName] }]); | ||
| 74 | + verify.referenceGroups(classDecl1_implementsKeyword, [{ definition: "interface Implemented1", ranges: [implemented1Decl_name, classDecl1_implementsName] }]); | ||
| 75 | 75 | for (const keyword of [getDecl_getKeyword, setDecl_setKeyword]) { | |
| 76 | 76 | verify.referenceGroups(keyword, [{ definition: "(property) C1.e: number", ranges: [getDecl_name, setDecl_name] }]); | |
| 77 | 77 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,17 +3,42 @@ | |||
| 3 | 3 | ////[|class [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeDelta": -1 |}C|] { | |
| 4 | 4 | //// [|static [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeDelta": -1 |}x|] = 1;|] | |
| 5 | 5 | ////}|] | |
| 6 | - /////*newKeyword*/new [|C|](); | ||
| 7 | - /////*voidKeyword*/void [|C|]; | ||
| 8 | - /////*typeofKeyword*/typeof [|C|]; | ||
| 9 | - /////*deleteKeyword*/delete [|C|].[|x|]; | ||
| 6 | + ////[|new|] [|C|](); | ||
| 7 | + ////[|void|] [|C|]; | ||
| 8 | + ////[|typeof|] [|C|]; | ||
| 9 | + ////[|delete|] [|C|].[|x|]; | ||
| 10 | 10 | ////async function* f() { | |
| 11 | - //// /*yieldKeyword*/yield [|C|]; | ||
| 12 | - //// /*awaitKeyword*/await [|C|]; | ||
| 11 | + //// [|yield|] [|C|]; | ||
| 12 | + //// [|await|] [|C|]; | ||
| 13 | 13 | ////} | |
| 14 | + ////"x" [|in|] [|C|]; | ||
| 15 | + ////undefined [|instanceof|] [|C|]; | ||
| 16 | + ////undefined [|as|] [|C|]; | ||
| 14 | 17 | ||
| 15 | - const [, classDef,, xDef, newC, voidC, typeofC, deleteC, deleteCx, yieldC, awaitC] = test.ranges(); | ||
| 16 | - for (const keyword of ["newKeyword", "voidKeyword", "typeofKeyword", "yieldKeyword", "awaitKeyword"]) { | ||
| 17 | - verify.referenceGroups(keyword, [{ definition: "class C", ranges: [classDef, newC, voidC, typeofC, deleteC, yieldC, awaitC] }]); | ||
| 18 | - } | ||
| 19 | - verify.referenceGroups("deleteKeyword", [{ definition: "(property) C.x: number", ranges: [xDef, deleteCx] }]); | ||
| 18 | + const [ | ||
| 19 | + classDecl, | ||
| 20 | + classDecl_name, | ||
| 21 | + fieldDecl, | ||
| 22 | + fieldDecl_name, | ||
| 23 | + newKeyword, | ||
| 24 | + newC, | ||
| 25 | + voidKeyword, | ||
| 26 | + voidC, | ||
| 27 | + typeofKeyword, | ||
| 28 | + typeofC, | ||
| 29 | + deleteKeyword, | ||
| 30 | + deleteC, | ||
| 31 | + deleteCx, | ||
| 32 | + yieldKeyword, | ||
| 33 | + yieldC, | ||
| 34 | + awaitKeyword, | ||
| 35 | + awaitC, | ||
| 36 | + inKeyword, | ||
| 37 | + inC, | ||
| 38 | + instanceofKeyword, | ||
| 39 | + instanceofC, | ||
| 40 | + asKeyword, | ||
| 41 | + asC, | ||
| 42 | + ] = test.ranges(); | ||
| 43 | + verify.referenceGroups([newKeyword, voidKeyword, typeofKeyword, yieldKeyword, awaitKeyword, inKeyword, instanceofKeyword, asKeyword], [{ definition: "class C", ranges: [classDecl_name, newC, voidC, typeofC, deleteC, yieldC, awaitC, inC, instanceofC, asC] }]); | ||
| 44 | + verify.referenceGroups(deleteKeyword, [{ definition: "(property) C.x: number", ranges: [fieldDecl_name, deleteCx] }]); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -249,7 +249,7 @@ verify.referenceGroups([exportDecl4_exportKeyword, exportDecl4_typeKeyword, expo | |||
| 249 | 249 | verify.referenceGroups(exportDecl4_asKeyword, [{ definition: "(alias) const j3: 2\nexport j3", ranges: [exportDecl4_name] }]); | |
| 250 | 250 | ||
| 251 | 251 | // exportDecl5: | |
| 252 | - verify.referenceGroups([exportDecl5_exportKeyword, exportDecl5_typeKeyword], [{ definition: "", ranges: [typeDecl1_name, exportDecl5_name] }]); | ||
| 252 | + verify.referenceGroups([exportDecl5_exportKeyword, exportDecl5_typeKeyword], [{ definition: "type Z1 = 1", ranges: [typeDecl1_name, exportDecl5_name] }]); | ||
| 253 | 253 | ||
| 254 | 254 | // exportDecl6: | |
| 255 | 255 | verify.noReferences(exportDecl6_exportKeyword); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,43 @@ | |||
| 1 | + /// <reference path='fourslash.ts'/> | ||
| 2 | + | ||
| 3 | + ////[|{| "id": "interfaceDecl" |}interface [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeId": "interfaceDecl" |}I|] {}|] | ||
| 4 | + ////function f<T [|extends|] [|I|]>() {} | ||
| 5 | + ////type A1<T, [|{| "isWriteAccess": true, "isDefinition": true |}U|]> = T [|extends|] [|U|] ? 1 : 0; | ||
| 6 | + ////type A2<T> = T extends [|infer|] [|{| "isWriteAccess": true, "isDefinition": true |}U|] ? 1 : 0; | ||
| 7 | + ////type A3<T> = { [[|{| "id": "mappedType_param" |}[|{| "isWriteAccess": true, "isDefinition": true, "contextRangeId": "mappedType_param" |}P|] [|in|] keyof T|]]: 1 }; | ||
| 8 | + ////type A4<[|{| "isWriteAccess": true, "isDefinition": true |}T|]> = [|keyof|] [|T|]; | ||
| 9 | + ////type A5<[|{| "isWriteAccess": true, "isDefinition": true |}T|]> = [|readonly|] [|T|][]; | ||
| 10 | + | ||
| 11 | + const [ | ||
| 12 | + interfaceDecl, | ||
| 13 | + interfaceDecl_name, | ||
| 14 | + | ||
| 15 | + typeParam_extendsKeyword, | ||
| 16 | + typeParam_constraint, | ||
| 17 | + | ||
| 18 | + typeParamA1_name, | ||
| 19 | + conditionalType_extendsKeyword, | ||
| 20 | + conditionalType_extendsType, | ||
| 21 | + | ||
| 22 | + inferType_inferKeyword, | ||
| 23 | + inferType_type, | ||
| 24 | + | ||
| 25 | + mappedType_param, | ||
| 26 | + mappedType_name, | ||
| 27 | + mappedType_inOperator, | ||
| 28 | + | ||
| 29 | + typeParamA4_name, | ||
| 30 | + keyofOperator_keyofKeyword, | ||
| 31 | + keyofOperator_type, | ||
| 32 | + | ||
| 33 | + typeParamA5_name, | ||
| 34 | + readonlyOperator_readonlyKeyword, | ||
| 35 | + readonlyOperator_elementType, | ||
| 36 | + ] = test.ranges(); | ||
| 37 | + | ||
| 38 | + verify.referenceGroups(typeParam_extendsKeyword, [{ definition: "interface I", ranges: [interfaceDecl_name, typeParam_constraint] }]); | ||
| 39 | + verify.referenceGroups(conditionalType_extendsKeyword, [{ definition: "(type parameter) U in type A1<T, U>", ranges: [typeParamA1_name, conditionalType_extendsType] }]); | ||
| 40 | + verify.referenceGroups(inferType_inferKeyword, [{ definition: "(type parameter) U", ranges: [inferType_type] }]); | ||
| 41 | + verify.referenceGroups(mappedType_inOperator, [{ definition: "(type parameter) P", ranges: [mappedType_name] }]); | ||
| 42 | + verify.referenceGroups(keyofOperator_keyofKeyword, [{ definition: "(type parameter) T in type A4<T>", ranges: [typeParamA4_name, keyofOperator_type] }]); | ||
| 43 | + verify.referenceGroups(readonlyOperator_readonlyKeyword, [{ definition: "(type parameter) T in type A5<T>", ranges: [typeParamA5_name, readonlyOperator_elementType] }]); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments