private static AssociativeNode RewriteIdentifierListNode(AssociativeNode identifier, Queue <string> resolvedNames) { var resolvedName = resolvedNames.Dequeue(); // if resolved name is null or empty, return the identifier list node as is if (string.IsNullOrEmpty(resolvedName)) { return(identifier); } var newIdentList = CoreUtils.CreateNodeFromString(resolvedName); Validity.Assert(newIdentList is IdentifierListNode); var identListNode = identifier as IdentifierListNode; AssociativeNode rightNode = identListNode != null ? identListNode.RightNode : identifier; // The last ident list for the functioncall or identifier rhs var lastIdentList = new IdentifierListNode { LeftNode = newIdentList, RightNode = rightNode, Optr = Operator.dot }; return(lastIdentList); }
private IdentifierListNode GenerateNewIdentifierList(string newNodeName, FunctionCallNode funcCall) { var newNode = CoreUtils.CreateNodeFromString(newNodeName); if (newNode == null) { return(null); } // append argument list from original method to newNode var newMethodName = ((IdentifierListNode)newNode).RightNode.Name; var newMethod = new FunctionCallNode { Function = AstFactory.BuildIdentifier(newMethodName), FormalArguments = funcCall.FormalArguments }; var newIdentList = new IdentifierListNode { LeftNode = ((IdentifierListNode)newNode).LeftNode, RightNode = newMethod, Optr = Operator.dot }; return(newIdentList); }
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 AssociativeNode RewriteIdentifierListNode(AssociativeNode identifierList) { var resolvedName = ResolveClassName(identifierList); if (string.IsNullOrEmpty(resolvedName)) { return(identifierList); } var identListNode = identifierList as IdentifierListNode; var newIdentList = CoreUtils.CreateNodeFromString(resolvedName); if (newIdentList == null) { return(null); } // 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); // The last ident list for the functioncall or identifier rhs var lastIdentList = new IdentifierListNode { LeftNode = lNode, RightNode = rightNode, Optr = Operator.dot }; return(lastIdentList); }
public override AssociativeNode VisitTypedIdentifierNode(TypedIdentifierNode node) { if (node == null) { return(null); } // If type is primitive type if (node.datatype.UID != (int)PrimitiveType.InvalidType && node.datatype.UID < (int)PrimitiveType.MaxPrimitive) { return(node); } // build an idlistnode from the full type name var identListNode = CoreUtils.CreateNodeFromString(node.TypeAlias); if (identListNode == null) { return(node); } // visit the idlist var shortNameNode = identListNode.Accept(this); if (shortNameNode == null) { return(node); } var resultingNode = new TypedIdentifierNode { Name = node.Name, Value = node.Name, datatype = node.datatype }; //return a typedIdNode built from the shortNameId returned above. resultingNode.TypeAlias = shortNameNode.ToString(); //modify the AST node that was passed to the visitor. node.Name = resultingNode.Name; node.Value = resultingNode.Value; node.datatype = resultingNode.datatype; node.TypeAlias = resultingNode.TypeAlias; return(node); }
private bool IsMatchingResolvedName(IdentifierListNode identifierList, out AssociativeNode newIdentList) { newIdentList = null; var resolvedName = ResolveClassName(identifierList); if (string.IsNullOrEmpty(resolvedName)) { return(false); } newIdentList = CoreUtils.CreateNodeFromString(resolvedName); var symbol = new Symbol(resolvedName); return(symbol.Matches(identifierList.ToString())); }
public override AssociativeNode VisitTypedIdentifierNode(TypedIdentifierNode node) { // If type is primitive type if (node.datatype.UID != (int)PrimitiveType.InvalidType && node.datatype.UID < (int)PrimitiveType.MaxPrimitive) { return(node); } var identListNode = CoreUtils.CreateNodeFromString(node.TypeAlias); if (identListNode == null) { return(null); } // Rewrite node with resolved name if (identListNode is IdentifierNode) { identListNode = RewriteIdentifierListNode(identListNode); } else { identListNode = identListNode.Accept(this); } var identListString = identListNode.ToString(); var type = new Type { Name = identListString, UID = classTable.IndexOf(identListString), rank = node.datatype.rank }; var typedNode = new TypedIdentifierNode { Name = node.Name, Value = node.Name, datatype = type, TypeAlias = node.TypeAlias }; NodeUtils.CopyNodeLocation(typedNode, node); return(typedNode); }
private AssociativeNode CreateNodeFromShortName(string className, string qualifiedName) { // Get the list of conflicting namespaces that contain the same class name var matchingClasses = CoreUtils.GetResolvedClassName(classTable, AstFactory.BuildIdentifier(className)); if (matchingClasses.Length == 0) { return(null); } string shortName; // if there is no class conflict simply use the class name as the shortest name if (matchingClasses.Length == 1) { shortName = className; } else { shortName = resolver != null?resolver.LookupShortName(qualifiedName) : null; if (string.IsNullOrEmpty(shortName)) { // Use the namespace list as input to derive the list of shortest unique names var symbolList = matchingClasses.Select(matchingClass => new ProtoCore.Namespace.Symbol(matchingClass)) .ToList(); var shortNames = ProtoCore.Namespace.Symbol.GetShortestUniqueNames(symbolList); // Get the shortest name corresponding to the fully qualified name shortName = shortNames[new ProtoCore.Namespace.Symbol(qualifiedName)]; } } // Rewrite the AST using the shortest name var newIdentList = CoreUtils.CreateNodeFromString(shortName); return(newIdentList); }
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); }
private void DfsTraverse(ref AssociativeNode astNode, ICollection <AssociativeNode> classIdentifiers, Queue <string> resolvedNames) { if (astNode is BinaryExpressionNode) { var bnode = astNode as BinaryExpressionNode; AssociativeNode leftNode = bnode.LeftNode; AssociativeNode rightNode = bnode.RightNode; DfsTraverse(ref leftNode, classIdentifiers, resolvedNames); DfsTraverse(ref rightNode, classIdentifiers, resolvedNames); bnode.LeftNode = leftNode; bnode.RightNode = rightNode; } else if (astNode is FunctionCallNode) { var fCall = astNode as FunctionCallNode; for (int n = 0; n < fCall.FormalArguments.Count; ++n) { AssociativeNode argNode = fCall.FormalArguments[n]; DfsTraverse(ref argNode, classIdentifiers, resolvedNames); fCall.FormalArguments[n] = argNode; } } else if (astNode is ExprListNode) { var exprList = astNode as ExprListNode; for (int n = 0; n < exprList.list.Count; ++n) { AssociativeNode exprNode = exprList.list[n]; DfsTraverse(ref exprNode, classIdentifiers, resolvedNames); exprList.list[n] = exprNode; } } else if (astNode is InlineConditionalNode) { var inlineNode = astNode as InlineConditionalNode; AssociativeNode condition = inlineNode.ConditionExpression; AssociativeNode trueBody = inlineNode.TrueExpression; AssociativeNode falseBody = inlineNode.FalseExpression; DfsTraverse(ref condition, classIdentifiers, resolvedNames); DfsTraverse(ref trueBody, classIdentifiers, resolvedNames); DfsTraverse(ref falseBody, classIdentifiers, resolvedNames); inlineNode.ConditionExpression = condition; inlineNode.FalseExpression = falseBody; inlineNode.TrueExpression = trueBody; } else if (astNode is TypedIdentifierNode) { var typedNode = astNode as TypedIdentifierNode; // If type is primitive type if (typedNode.datatype.UID != (int)PrimitiveType.kInvalidType && typedNode.datatype.UID < (int)PrimitiveType.kMaxPrimitives) { return; } var identListNode = CoreUtils.CreateNodeFromString(typedNode.TypeAlias); // Rewrite node with resolved name if (resolvedNames.Any()) { if (identListNode is IdentifierNode) { identListNode = RewriteIdentifierListNode(identListNode, resolvedNames); } else { DfsTraverse(ref identListNode, classIdentifiers, resolvedNames); } var identListString = identListNode.ToString(); int indx = identListString.LastIndexOf('.'); string name = indx >= 0 ? identListString.Remove(indx) : identListString; var type = new Type { Name = name, UID = classTable.IndexOf(name), rank = typedNode.datatype.rank }; typedNode = new TypedIdentifierNode { Name = astNode.Name, Value = astNode.Name, datatype = type }; NodeUtils.CopyNodeLocation(typedNode, astNode); astNode = typedNode; } else if (identListNode is IdentifierNode) { classIdentifiers.Add(identListNode); } else { DfsTraverse(ref identListNode, classIdentifiers, resolvedNames); } } else if (astNode is IdentifierListNode) { var identListNode = astNode as IdentifierListNode; var rightNode = identListNode.RightNode; if (rightNode is FunctionCallNode) { DfsTraverse(ref rightNode, classIdentifiers, resolvedNames); } if (resolvedNames.Any()) { astNode = RewriteIdentifierListNode(identListNode, resolvedNames); } else { classIdentifiers.Add(identListNode); } } }
private AssociativeNode CreateNodeFromShortName(string className, string qualifiedName) { // Get the list of conflicting namespaces that contain the same class name var matchingClasses = classTable.ClassNodes.Where( x => x.Name.Split('.').Last().Equals(className)).ToList(); if (matchingClasses.Count == 0) { return(null); } if (matchingClasses.Count == 1) { // If there is no class conflict simply use the class name as the shortest name. return(CoreUtils.CreateNodeFromString(className)); } var shortName = resolver?.LookupShortName(qualifiedName); if (!string.IsNullOrEmpty(shortName)) { return(CoreUtils.CreateNodeFromString(shortName)); } // Use the namespace list to derive the list of shortest unique names var symbolList = matchingClasses.Select(matchingClass => new Symbol(matchingClass.Name)); var shortNames = Symbol.GetShortestUniqueNames(symbolList); // remove hidden class if any from shortNames before proceeding var hiddenClassNodes = matchingClasses. Where(x => x.ClassAttributes?.HiddenInLibrary ?? false).ToList(); if (hiddenClassNodes.Any()) { foreach (var hiddenClassNode in hiddenClassNodes) { var keyToRemove = new Symbol(hiddenClassNode.Name); shortNames.Remove(keyToRemove); } } // Get the shortest name corresponding to the fully qualified name if (shortNames.TryGetValue(new Symbol(qualifiedName), out shortName)) { return(CoreUtils.CreateNodeFromString(shortName)); } // If shortName for fully qualified classname is not found, it could be a base class // present in class hierarchy of any of the other matchingClasses, in which case // set shortName to the one for the derived class. var qualifiedClassNode = matchingClasses.FirstOrDefault(x => x.Name == qualifiedName); var classHierarchies = matchingClasses.Where(x => x != qualifiedClassNode). Select(y => classTable.GetClassHierarchy(y)); foreach (var hierarchy in classHierarchies) { // If A derives from B, which derives from C, the hierarchy for A // is listed in that order: [A, B, C], so we start searching in reverse order. for (int i = hierarchy.Count - 1; i > 0; i--) { if (hierarchy[i] == qualifiedClassNode) { shortName = shortNames[new Symbol(hierarchy[0].Name)]; return(CoreUtils.CreateNodeFromString(shortName)); } } } return(null); }