示例#1
0
        internal override void ResolveVariableOrigins(ParserContext parser, VariableScope varIds, VariableIdAllocPhase phase)
        {
            this.IterationExpression.ResolveVariableOrigins(parser, varIds, phase);

            if ((phase & VariableIdAllocPhase.REGISTER) != 0)
            {
                varIds.RegisterVariable(this.IterationType, this.IterationVariable.Value);
                this.IndexLocalId = varIds.RegisterSyntheticVariable(AType.Integer(this.FirstToken));
                this.ListLocalId  = varIds.RegisterSyntheticVariable(AType.Any(this.FirstToken));
            }

            if (phase != VariableIdAllocPhase.REGISTER_AND_ALLOC)
            {
                foreach (Executable ex in this.Code)
                {
                    ex.ResolveVariableOrigins(parser, varIds, phase);
                }
            }
            else
            {
                foreach (Executable ex in this.Code)
                {
                    ex.ResolveVariableOrigins(parser, varIds, VariableIdAllocPhase.REGISTER);
                }

                foreach (Executable ex in this.Code)
                {
                    ex.ResolveVariableOrigins(parser, varIds, VariableIdAllocPhase.ALLOC);
                }
            }

            this.IterationVariableId = varIds.GetVarId(this.IterationVariable);
        }
示例#2
0
        internal override void ResolveVariableOrigins(ParserContext parser, VariableScope varIds, VariableIdAllocPhase phase)
        {
            if ((phase & VariableIdAllocPhase.ALLOC) != 0)
            {
                this.VarId = varIds.GetVarId(this.FirstToken);
                if (this.VarId == null)
                {
                    string name = this.FirstToken.Value;

                    if (parser.ScopeManager.IsValidAssemblyNameFromLocale(this.Locale, name))
                    {
                        throw new ParserException(this, "'" + name + "' is referenced but not imported in this file.");
                    }

                    Node owner = this.Owner;
                    while (owner != null && !(owner is ClassDefinition))
                    {
                        owner = owner.Owner;
                    }

                    if (owner != null)
                    {
                        ClassDefinition cd = (ClassDefinition)owner;
                        foreach (FieldDefinition fd in cd.Fields)
                        {
                            if (fd.NameToken.Value == name)
                            {
                                string message = "'" + name + "' is used like a local variable but it is " + (fd.Modifiers.HasStatic ? "a static" : "an instance") + " field.";
                                message += " Did you mean '" + (fd.Modifiers.HasStatic ? cd.NameToken.Value : "this") + "." + name + "' instead of '" + name + "'?";
                                throw new ParserException(this, message);
                            }
                        }

                        foreach (FunctionDefinition fd in cd.Methods)
                        {
                            if (fd.NameToken.Value == name)
                            {
                                string message = "'" + name + "' is used like a standalone function but it is " + (fd.Modifiers.HasStatic ? "a static" : "an instance") + " method.";
                                message += " Did you mean '" + (fd.Modifiers.HasStatic ? cd.NameToken.Value : "this") + "." + name + "' instead of '" + name + "'?";
                                throw new ParserException(this, message);
                            }
                        }
                    }

                    if (this.Owner is ConstDefinition)
                    {
                        throw new ParserException(this, "The expression '" + name + "' is not defined. Are you missing a const definition?");
                    }

                    // TODO: But if it's being called like a function then...
                    // - give a better error message "function 'foo' is not defined"
                    // - give an even better error message when there's a class or instance function with the same name
                    //   e.g. "'foo' is a static function and must be invoked with the class name: FooClass.foo(...)
                    // - if there's a method, suggest using "this."
                    // - if the variable name matches a library that is available, suggest it as a missing import.
                    throw new ParserException(this, "The variable '" + name + "' is used but is never assigned to.");
                }
            }
        }
