예제 #1
0
 public override void CheckScope(ParsingContext context)
 {
     if (TreeFuncs != null)
     {
         Method found = TreeFuncs.FirstOrDefault(func => func.Name == Name.Text); // look for a script function first
         if (found == null)
         {
             // if not found, find all matching extern not case sensitive, and check parameters
             IEnumerable <Method> matchingExterns = null;
             matchingExterns = CoreCommands.Funcs.Where(func => func.Name.ToLower() == Name.Text.ToLower());
             if (matchingExterns == null || matchingExterns.Count() == 0)
             {
                 context.AddParserMessage(ParserErrorLevel.Error, this.Span, "Undeclared function {0}.", Name.Text);
             }
             else if ((found = matchingExterns.FirstOrDefault(func => AreSameParams(func.Parameters, this.Arguments, true))) == null)
             {
                 context.AddParserMessage(ParserErrorLevel.Error, this.Span, "Invalid params for core function {0}.", Name.Text);
             }
             else
             {
                 found.AddReference(this);
             }
         }
         else
         {
             // check params
             if ((Arguments == null || Arguments.Count == 0) != (found.Parameters == null || found.Parameters.Count == 0))
             {
                 context.AddParserMessage(ParserErrorLevel.Error, this.Span, "Argument mismatch.");
             }
             else if (found.Parameters != null && found.Parameters.Count > 0)
             {
                 if (Arguments == null || Arguments.Count == 0)
                 {
                     context.AddParserMessage(ParserErrorLevel.Error, this.Span, "This function call requires arguments.");
                 }
                 else
                 {
                     for (int i = 0; i < found.Parameters.Count; i++)
                     {
                         if (i >= Arguments.Count)
                         {
                             context.AddParserMessage(ParserErrorLevel.Error, this.ChildNodes[this.ChildNodes.Count - 1].Span, "Insufficient arguments.");
                             break;
                         }
                         if (Arguments[i].UoTypeToken != found.Parameters[i].UoTypeToken)
                         {
                             if (Arguments[i].UoTypeToken == null)
                             {
                                 context.AddParserMessage(ParserErrorLevel.Info, this.ChildNodes[i].Span, "Use of \"any\" as a typed argument.");
                             }
                             else
                             {
                                 context.AddParserMessage(ParserErrorLevel.Error, this.ChildNodes[i].Span, "Argument type mismatch.");
                             }
                         }
                     }
                 }
                 if (Arguments.Count > found.Parameters.Count)
                 {
                     context.AddParserMessage(ParserErrorLevel.Error, this.ChildNodes[found.Parameters.Count].Span, "Too many arguments.");
                 }
             }
             // check location
             if (found.DefNode == null)
             {
                 context.AddParserMessage(ParserErrorLevel.Error, this.Span, "Function {0} is declared, but not defined.", found.Name);
             }
             else if (found.DefFilename == context.CurrentParseTree.FileName && found.DefNode.Location.Position > this.Location.Position && (found.ForwardNode == null || found.ForwardNode.Location.Position > this.Location.Position))
             {
                 context.AddParserMessage(ParserErrorLevel.Error, this.Span, "Function {0} must be declared before it is used.", found.Name);
             }
         }
         if (found != null)
         {
             this.SetUoTypeToken(found.UoTypeToken);
             found.AddReference(this);
         }
     }
 }