//Initialized a new CodeGenerator for generation of SourceGeneratorSymbol (state machine's next method) private void GenerateStateMachinesNextMethod(CodeGenerator cg, Microsoft.CodeAnalysis.CodeGen.ILBuilder _il, SourceGeneratorSymbol genSymbol) { // TODO: get correct ThisPlace, ReturnType etc. resolution & binding out of the box without GN_SGS hacks // using SourceGeneratorSymbol //Refactor parameters references to proper fields using (var stateMachineNextCg = new CodeGenerator( _il, cg.Module, cg.Diagnostics, cg.DeclaringCompilation.Options.OptimizationLevel, cg.EmitPdbSequencePoints, this.ContainingType, contextPlace: new ParamPlace(genSymbol.ContextParameter), thisPlace: new ParamPlace(genSymbol.ThisParameter), routine: this, locals: new ParamPlace(genSymbol.LocalsParameter), localsInitialized: true, tempLocals: new ParamPlace(genSymbol.TmpLocalsParameter) ) { GeneratorStateMachineMethod = genSymbol, // Pass SourceGeneratorSymbol to CG for additional yield and StartBlock emit }) { stateMachineNextCg.GenerateScope(this.ControlFlowGraph.Start, int.MaxValue); } }
private void InitializeParametersForGeneratorMethod(CodeGenerator cg, Microsoft.CodeAnalysis.CodeGen.ILBuilder il, Microsoft.CodeAnalysis.CodeGen.LocalDefinition generatorsLocals) { // Emit init of unoptimized BoundParameters using separate CodeGenerator that has locals place pointing to our generator's locals array using (var localsArrayCg = new CodeGenerator( il, cg.Module, cg.Diagnostics, cg.DeclaringCompilation.Options.OptimizationLevel, cg.EmitPdbSequencePoints, this.ContainingType, contextPlace: null, thisPlace: null, routine: this, // needed to support static variables (they need enclosing routine while binding) locals: new LocalPlace(generatorsLocals), localsInitialized: false )) { // EmitInit (for UnoptimizedLocals) copies arguments to locals array, does nothing for normal variables, handles local statics, global variables ... LocalsTable.Variables.ForEach(v => v.EmitInit(localsArrayCg)); } }
//Initialized a new CodeGenerator for generation of SourceGeneratorSymbol (state machine's next method) private void generateStateMachinesNextMethod(CodeGenerator cg, Microsoft.CodeAnalysis.CodeGen.ILBuilder _il, SourceGeneratorSymbol genSymbol) { // TODO: Pass SourceGeneratorSymbol to CG instead of this to get correct ThisPlace, ReturnType etc. resolution & binding out of the box without GN_SGS hacks // ..can't do that easily beacuse CodeGenerator accepts only SourceRoutineSymbol and SGS derives from SynthesizedMethodSymbol (shim over too general MethodSymbol) //Refactor parameters references to proper fields using (var stateMachineNextCg = new CodeGenerator( _il, cg.Module, cg.Diagnostics, cg.DeclaringCompilation.Options.OptimizationLevel, cg.EmitPdbSequencePoints, this.ContainingType, contextPlace: new ParamPlace(genSymbol.Parameters[0]), thisPlace: new ParamPlace(genSymbol.Parameters[1]), routine: this, locals: new ParamPlace(genSymbol.Parameters[2]), localsInitialized: true )) { stateMachineNextCg.GenerateScope(this.ControlFlowGraph.Start, int.MaxValue); } }