示例#3
0
        internal override void ResolveVariableOrigins(ParserContext parser, VariableScope varIds, VariableIdAllocPhase phase)
        {
            foreach (Executable ex in this.TryBlock)
            {
                ex.ResolveVariableOrigins(parser, varIds, phase);
            }

            foreach (CatchBlock cb in this.CatchBlocks)
            {
                if (cb.ExceptionVariableToken != null)
                {
                    if ((phase & VariableIdAllocPhase.REGISTER) != 0)
                    {
                        // TODO: this is a little flawed. Should find the common base class.
                        AType exceptionType = cb.Types.Length == 1
                            ? AType.ProvideRoot(cb.TypeTokens[0], cb.Types[0])
                            : AType.ProvideRoot(cb.CatchToken, "Core.Exception");
                        varIds.RegisterVariable(exceptionType, cb.ExceptionVariableToken.Value);
                    }

                    if ((phase & VariableIdAllocPhase.ALLOC) != 0)
                    {
                        cb.VariableLocalScopeId = varIds.GetVarId(cb.ExceptionVariableToken);
                    }
                }

                foreach (Executable ex in cb.Code)
                {
                    ex.ResolveVariableOrigins(parser, varIds, phase);
                }
            }

            if (this.FinallyBlock != null)
            {
                foreach (Executable ex in this.FinallyBlock)
                {
                    ex.ResolveVariableOrigins(parser, varIds, phase);
                }
            }
        }
示例#4
0
        internal override void ResolveVariableOrigins(ParserContext parser, VariableScope varIds, VariableIdAllocPhase phase)
        {
            if ((phase & VariableIdAllocPhase.ALLOC) != 0)
            {
                this.VarId = varIds.GetVarId(this.FirstToken);
                if (this.VarId == null)
                {
                    string name = this.FirstToken.Value;

                    if (parser.ScopeManager.IsAlreadyImportedAnywhere(this.Locale, name))
                    {
                        throw new ParserException(this, "'" + name + "' is referenced but not imported in this file.");
                    }

                    Node owner = this.Owner;
                    while (owner != null && !(owner is ClassDefinition))
                    {
                        owner = owner.Owner;
                    }

                    if (owner != null)
                    {
                        ClassDefinition cd = (ClassDefinition)owner;
                        foreach (FieldDefinition fd in cd.Fields)
                        {
                            if (fd.NameToken.Value == name)
                            {
                                string message = "'" + name + "' is used like a local variable but it is " + (fd.Modifiers.HasStatic ? "a static" : "an instance") + " field.";
                                message += " Did you mean '" + (fd.Modifiers.HasStatic ? cd.NameToken.Value : "this") + "." + name + "' instead of '" + name + "'?";
                                throw new ParserException(this, message);
                            }
                        }

                        foreach (FunctionDefinition fd in cd.Methods)
                        {
                            if (fd.NameToken.Value == name)
                            {
                                string message = "'" + name + "' is used like a standalone function but it is " + (fd.Modifiers.HasStatic ? "a static" : "an instance") + " method.";
                                message += " Did you mean '" + (fd.Modifiers.HasStatic ? cd.NameToken.Value : "this") + "." + name + "' instead of '" + name + "'?";
                                throw new ParserException(this, message);
                            }
                        }
                    }

                    if (this.Owner is ConstDefinition)
                    {
                        throw new ParserException(this, "The expression '" + name + "' is not defined. Are you missing a const definition?");
                    }

                    if (this.DirectOwner != null && this.DirectOwner is FunctionCall)
                    {
                        throw new ParserException(this.FirstToken, "Function '" + name + "' is not defined.");
                    }

                    if (this.CompilationScope.Dependencies.Where(dep => dep.Name == name).FirstOrDefault() != null)
                    {
                        throw new ParserException(this.FirstToken, "The library '" + name + "' is referenced here, but it has not been imported in this file. Add 'import " + name + "' to use it.");
                    }

                    throw new ParserException(this, "The variable '" + name + "' is used but is never assigned to.");
                }
            }
        }