예제 #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");
        }
        bool TrySuggestMembers(FunctionCompiler fc, Expression dte, bool includeBlocks)
        {
            var pe = fc.ResolveExpression(dte, null);

            fc.Compiler.AstProcessor.Process();

            if (pe != null)
            {
                var extensionTypeMethods = FindAllExtensionTypeMethods(fc, dte.Source);
                switch (pe.ExpressionType)
                {
                case PartialExpressionType.Namespace: SuggestNamespaceMembers((pe as PartialNamespace).Namespace, includeBlocks); break;

                case PartialExpressionType.Type: SuggestTypeMembers((pe as PartialType).Type, AccessorLevel.Unknown, true, includeBlocks, true, extensionTypeMethods); break;

                case PartialExpressionType.Block: SuggestBlockItems((pe as PartialBlock).Block); break;

                case PartialExpressionType.Variable: SuggestTypeMembers((pe as PartialVariable).Variable.ValueType, AccessorLevel.Unknown, false, false, true, extensionTypeMethods); break;

                case PartialExpressionType.Parameter: SuggestTypeMembers((pe as PartialParameter).Function.Match(f => f.Parameters, l => l.Parameters)[(pe as PartialParameter).Index].Type, AccessorLevel.Unknown, false, false, true, extensionTypeMethods); break;

                case PartialExpressionType.Field: SuggestTypeMembers((pe as PartialField).Field.ReturnType, AccessorLevel.Unknown, false, false, true, extensionTypeMethods); break;

                case PartialExpressionType.Event: break;

                case PartialExpressionType.Property: SuggestTypeMembers((pe as PartialProperty).Property.ReturnType, AccessorLevel.Unknown, false, false, true, extensionTypeMethods); break;

                case PartialExpressionType.Indexer: SuggestTypeMembers((pe as PartialIndexer).Indexer.ReturnType, AccessorLevel.Unknown, false, false, true, extensionTypeMethods); break;

                case PartialExpressionType.ArrayElement: SuggestTypeMembers((pe as PartialArrayElement).ElementType, AccessorLevel.Unknown, false, false, true, extensionTypeMethods); break;

                case PartialExpressionType.MethodGroup: break;

                case PartialExpressionType.This:
                {
                    if (fc.Function != null && fc.Function.DeclaringType != null)
                    {
                        SuggestTypeMembers(fc.Function.DeclaringType, AccessorLevel.Private, fc.Function.IsStatic, false, true, extensionTypeMethods);
                    }
                }
                break;

                case PartialExpressionType.Value:
                {
                    SuggestTypeMembers((pe as PartialValue).Value.ReturnType, AccessorLevel.Unknown, false, false, true, extensionTypeMethods);

                    if (dte.ExpressionType == ExpressionType.Identifier)
                    {
                        var lastNamescope = Enumerable.Last(_context.NodePath).TypeOrNamespace;
                        if (lastNamescope != null)
                        {
                            var identifier = dte as AstIdentifier;
                            var pt         = _context.Compiler.NameResolver.TryResolveMemberRecursive(lastNamescope, identifier, null);
                            if (pt == null)
                            {
                                pt = _context.Compiler.NameResolver.TryResolveUsingNamespace(lastNamescope, identifier, null);
                            }
                            if (pt is PartialType)
                            {
                                SuggestTypeMembers((pt as PartialType).Type, AccessorLevel.Public, true, true, true, extensionTypeMethods);
                            }
                        }
                    }
                }
                break;

                default: return(false);
                }
                return(true);
            }

            return(false);
        }
예제 #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");
        }