/// <summary> /// Decides if the current function definition is a reference of the symbol being searched for. /// A reference of the symbol will be a of type SymbolType.Function and have the same name as the symbol /// </summary> /// <param name="functionDefinitionAst">A functionDefinitionAst in the script's AST</param> /// <returns>A visit action that continues the search for references</returns> public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst functionDefinitionAst) { // Get the start column number of the function name, // instead of the the start column of 'function' and create new extent for the functionName int startColumnNumber = functionDefinitionAst.Extent.Text.IndexOf( functionDefinitionAst.Name) + 1; IScriptExtent nameExtent = new ScriptExtent() { Text = functionDefinitionAst.Name, StartLineNumber = functionDefinitionAst.Extent.StartLineNumber, EndLineNumber = functionDefinitionAst.Extent.StartLineNumber, StartColumnNumber = startColumnNumber, EndColumnNumber = startColumnNumber + functionDefinitionAst.Name.Length }; if (symbolRef.SymbolType.Equals(SymbolType.Function) && nameExtent.Text.Equals(symbolRef.SymbolName, StringComparison.CurrentCultureIgnoreCase)) { this.FoundReferences.Add(new SymbolReference( SymbolType.Function, nameExtent)); } return(base.VisitFunctionDefinition(functionDefinitionAst)); }
/// <summary> /// Adds keys in the input hashtable to the symbol reference /// </summary> public override AstVisitAction VisitHashtable(HashtableAst hashtableAst) { if (hashtableAst.KeyValuePairs == null) { return AstVisitAction.Continue; } foreach (var kvp in hashtableAst.KeyValuePairs) { if (kvp.Item1 is StringConstantExpressionAst keyStrConstExprAst) { IScriptExtent nameExtent = new ScriptExtent() { Text = keyStrConstExprAst.Value, StartLineNumber = kvp.Item1.Extent.StartLineNumber, EndLineNumber = kvp.Item2.Extent.EndLineNumber, StartColumnNumber = kvp.Item1.Extent.StartColumnNumber, EndColumnNumber = kvp.Item2.Extent.EndColumnNumber, File = hashtableAst.Extent.File }; SymbolType symbolType = SymbolType.HashtableKey; this.SymbolReferences.Add( new SymbolReference( symbolType, nameExtent)); } } return AstVisitAction.Continue; }
/// <summary> /// Checks to see if this function definition is the symbol we are looking for. /// </summary> /// <param name="functionDefinitionAst">A functionDefinitionAst object in the script's AST</param> /// <returns>A decision to stop searching if the right symbol was found, /// or a decision to continue if it wasn't found</returns> public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst functionDefinitionAst) { int startColumnNumber = 1; if (!includeFunctionDefinitions) { startColumnNumber = functionDefinitionAst.Extent.Text.IndexOf( functionDefinitionAst.Name) + 1; } IScriptExtent nameExtent = new ScriptExtent() { Text = functionDefinitionAst.Name, StartLineNumber = functionDefinitionAst.Extent.StartLineNumber, EndLineNumber = functionDefinitionAst.Extent.EndLineNumber, StartColumnNumber = startColumnNumber, EndColumnNumber = startColumnNumber + functionDefinitionAst.Name.Length, File = functionDefinitionAst.Extent.File }; if (IsPositionInExtent(nameExtent)) { FoundSymbolReference = new SymbolReference( SymbolType.Function, nameExtent); return(AstVisitAction.StopVisit); } return(base.VisitFunctionDefinition(functionDefinitionAst)); }
/// <summary> /// Decides if the current function definition is the right definition /// for the symbol being searched for. The definition of the symbol will be a of type /// SymbolType.Function and have the same name as the symbol /// </summary> /// <param name="functionDefinitionAst">A FunctionDefinitionAst in the script's AST</param> /// <returns>A decision to stop searching if the right FunctionDefinitionAst was found, /// or a decision to continue if it wasn't found</returns> public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst functionDefinitionAst) { // Get the start column number of the function name, // instead of the the start column of 'function' and create new extent for the functionName int startColumnNumber = functionDefinitionAst.Extent.Text.IndexOf( functionDefinitionAst.Name, StringComparison.OrdinalIgnoreCase) + 1; IScriptExtent nameExtent = new ScriptExtent() { Text = functionDefinitionAst.Name, StartLineNumber = functionDefinitionAst.Extent.StartLineNumber, StartColumnNumber = startColumnNumber, EndLineNumber = functionDefinitionAst.Extent.StartLineNumber, EndColumnNumber = startColumnNumber + functionDefinitionAst.Name.Length, File = functionDefinitionAst.Extent.File }; // We compare to the SymbolName instead of its text because it may have been resolved // from an alias. if (symbolRef.SymbolType.Equals(SymbolType.Function) && nameExtent.Text.Equals(symbolRef.SymbolName, StringComparison.CurrentCultureIgnoreCase)) { FoundDeclaration = new SymbolReference( SymbolType.Function, nameExtent); return(AstVisitAction.StopVisit); } return(base.VisitFunctionDefinition(functionDefinitionAst)); }
private void ValidateExtend(string searchName, string foundName, Ast ast) { if (!foundName.Equals(searchName, StringComparison.CurrentCultureIgnoreCase)) { return; } int startColumnNumber = ast.Extent.StartScriptPosition.ColumnNumber + ast.Extent.Text.IndexOf(foundName, StringComparison.OrdinalIgnoreCase); IScriptExtent nameExtent = new ScriptExtent() { Text = foundName, StartLineNumber = ast.Extent.StartLineNumber, StartColumnNumber = startColumnNumber, EndLineNumber = ast.Extent.StartLineNumber, EndColumnNumber = startColumnNumber + foundName.Length, File = ast.Extent.File }; this.FoundReferences.Add(new SymbolReference(SymbolType.Function, nameExtent)); }
/// <summary> /// Finds the symbol at a given file location /// </summary> /// <param name="scriptAst">The abstract syntax tree of the given script</param> /// <param name="lineNumber">The line number of the cursor for the given script</param> /// <param name="columnNumber">The coulumn number of the cursor for the given script</param> /// <param name="includeFunctionDefinitions">Includes full function definition ranges in the search.</param> /// <returns>SymbolReference of found symbol</returns> public static SymbolReference FindSymbolAtPosition( Ast scriptAst, int lineNumber, int columnNumber, bool includeFunctionDefinitions = false) { var condition = new Func <Ast, bool> (x => (x.Extent.StartLineNumber == lineNumber && x.Extent.EndLineNumber == lineNumber && x.Extent.StartColumnNumber <= columnNumber && x.Extent.EndColumnNumber >= columnNumber)); List <Ast> lAst = scriptAst.FindAll(condition, true)?.OrderBy(x => x.Extent.Text.Length).Take(1).ToList(); if (lAst.Count == 0) { condition = new Func <Ast, bool>(x => (x.Extent.StartLineNumber == lineNumber && x.Extent.EndLineNumber > lineNumber && x.Extent.StartColumnNumber <= columnNumber)); lAst = scriptAst.FindAll(condition, true)?.OrderBy(x => x.Extent.Text.Length).Take(1).ToList(); } if (lAst.Count == 0) { return(null); } Ast ast = lAst[0]; string name = null; name = (ast is PropertyMemberAst) ? (ast as PropertyMemberAst).Name : (ast is FunctionDefinitionAst) ? (ast as FunctionDefinitionAst).Name : (ast is FunctionMemberAst) ? (ast as FunctionMemberAst).Name : //(ast is NamedBlockAst) ? (ast as NamedBlockAst).BlockKind.ToString() : (ast is TypeExpressionAst) ? (ast as TypeExpressionAst).TypeName.ToString() : null; if (name != null) { int startColumnNumber = ast.Extent.Text.IndexOf(name) + 1; IScriptExtent nameExtent = new ScriptExtent() { Text = name, StartLineNumber = ast.Extent.StartLineNumber, EndLineNumber = ast.Extent.EndLineNumber, StartColumnNumber = ast.Extent.StartColumnNumber + startColumnNumber, EndColumnNumber = ast.Extent.StartColumnNumber + name.Length, File = ast.Extent.File }; return(new SymbolReference(SymbolType.Function, nameExtent)); } return(new SymbolReference(SymbolType.Function, ast.Extent)); }
/// <summary> /// Decides if the current function definition is a reference of the symbol being searched for. /// A reference of the symbol will be a of type SymbolType.Function and have the same name as the symbol /// </summary> /// <param name="functionDefinitionAst">A functionDefinitionAst in the script's AST</param> /// <returns>A visit action that continues the search for references</returns> public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst functionDefinitionAst) { (int startColumnNumber, int startLineNumber) = GetStartColumnAndLineNumbersFromAst(functionDefinitionAst); IScriptExtent nameExtent = new ScriptExtent() { Text = functionDefinitionAst.Name, StartLineNumber = startLineNumber, EndLineNumber = startLineNumber, StartColumnNumber = startColumnNumber, EndColumnNumber = startColumnNumber + functionDefinitionAst.Name.Length, File = functionDefinitionAst.Extent.File }; if (_symbolRef.SymbolType.Equals(SymbolType.Function) && nameExtent.Text.Equals(_symbolRef.SymbolName, StringComparison.CurrentCultureIgnoreCase)) { FoundReferences.Add(new SymbolReference(SymbolType.Function, nameExtent)); } return(base.VisitFunctionDefinition(functionDefinitionAst)); }
/// <summary> /// Adds each function definition as a /// </summary> /// <param name="functionDefinitionAst">A functionDefinitionAst object in the script's AST</param> /// <returns>A decision to stop searching if the right symbol was found, /// or a decision to continue if it wasn't found</returns> public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst functionDefinitionAst) { IScriptExtent nameExtent = new ScriptExtent() { Text = functionDefinitionAst.Name, StartLineNumber = functionDefinitionAst.Extent.StartLineNumber, EndLineNumber = functionDefinitionAst.Extent.EndLineNumber, StartColumnNumber = functionDefinitionAst.Extent.StartColumnNumber, EndColumnNumber = functionDefinitionAst.Extent.EndColumnNumber, File = functionDefinitionAst.Extent.File }; SymbolType symbolType = functionDefinitionAst.IsWorkflow ? SymbolType.Workflow : SymbolType.Function; this.SymbolReferences.Add( new SymbolReference( symbolType, nameExtent)); return AstVisitAction.Continue; }