Beispiel #1
0
        internal void ResolveVariableOrigins(ParserContext parser)
        {
            VariableScope varScope = VariableScope.NewEmptyScope(this.CompilationScope.IsStaticallyTyped);

            this.ArgLocalIds = new VariableId[this.ArgNames.Length];
            for (int i = 0; i < this.ArgNames.Length; ++i)
            {
                this.ArgLocalIds[i] = varScope.RegisterVariable(this.ArgTypes[i], this.ArgNames[i].Value);
            }

            foreach (Expression arg in this.BaseArgs)
            {
                arg.ResolveVariableOrigins(parser, varScope, VariableIdAllocPhase.ALLOC);
            }

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

            Lambda.DoVarScopeIdAllocationForLambdaContainer(parser, varScope, this);

            varScope.FinalizeScopeIds();

            this.LocalScopeSize = varScope.Size;
        }
Beispiel #2
0
        internal void ResolveVariableOrigins(ParserContext parser)
        {
            if (this.DefaultValue != null)
            {
                VariableScope varScope = VariableScope.NewEmptyScope(this.CompilationScope.IsStaticallyTyped);
                this.DefaultValue.ResolveVariableOrigins(parser, varScope, VariableIdAllocPhase.REGISTER_AND_ALLOC);

                if (varScope.Size > 0)
                {
                    // Although if you manage to trigger this, I'd love to know how.
                    throw new ParserException(this, "Cannot declare a variable this way.");
                }

                Lambda.DoVarScopeIdAllocationForLambdaContainer(parser, varScope, this);
            }
        }
Beispiel #3
0
        public static TopLevelEntity[] Resolve(ParserContext parser, ICollection <CompilationScope> compilationScopesRaw)
        {
            List <TopLevelEntity> originalCode = new List <TopLevelEntity>();
            Dictionary <string, CompilationScope> compilationScopeLookup = new Dictionary <string, CompilationScope>();

            foreach (CompilationScope scope in compilationScopesRaw.OrderBy(scope => scope.ScopeKey))
            {
                originalCode.AddRange(scope.GetTopLevelEntities());
                compilationScopeLookup[scope.Metadata.ID] = scope;
            }
            TopLevelEntity[] code = originalCode.ToArray();

            parser.VerifyNoBadImports();

            ExternalAssemblyMetadata[] assembliesInDependencyOrder = AssemblyDependencyUtil.GetAssemblyResolutionOrder(parser.ScopeManager.ImportedAssemblyScopes.Select(scope => scope.Metadata));

            List <CompilationScope> compilationScopes = new List <CompilationScope>(
                assembliesInDependencyOrder.Select(asm => compilationScopeLookup[asm.ID]));

            compilationScopes.Add(parser.RootScope);

            // Resolve raw names into the actual things they refer to based on namespaces and imports.
            foreach (CompilationScope scope in compilationScopes)
            {
                EntityNameResolver.Resolve(parser, scope);
            }

            LocalScopeVariableIdAllocator.Run(parser, code.Where(tle => !(tle is ConstDefinition || tle is EnumDefinition)));

            foreach (CompilationScope scope in compilationScopes)
            {
                TopLevelEntity[]     topLevelEntities = scope.GetTopLevelEntities();
                ConstDefinition[]    consts           = topLevelEntities.OfType <ConstDefinition>().ToArray();
                EnumDefinition[]     enums            = topLevelEntities.OfType <EnumDefinition>().ToArray();
                ClassDefinition[]    classes          = topLevelEntities.OfType <ClassDefinition>().ToArray();
                FunctionDefinition[] functions        = topLevelEntities.OfType <FunctionDefinition>().ToArray();

                // Constants are provided in dependency order. Type resolution running in this order
                // will not encounter anything unknown. Const dependency loops are found by .SortConstants()
                // Note that this sorting is for the purposes of type resolution. All enums are automatically
                // known to be integers, so there's possibly still some dependency loops there, which are
                // caught during the consolidation in the Resolve() phase.

                TopLevelEntity[] topLevelEntitiesWithoutConstants = new TopLevelEntity[0]
                                                                    .Concat(enums)
                                                                    .Concat(functions)
                                                                    .Concat(classes)
                                                                    .ToArray();

                // The type of the overall constant is dependent on the expression's type when there are
                // no type declarations (i.e. Crayon). Because signature types need to be resolved before
                // the expression itself, these are sorted in dependency order. Enum values, even though
                // a const expression can depend on them, are always an integer, so they don't need to be
                // type-resolved at this time.
                ConstDefinition[] dependencySortedConstants = new ConstantDependencySorter(consts).SortConstants();
                foreach (ConstDefinition cnst in dependencySortedConstants)
                {
                    TypeResolver typeResolver = new TypeResolver(parser.TypeContext, cnst);

                    // This shouldn't pick anything up, but it'll fire any errors when undeclared variable-like expressions are used.
                    cnst.Expression.ResolveVariableOrigins(parser, VariableScope.NewEmptyScope(false), VariableIdAllocPhase.REGISTER_AND_ALLOC);

                    cnst.ResolveTypes(parser, typeResolver);
                    cnst.ValidateConstTypeSignature();
                }

                foreach (TopLevelEntity tle in topLevelEntitiesWithoutConstants)
                {
                    TypeResolver typeResolver = new TypeResolver(parser.TypeContext, tle);
                    tle.ResolveSignatureTypes(parser, typeResolver);
                }

                foreach (TopLevelEntity tle in topLevelEntitiesWithoutConstants.Where(t => !(t is EnumDefinition)))
                {
                    tle.EnsureModifierAndTypeSignatureConsistency(parser.TypeContext);
                }

                foreach (TopLevelEntity tle in topLevelEntitiesWithoutConstants)
                {
                    TypeResolver typeResolver = new TypeResolver(parser.TypeContext, tle);
                    tle.ResolveTypes(parser, typeResolver);
                }
            }

            SpecialFunctionFinder.Run(parser);

            List <TopLevelEntity> newCode = new List <TopLevelEntity>();

            foreach (CompilationScope scope in compilationScopes)
            {
                TopLevelEntity[] everything     = scope.GetTopLevelEntities();
                TopLevelEntity[] constsAndEnums = new TopLevelEntity[0]
                                                  .Concat(everything.OfType <ConstDefinition>())
                                                  .Concat(everything.OfType <EnumDefinition>())
                                                  .ToArray();
                TopLevelEntity[] codeContainers = new TopLevelEntity[0]
                                                  .Concat(everything.OfType <FunctionDefinition>())
                                                  .Concat(everything.OfType <ClassDefinition>())
                                                  .ToArray();
                foreach (TopLevelEntity tle in everything.Concat(codeContainers))
                {
                    tle.Resolve(parser);
                }
                newCode.AddRange(DependencyBasedClassSorter.Run(codeContainers));
            }

            code = newCode.ToArray();

            parser.InlinableLibraryFunctions = InlineableLibraryFunctionFinder.Find(code);

            return(code);
        }