예제 #1
0
        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);
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
 internal override IEnumerable<Cci.INamespaceTypeDefinition> GetTopLevelTypesCore(Context context)
 {
     return this.changes.GetTopLevelTypes(context);
 }
예제 #5
0
 ITypeReference ICustomModifier.GetModifier(Context context)
 {
     throw new NotImplementedException();
 }
예제 #6
0
 Cci.PrimitiveTypeCode Cci.ITypeReference.TypeCode(Context context)
 {
     return Cci.PrimitiveTypeCode.NotPrimitive;
 }
예제 #7
0
 Cci.ITypeDefinition Cci.ITypeReference.GetResolvedType(Context context)
 {
     return null;
 }
예제 #8
0
        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;
                    }
                }
            }
        }
예제 #9
0
 protected override IEnumerable<Cci.ITypeReference> GetConstraints(Context context)
 {
     return ((Cci.IGenericParameter)UnderlyingTypeParameter).GetConstraints(context);
 }
예제 #10
0
 Cci.IAssemblyReference Cci.IModuleReference.GetContainingAssembly(Context context)
 {
     return this;
 }
예제 #11
0
 Cci.IUnitReference Cci.INamespaceTypeReference.GetUnit(Context context)
 {
     return ErrorAssembly.Singleton;
 }
예제 #12
0
 Cci.ITypeDefinition Cci.ITypeReference.AsTypeDefinition(Context context)
 {
     return null;
 }
예제 #13
0
 Cci.INamespaceTypeDefinition Cci.ITypeReference.AsNamespaceTypeDefinition(Context context)
 {
     return null;
 }
예제 #14
0
 protected override Cci.IMetadataConstant GetDefaultValue(Context context)
 {
     return UnderlyingParameter.GetMetadataConstantValue(context);
 }
예제 #15
0
 protected override System.Reflection.MethodImplAttributes GetImplementationAttributes(Context context)
 {
     return UnderlyingMethod.ImplementationAttributes;
 }
예제 #16
0
 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));
        }
예제 #18
0
 Cci.IDefinition Cci.IReference.AsDefinition(Context context)
 {
     return null;
 }
예제 #19
0
        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.
        }
예제 #20
0
 protected override Cci.IMetadataConstant GetCompileTimeValue(Context context)
 {
     return UnderlyingField.GetMetadataConstantValue(context);
 }