/// <summary> /// Find a child node at the specified position. /// </summary> /// <param name="syntaxNode"> /// The syntax node to be searched. /// </param> /// <param name="position"> /// The target position. /// </param> /// <param name="xmlPositions"> /// The XML position lookup. /// </param> /// <returns> /// The syntax node, or <c>null</c> if no node was found at the specified position. /// </returns> public static SyntaxNode FindNode(this SyntaxNode syntaxNode, Position position, TextPositions xmlPositions) { if (syntaxNode == null) { throw new ArgumentNullException(nameof(syntaxNode)); } if (xmlPositions == null) { throw new ArgumentNullException(nameof(xmlPositions)); } return(SyntaxLocator.FindNode(syntaxNode, position: xmlPositions.GetAbsolutePosition(position) )); }
/// <summary> /// Returns the URL of the file that contains the definition of the item at the current position /// </summary> /// <param name="filePath">Current file</param> /// <param name="sourceText">Text in the current file</param> /// <param name="position">Position of item that is to be resolved</param> /// <returns></returns> public List <Definition> ResolveDefinition(string filePath, string sourceText, int position) { Verify.NotDisposed(this); List <Definition> definitions = new List <Definition>(); if (_project != null) { XmlDocumentSyntax root = Parser.ParseText(sourceText); SyntaxNode syntaxNode = SyntaxLocator.FindNode(root, position); // Resolves Definition for properties e.g. $(foo) if (syntaxNode.Kind == SyntaxKind.XmlTextLiteralToken && Utilities.IsProperty(sourceText.Substring(syntaxNode.Span.Start, syntaxNode.FullWidth), position - syntaxNode.Span.Start, out string propertyName)) { foreach (ProjectProperty property in _project.Properties) { if (property.Name == propertyName) { ProjectProperty currentProperty = property; while (currentProperty.Predecessor != null) { if (currentProperty.Xml?.Location != null) { ElementLocation location = currentProperty.Xml.Location; definitions.Add(new Definition(location.File, Path.GetFileNameWithoutExtension(_project.Xml.Location.File), currentProperty.Name + " Definitions", currentProperty.EvaluatedValue, location.Line, location.Column)); } currentProperty = currentProperty.Predecessor; } if (currentProperty.Xml?.Location != null) { ElementLocation lastLocation = currentProperty.Xml.Location; definitions.Add(new Definition(lastLocation.File, Path.GetFileNameWithoutExtension(_project.Xml.Location.File), currentProperty.Name + " Definitions", currentProperty.EvaluatedValue, lastLocation.Line, lastLocation.Column)); } break; } } } // Resolves Definition for regular imports else if (syntaxNode.ParentElement != null && syntaxNode.ParentElement.Name.Equals(SyntaxNames.Import)) { while (syntaxNode.Parent.ParentElement == syntaxNode.ParentElement) { syntaxNode = syntaxNode.Parent; } int nodeStart = syntaxNode.Parent.Span.Start; int col = nodeStart - Utilities.GetStartOfLine(sourceText, nodeStart) + 1; int line = Utilities.GetLine(sourceText, nodeStart) + 1; foreach (ResolvedImport import in _project.Imports) { ElementLocation location = import.ImportingElement.Location; if (location.File == filePath && col == location.Column && line == location.Line) { definitions.Add(new Definition(import.ImportedProject.FullPath, Path.GetFileNameWithoutExtension(_project.Xml.Location.File), "Imported Files", Path.GetFileName(import.ImportedProject.FullPath))); } } } // Resolves Definition for the project's sdk else if (syntaxNode.ParentElement != null && syntaxNode.ParentElement.Name.Equals(SyntaxNames.Project)) { bool foundSdk = false; for (int i = 0; i < 3; i++) { if (sourceText.Substring(syntaxNode.Start, 3).Equals(SyntaxNames.Sdk)) { foundSdk = true; break; } syntaxNode = syntaxNode.Parent; } if (foundSdk) { foreach (ResolvedImport import in _project.Imports) { ElementLocation location = import.ImportingElement.Location; if (location.File == filePath && 0 == location.Column && 0 == location.Line) { definitions.Add(new Definition(import.ImportedProject.FullPath, Path.GetFileNameWithoutExtension(_project.Xml.Location.File), "Sdk Imports", Path.GetFileName(import.ImportedProject.FullPath))); } } } } } return(definitions); }