Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
        }