/// <summary> /// Determines if the completion string is a valid type and /// enumerates the list of completion members on the type /// </summary> /// <param name="code"> code typed in the code block </param> /// <param name="stringToComplete"> Class name or declared variable </param> /// <param name="resolver"></param> /// <returns> list of method and property members of the type </returns> internal IEnumerable<CompletionData> GetCompletionsOnType(string code, string stringToComplete, ElementResolver resolver = null) { IEnumerable<StaticMirror> members = null; if (resolver != null) { stringToComplete = resolver.LookupResolvedName(stringToComplete) ?? stringToComplete; } // Determine if the string to be completed is a class var type = GetClassType(stringToComplete); if (type != null) { members = type.GetMembers(); } // If not of class type else { // Check if the string to be completed is a declared variable string typeName = CodeCompletionParser.GetVariableType(code, stringToComplete); if (typeName != null) type = GetClassType(typeName); if (type != null) { members = type.GetInstanceMembers(); } } return members.Select(x => CompletionData.ConvertMirrorToCompletionData(x)); }
internal void LookupResolvedNameAndRewriteAst(ElementResolver elementResolver, ref AssociativeNode astNode) { Debug.Assert(elementResolver != null); // Get partial class identifier/identifier lists var classIdentifiers = GetClassIdentifiers(astNode); var resolvedNames = new Queue <string>(); foreach (var identifier in classIdentifiers) { string partialName = string.Empty; var identifierList = identifier as IdentifierListNode; if (identifierList != null) { partialName = CoreUtils.GetIdentifierExceptMethodName(identifierList); } else { partialName = identifier.Name; } var resolvedName = elementResolver.LookupResolvedName(partialName); if (string.IsNullOrEmpty(resolvedName)) { // If namespace resolution map does not contain entry for partial name, // back up on compiler to resolve the namespace from partial name var matchingClasses = CoreUtils.GetResolvedClassName(classTable, CoreUtils.CreateNodeFromString(partialName)); if (matchingClasses.Length == 1) { resolvedName = matchingClasses[0]; var assemblyName = CoreUtils.GetAssemblyFromClassName(classTable, resolvedName); elementResolver.AddToResolutionMap(partialName, resolvedName, assemblyName); } else { // Class name could not be resolved - Possible namespace conflict // This will be reported subsequently in the pre-compilation stage if there's a conflict // Enter an empty resolved name to the list and continue resolvedNames.Enqueue(string.Empty); continue; } } resolvedNames.Enqueue(resolvedName); } if (resolvedNames.Any()) { RewriteAstWithResolvedName(ref astNode, resolvedNames); } }
private string ResolveClassName(AssociativeNode identifierList) { var identListNode = identifierList as IdentifierListNode; string partialName = identListNode != null? CoreUtils.GetIdentifierExceptMethodName(identListNode) : identifierList.Name; if (string.IsNullOrEmpty(partialName)) { return(String.Empty); } var resolvedName = elementResolver.LookupResolvedName(partialName); if (!string.IsNullOrEmpty(resolvedName)) { return(resolvedName); } // If namespace resolution map does not contain entry for partial name, // back up on compiler to resolve the namespace from partial name var matchingClasses = CoreUtils.GetResolvedClassName(classTable, identifierList); if (matchingClasses.Length == 1) { resolvedName = matchingClasses[0]; var classNode = classTable.ClassNodes.FirstOrDefault(x => x.Name == resolvedName); var isHiddenInLibrary = classNode.ClassAttributes?.HiddenInLibrary ?? false; // Do not add a hidden class to element resolver. if (!isHiddenInLibrary) { var assemblyName = CoreUtils.GetAssemblyFromClassName(classTable, resolvedName); elementResolver.AddToResolutionMap(partialName, resolvedName, assemblyName); } } else if (matchingClasses.Length > 1) { OnLogSymbolConflictWarning(partialName, matchingClasses); } return(resolvedName); }
private void VerifyResult(string fullName, string partialName, string functionOrProperty, bool isProperty = false) { var testCore = thisTest.GetTestCore(); var astNodes = CoreUtils.BuildASTList(testCore, string.Format("d = {0}.{1};", partialName, functionOrProperty)); var elementResolver = new ElementResolver(); var newNodes = ElementRewriter.RewriteElementNames(testCore.ClassTable, elementResolver, astNodes); Assert.AreEqual(string.Format("d = {0}.{1};\n", fullName, functionOrProperty), newNodes.ElementAt(0).ToString()); if (!isProperty) { // Add verification for contents of element resolver resolution map var assembly = elementResolver.LookupAssemblyName(partialName); var resolvedName = elementResolver.LookupResolvedName(partialName); Assert.AreEqual("FFITarget.dll", assembly); Assert.AreEqual(fullName, resolvedName); } }
public void LookupResolvedName_FromCompiler_RewriteAst() { const string code = @"import (""FFITarget.dll"");"; var mirror = thisTest.RunScriptSource(code); var testCore = thisTest.GetTestCore(); var astNodes = CoreUtils.BuildASTList(testCore, "d = ElementResolverTarget.ElementResolverTarget();"); var elementResolver = new ElementResolver(); var newNodes = ElementRewriter.RewriteElementNames(testCore.ClassTable, elementResolver, astNodes); Assert.AreEqual("d = FFITarget.ElementResolverTarget.ElementResolverTarget();\n", newNodes.ElementAt(0).ToString()); // Add verification for contents of element resolver resolution map Assert.AreEqual(1, elementResolver.ResolutionMap.Count); var assembly = elementResolver.LookupAssemblyName("ElementResolverTarget"); var resolvedName = elementResolver.LookupResolvedName("ElementResolverTarget"); Assert.AreEqual("FFITarget.dll", assembly); Assert.AreEqual("FFITarget.ElementResolverTarget", resolvedName); }
public void LookupResolvedName_ForNestedNamespacesExpressionFromCompiler_RewriteAst() { const string code = @"import (""FFITarget.dll"");"; var mirror = thisTest.RunScriptSource(code); var testCore = thisTest.GetTestCore(); string class1 = "NestedResolverTarget"; string class2 = "ElementResolverTarget"; string fullName1 = "FFITarget.NameSpaceA.NameSpaceB.NameSpaceC.NestedResolverTarget"; string fullName2 = "FFITarget.ElementResolverTarget"; var astNodes = CoreUtils.BuildASTList(testCore, string.Format("d = {0}.Property.Method({1}.Create().Property.Method({0}.Property.Property));", class1, class2)); var elementResolver = new ElementResolver(); var newNodes = ElementRewriter.RewriteElementNames(testCore.ClassTable, elementResolver, astNodes); Assert.AreEqual( string.Format("d = {0}.Property.Method({1}.Create().Property.Method({0}.Property.Property));\n", fullName1, fullName2), newNodes.ElementAt(0).ToString()); // Add verification for contents of element resolver resolution map var assembly = elementResolver.LookupAssemblyName(class2); var resolvedName = elementResolver.LookupResolvedName(class2); Assert.AreEqual("FFITarget.dll", assembly); Assert.AreEqual(fullName2, resolvedName); /////////////////////////////////////////////// astNodes = CoreUtils.BuildASTList(testCore, string.Format("d = {0}.Property.Method({1}.Create().Property.Method({0}.Property.Property));", fullName1, fullName2)); elementResolver = new ElementResolver(); newNodes = ElementRewriter.RewriteElementNames(testCore.ClassTable, elementResolver, astNodes); Assert.AreEqual( string.Format("d = {0}.Property.Method({1}.Create().Property.Method({0}.Property.Property));\n", fullName1, fullName2), newNodes.ElementAt(0).ToString()); // Add verification for contents of element resolver resolution map assembly = elementResolver.LookupAssemblyName(fullName2); resolvedName = elementResolver.LookupResolvedName(fullName2); Assert.AreEqual("FFITarget.dll", assembly); Assert.AreEqual(fullName2, resolvedName); }
private AssociativeNode RewriteIdentifierListNode(AssociativeNode identifierList) { var identListNode = identifierList as IdentifierListNode; string partialName = identListNode != null? CoreUtils.GetIdentifierExceptMethodName(identListNode) : identifierList.Name; var resolvedName = elementResolver.LookupResolvedName(partialName); if (string.IsNullOrEmpty(resolvedName)) { // If namespace resolution map does not contain entry for partial name, // back up on compiler to resolve the namespace from partial name var matchingClasses = CoreUtils.GetResolvedClassName(classTable, identifierList); if (matchingClasses.Length == 1) { resolvedName = matchingClasses[0]; var assemblyName = CoreUtils.GetAssemblyFromClassName(classTable, resolvedName); elementResolver.AddToResolutionMap(partialName, resolvedName, assemblyName); } } if (string.IsNullOrEmpty(resolvedName)) { return(identifierList); } var newIdentList = CoreUtils.CreateNodeFromString(resolvedName); Validity.Assert(newIdentList is IdentifierListNode); // If the original input node matches with the resolved name, simply return // the identifier list constructed from the resolved name var symbol = new Symbol(resolvedName); if (symbol.Matches(identifierList.ToString())) { return(newIdentList); } // Remove partialName from identListNode and replace with newIdentList AssociativeNode leftNode = identListNode != null ? identListNode.LeftNode : identifierList; AssociativeNode rightNode = identListNode != null ? identListNode.RightNode : identifierList; var intermediateNodes = new List <AssociativeNode>(); while (leftNode is IdentifierListNode && !symbol.Matches(leftNode.ToString())) { intermediateNodes.Insert(0, ((IdentifierListNode)leftNode).RightNode); leftNode = ((IdentifierListNode)leftNode).LeftNode; } intermediateNodes.Insert(0, newIdentList); var lNode = CoreUtils.CreateNodeByCombiningIdentifiers(intermediateNodes); Validity.Assert(lNode is IdentifierListNode); // The last ident list for the functioncall or identifier rhs var lastIdentList = new IdentifierListNode { LeftNode = lNode, RightNode = rightNode, Optr = Operator.dot }; return(lastIdentList); }
/// <summary> /// Returns the list of function signatures of all overloads of a given method /// </summary> /// <param name="code"> code being typed in code block </param> /// <param name="functionName"> given method name for which signature is queried </param> /// <param name="functionPrefix"> class name in case of constructor or static method, OR /// declared instance variable on which method is invoked </param> /// <param name="resolver"></param> /// <returns> list of method overload signatures </returns> internal IEnumerable<CompletionData> GetFunctionSignatures(string code, string functionName, string functionPrefix, ElementResolver resolver = null) { IEnumerable<MethodMirror> candidates = null; // if function is global, search for function in Built-ins if (string.IsNullOrEmpty(functionPrefix)) { return StaticMirror.GetOverloadsOnBuiltIns(core, functionName). Select(x => { return new CompletionData(x.MethodName, CompletionData.CompletionType.Method) { Stub = x.ToString() }; }); } // Determine if the function prefix is a class name if (resolver != null) { functionPrefix = resolver.LookupResolvedName(functionPrefix) ?? functionPrefix; } var type = GetClassType(functionPrefix); if (type != null) { candidates = type.GetOverloadsOnType(functionName); } // If not of class type else { // Check if the function prefix is a typed identifier string typeName = CodeCompletionParser.GetVariableType(code, functionPrefix); if (typeName != null) type = GetClassType(typeName); if (type != null) { candidates = type.GetOverloadsOnInstance(functionName); } } return candidates.Select(x => CompletionData.ConvertMirrorToCompletionData(x)); }