/// <summary> /// Create a context to compile expressions within a method scope. /// </summary> internal CompilationContext( CSharpCompilation compilation, MethodSymbol currentFrame, ImmutableArray<LocalSymbol> locals, InScopeHoistedLocals inScopeHoistedLocals, MethodDebugInfo<TypeSymbol, LocalSymbol> methodDebugInfo, CSharpSyntaxNode syntax) { Debug.Assert((syntax == null) || (syntax is ExpressionSyntax) || (syntax is LocalDeclarationStatementSyntax)); // TODO: syntax.SyntaxTree should probably be added to the compilation, // but it isn't rooted by a CompilationUnitSyntax so it doesn't work (yet). _currentFrame = currentFrame; _syntax = syntax; _methodNotType = !locals.IsDefault; // NOTE: Since this is done within CompilationContext, it will not be cached. // CONSIDER: The values should be the same everywhere in the module, so they // could be cached. // (Catch: what happens in a type context without a method def?) this.Compilation = GetCompilationWithExternAliases(compilation, methodDebugInfo.ExternAliasRecords); // Each expression compile should use a unique compilation // to ensure expression-specific synthesized members can be // added (anonymous types, for instance). Debug.Assert(this.Compilation != compilation); this.NamespaceBinder = CreateBinderChain( this.Compilation, (PEModuleSymbol)currentFrame.ContainingModule, currentFrame.ContainingNamespace, methodDebugInfo.ImportRecordGroups); if (_methodNotType) { _locals = locals; ImmutableArray<string> displayClassVariableNamesInOrder; GetDisplayClassVariables( currentFrame, _locals, inScopeHoistedLocals, out displayClassVariableNamesInOrder, out _displayClassVariables, out _hoistedParameterNames); Debug.Assert(displayClassVariableNamesInOrder.Length == _displayClassVariables.Count); _localsForBinding = GetLocalsForBinding(_locals, displayClassVariableNamesInOrder, _displayClassVariables); } else { _locals = ImmutableArray<LocalSymbol>.Empty; _displayClassVariables = ImmutableDictionary<string, DisplayClassVariable>.Empty; _localsForBinding = ImmutableArray<LocalSymbol>.Empty; } // Assert that the cheap check for "this" is equivalent to the expensive check for "this". Debug.Assert( _displayClassVariables.ContainsKey(GeneratedNames.ThisProxyFieldName()) == _displayClassVariables.Values.Any(v => v.Kind == DisplayClassVariableKind.This)); }
private EvaluationContext( MethodContextReuseConstraints? methodContextReuseConstraints, CSharpCompilation compilation, MethodSymbol currentFrame, ImmutableArray<LocalSymbol> locals, InScopeHoistedLocals inScopeHoistedLocals, MethodDebugInfo<TypeSymbol, LocalSymbol> methodDebugInfo) { Debug.Assert(inScopeHoistedLocals != null); Debug.Assert(methodDebugInfo != null); this.MethodContextReuseConstraints = methodContextReuseConstraints; this.Compilation = compilation; _currentFrame = currentFrame; _locals = locals; _inScopeHoistedLocals = inScopeHoistedLocals; _methodDebugInfo = methodDebugInfo; }
public MethodDebugInfo Build() { // Global header _bytesBuilder.Insert(0, Version); _bytesBuilder.Insert(1, (byte)_recordCount); _bytesBuilder.Insert(2, Padding); _bytesBuilder.Insert(3, Padding); Assert.Equal(0, _bytesBuilder.Count % 4); var info = new MethodDebugInfo(_bytesBuilder.ToImmutableAndFree(), _method); _bytesBuilder = null; // We'll blow up if any other methods are called. return info; }