private static void AppendAssemblyQualifierIfNecessary(StringBuilder sb, ITypeReference typeReference, out bool isAssemQualified, EmitContext context)
        {
            INestedTypeReference nestedType = typeReference.AsNestedTypeReference;

            if (nestedType != null)
            {
                AppendAssemblyQualifierIfNecessary(sb, nestedType.GetContainingType(context), out isAssemQualified, context);
                return;
            }

            IGenericTypeInstanceReference genInst = typeReference.AsGenericTypeInstanceReference;

            if (genInst != null)
            {
                AppendAssemblyQualifierIfNecessary(sb, genInst.GenericType, out isAssemQualified, context);
                return;
            }

            IArrayTypeReference arrType = typeReference as IArrayTypeReference;

            if (arrType != null)
            {
                AppendAssemblyQualifierIfNecessary(sb, arrType.GetElementType(context), out isAssemQualified, context);
                return;
            }

            IPointerTypeReference pointer = typeReference as IPointerTypeReference;

            if (pointer != null)
            {
                AppendAssemblyQualifierIfNecessary(sb, pointer.GetTargetType(context), out isAssemQualified, context);
                return;
            }

            IManagedPointerTypeReference reference = typeReference as IManagedPointerTypeReference;

            if (reference != null)
            {
                AppendAssemblyQualifierIfNecessary(sb, pointer.GetTargetType(context), out isAssemQualified, context);
                return;
            }

            isAssemQualified = false;
            IAssemblyReference      referencedAssembly = null;
            INamespaceTypeReference namespaceType      = typeReference.AsNamespaceTypeReference;

            if (namespaceType != null)
            {
                referencedAssembly = namespaceType.GetUnit(context) as IAssemblyReference;
            }

            if (referencedAssembly != null)
            {
                var containingAssembly = context.Module.GetContainingAssembly(context);

                if (containingAssembly == null || !ReferenceEquals(referencedAssembly, containingAssembly))
                {
                    sb.Append(", ");
                    sb.Append(MetadataWriter.StrongName(referencedAssembly));
                    isAssemQualified = true;
                }
            }
        }
Example #2
0
        public byte[] SerializeMethodDebugInfo(EmitContext context, IMethodBody methodBody, int methodToken, bool isEncDelta, bool suppressNewCustomDebugInfo, out bool emitExternNamespaces)
        {
            emitExternNamespaces = false;

            // CONSIDER: this may not be the same "first" method as in Dev10, but
            // it shouldn't matter since all methods will still forward to a method
            // containing the appropriate information.
            if (_methodBodyWithModuleInfo == null) //UNDONE: || edit-and-continue
            {
                // This module level information could go on every method (and does in
                // the edit-and-continue case), but - as an optimization - we'll just
                // put it on the first method we happen to encounter and then put a
                // reference to the first method's token in every other method (so they
                // can find the information).
                if (context.Module.GetAssemblyReferenceAliases(context).Any())
                {
                    _methodTokenWithModuleInfo = methodToken;
                    _methodBodyWithModuleInfo  = methodBody;
                    emitExternNamespaces       = true;
                }
            }

            var customDebugInfo = ArrayBuilder <PooledBlobBuilder> .GetInstance();

            SerializeIteratorClassMetadata(methodBody, customDebugInfo);

            // NOTE: This is an attempt to match Dev10's apparent behavior.  For iterator methods (i.e. the method
            // that appears in source, not the synthesized ones), Dev10 only emits the ForwardIterator and IteratorLocal
            // custom debug info (e.g. there will be no information about the usings that were in scope).
            // NOTE: There seems to be an unusual behavior in ISymUnmanagedWriter where, if all the methods in a type are
            // iterator methods, no custom debug info is emitted for any method.  Adding a single non-iterator
            // method causes the custom debug info to be produced for all methods (including the iterator methods).
            // Since we are making the same ISymUnmanagedWriter calls as Dev10, we see the same behavior (i.e. this
            // is not a regression).
            if (methodBody.StateMachineTypeName == null)
            {
                SerializeNamespaceScopeMetadata(context, methodBody, customDebugInfo);
                SerializeStateMachineLocalScopes(methodBody, customDebugInfo);
            }

            if (!suppressNewCustomDebugInfo)
            {
                SerializeDynamicLocalInfo(methodBody, customDebugInfo);
                SerializeTupleElementNames(methodBody, customDebugInfo);

                // delta doesn't need this information - we use information recorded by previous generation emit
                if (!isEncDelta)
                {
                    var encMethodInfo = MetadataWriter.GetEncMethodDebugInfo(methodBody);
                    SerializeCustomDebugInformation(encMethodInfo, customDebugInfo);
                }
            }

            byte[] result = SerializeCustomDebugMetadata(customDebugInfo);

            foreach (var builder in customDebugInfo)
            {
                builder.Free();
            }

            customDebugInfo.Free();

            return(result);
        }
Example #3
0
 internal PdbMetadataWrapper(MetadataWriter writer)
 {
     _writer = writer;
 }
Example #4
0
 internal MemberRefComparer(MetadataWriter metadataWriter)
 {
     _metadataWriter = metadataWriter;
 }
Example #5
0
        public byte[] SerializeMethodDebugInfo(
            EmitContext context,
            IMethodBody methodBody,
            MethodDefinitionHandle methodHandle,
            bool emitStateMachineInfo,
            bool emitEncInfo,
            bool emitDynamicAndTupleInfo,
            out bool emitExternNamespaces)
        {
            emitExternNamespaces = false;

            // CONSIDER: this may not be the same "first" method as in Dev10, but
            // it shouldn't matter since all methods will still forward to a method
            // containing the appropriate information.
            if (_methodBodyWithModuleInfo == null)
            {
                // This module level information could go on every method (and does in
                // the edit-and-continue case), but - as an optimization - we'll just
                // put it on the first method we happen to encounter and then put a
                // reference to the first method's token in every other method (so they
                // can find the information).
                if (context.Module.GetAssemblyReferenceAliases(context).Any())
                {
                    _methodWithModuleInfo     = methodHandle;
                    _methodBodyWithModuleInfo = methodBody;
                    emitExternNamespaces      = true;
                }
            }

            var pooledBuilder = PooledBlobBuilder.GetInstance();
            var encoder       = new CustomDebugInfoEncoder(pooledBuilder);

            if (emitStateMachineInfo)
            {
                if (methodBody.StateMachineTypeName != null)
                {
                    encoder.AddStateMachineTypeName(methodBody.StateMachineTypeName);
                }
                else
                {
                    SerializeNamespaceScopeMetadata(ref encoder, context, methodBody);

                    encoder.AddStateMachineHoistedLocalScopes(methodBody.StateMachineHoistedLocalScopes);
                }
            }

            if (emitDynamicAndTupleInfo)
            {
                SerializeDynamicLocalInfo(ref encoder, methodBody);
                SerializeTupleElementNames(ref encoder, methodBody);
            }

            if (emitEncInfo)
            {
                var encMethodInfo = MetadataWriter.GetEncMethodDebugInfo(methodBody);
                SerializeCustomDebugInformation(ref encoder, encMethodInfo);
            }

            byte[] result = encoder.ToArray() ?? Array.Empty <byte>();
            pooledBuilder.Free();
            return(result);
        }