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; } } }
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); }
internal PdbMetadataWrapper(MetadataWriter writer) { _writer = writer; }
internal MemberRefComparer(MetadataWriter metadataWriter) { _metadataWriter = metadataWriter; }
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); }