internal override void DoEmit(CompilingContext context) { _condition.CompileBy(context.Compiler, false); context.Compiler.Emitter.Emit(OpCode.GotoIfFalse, context.EndLabel); Statement.CompileBy(context.Compiler); context.Compiler.Emitter.Emit(OpCode.Goto, context.StartLabel); }
internal TemplateTransformer(string workingFolder, string generatedCodeFolder, CompileAssembly assembly) { _workingFolder = workingFolder; _generatedCodeFolder = generatedCodeFolder; _assembly = assembly; _compilingContext = new CompilingContext(assembly); }
internal TemplateTransformer(ProjectCompilingContext context) { _context = context; _workingFolder = context.WorkingFolder; _generatedCodeFolder = context.GeneratedCodeFolder; _assembly = context.Assembly; _compilingContext = new CompilingContext(context.Assembly); }
public override string Fill(CompilingContext context) { var lambda = Compile(context); var codeSnippet = lambda(context); codeSnippet = $@"new {ReturnType}[] {{ {codeSnippet}}}"; return(codeSnippet); }
internal override void DoEmit(CompilingContext context) { if (_condition != null) { _condition.CompileBy(context.Compiler, false); context.Compiler.Emitter.Emit(OpCode.GotoIfFalse, context.EndLabel); } Statement.CompileBy(context.Compiler); if (_increment != null) { _increment.CompileBy(context.Compiler, true); } context.Compiler.Emitter.Emit(OpCode.Goto, context.StartLabel); }
/// <summary> /// 将占位符中的在编译期执行的 Lambda 表达式编译成可执行函数。 /// </summary> /// <returns>用于调用占位符中编译期可执行代码的委托。</returns> private Func <ICompilingContext, string> Compile(CompilingContext context) { var builder = new StringBuilder(ClassTemplate) .Replace("{parameterName}", InvocationParameterName) .Replace("{body}", InvocationBody); var syntaxTree = CSharpSyntaxTree.ParseText(builder.ToString()); var types = syntaxTree.Compile(context.References, "PlaceholderInvoking.g"); var placeholderImpl = types.First(x => x.Name == PlaceholderClassName); var method = placeholderImpl.GetMethod("InvokePlaceholder"); Debug.Assert(method != null, nameof(method) + " != null"); var func = (Func <ICompilingContext, string>)method.CreateDelegate(typeof(Func <ICompilingContext, string>)); return(func); }
/// <summary> /// 创建 <see cref="CompileFile"/> 的新实例,通过此实例可以获取文件中的相关类型信息。 /// </summary> /// <param name="context"></param> /// <param name="fullName"></param> /// <param name="preprocessorSymbols"></param> public CompileFile(CompilingContext context, string fullName, IEnumerable <string> preprocessorSymbols) { _context = context; FullName = fullName; Name = Path.GetFileName(fullName); var originalText = File.ReadAllText(fullName); _syntaxTree = CSharpSyntaxTree.ParseText(originalText, new CSharpParseOptions( LanguageVersion.Latest, DocumentationMode.None, SourceCodeKind.Regular, preprocessorSymbols)); var compileTypeVisitor = new CompileTypeVisitor(); compileTypeVisitor.Visit(_syntaxTree.GetRoot()); Types = compileTypeVisitor.Types.ToList(); UsingNamespaceList = compileTypeVisitor.UsingNamespaceList; AssemblyAttributes = compileTypeVisitor.AssemblyAttributes.ToList(); }
public override string Fill(CompilingContext context) { var collectedItems = CollectAttributedTypes(context); return(_useMetadata // 如果使户使用了元数据,那么就生成更多的信息供用户调用。 ? $@"new System.Collections.Generic.List<(Type Type, {_attributeType} Attribute, Func<{_baseType}> Creator)> {{ {string.Join(@", ", collectedItems.Select(item => $@"(typeof({item.typeName}), {item.attributeCreator}, () => new {item.typeName}())"))} }}" // 如果用户没有使用元数据,那么就直接返回类型声明的返回值。 : $@"new (Type, {_attributeType})[] {{ {string.Join(@", ", collectedItems.Select(item => $@"(typeof({item.typeName}), {item.attributeCreator})"))} }}"); }
internal override sealed void CompileBy(FunctionCompiler compiler) { DoEmitProlog(compiler); var context = new CompilingContext(compiler); try { compiler.StatementStarts.Add(this, context.StartLabel); compiler.StatementEnds.Add(this, context.EndLabel); compiler.Emitter.MarkLabel(context.StartLabel); DoEmit(context); compiler.Emitter.MarkLabel(context.EndLabel); } finally { compiler.StatementEnds.Remove(this); compiler.StatementStarts.Remove(this); } DoEmitEpilog(compiler); compiler.MarkEndOfStatement(); }
internal override void DoEmit(CompilingContext context) { context.Compiler.Emitter.Emit(OpCode.MoveNext, _variableName); context.Compiler.Emitter.Emit(OpCode.GotoIfFalse, context.EndLabel); // В случае режима eval необходимо переставить местами перечислитель // и результат последнего ExpressionStatement в стеке вычислений if (context.Compiler.IsEvalMode) { context.Compiler.Emitter.Emit(OpCode.Swap); } Statement.CompileBy(context.Compiler); // В случае режима eval необходимо вернуть в исходное состояние стек вычислений if (context.Compiler.IsEvalMode) { context.Compiler.Emitter.Emit(OpCode.Swap); } context.Compiler.Emitter.Emit(OpCode.Goto, context.StartLabel); }
public abstract string Fill(CompilingContext context);
internal abstract void DoEmit(CompilingContext context);