private Result <ArrayOrObject <Location, Location>, ResponseError> GetDefinitionForPropertyAssignment(INode node) { var symbol = DScriptUtilities.GetPropertySymbolsFromContextualType(node, TypeChecker).FirstOrDefault(); if (symbol == null) { return(SilentError()); } return(GetDefinitionFromSymbol(symbol, node)); }
private Result <ArrayOrObject <Location, Location>, ResponseError> GetDefinitionFromSymbol([NotNull] ISymbol symbol, INode node) { var result = new List <Location>(); var declarations = symbol.GetDeclarations(); var symbolName = TypeChecker.SymbolToString(symbol); var symbolKind = DScriptUtilities.GetSymbolKind(symbol, node); var containerSymbol = symbol.Parent; var containerName = containerSymbol != null?TypeChecker.SymbolToString(containerSymbol, node) : string.Empty; if (!TryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) && !TryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) { // Just add all the declarations foreach (var declaration in declarations) { result.Add(GetLocationFromNode(declaration)); } } return(Success(result.ToArray())); }
private static bool TryAddCallSignature( ISymbol symbol, INode location, string symbolKind, string symbolName, string containerName, List <Location> result) { if (DScriptUtilities.IsCallExpressionTarget(location) || DScriptUtilities.IsNewExpressionTarget(location) || DScriptUtilities.IsNameOfFunctionDeclaration(location)) { return(TryAddSignature( symbol.Declarations, /*selectConstructors*/ false, symbolKind, symbolName, containerName, result)); } return(false); }
private static bool TryAddConstructSignature( ISymbol symbol, INode location, string symbolKind, string symbolName, string containerName, List <Location> result) { // 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 (DScriptUtilities.IsNewExpressionTarget(location) || location.Kind == SyntaxKind.ConstructorKeyword) { if ((symbol.Flags & SymbolFlags.Class) != SymbolFlags.None) { // Find the first class-like declaration and try to get the construct signature. foreach (var declaration in symbol.GetDeclarations()) { var classLikeDeclaration = NodeUtilities.IsClassLike(declaration); if (classLikeDeclaration != null) { return(TryAddSignature( classLikeDeclaration.Members.Elements, /*selectConstructors*/ true, symbolKind, symbolName, containerName, result)); } } Debug.Fail("Expected declaration to have at least one class-like declaration"); } } return(false); }
/// <nodoc /> public Result <ArrayOrObject <Location, Location>, ResponseError> GetDefinitionAtPosition(TextDocumentPositionParams @params, CancellationToken token) { // TODO: support cancellation if (!TryFindNode(@params, out var node)) { return(SilentError()); } // TODO: consider special hint/message if the current node is a template expression with interpolated expressions. if (node.Kind == SyntaxKind.NoSubstitutionTemplateLiteral && node.Parent.Kind == SyntaxKind.TaggedTemplateExpression && node.Parent.Cast <ITaggedTemplateExpression>().IsWellKnownTemplateExpression(out var name)) { return(DefinitionForTemplateExpression(node, name)); } var result = GetDefinitionFromVariableDeclarationList(node); if (result != null) { return(result); } if (DScriptUtilities.IsJumpStatementTarget(node)) { var labelName = node.Cast <IIdentifier>().Text; var label = DScriptUtilities.GetTargetLabel(node.Parent, labelName); // TODO: saqadri - Port // return label ? [createDefinitionInfo(label, ScriptElementKind.label, labelName, /*containerName*/ undefined)] : undefined; return(Success(new[] { GetLocationFromNode(label), })); } // TODO: saqadri - port // Triple slash reference comments // const comment = forEach(sourceFile.referencedFiles, r => (r.pos <= position && position < r.end) ? r : undefined); // if (comment) // { // const referenceFile = tryResolveScriptReference(program, sourceFile, comment); // if (referenceFile) // { // return [{ // fileName: referenceFile.fileName, // textSpan: createTextSpanFromBounds(0, 0), // kind: ScriptElementKind.scriptElement, // name: comment.fileName, // containerName: undefined, // containerKind: undefined // }]; // } // return undefined; // } var symbol = TypeChecker.GetSymbolAtLocation(node) ?? node.Symbol ?? node.ResolvedSymbol; // Could not find a symbol e.g. node is string or number keyword, // or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol if (symbol == null) { // return null; return(SilentError()); } // If this is an alias, and the request came at the declaration location // get the aliased symbol instead. This allows for goto def on an import e.g. // import {A, B} from "mod"; // to jump to the implementation directly. if ((symbol.Flags & SymbolFlags.Alias) != SymbolFlags.None) { var declaration = symbol.Declarations.FirstOrDefault(); // Go to the original declaration for cases: // // (1) when the aliased symbol was declared in the location(parent). // (2) when the aliased symbol is originating from a named import. if (node.Kind == SyntaxKind.Identifier && declaration != null && (node.Parent.ResolveUnionType() == declaration.ResolveUnionType() || (declaration.Kind == SyntaxKind.ImportSpecifier && declaration?.Parent.Kind == SyntaxKind.NamedImports))) { symbol = TypeChecker.GetAliasedSymbol(symbol); } } // Because name in short-hand property assignment has two different meanings: property name and property value, // using go-to-definition at such position should go to the variable declaration of the property value rather than // go to the declaration of the property name (in this case stay at the same position). However, if go-to-definition // is performed at the location of property access, we would like to go to definition of the property in the short-hand // assignment. This case and others are handled by the following code. if (node.Parent.Kind == SyntaxKind.ShorthandPropertyAssignment) { var shorthandSymbol = TypeChecker.GetShorthandAssignmentValueSymbol(symbol.ValueDeclaration); if (shorthandSymbol == null) { return(Success(new Location[] { })); } var shorthandDeclaratons = shorthandSymbol.GetDeclarations(); // var shorthandSymbolKind = GetSymbolKind(shorthandSymbol, node); // var shorthandSymbolName = TypeChecker.SymbolToString(shorthandSymbol); // var shorthandContainerName = TypeChecker.SymbolToString(shorthandSymbol.Parent, node); return(Success(shorthandDeclaratons.Select( declaration => GetLocationFromNode(declaration)).ToArray())); } if (DScriptUtilities.IsNameOfPropertyAssignment(node)) { return(GetDefinitionForPropertyAssignment(node)); } return(GetDefinitionFromSymbol(symbol, node)); }