Beispiel #1
0
 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);
 }
Beispiel #2
0
 internal TemplateTransformer(string workingFolder, string generatedCodeFolder, CompileAssembly assembly)
 {
     _workingFolder       = workingFolder;
     _generatedCodeFolder = generatedCodeFolder;
     _assembly            = assembly;
     _compilingContext    = new CompilingContext(assembly);
 }
Beispiel #3
0
 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);
        }
Beispiel #5
0
 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);
        }
Beispiel #7
0
        /// <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();
        }
Beispiel #8
0
        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})"))}
            }}");
        }
Beispiel #9
0
        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();
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
 public abstract string Fill(CompilingContext context);
Beispiel #12
0
 internal abstract void DoEmit(CompilingContext context);