/// <summary> /// Create a context for evaluating expressions at a type scope. /// </summary> /// <param name="previous">Previous context, if any, for possible re-use.</param> /// <param name="metadataBlocks">Module metadata</param> /// <param name="moduleVersionId">Module containing type</param> /// <param name="typeToken">Type metadata token</param> /// <returns>Evaluation context</returns> /// <remarks> /// No locals since locals are associated with methods, not types. /// </remarks> internal static EvaluationContext CreateTypeContext( CSharpMetadataContext previous, ImmutableArray <MetadataBlock> metadataBlocks, Guid moduleVersionId, int typeToken) { Debug.Assert(MetadataTokens.Handle(typeToken).Kind == HandleKind.TypeDefinition); // Re-use the previous compilation if possible. var compilation = previous.Matches(metadataBlocks) ? previous.Compilation : metadataBlocks.ToCompilation(); MetadataDecoder metadataDecoder; var currentType = compilation.GetType(moduleVersionId, typeToken, out metadataDecoder); Debug.Assert((object)currentType != null); Debug.Assert(metadataDecoder != null); var currentFrame = new SynthesizedContextMethodSymbol(currentType); return(new EvaluationContext( metadataBlocks, null, compilation, metadataDecoder, currentFrame, default(ImmutableArray <LocalSymbol>), InScopeHoistedLocals.Empty, default(MethodDebugInfo))); }
/// <summary> /// Create a context for evaluating expressions at a type scope. /// </summary> /// <param name="previous">Previous context, if any, for possible re-use.</param> /// <param name="metadataBlocks">Module metadata</param> /// <param name="moduleVersionId">Module containing type</param> /// <param name="typeToken">Type metadata token</param> /// <returns>Evaluation context</returns> /// <remarks> /// No locals since locals are associated with methods, not types. /// </remarks> internal static EvaluationContext CreateTypeContext( CSharpMetadataContext previous, ImmutableArray<MetadataBlock> metadataBlocks, Guid moduleVersionId, int typeToken) { // Re-use the previous compilation if possible. var compilation = previous.Matches(metadataBlocks) ? previous.Compilation : metadataBlocks.ToCompilation(); return CreateTypeContext(compilation, moduleVersionId, typeToken); }
/// <summary> /// Create a context for evaluating expressions at a type scope. /// </summary> /// <param name="previous">Previous context, if any, for possible re-use.</param> /// <param name="metadataBlocks">Module metadata</param> /// <param name="moduleVersionId">Module containing type</param> /// <param name="typeToken">Type metadata token</param> /// <returns>Evaluation context</returns> /// <remarks> /// No locals since locals are associated with methods, not types. /// </remarks> internal static EvaluationContext CreateTypeContext( CSharpMetadataContext previous, ImmutableArray <MetadataBlock> metadataBlocks, Guid moduleVersionId, int typeToken) { // Re-use the previous compilation if possible. var compilation = previous.Matches(metadataBlocks) ? previous.Compilation : metadataBlocks.ToCompilation(); return(CreateTypeContext(compilation, moduleVersionId, typeToken)); }
/// <summary> /// Create a context for evaluating expressions within a method scope. /// </summary> /// <param name="previous">Previous context, if any, for possible re-use.</param> /// <param name="metadataBlocks">Module metadata</param> /// <param name="symReader"><see cref="ISymUnmanagedReader"/> for PDB associated with <paramref name="moduleVersionId"/></param> /// <param name="moduleVersionId">Module containing method</param> /// <param name="methodToken">Method metadata token</param> /// <param name="methodVersion">Method version.</param> /// <param name="ilOffset">IL offset of instruction pointer in method</param> /// <param name="localSignatureToken">Method local signature token</param> /// <returns>Evaluation context</returns> internal static EvaluationContext CreateMethodContext( CSharpMetadataContext previous, ImmutableArray <MetadataBlock> metadataBlocks, object symReader, Guid moduleVersionId, int methodToken, int methodVersion, uint ilOffset, int localSignatureToken) { var offset = NormalizeILOffset(ilOffset); // Re-use the previous compilation if possible. CSharpCompilation compilation; if (previous.Matches(metadataBlocks)) { // Re-use entire context if method scope has not changed. var previousContext = previous.EvaluationContext; if (previousContext != null && previousContext.MethodContextReuseConstraints.HasValue && previousContext.MethodContextReuseConstraints.GetValueOrDefault().AreSatisfied(moduleVersionId, methodToken, methodVersion, offset)) { return(previousContext); } compilation = previous.Compilation; } else { compilation = metadataBlocks.ToCompilation(); } return(CreateMethodContext( compilation, symReader, moduleVersionId, methodToken, methodVersion, offset, localSignatureToken)); }
/// <summary> /// Create a context for evaluating expressions within a method scope. /// </summary> /// <param name="previous">Previous context, if any, for possible re-use.</param> /// <param name="metadataBlocks">Module metadata</param> /// <param name="symReader"><see cref="ISymUnmanagedReader"/> for PDB associated with <paramref name="moduleVersionId"/></param> /// <param name="moduleVersionId">Module containing method</param> /// <param name="methodToken">Method metadata token</param> /// <param name="methodVersion">Method version.</param> /// <param name="ilOffset">IL offset of instruction pointer in method</param> /// <param name="localSignatureToken">Method local signature token</param> /// <returns>Evaluation context</returns> internal static EvaluationContext CreateMethodContext( CSharpMetadataContext previous, ImmutableArray<MetadataBlock> metadataBlocks, object symReader, Guid moduleVersionId, int methodToken, int methodVersion, int ilOffset, int localSignatureToken) { // Re-use the previous compilation if possible. CSharpCompilation compilation; if (previous.Matches(metadataBlocks)) { // Re-use entire context if method scope has not changed. var previousContext = previous.EvaluationContext; if (previousContext != null && previousContext.MethodContextReuseConstraints.HasValue && previousContext.MethodContextReuseConstraints.GetValueOrDefault().AreSatisfied(moduleVersionId, methodToken, methodVersion, ilOffset)) { return previousContext; } compilation = previous.Compilation; } else { compilation = metadataBlocks.ToCompilation(); } return CreateMethodContext( compilation, symReader, moduleVersionId, methodToken, methodVersion, ilOffset, localSignatureToken); }
/// <summary> /// Create a context for evaluating expressions within a method scope. /// </summary> /// <param name="previous">Previous context, if any, for possible re-use.</param> /// <param name="metadataBlocks">Module metadata</param> /// <param name="symReader"><see cref="ISymUnmanagedReader"/> for PDB associated with <paramref name="moduleVersionId"/></param> /// <param name="moduleVersionId">Module containing method</param> /// <param name="methodToken">Method metadata token</param> /// <param name="methodVersion">Method version.</param> /// <param name="ilOffset">IL offset of instruction pointer in method</param> /// <param name="localSignatureToken">Method local signature token</param> /// <returns>Evaluation context</returns> internal static EvaluationContext CreateMethodContext( CSharpMetadataContext previous, ImmutableArray <MetadataBlock> metadataBlocks, object symReader, Guid moduleVersionId, int methodToken, int methodVersion, int ilOffset, int localSignatureToken) { Debug.Assert(MetadataTokens.Handle(methodToken).Kind == HandleKind.MethodDefinition); // Re-use the previous compilation if possible. CSharpCompilation compilation; if (previous.Matches(metadataBlocks)) { // Re-use entire context if method scope has not changed. var previousContext = previous.EvaluationContext; if (previousContext != null && previousContext.MethodContextReuseConstraints.HasValue && previousContext.MethodContextReuseConstraints.GetValueOrDefault().AreSatisfied(moduleVersionId, methodToken, methodVersion, ilOffset)) { return(previousContext); } compilation = previous.Compilation; } else { compilation = metadataBlocks.ToCompilation(); } var typedSymReader = (ISymUnmanagedReader)symReader; var allScopes = ArrayBuilder <ISymUnmanagedScope> .GetInstance(); var containingScopes = ArrayBuilder <ISymUnmanagedScope> .GetInstance(); typedSymReader.GetScopes(methodToken, methodVersion, ilOffset, IsLocalScopeEndInclusive, allScopes, containingScopes); var methodContextReuseConstraints = allScopes.GetReuseConstraints(moduleVersionId, methodToken, methodVersion, ilOffset, IsLocalScopeEndInclusive); allScopes.Free(); var localNames = containingScopes.GetLocalNames(); var inScopeHoistedLocals = InScopeHoistedLocals.Empty; var methodDebugInfo = default(MethodDebugInfo); if (typedSymReader != null) { try { // TODO (https://github.com/dotnet/roslyn/issues/702): switch on the type of typedSymReader and call the appropriate helper. methodDebugInfo = typedSymReader.GetMethodDebugInfo(methodToken, methodVersion, localNames.FirstOrDefault()); var inScopeHoistedLocalIndices = methodDebugInfo.GetInScopeHoistedLocalIndices(ilOffset, ref methodContextReuseConstraints); inScopeHoistedLocals = new CSharpInScopeHoistedLocals(inScopeHoistedLocalIndices); } catch (InvalidOperationException) { // bad CDI, ignore } } var methodHandle = (MethodDefinitionHandle)MetadataTokens.Handle(methodToken); var currentFrame = compilation.GetMethod(moduleVersionId, methodHandle); Debug.Assert((object)currentFrame != null); var metadataDecoder = new MetadataDecoder((PEModuleSymbol)currentFrame.ContainingModule, currentFrame); var localInfo = metadataDecoder.GetLocalInfo(localSignatureToken); var localBuilder = ArrayBuilder <LocalSymbol> .GetInstance(); var sourceAssembly = compilation.SourceAssembly; GetLocals(localBuilder, currentFrame, localNames, localInfo, methodDebugInfo.DynamicLocalMap, sourceAssembly); GetConstants(localBuilder, currentFrame, containingScopes.GetConstantSignatures(), metadataDecoder, methodDebugInfo.DynamicLocalConstantMap, sourceAssembly); containingScopes.Free(); var locals = localBuilder.ToImmutableAndFree(); return(new EvaluationContext( metadataBlocks, methodContextReuseConstraints, compilation, metadataDecoder, currentFrame, locals, inScopeHoistedLocals, methodDebugInfo)); }