internal static EvaluationContext CreateMethodContext( AppDomain appDomain, ImmutableArray <MetadataBlock> blocks, ISymUnmanagedReader symReader, Guid moduleVersionId, int methodToken, int methodVersion, uint ilOffset, int localSignatureToken, MakeAssemblyReferencesKind kind = MakeAssemblyReferencesKind.AllAssemblies ) { return(CSharpExpressionCompiler.CreateMethodContext( appDomain, ad => ad.GetMetadataContext(), (ad, mc, report) => ad.SetMetadataContext(mc), blocks, symReader, moduleVersionId, methodToken, methodVersion, ilOffset, localSignatureToken, kind )); }
internal static CSharpCompilation ToCompilation( this ImmutableArray <MetadataBlock> metadataBlocks, Guid moduleVersionId, MakeAssemblyReferencesKind kind ) { var references = metadataBlocks.MakeAssemblyReferences( moduleVersionId, IdentityComparer, kind, out var referencesBySimpleName ); var options = s_compilationOptions; if (referencesBySimpleName != null) { Debug.Assert(kind == MakeAssemblyReferencesKind.AllReferences); var resolver = new EEMetadataReferenceResolver( IdentityComparer, referencesBySimpleName ); options = options.WithMetadataReferenceResolver(resolver); } return(CSharpCompilation.Create( assemblyName: ExpressionCompilerUtilities.GenerateUniqueName(), references: references, options: options )); }
internal static MetadataContextId GetContextId( Guid moduleVersionId, MakeAssemblyReferencesKind kind ) { return(kind switch { MakeAssemblyReferencesKind.AllAssemblies => default,
internal static EvaluationContext CreateTypeContext <TAppDomain>( TAppDomain appDomain, GetMetadataContextDelegate <TAppDomain> getMetadataContext, ImmutableArray <MetadataBlock> metadataBlocks, Guid moduleVersionId, int typeToken, MakeAssemblyReferencesKind kind) { CSharpCompilation?compilation; if (kind == MakeAssemblyReferencesKind.DirectReferencesOnly) { // Avoid using the cache for referenced assemblies only // since this should be the exceptional case. compilation = metadataBlocks.ToCompilationReferencedModulesOnly(moduleVersionId); return(EvaluationContext.CreateTypeContext( compilation, moduleVersionId, typeToken)); } var contextId = MetadataContextId.GetContextId(moduleVersionId, kind); var previous = getMetadataContext(appDomain); CSharpMetadataContext previousMetadataContext = default; if (previous.Matches(metadataBlocks)) { previous.AssemblyContexts.TryGetValue(contextId, out previousMetadataContext); } // Re-use the previous compilation if possible. compilation = previousMetadataContext.Compilation; if (compilation == null) { compilation = metadataBlocks.ToCompilation(moduleVersionId, kind); } var context = EvaluationContext.CreateTypeContext( compilation, moduleVersionId, typeToken); // New type context is not attached to the AppDomain since it is less // re-usable than the previous attached method context. (We could hold // on to it if we don't have a previous method context but it's unlikely // that we evaluated a type-level expression before a method-level.) Debug.Assert(context != previousMetadataContext.EvaluationContext); return(context); }
internal static MetadataContextId GetContextId(Guid moduleVersionId, MakeAssemblyReferencesKind kind) { switch (kind) { case MakeAssemblyReferencesKind.AllAssemblies: return(default); case MakeAssemblyReferencesKind.AllReferences: return(new MetadataContextId(moduleVersionId)); default: throw ExceptionUtilities.UnexpectedValue(kind); } }
internal static EvaluationContext CreateTypeContext( AppDomain appDomain, ImmutableArray <MetadataBlock> blocks, Guid moduleVersionId, int typeToken, MakeAssemblyReferencesKind kind = MakeAssemblyReferencesKind.AllAssemblies) { return(CSharpExpressionCompiler.CreateTypeContext( appDomain, ad => ad.GetMetadataContext(), blocks, moduleVersionId, typeToken, kind)); }
internal static EvaluationContext CreateMethodContext <TAppDomain>( TAppDomain appDomain, GetMetadataContextDelegate <TAppDomain> getMetadataContext, SetMetadataContextDelegate <TAppDomain> setMetadataContext, ImmutableArray <MetadataBlock> metadataBlocks, object?symReader, Guid moduleVersionId, int methodToken, int methodVersion, uint ilOffset, int localSignatureToken, MakeAssemblyReferencesKind kind) { CSharpCompilation compilation; int offset = EvaluationContextBase.NormalizeILOffset(ilOffset); if (kind == MakeAssemblyReferencesKind.DirectReferencesOnly) { // Avoid using the cache for referenced assemblies only // since this should be the exceptional case. compilation = metadataBlocks.ToCompilationReferencedModulesOnly(moduleVersionId); return(EvaluationContext.CreateMethodContext( compilation, symReader, moduleVersionId, methodToken, methodVersion, offset, localSignatureToken)); } var contextId = MetadataContextId.GetContextId(moduleVersionId, kind); var previous = getMetadataContext(appDomain); var assemblyContexts = previous.Matches(metadataBlocks) ? previous.AssemblyContexts : ImmutableDictionary <MetadataContextId, CSharpMetadataContext> .Empty; CSharpMetadataContext previousMetadataContext; assemblyContexts.TryGetValue(contextId, out previousMetadataContext); // Re-use the previous compilation if possible. compilation = previousMetadataContext.Compilation; if (compilation != null) { // Re-use entire context if method scope has not changed. var previousContext = previousMetadataContext.EvaluationContext; if (previousContext != null && previousContext.MethodContextReuseConstraints.HasValue && previousContext.MethodContextReuseConstraints.GetValueOrDefault().AreSatisfied(moduleVersionId, methodToken, methodVersion, offset)) { return(previousContext); } } else { compilation = metadataBlocks.ToCompilation(moduleVersionId, kind); } var context = EvaluationContext.CreateMethodContext( compilation, symReader, moduleVersionId, methodToken, methodVersion, offset, localSignatureToken); if (context != previousMetadataContext.EvaluationContext) { setMetadataContext( appDomain, new MetadataContext <CSharpMetadataContext>( metadataBlocks, assemblyContexts.SetItem(contextId, new CSharpMetadataContext(context.Compilation, context))), report: kind == MakeAssemblyReferencesKind.AllReferences); } return(context); }
/// <summary> /// Group module metadata into assemblies. /// If <paramref name="moduleVersionId"/> is set, the /// assemblies are limited to those referenced by that module. /// </summary> internal static ImmutableArray <MetadataReference> MakeAssemblyReferences( this ImmutableArray <MetadataBlock> metadataBlocks, Guid moduleVersionId, AssemblyIdentityComparer identityComparer, MakeAssemblyReferencesKind kind, out IReadOnlyDictionary <