Ejemplo n.º 1
0
        void CompileApply(AstApply ast, BlockBase parent)
        {
            var e   = ast.Block;
            var src = e.Source;
            var fc  = new FunctionCompiler(_compiler, parent);
            var p   = fc.ResolveExpression(e, null);

            if (p.IsInvalid)
            {
                return;
            }

            if (p is PartialType)
            {
                var dt = (p as PartialType).Type;

                if (dt.Block != null)
                {
                    dt.PopulateMembers();
                    dt.Block.Populate();
                    parent.Members.Add(new Apply(src, ast.Modifier, dt.Block, null));
                    return;
                }
            }
            else if (p is PartialBlock)
            {
                var b = (p as PartialBlock).Block;
                b.Populate();
                parent.Members.Add(new Apply(src, ast.Modifier, b, null));
                return;
            }

            var sym = fc.CompilePartial(p);

            if (sym.IsInvalid)
            {
                return;
            }

            if (sym.ReturnType.Block != null)
            {
                sym.ReturnType.PopulateMembers();
                sym.ReturnType.Block.Populate();
                parent.Members.Add(new Apply(src, ast.Modifier, sym.ReturnType.Block, sym));
                return;
            }

            Log.Error(src, ErrorCode.E3213, "Only 'block', 'class', 'struct' or 'interface' types can be applied");
        }
Ejemplo n.º 2
0
        public void PopulateBlock(AstBlockBase ast, BlockBase result)
        {
            // TODO

            /*
             * if (result is Block)
             *  ((Block) result).SetAttributes(_compiler.CompileAttributes(result.Parent, ast.Attributes));
             */
            if (ast is AstBlock)
            {
                var blockDecl   = ast as AstBlock;
                var usingBlocks = new Block[blockDecl.UsingBlocks?.Count ?? 0];

                for (int i = 0; i < usingBlocks.Length; i++)
                {
                    usingBlocks[i] = _resolver.GetBlock(result.Parent, blockDecl.UsingBlocks[i]);
                }

                ((Block)result).SetUsingBlocks(usingBlocks);
            }

            var dt = result.ParentType;

            dt?.PopulateMembers();

            if (result is Block)
            {
                foreach (var block in (result as Block).UsingBlocks)
                {
                    block.Populate();
                }
            }

            foreach (var item in ast.Members)
            {
                switch (item.MemberType)
                {
                case AstMemberType.ApplyStatement:
                    CompileApply((AstApply)item, result);
                    continue;

                case AstMemberType.Block:
                    CreateBlock((AstBlock)item, result);
                    continue;

                case AstMemberType.MetaProperty:
                    result.Members.Add(CreateMetaProperty((AstMetaProperty)item, result));
                    continue;

                case AstMemberType.NodeBlock:
                    result.Members.Add(new Node(CreateNodeBlock((AstNode)item, result)));
                    continue;

                case AstMemberType.Field:
                case AstMemberType.Property:
                    if (dt == null)
                    {
                        break;
                    }

                    var f  = (AstNamedMember)item;
                    var fd = f as AstField;
                    var pd = f as AstProperty;

                    if (f.Modifiers.HasFlag(Modifiers.Static) ||
                        !_compiler.Environment.Test(f.Name.Source, f.OptionalCondition) ||
                        fd != null && fd.FieldModifiers.HasFlag(FieldModifiers.Const) ||
                        pd != null && (pd.Get == null || pd.OptionalInterfaceType != null))
                    {
                        continue;
                    }

                    var pt = _compiler.TypeBuilder.Parameterize(dt);
                    var fc = new FunctionCompiler(_compiler, pt);
                    var pe = fc.TryResolveTypeMember(pt, f.Name, null, null, new GetMetaObject(f.Name.Source, pt));

                    if (pe == null)
                    {
                        if (!dt.CanLink)
                        {
                            Log.Warning(f.Name.Source, ErrorCode.IW3205, f.Name.Symbol.Quote() + " was not found in class scope");
                        }
                        continue;
                    }

                    var mp = new MetaProperty(f.Name.Source, result, _resolver.GetType(pt, f.ReturnType), f.Name.Symbol, f.Modifiers.HasFlag(Modifiers.Public) ? MetaVisibility.Public : 0);
                    mp.SetDefinitions(new MetaDefinition(fc.CompilePartial(pe), new string[0], new ReqObject(f.Name.Source, pt)));
                    result.Members.Add(mp);
                    break;
                }

                if (dt == null)
                {
                    Log.Error(((item as AstNamedMember)?.Name ?? ast.Name).Source, ErrorCode.E3207, "<" + item.MemberType + "> is not allowed in this scope");
                }
            }
        }
Ejemplo n.º 3
0
        void CompileApply(AstApply ast, BlockBase parent)
        {
            var e   = ast.Block;
            var src = e.Source;

            // Invoke apply plugin
            if (e.ExpressionType == AstExpressionType.Call)
            {
                var call    = (AstCall)e;
                var factory = _compiler.TryCompileSuffixedObject(parent, call.Base, "BlockFactory", call.Arguments);

                if (factory == null)
                {
                    return;
                }

                if (factory.ReturnType.Base == null ||
                    factory.ReturnType.Base.MasterDefinition != _ilf.Essentials.BlockFactory)
                {
                    Log.Error(factory.Source, ErrorCode.E0000, "Block Factory must be a type derived directly from " + _ilf.Essentials.BlockFactory.Quote());
                    return;
                }

                BlockFactory plugin;
                if (!_compiler.Plugins.TryGetBlockFactory(factory.ReturnType, out plugin))
                {
                    Log.Error(factory.Source, ErrorCode.E2048, "Unsupported block factory " + factory.ReturnType.Quote());
                    return;
                }

                if (!_compiler.ExpandFilenames(factory, 0))
                {
                    return;
                }

                var block = CreateBlock(
                    plugin.Create(
                        new ApplyContext(
                            src,
                            factory.GetArgumentValues())),
                    _il);

                block.Populate();
                parent.Members.Add(new Apply(src, ast.Modifier, block, null));
                _compiler.ILVerifier.VerifyConstUsage(factory.Source, factory.Constructor, parent);
                return;
            }

            var fc = new FunctionCompiler(_compiler, parent);
            var p  = fc.ResolveExpression(e, null);

            if (p.IsInvalid)
            {
                return;
            }

            if (p is PartialType)
            {
                var dt = (p as PartialType).Type;

                if (dt.Block != null)
                {
                    dt.PopulateMembers();
                    dt.Block.Populate();
                    parent.Members.Add(new Apply(src, ast.Modifier, dt.Block, null));
                    return;
                }
            }
            else if (p is PartialBlock)
            {
                var b = (p as PartialBlock).Block;
                b.Populate();
                parent.Members.Add(new Apply(src, ast.Modifier, b, null));
                return;
            }

            var sym = fc.CompilePartial(p);

            if (sym.IsInvalid)
            {
                return;
            }

            if (sym.ReturnType.Block != null)
            {
                sym.ReturnType.PopulateMembers();
                sym.ReturnType.Block.Populate();
                parent.Members.Add(new Apply(src, ast.Modifier, sym.ReturnType.Block, sym));
                return;
            }

            Log.Error(src, ErrorCode.E3213, "Only 'block', 'class', 'struct' or 'interface' types can be applied");
        }