예제 #1
0
 internal override Expression ResolveNames(ParserContext parser)
 {
     this.Expression.ResolveNames(parser);
     this.ClassDefinition = Node.DoClassLookup(this.Owner, this.ClassToken, this.ClassName);
     return(this);
 }
예제 #2
0
        internal override Executable ResolveNames(ParserContext parser)
        {
            this.BatchExecutableNameResolver(parser, this.TryBlock);

            Common.TODO.GetCoreNameFromMetadataWithLocale();
            string coreExceptionName = "Core.Exception";

            ClassDefinition simpleException = Node.DoClassLookup(this.Owner, null, coreExceptionName);

            foreach (CatchBlock cb in this.CatchBlocks)
            {
                string[] types      = cb.Types;
                Token[]  typeTokens = cb.TypeTokens;
                int      typeCount  = types.Length;
                cb.TypeClasses = new ClassDefinition[typeCount];
                for (int i = 0; i < typeCount; ++i)
                {
                    string          typeName     = types[i] ?? coreExceptionName;
                    Token           token        = typeTokens[i] ?? cb.CatchToken;
                    ClassDefinition resolvedType = Node.DoClassLookup(this.Owner, token, typeName, true);
                    if (resolvedType == null)
                    {
                        throw new ParserException(token, "Could not resolve class name for catch.");
                    }
                    if (!resolvedType.ExtendsFrom(simpleException))
                    {
                        if (resolvedType.BaseClass == null && resolvedType.Library == null)
                        {
                            throw new ParserException(token, "This class does not extend from Core.Exception.");
                        }
                        else
                        {
                            throw new ParserException(token, "Only classes that extend from Core.Exception may be caught.");
                        }
                    }
                    cb.TypeClasses[i] = resolvedType;

                    // There's only one type, it doesn't resolve into a class, there's no variable, and there's no '.' in the type name.
                    if (resolvedType == null &&
                        typeCount == 1 &&
                        cb.ExceptionVariableToken == null &&
                        !typeName.Contains("."))
                    {
                        // ...that means this is not a type but is actually a variable.

                        // Change the type to "Core.Exception", move this token to a variable
                        types[0] = coreExceptionName;
                        cb.ExceptionVariableToken = token;
                        typeTokens[0]             = null;
                        --i; // and then try resolving again.
                    }
                }

                /*
                 *  TODO: throw an error or warning if an exception catch is followed by a more specific catch.
                 *  e.g.
                 *  try { ... }
                 *  catch (Exception) { ... }
                 *  catch (InvalidArgumentException) { ... }
                 */

                this.BatchExecutableNameResolver(parser, cb.Code);
            }

            if (this.FinallyBlock != null)
            {
                this.BatchExecutableNameResolver(parser, this.FinallyBlock);
            }

            return(this);
        }
예제 #3
0
 internal override Expression ResolveNames(ParserContext parser)
 {
     this.BatchExpressionNameResolver(parser, this.Args);
     this.Class = Node.DoClassLookup(this.Owner, this.NameToken, this.Name);
     return(this);
 }