private Symbol Resolve(SubclassSymbol subclassSymbol) { SubclassNode symbolNode = (SubclassNode)subclassSymbol.Node; InheritanceParentReferenceNode parentReferenceNode = symbolNode.InheritanceParentReferenceNode; if (_resolvedSymbolsCurrentIteration.Contains(subclassSymbol)) { parentReferenceNode.Annotations.Add(new InfiniteInheritanceReferenceLoopError()); return(null); } if (_resolvedSymbols.Contains(subclassSymbol)) { return(subclassSymbol.BaseClassSymbol); } _resolvedSymbolsCurrentIteration.Add(subclassSymbol); _resolvedSymbols.Add(subclassSymbol); if (parentReferenceNode.PartNodes.Count > 0) { // TODO it's impossible scenario for current grammar parentReferenceNode.Annotations.Add(new NotClassOrPrototypeReferenceError()); return(null); } parentReferenceNode.Symbol = GetSymbol(parentReferenceNode.Name); switch (parentReferenceNode.Symbol) { case null: parentReferenceNode.Annotations.Add(new UndeclaredIdentifierError(parentReferenceNode.Name)); break; case SubclassSymbol parentSubclassSymbol: subclassSymbol.InheritanceParentSymbol = parentSubclassSymbol; subclassSymbol.BaseClassSymbol = (ClassSymbol)Resolve(parentSubclassSymbol); break; case ClassSymbol classSymbol: subclassSymbol.InheritanceParentSymbol = classSymbol; subclassSymbol.BaseClassSymbol = classSymbol; break; default: parentReferenceNode.Annotations.Add(new NotClassOrPrototypeReferenceError()); break; } if (parentReferenceNode.Symbol != null) { DeclarationNode declarationNode = (DeclarationNode)parentReferenceNode.Symbol.Node; declarationNode.Usages.Add(parentReferenceNode); } return(subclassSymbol.BaseClassSymbol); }
private HashSet <string> GetInitializedAttributesPaths(SubclassNode initialSubclassNode) { HashSet <string> initializedAttributesPaths = new HashSet <string>(); ASTNode node = initialSubclassNode; while (node is SubclassNode subclassNode) { initializedAttributesPaths.UnionWith(_node2InitializedAttributesPaths[subclassNode]); SubclassSymbol subclassSymbol = (SubclassSymbol)subclassNode.Symbol; node = subclassSymbol.InheritanceParentSymbol.Node; } return(initializedAttributesPaths); }
private Symbol GetBaseReferenceSymbol(ReferenceNode referenceNode) { ASTNode ancestor = referenceNode.GetFirstSignificantAncestorNode(); string referenceNameUpper = referenceNode.Name.ToUpper(); if (ancestor is InstanceDefinitionNode instanceDefinitionNode) { /* * TODO once transpiler is done, make only THIS to be available keywords since SELF makes name collision with self global object */ if (referenceNameUpper == "THIS" || referenceNameUpper == "SELF") { referenceNode.Name = instanceDefinitionNode.NameNode.Value; referenceNameUpper = referenceNode.Name.ToUpper(); return(_symbolTable[referenceNameUpper]); } } NestableSymbol nestableSymbol; switch (ancestor) { case SubclassNode subclassNode: // look for local variable SubclassSymbol subclassSymbol = (SubclassSymbol)subclassNode.Symbol; if (subclassSymbol.BodySymbols.TryGetValue(referenceNameUpper, out nestableSymbol)) { return(nestableSymbol); } // look for class variable if (subclassSymbol.BaseClassSymbol != null) { var classSymbol = subclassSymbol.BaseClassSymbol; if (classSymbol.BodySymbols.TryGetValue(referenceNameUpper, out nestableSymbol)) { return(nestableSymbol); } } break; case FunctionDefinitionNode functionDefinitionNode: // look for local variable FunctionSymbol functionSymbol = (FunctionSymbol)functionDefinitionNode.Symbol; if (functionSymbol.BodySymbols.TryGetValue(referenceNameUpper, out nestableSymbol)) { return(nestableSymbol); } break; case ClassDefinitionNode _: case FileNode _: break; default: throw new Exception(); } if (_symbolTable.ContainsKey(referenceNameUpper)) { return(_symbolTable[referenceNameUpper]); } return(null); }