mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-03-06 02:00:01 -06:00
Merge pull request #2966 from Microsoft/getTypeDefinitionAtPosition
Get type definition at position
This commit is contained in:
commit
15f4b58d6c
@ -1570,6 +1570,28 @@ module FourSlash {
|
||||
this.currentCaretPosition = definition.textSpan.start;
|
||||
}
|
||||
|
||||
public goToTypeDefinition(definitionIndex: number) {
|
||||
if (definitionIndex === 0) {
|
||||
this.scenarioActions.push('<GoToTypeDefinition />');
|
||||
}
|
||||
else {
|
||||
this.taoInvalidReason = 'GoToTypeDefinition not supported for non-zero definition indices';
|
||||
}
|
||||
|
||||
var definitions = this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
if (!definitions || !definitions.length) {
|
||||
this.raiseError('goToTypeDefinition failed - expected to at least one definition location but got 0');
|
||||
}
|
||||
|
||||
if (definitionIndex >= definitions.length) {
|
||||
this.raiseError('goToTypeDefinition failed - definitionIndex value (' + definitionIndex + ') exceeds definition list size (' + definitions.length + ')');
|
||||
}
|
||||
|
||||
var definition = definitions[definitionIndex];
|
||||
this.openFile(definition.fileName);
|
||||
this.currentCaretPosition = definition.textSpan.start;
|
||||
}
|
||||
|
||||
public verifyDefinitionLocationExists(negative: boolean) {
|
||||
this.taoInvalidReason = 'verifyDefinitionLocationExists NYI';
|
||||
|
||||
@ -1589,8 +1611,18 @@ module FourSlash {
|
||||
var assertFn = negative ? assert.notEqual : assert.equal;
|
||||
|
||||
var definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
var actualCount = definitions && definitions.length || 0;
|
||||
|
||||
assertFn(definitions.length, expectedCount, this.messageAtLastKnownMarker("Definitions Count"));
|
||||
assertFn(actualCount, expectedCount, this.messageAtLastKnownMarker("Definitions Count"));
|
||||
}
|
||||
|
||||
public verifyTypeDefinitionsCount(negative: boolean, expectedCount: number) {
|
||||
var assertFn = negative ? assert.notEqual : assert.equal;
|
||||
|
||||
var definitions = this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
var actualCount = definitions && definitions.length || 0;
|
||||
|
||||
assertFn(actualCount, expectedCount, this.messageAtLastKnownMarker("Type definitions Count"));
|
||||
}
|
||||
|
||||
public verifyDefinitionsName(negative: boolean, expectedName: string, expectedContainerName: string) {
|
||||
|
||||
@ -342,6 +342,9 @@ module Harness.LanguageService {
|
||||
getDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] {
|
||||
return unwrapJSONCallResult(this.shim.getDefinitionAtPosition(fileName, position));
|
||||
}
|
||||
getTypeDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[]{
|
||||
return unwrapJSONCallResult(this.shim.getTypeDefinitionAtPosition(fileName, position));
|
||||
}
|
||||
getReferencesAtPosition(fileName: string, position: number): ts.ReferenceEntry[] {
|
||||
return unwrapJSONCallResult(this.shim.getReferencesAtPosition(fileName, position));
|
||||
}
|
||||
|
||||
@ -300,6 +300,32 @@ module ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] {
|
||||
var lineOffset = this.positionToOneBasedLineOffset(fileName, position);
|
||||
var args: protocol.FileLocationRequestArgs = {
|
||||
file: fileName,
|
||||
line: lineOffset.line,
|
||||
offset: lineOffset.offset,
|
||||
};
|
||||
|
||||
var request = this.processRequest<protocol.TypeDefinitionRequest>(CommandNames.TypeDefinition, args);
|
||||
var response = this.processResponse<protocol.TypeDefinitionResponse>(request);
|
||||
|
||||
return response.body.map(entry => {
|
||||
var fileName = entry.file;
|
||||
var start = this.lineOffsetToPosition(fileName, entry.start);
|
||||
var end = this.lineOffsetToPosition(fileName, entry.end);
|
||||
return {
|
||||
containerKind: "",
|
||||
containerName: "",
|
||||
fileName: fileName,
|
||||
textSpan: ts.createTextSpanFromBounds(start, end),
|
||||
kind: "",
|
||||
name: ""
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
findReferences(fileName: string, position: number): ReferencedSymbol[]{
|
||||
// Not yet implemented.
|
||||
return [];
|
||||
|
||||
@ -773,7 +773,7 @@ module ts.server {
|
||||
findConfigFile(searchPath: string): string {
|
||||
while (true) {
|
||||
var fileName = ts.combinePaths(searchPath, "tsconfig.json");
|
||||
if (sys.fileExists(fileName)) {
|
||||
if (this.host.fileExists(fileName)) {
|
||||
return fileName;
|
||||
}
|
||||
var parentPath = ts.getDirectoryPath(searchPath);
|
||||
@ -923,7 +923,7 @@ module ts.server {
|
||||
var proj = this.createProject(configFilename, projectOptions);
|
||||
for (var i = 0, len = parsedCommandLine.fileNames.length; i < len; i++) {
|
||||
var rootFilename = parsedCommandLine.fileNames[i];
|
||||
if (ts.sys.fileExists(rootFilename)) {
|
||||
if (this.host.fileExists(rootFilename)) {
|
||||
var info = this.openFile(rootFilename, clientFileName == rootFilename);
|
||||
proj.addRoot(info);
|
||||
}
|
||||
|
||||
15
src/server/protocol.d.ts
vendored
15
src/server/protocol.d.ts
vendored
@ -125,6 +125,14 @@ declare module ts.server.protocol {
|
||||
export interface DefinitionRequest extends FileLocationRequest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to type request; value of command field is
|
||||
* "typeDefinition". Return response giving the file locations that
|
||||
* define the type for the symbol found in file at location line, col.
|
||||
*/
|
||||
export interface TypeDefinitionRequest extends FileLocationRequest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Location in source code expressed as (one-based) line and character offset.
|
||||
*/
|
||||
@ -165,6 +173,13 @@ declare module ts.server.protocol {
|
||||
body?: FileSpan[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Definition response message. Gives text range for definition.
|
||||
*/
|
||||
export interface TypeDefinitionResponse extends Response {
|
||||
body?: FileSpan[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get occurrences request; value of command field is
|
||||
* "occurrences". Return response giving spans that are relevant
|
||||
|
||||
@ -97,6 +97,7 @@ module ts.server {
|
||||
export var Rename = "rename";
|
||||
export var Saveto = "saveto";
|
||||
export var SignatureHelp = "signatureHelp";
|
||||
export var TypeDefinition = "typeDefinition";
|
||||
export var Unknown = "unknown";
|
||||
}
|
||||
|
||||
@ -285,7 +286,29 @@ module ts.server {
|
||||
}));
|
||||
}
|
||||
|
||||
getOccurrences(line: number, offset: number, fileName: string): protocol.OccurrencesResponseItem[] {
|
||||
getTypeDefinition(line: number, offset: number, fileName: string): protocol.FileSpan[] {
|
||||
var file = ts.normalizePath(fileName);
|
||||
var project = this.projectService.getProjectForFile(file);
|
||||
if (!project) {
|
||||
throw Errors.NoProject;
|
||||
}
|
||||
|
||||
var compilerService = project.compilerService;
|
||||
var position = compilerService.host.lineOffsetToPosition(file, line, offset);
|
||||
|
||||
var definitions = compilerService.languageService.getTypeDefinitionAtPosition(file, position);
|
||||
if (!definitions) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return definitions.map(def => ({
|
||||
file: def.fileName,
|
||||
start: compilerService.host.positionToLineOffset(def.fileName, def.textSpan.start),
|
||||
end: compilerService.host.positionToLineOffset(def.fileName, ts.textSpanEnd(def.textSpan))
|
||||
}));
|
||||
}
|
||||
|
||||
getOccurrences(line: number, offset: number, fileName: string): protocol.OccurrencesResponseItem[]{
|
||||
fileName = ts.normalizePath(fileName);
|
||||
let project = this.projectService.getProjectForFile(fileName);
|
||||
|
||||
@ -817,6 +840,11 @@ module ts.server {
|
||||
response = this.getDefinition(defArgs.line, defArgs.offset, defArgs.file);
|
||||
break;
|
||||
}
|
||||
case CommandNames.TypeDefinition: {
|
||||
var defArgs = <protocol.FileLocationRequestArgs>request.arguments;
|
||||
response = this.getTypeDefinition(defArgs.line, defArgs.offset, defArgs.file);
|
||||
break;
|
||||
}
|
||||
case CommandNames.References: {
|
||||
var refArgs = <protocol.FileLocationRequestArgs>request.arguments;
|
||||
response = this.getReferences(refArgs.line, refArgs.offset, refArgs.file);
|
||||
|
||||
@ -1001,6 +1001,8 @@ module ts {
|
||||
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[];
|
||||
|
||||
getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[];
|
||||
getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[];
|
||||
|
||||
getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[];
|
||||
findReferences(fileName: string, position: number): ReferencedSymbol[];
|
||||
getDocumentHighlights(fileName: string, position: number, filesToSearch: string[]): DocumentHighlights[];
|
||||
@ -3502,19 +3504,6 @@ module ts {
|
||||
return ScriptElementKind.unknown;
|
||||
}
|
||||
|
||||
function getTypeKind(type: Type): string {
|
||||
let flags = type.getFlags();
|
||||
|
||||
if (flags & TypeFlags.Enum) return ScriptElementKind.enumElement;
|
||||
if (flags & TypeFlags.Class) return ScriptElementKind.classElement;
|
||||
if (flags & TypeFlags.Interface) return ScriptElementKind.interfaceElement;
|
||||
if (flags & TypeFlags.TypeParameter) return ScriptElementKind.typeParameterElement;
|
||||
if (flags & TypeFlags.Intrinsic) return ScriptElementKind.primitiveType;
|
||||
if (flags & TypeFlags.StringLiteral) return ScriptElementKind.primitiveType;
|
||||
|
||||
return ScriptElementKind.unknown;
|
||||
}
|
||||
|
||||
function getSymbolModifiers(symbol: Symbol): string {
|
||||
return symbol && symbol.declarations && symbol.declarations.length > 0
|
||||
? getNodeModifiers(symbol.declarations[0])
|
||||
@ -3929,6 +3918,71 @@ module ts {
|
||||
};
|
||||
}
|
||||
|
||||
function getDefinitionFromSymbol(symbol: Symbol, node: Node): DefinitionInfo[] {
|
||||
let typeChecker = program.getTypeChecker();
|
||||
let result: DefinitionInfo[] = [];
|
||||
let declarations = symbol.getDeclarations();
|
||||
let symbolName = typeChecker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol
|
||||
let symbolKind = getSymbolKind(symbol, node);
|
||||
let containerSymbol = symbol.parent;
|
||||
let containerName = containerSymbol ? typeChecker.symbolToString(containerSymbol, node) : "";
|
||||
|
||||
if (!tryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) &&
|
||||
!tryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) {
|
||||
// Just add all the declarations.
|
||||
forEach(declarations, declaration => {
|
||||
result.push(createDefinitionInfo(declaration, symbolKind, symbolName, containerName));
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
function tryAddConstructSignature(symbol: Symbol, location: Node, symbolKind: string, symbolName: string, containerName: string, result: DefinitionInfo[]) {
|
||||
// Applicable only if we are in a new expression, or we are on a constructor declaration
|
||||
// and in either case the symbol has a construct signature definition, i.e. class
|
||||
if (isNewExpressionTarget(location) || location.kind === SyntaxKind.ConstructorKeyword) {
|
||||
if (symbol.flags & SymbolFlags.Class) {
|
||||
let classDeclaration = <ClassDeclaration>symbol.getDeclarations()[0];
|
||||
Debug.assert(classDeclaration && classDeclaration.kind === SyntaxKind.ClassDeclaration);
|
||||
|
||||
return tryAddSignature(classDeclaration.members, /*selectConstructors*/ true, symbolKind, symbolName, containerName, result);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function tryAddCallSignature(symbol: Symbol, location: Node, symbolKind: string, symbolName: string, containerName: string, result: DefinitionInfo[]) {
|
||||
if (isCallExpressionTarget(location) || isNewExpressionTarget(location) || isNameOfFunctionDeclaration(location)) {
|
||||
return tryAddSignature(symbol.declarations, /*selectConstructors*/ false, symbolKind, symbolName, containerName, result);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function tryAddSignature(signatureDeclarations: Declaration[], selectConstructors: boolean, symbolKind: string, symbolName: string, containerName: string, result: DefinitionInfo[]) {
|
||||
let declarations: Declaration[] = [];
|
||||
let definition: Declaration;
|
||||
|
||||
forEach(signatureDeclarations, d => {
|
||||
if ((selectConstructors && d.kind === SyntaxKind.Constructor) ||
|
||||
(!selectConstructors && (d.kind === SyntaxKind.FunctionDeclaration || d.kind === SyntaxKind.MethodDeclaration || d.kind === SyntaxKind.MethodSignature))) {
|
||||
declarations.push(d);
|
||||
if ((<FunctionLikeDeclaration>d).body) definition = d;
|
||||
}
|
||||
});
|
||||
|
||||
if (definition) {
|
||||
result.push(createDefinitionInfo(definition, symbolKind, symbolName, containerName));
|
||||
return true;
|
||||
}
|
||||
else if (declarations.length) {
|
||||
result.push(createDefinitionInfo(lastOrUndefined(declarations), symbolKind, symbolName, containerName));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Goto definition
|
||||
function getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] {
|
||||
synchronizeHostData();
|
||||
@ -4003,67 +4057,47 @@ module ts {
|
||||
declaration => createDefinitionInfo(declaration, shorthandSymbolKind, shorthandSymbolName, shorthandContainerName));
|
||||
}
|
||||
|
||||
let result: DefinitionInfo[] = [];
|
||||
let declarations = symbol.getDeclarations();
|
||||
let symbolName = typeChecker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol
|
||||
let symbolKind = getSymbolKind(symbol, node);
|
||||
let containerSymbol = symbol.parent;
|
||||
let containerName = containerSymbol ? typeChecker.symbolToString(containerSymbol, node) : "";
|
||||
return getDefinitionFromSymbol(symbol, node);
|
||||
}
|
||||
|
||||
if (!tryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) &&
|
||||
!tryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) {
|
||||
// Just add all the declarations.
|
||||
forEach(declarations, declaration => {
|
||||
result.push(createDefinitionInfo(declaration, symbolKind, symbolName, containerName));
|
||||
});
|
||||
/// Goto type
|
||||
function getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] {
|
||||
synchronizeHostData();
|
||||
|
||||
let sourceFile = getValidSourceFile(fileName);
|
||||
|
||||
let node = getTouchingPropertyName(sourceFile, position);
|
||||
if (!node) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return result;
|
||||
let typeChecker = program.getTypeChecker();
|
||||
|
||||
function tryAddConstructSignature(symbol: Symbol, location: Node, symbolKind: string, symbolName: string, containerName: string, result: DefinitionInfo[]) {
|
||||
// Applicable only if we are in a new expression, or we are on a constructor declaration
|
||||
// and in either case the symbol has a construct signature definition, i.e. class
|
||||
if (isNewExpressionTarget(location) || location.kind === SyntaxKind.ConstructorKeyword) {
|
||||
if (symbol.flags & SymbolFlags.Class) {
|
||||
let classDeclaration = <ClassDeclaration>symbol.getDeclarations()[0];
|
||||
Debug.assert(classDeclaration && classDeclaration.kind === SyntaxKind.ClassDeclaration);
|
||||
|
||||
return tryAddSignature(classDeclaration.members, /*selectConstructors*/ true, symbolKind, symbolName, containerName, result);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
let symbol = typeChecker.getSymbolAtLocation(node);
|
||||
if (!symbol) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function tryAddCallSignature(symbol: Symbol, location: Node, symbolKind: string, symbolName: string, containerName: string, result: DefinitionInfo[]) {
|
||||
if (isCallExpressionTarget(location) || isNewExpressionTarget(location) || isNameOfFunctionDeclaration(location)) {
|
||||
return tryAddSignature(symbol.declarations, /*selectConstructors*/ false, symbolKind, symbolName, containerName, result);
|
||||
}
|
||||
return false;
|
||||
let type = typeChecker.getTypeOfSymbolAtLocation(symbol, node);
|
||||
if (!type) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function tryAddSignature(signatureDeclarations: Declaration[], selectConstructors: boolean, symbolKind: string, symbolName: string, containerName: string, result: DefinitionInfo[]) {
|
||||
let declarations: Declaration[] = [];
|
||||
let definition: Declaration;
|
||||
|
||||
forEach(signatureDeclarations, d => {
|
||||
if ((selectConstructors && d.kind === SyntaxKind.Constructor) ||
|
||||
(!selectConstructors && (d.kind === SyntaxKind.FunctionDeclaration || d.kind === SyntaxKind.MethodDeclaration || d.kind === SyntaxKind.MethodSignature))) {
|
||||
declarations.push(d);
|
||||
if ((<FunctionLikeDeclaration>d).body) definition = d;
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
var result: DefinitionInfo[] = [];
|
||||
forEach((<UnionType>type).types, t => {
|
||||
if (t.symbol) {
|
||||
result.push(...getDefinitionFromSymbol(t.symbol, node));
|
||||
}
|
||||
});
|
||||
|
||||
if (definition) {
|
||||
result.push(createDefinitionInfo(definition, symbolKind, symbolName, containerName));
|
||||
return true;
|
||||
}
|
||||
else if (declarations.length) {
|
||||
result.push(createDefinitionInfo(lastOrUndefined(declarations), symbolKind, symbolName, containerName));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!type.symbol) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return getDefinitionFromSymbol(type.symbol, node);
|
||||
}
|
||||
|
||||
function getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[] {
|
||||
@ -6496,6 +6530,7 @@ module ts {
|
||||
getSignatureHelpItems,
|
||||
getQuickInfoAtPosition,
|
||||
getDefinitionAtPosition,
|
||||
getTypeDefinitionAtPosition,
|
||||
getReferencesAtPosition,
|
||||
findReferences,
|
||||
getOccurrencesAtPosition,
|
||||
|
||||
@ -132,6 +132,14 @@ module ts {
|
||||
*/
|
||||
getDefinitionAtPosition(fileName: string, position: number): string;
|
||||
|
||||
/**
|
||||
* Returns a JSON-encoded value of the type:
|
||||
* { fileName: string; textSpan: { start: number; length: number}; kind: string; name: string; containerKind: string; containerName: string }
|
||||
*
|
||||
* Or undefined value if no definition can be found.
|
||||
*/
|
||||
getTypeDefinitionAtPosition(fileName: string, position: number): string;
|
||||
|
||||
/**
|
||||
* Returns a JSON-encoded value of the type:
|
||||
* { fileName: string; textSpan: { start: number; length: number}; isWriteAccess: boolean }[]
|
||||
@ -589,6 +597,20 @@ module ts {
|
||||
});
|
||||
}
|
||||
|
||||
/// GOTO Type
|
||||
|
||||
/**
|
||||
* Computes the definition location of the type of the symbol
|
||||
* at the requested position.
|
||||
*/
|
||||
public getTypeDefinitionAtPosition(fileName: string, position: number): string {
|
||||
return this.forwardJSONCall(
|
||||
"getTypeDefinitionAtPosition('" + fileName + "', " + position + ")",
|
||||
() => {
|
||||
return this.languageService.getTypeDefinitionAtPosition(fileName, position);
|
||||
});
|
||||
}
|
||||
|
||||
public getRenameInfo(fileName: string, position: number): string {
|
||||
return this.forwardJSONCall(
|
||||
"getRenameInfo('" + fileName + "', " + position + ")",
|
||||
|
||||
@ -119,6 +119,10 @@ module FourSlashInterface {
|
||||
FourSlash.currentTestState.goToDefinition(definitionIndex);
|
||||
}
|
||||
|
||||
public type(definitionIndex: number = 0) {
|
||||
FourSlash.currentTestState.goToTypeDefinition(definitionIndex);
|
||||
}
|
||||
|
||||
public position(position: number, fileIndex?: number);
|
||||
public position(position: number, fileName?: string);
|
||||
public position(position: number, fileNameOrIndex?: any) {
|
||||
@ -234,6 +238,10 @@ module FourSlashInterface {
|
||||
FourSlash.currentTestState.verifyDefinitionsCount(this.negative, expectedCount);
|
||||
}
|
||||
|
||||
public typeDefinitionCountIs(expectedCount: number) {
|
||||
FourSlash.currentTestState.verifyTypeDefinitionsCount(this.negative, expectedCount);
|
||||
}
|
||||
|
||||
public definitionLocationExists() {
|
||||
FourSlash.currentTestState.verifyDefinitionLocationExists(this.negative);
|
||||
}
|
||||
|
||||
14
tests/cases/fourslash/goToTypeDefinition.ts
Normal file
14
tests/cases/fourslash/goToTypeDefinition.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: goToTypeDefinition_Definition.ts
|
||||
/////*definition*/class C {
|
||||
//// p;
|
||||
////}
|
||||
////var c: C;
|
||||
|
||||
// @Filename: goToTypeDefinition_Consumption.ts
|
||||
/////*reference*/c = undefined;
|
||||
|
||||
goTo.marker('reference');
|
||||
goTo.type();
|
||||
verify.caretAtMarker('definition');
|
||||
18
tests/cases/fourslash/goToTypeDefinition2.ts
Normal file
18
tests/cases/fourslash/goToTypeDefinition2.ts
Normal file
@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: goToTypeDefinition2_Definition.ts
|
||||
/////*definition*/interface I1 {
|
||||
//// p;
|
||||
////}
|
||||
////type propertyType = I1;
|
||||
////interface I2 {
|
||||
//// property: propertyType;
|
||||
////}
|
||||
|
||||
// @Filename: goToTypeDefinition2_Consumption.ts
|
||||
////var i2: I2;
|
||||
////i2.prop/*reference*/erty;
|
||||
|
||||
goTo.marker('reference');
|
||||
goTo.type();
|
||||
verify.caretAtMarker('definition');
|
||||
24
tests/cases/fourslash/goToTypeDefinitionAliases.ts
Normal file
24
tests/cases/fourslash/goToTypeDefinitionAliases.ts
Normal file
@ -0,0 +1,24 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: goToTypeDefinitioAliases_module1.ts
|
||||
/////*definition*/interface I {
|
||||
//// p;
|
||||
////}
|
||||
////export {I as I2};
|
||||
|
||||
// @Filename: goToTypeDefinitioAliases_module2.ts
|
||||
////import {I2 as I3} from "goToTypeDefinitioAliases_module1";
|
||||
////var v1: I3;
|
||||
////export {v1 as v2};
|
||||
|
||||
// @Filename: goToTypeDefinitioAliases_module3.ts
|
||||
////import {/*reference1*/v2 as v3} from "goToTypeDefinitioAliases_module2";
|
||||
/////*reference2*/v3;
|
||||
|
||||
goTo.marker('reference1');
|
||||
goTo.type();
|
||||
verify.caretAtMarker('definition');
|
||||
|
||||
goTo.marker('reference2');
|
||||
goTo.type();
|
||||
verify.caretAtMarker('definition');
|
||||
13
tests/cases/fourslash/goToTypeDefinitionEnumMembers.ts
Normal file
13
tests/cases/fourslash/goToTypeDefinitionEnumMembers.ts
Normal file
@ -0,0 +1,13 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
/////*definition*/enum E {
|
||||
//// value1,
|
||||
//// value2
|
||||
////}
|
||||
////var x = E.value2;
|
||||
////
|
||||
/////*reference*/x;
|
||||
|
||||
goTo.marker('reference');
|
||||
goTo.type();
|
||||
verify.caretAtMarker('definition');
|
||||
19
tests/cases/fourslash/goToTypeDefinitionModule.ts
Normal file
19
tests/cases/fourslash/goToTypeDefinitionModule.ts
Normal file
@ -0,0 +1,19 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: goToTypeDefinitioAliases_module1.ts
|
||||
/////*definition*/module M {
|
||||
//// export var p;
|
||||
////}
|
||||
////var m: typeof M;
|
||||
|
||||
// @Filename: goToTypeDefinitioAliases_module3.ts
|
||||
/////*reference1*/M;
|
||||
/////*reference2*/m;
|
||||
|
||||
goTo.marker('reference1');
|
||||
goTo.type();
|
||||
verify.caretAtMarker('definition');
|
||||
|
||||
goTo.marker('reference2');
|
||||
goTo.type();
|
||||
verify.caretAtMarker('definition');
|
||||
25
tests/cases/fourslash/goToTypeDefinitionPrimitives.ts
Normal file
25
tests/cases/fourslash/goToTypeDefinitionPrimitives.ts
Normal file
@ -0,0 +1,25 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: module1.ts
|
||||
////var w: {a: number};
|
||||
////var x = "string";
|
||||
////var y: number | string;
|
||||
////var z; // any
|
||||
|
||||
// @Filename: module2.ts
|
||||
////w./*reference1*/a;
|
||||
/////*reference2*/x;
|
||||
/////*reference3*/y;
|
||||
/////*reference4*/y;
|
||||
|
||||
goTo.marker('reference1');
|
||||
verify.typeDefinitionCountIs(0);
|
||||
|
||||
goTo.marker('reference1');
|
||||
verify.typeDefinitionCountIs(0);
|
||||
|
||||
goTo.marker('reference2');
|
||||
verify.typeDefinitionCountIs(0);
|
||||
|
||||
goTo.marker('reference4');
|
||||
verify.typeDefinitionCountIs(0);
|
||||
31
tests/cases/fourslash/goToTypeDefinitionUnionType.ts
Normal file
31
tests/cases/fourslash/goToTypeDefinitionUnionType.ts
Normal file
@ -0,0 +1,31 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
/////*definition0*/class C {
|
||||
//// p;
|
||||
////}
|
||||
////
|
||||
/////*definition1*/interface I {
|
||||
//// x;
|
||||
////}
|
||||
////
|
||||
////module M {
|
||||
//// /*definition2*/export interface I {
|
||||
//// y;
|
||||
//// }
|
||||
////}
|
||||
////
|
||||
////var x: C | I | M.I;
|
||||
////
|
||||
/////*reference*/x;
|
||||
|
||||
goTo.marker('reference');
|
||||
goTo.type(0);
|
||||
verify.caretAtMarker('definition0');
|
||||
|
||||
goTo.marker('reference');
|
||||
goTo.type(1);
|
||||
verify.caretAtMarker('definition1');
|
||||
|
||||
goTo.marker('reference');
|
||||
goTo.type(2);
|
||||
verify.caretAtMarker('definition2');
|
||||
12
tests/cases/fourslash/server/typedefinition01.ts
Normal file
12
tests/cases/fourslash/server/typedefinition01.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/// <reference path="../fourslash.ts"/>
|
||||
|
||||
// @Filename: b.ts
|
||||
////import n = require('a');
|
||||
////var x/*1*/ = new n.Foo();
|
||||
|
||||
// @Filename: a.ts
|
||||
//// /*2*/export class Foo {}
|
||||
|
||||
goTo.marker('1');
|
||||
goTo.type();
|
||||
verify.caretAtMarker('2');
|
||||
14
tests/cases/fourslash/shims/goToTypeDefinition.ts
Normal file
14
tests/cases/fourslash/shims/goToTypeDefinition.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: goToTypeDefinition_Definition.ts
|
||||
/////*definition*/class C {
|
||||
//// p;
|
||||
////}
|
||||
////var c: C;
|
||||
|
||||
// @Filename: goToTypeDefinition_Consumption.ts
|
||||
/////*reference*/c = undefined;
|
||||
|
||||
goTo.marker('reference');
|
||||
goTo.type();
|
||||
verify.caretAtMarker('definition');
|
||||
Loading…
x
Reference in New Issue
Block a user