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); }
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"); }