public PEDeltaAssemblyBuilder( SourceAssemblySymbol sourceAssembly, string outputName, OutputKind outputKind, ModulePropertiesForSerialization serializationProperties, IEnumerable<ResourceDescription> manifestResources, Func<AssemblySymbol, AssemblyIdentity> assemblySymbolMapper, EmitBaseline previousGeneration, IEnumerable<SemanticEdit> edits) : base(sourceAssembly, outputName, outputKind, serializationProperties, manifestResources, assemblySymbolMapper, additionalTypes: ImmutableArray<NamedTypeSymbol>.Empty) { var context = new Context(this, null, new DiagnosticBag()); var module = previousGeneration.OriginalMetadata; var compilation = sourceAssembly.DeclaringCompilation; var metadataAssembly = compilation.GetBoundReferenceManager().CreatePEAssemblyForAssemblyMetadata(AssemblyMetadata.Create(module), MetadataImportOptions.All); var metadataDecoder = new Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.MetadataDecoder(metadataAssembly.PrimaryModule); previousGeneration = EnsureInitialized(previousGeneration, metadataDecoder); var matchToMetadata = new SymbolMatcher(previousGeneration.AnonymousTypeMap, sourceAssembly, context, metadataAssembly); SymbolMatcher matchToPrevious = null; if (previousGeneration.Ordinal > 0) { var previousAssembly = ((CSharpCompilation)previousGeneration.Compilation).SourceAssembly; var previousContext = new Context((PEModuleBuilder)previousGeneration.PEModuleBuilder, null, new DiagnosticBag()); matchToPrevious = new SymbolMatcher(previousGeneration.AnonymousTypeMap, sourceAssembly, context, previousAssembly, previousContext); } this.previousDefinitions = new DefinitionMap(previousGeneration.OriginalMetadata.Module, metadataDecoder, matchToMetadata, matchToPrevious, GenerateMethodMap(edits)); this.previousGeneration = previousGeneration; this.changes = new SymbolChanges(this.previousDefinitions, edits); }
object Cci.IMarshallingInformation.GetCustomMarshaller(Emit.Context context) { Debug.Assert(marshalType == Cci.Constants.UnmanagedType_CustomMarshaler); var typeSymbol = marshalTypeNameOrSymbol as ITypeSymbol; if (typeSymbol != null) { return(((Emit.CommonPEModuleBuilder)context.Module).Translate(typeSymbol, context.SyntaxNodeOpt, context.Diagnostics)); } else { Debug.Assert(marshalTypeNameOrSymbol == null || marshalTypeNameOrSymbol is string); return(marshalTypeNameOrSymbol); } }
IEnumerable <Cci.IFileReference> Cci.IAssembly.GetFiles(Microsoft.CodeAnalysis.Emit.Context context) { if (lazyFiles.IsDefault) { var builder = ArrayBuilder <Cci.IFileReference> .GetInstance(); try { var modules = sourceAssembly.Modules; for (int i = 1; i < modules.Length; i++) { builder.Add((Cci.IFileReference)Translate(modules[i], context.Diagnostics)); } foreach (ResourceDescription resource in ManifestResources) { if (!resource.IsEmbedded) { builder.Add(resource); } } // Dev12 compilers don't report ERR_CryptoHashFailed if there are no files to be hashed. if (ImmutableInterlocked.InterlockedInitialize(ref lazyFiles, builder.ToImmutable()) && lazyFiles.Length > 0) { if (!CryptographicHashProvider.IsSupportedAlgorithm(sourceAssembly.AssemblyHashAlgorithm)) { context.Diagnostics.Add(new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_CryptoHashFailed), NoLocation.Singleton)); } } } finally { builder.Free(); } } return(lazyFiles); }
internal override IEnumerable<Cci.INamespaceTypeDefinition> GetTopLevelTypesCore(Context context) { return this.changes.GetTopLevelTypes(context); }
ITypeReference ICustomModifier.GetModifier(Context context) { throw new NotImplementedException(); }
Cci.PrimitiveTypeCode Cci.ITypeReference.TypeCode(Context context) { return Cci.PrimitiveTypeCode.NotPrimitive; }
Cci.ITypeDefinition Cci.ITypeReference.GetResolvedType(Context context) { return null; }
public IEnumerable<INamespaceTypeDefinition> GetTopLevelTypes(Context context) { var module = (CommonPEModuleBuilder)context.Module; foreach (var type in module.GetAnonymousTypes()) { yield return type; } foreach (var symbol in this.changes.Keys) { var typeDef = symbol as ITypeDefinition; if (typeDef != null) { var namespaceTypeDef = typeDef.AsNamespaceTypeDefinition(context); if (namespaceTypeDef != null) { yield return namespaceTypeDef; } } } }
protected override IEnumerable<Cci.ITypeReference> GetConstraints(Context context) { return ((Cci.IGenericParameter)UnderlyingTypeParameter).GetConstraints(context); }
Cci.IAssemblyReference Cci.IModuleReference.GetContainingAssembly(Context context) { return this; }
Cci.IUnitReference Cci.INamespaceTypeReference.GetUnit(Context context) { return ErrorAssembly.Singleton; }
Cci.ITypeDefinition Cci.ITypeReference.AsTypeDefinition(Context context) { return null; }
Cci.INamespaceTypeDefinition Cci.ITypeReference.AsNamespaceTypeDefinition(Context context) { return null; }
protected override Cci.IMetadataConstant GetDefaultValue(Context context) { return UnderlyingParameter.GetMetadataConstantValue(context); }
protected override System.Reflection.MethodImplAttributes GetImplementationAttributes(Context context) { return UnderlyingMethod.ImplementationAttributes; }
System.Collections.Generic.IEnumerable<Cci.ICustomAttribute> Cci.IReference.GetAttributes(Context context) { return SpecializedCollections.EmptyEnumerable<Cci.ICustomAttribute>(); }
Cci.ITypeReference Cci.IMarshallingInformation.GetSafeArrayElementUserDefinedSubtype(Emit.Context context) { Debug.Assert(marshalType == UnmanagedType.SafeArray); if (marshalTypeNameOrSymbol == null) { return(null); } return(((Emit.CommonPEModuleBuilder)context.Module).Translate((ITypeSymbol)marshalTypeNameOrSymbol, context.SyntaxNodeOpt, context.Diagnostics)); }
Cci.IDefinition Cci.IReference.AsDefinition(Context context) { return null; }
public void EmitMetadataOnly_SynthesizedExplicitImplementations() { var ilAssemblyReference = TestReferences.SymbolsTests.CustomModifiers.CppCli.dll; var libAssemblyName = "SynthesizedMethodMetadata"; var exeAssemblyName = "CallSynthesizedMethod"; // Setup: CppBase2 has methods that implement CppInterface1, but it doesn't declare // that it implements the interface. Class1 does declare that it implements the // interface, but it's empty so it counts on CppBase2 to provide the implementations. // Since CppBase2 is not in the current source module, bridge methods are inserted // into Class1 to implement the interface methods by delegating to CppBase2. var libText = @" public class Class1 : CppCli.CppBase2, CppCli.CppInterface1 { } "; var libComp = CreateCompilationWithMscorlib( text: libText, references: new MetadataReference[] { ilAssemblyReference }, compOptions: TestOptions.Dll, assemblyName: libAssemblyName); Assert.False(libComp.GetDiagnostics().Any()); EmitResult emitResult; byte[] dllImage; using (var output = new MemoryStream()) { emitResult = libComp.EmitMetadataOnly(output); dllImage = output.ToArray(); } Assert.True(emitResult.Success); emitResult.Diagnostics.Verify(); Assert.True(dllImage.Length > 0, "no metadata emitted"); // NOTE: this DLL won't PEVerify because there are no method bodies. var class1 = libComp.GlobalNamespace.GetMember<SourceNamedTypeSymbol>("Class1"); // We would prefer to check that the module used by Compiler.Emit does the right thing, // but we don't have access to that object, so we'll create our own and manipulate it // in the same way. var module = new PEAssemblyBuilder((SourceAssemblySymbol)class1.ContainingAssembly, null, OutputKind.DynamicallyLinkedLibrary, GetDefaultModulePropertiesForSerialization(), SpecializedCollections.EmptyEnumerable<ResourceDescription>()); Compiler.CompileSynthesizedMethodMetadata(libComp, module, default(CancellationToken)); var class1TypeDef = (Cci.ITypeDefinition)class1; var symbolSynthesized = class1.GetSynthesizedExplicitImplementations(CancellationToken.None); var context = new Microsoft.CodeAnalysis.Emit.Context(module, null, new DiagnosticBag()); var cciExplicit = class1TypeDef.GetExplicitImplementationOverrides(context); var cciMethods = class1TypeDef.GetMethods(context).Where(m => ((MethodSymbol)m).MethodKind != MethodKind.Constructor); context.Diagnostics.Verify(); var symbolsSynthesizedCount = symbolSynthesized.Length; Assert.True(symbolsSynthesizedCount > 0, "Expected more than 0 synthesized method symbols."); Assert.Equal(symbolsSynthesizedCount, cciExplicit.Count()); Assert.Equal(symbolsSynthesizedCount, cciMethods.Count()); var libAssemblyReference = new MetadataImageReference(dllImage.AsImmutableOrNull()); var exeText = @" class Class2 { public static void Main() { CppCli.CppInterface1 c = new Class1(); c.Method1(1); c.Method2(2); } } "; var exeComp = CreateCompilationWithMscorlib( text: exeText, references: new MetadataReference[] { ilAssemblyReference, libAssemblyReference }, assemblyName: exeAssemblyName); Assert.False(exeComp.GetDiagnostics().Any()); using (var output = new MemoryStream()) { emitResult = exeComp.Emit(output); Assert.True(emitResult.Success); emitResult.Diagnostics.Verify(); output.Flush(); Assert.True(output.Length > 0, "no metadata emitted"); } // NOTE: there's no point in trying to run the EXE since it depends on a DLL with no method bodies. }
protected override Cci.IMetadataConstant GetCompileTimeValue(Context context) { return UnderlyingField.GetMetadataConstantValue(context); }