Ejemplo n.º 1
0
        private void SerializeNamespaceScopeMetadata(ref CustomDebugInfoEncoder encoder, EmitContext context, IMethodBody methodBody)
        {
            if (context.Module.GenerateVisualBasicStylePdb)
            {
                return;
            }

            if (ShouldForwardToPreviousMethodWithUsingInfo(context, methodBody))
            {
                Debug.Assert(!ReferenceEquals(_previousMethodBodyWithUsingInfo, methodBody));
                encoder.AddForwardMethodInfo(_previousMethodWithUsingInfo);
                return;
            }

            var usingCounts = ArrayBuilder <int> .GetInstance();

            for (IImportScope scope = methodBody.ImportScope; scope != null; scope = scope.Parent)
            {
                usingCounts.Add(scope.GetUsedNamespaces().Length);
            }

            encoder.AddUsingGroups(usingCounts);
            usingCounts.Free();

            if (_methodBodyWithModuleInfo != null && !ReferenceEquals(_methodBodyWithModuleInfo, methodBody))
            {
                encoder.AddForwardModuleInfo(_methodWithModuleInfo);
            }
        }
Ejemplo n.º 2
0
        protected override void ProcessMethodBody(IMethodDefinition method)
        {
            if (method.HasBody() && !metadataWriter.MetadataOnly)
            {
                var body = method.GetBody(Context);

                if (body != null)
                {
                    this.Visit(body);

                    for (IImportScope scope = body.ImportScope; scope != null; scope = scope.Parent)
                    {
                        if (_alreadySeenScopes.Add(scope))
                        {
                            VisitImports(scope.GetUsedNamespaces());
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                else if (!metadataWriter.MetadataOnly)
                {
                    throw ExceptionUtilities.Unreachable;
                }
            }
        }
        private BlobHandle SerializeImportsBlob(IImportScope scope)
        {
            var writer = new BlobBuilder();

            foreach (UsedNamespaceOrType import in scope.GetUsedNamespaces())
            {
                SerializeImport(writer, import);
            }

            return(_debugMetadataOpt.GetOrAddBlob(writer));
        }
Ejemplo n.º 4
0
        private BlobIdx SerializeImportsBlob(IImportScope scope)
        {
            var writer = new BlobBuilder();

            foreach (UsedNamespaceOrType import in scope.GetUsedNamespaces())
            {
                SerializeImport(writer, import);
            }

            return(_debugHeapsOpt.GetBlobIndex(writer));
        }
Ejemplo n.º 5
0
        private void SerializeNamespaceScopeMetadata(EmitContext context, IMethodBody methodBody, ArrayBuilder <MemoryStream> customDebugInfo)
        {
            if (context.Module.GenerateVisualBasicStylePdb)
            {
                return;
            }

            if (ShouldForwardToPreviousMethodWithUsingInfo(context, methodBody))
            {
                Debug.Assert(!ReferenceEquals(_previousMethodBodyWithUsingInfo, methodBody));
                SerializeReferenceToPreviousMethodWithUsingInfo(customDebugInfo);
                return;
            }

            MemoryStream  customMetadata = new MemoryStream();
            List <ushort> usingCounts    = new List <ushort>();
            BinaryWriter  cmw            = new BinaryWriter(customMetadata);

            for (IImportScope scope = methodBody.ImportScope; scope != null; scope = scope.Parent)
            {
                usingCounts.Add((ushort)scope.GetUsedNamespaces().Length);
            }

            // ACASEY: This originally wrote (uint)12, (ushort)1, (ushort)0 in the
            // case where usingCounts was empty, but I'm not sure why.
            if (usingCounts.Count > 0)
            {
                uint streamLength;
                cmw.WriteByte(CDI.CdiVersion);
                cmw.WriteByte(CDI.CdiKindUsingInfo);
                cmw.Align(4);

                cmw.WriteUint(streamLength = BitArithmeticUtilities.Align((uint)usingCounts.Count * 2 + 10, 4));
                cmw.WriteUshort((ushort)usingCounts.Count);
                foreach (ushort uc in usingCounts)
                {
                    cmw.WriteUshort(uc);
                }

                cmw.Align(4);
                Debug.Assert(streamLength == customMetadata.Length);
                customDebugInfo.Add(customMetadata);
            }

            if (_methodBodyWithModuleInfo != null && !ReferenceEquals(_methodBodyWithModuleInfo, methodBody))
            {
                SerializeReferenceToMethodWithModuleInfo(customDebugInfo);
            }
        }
Ejemplo n.º 6
0
        private bool ShouldForwardToPreviousMethodWithUsingInfo(EmitContext context, IMethodBody methodBody)
        {
            if (_previousMethodBodyWithUsingInfo == null ||
                ReferenceEquals(_previousMethodBodyWithUsingInfo, methodBody))
            {
                return(false);
            }

            // VB includes method namespace in namespace scopes:
            if (context.Module.GenerateVisualBasicStylePdb)
            {
                if (_pdbWriter.GetOrCreateSerializedNamespaceName(_previousMethodBodyWithUsingInfo.MethodDefinition.ContainingNamespace) !=
                    _pdbWriter.GetOrCreateSerializedNamespaceName(methodBody.MethodDefinition.ContainingNamespace))
                {
                    return(false);
                }
            }

            IImportScope previousScopes = _previousMethodBodyWithUsingInfo.ImportScope;

            // methods share the same import scope (common case for methods declared in the same file)
            if (methodBody.ImportScope == previousScopes)
            {
                return(true);
            }

            // If methods are in different files they don't share the same scopes,
            // but the imports might be the same nevertheless.
            // Note: not comparing project-level imports since those are the same for all method bodies.
            IImportScope s1 = methodBody.ImportScope;
            IImportScope s2 = previousScopes;

            while (s1 != null && s2 != null)
            {
                if (!s1.GetUsedNamespaces().SequenceEqual(s2.GetUsedNamespaces()))
                {
                    return(false);
                }

                s1 = s1.Parent;
                s2 = s2.Parent;
            }

            return(s1 == s2);
        }
Ejemplo n.º 7
0
        private void DefineNamespaceScopes(IMethodBody methodBody)
        {
            var  module        = Module;
            bool isVisualBasic = module.GenerateVisualBasicStylePdb;

            IMethodDefinition method = methodBody.MethodDefinition;

            var namespaceScopes = methodBody.ImportScope;

            // NOTE: All extern aliases are stored on the outermost namespace scope.
            PooledHashSet <string> lazyDeclaredExternAliases = null;

            if (!isVisualBasic)
            {
                foreach (var import in GetLastScope(namespaceScopes).GetUsedNamespaces(Context))
                {
                    if (import.TargetNamespaceOpt == null && import.TargetTypeOpt == null)
                    {
                        Debug.Assert(import.AliasOpt != null);
                        Debug.Assert(import.TargetAssemblyOpt == null);

                        if (lazyDeclaredExternAliases == null)
                        {
                            lazyDeclaredExternAliases = PooledHashSet <string> .GetInstance();
                        }

                        lazyDeclaredExternAliases.Add(import.AliasOpt);
                    }
                }
            }

            // file and namespace level
            for (IImportScope scope = namespaceScopes; scope != null; scope = scope.Parent)
            {
                foreach (UsedNamespaceOrType import in scope.GetUsedNamespaces(Context))
                {
                    var importString = TryEncodeImport(import, lazyDeclaredExternAliases, isProjectLevel: false);
                    if (importString != null)
                    {
                        UsingNamespace(importString, method);
                    }
                }
            }

            lazyDeclaredExternAliases?.Free();

            // project level
            if (isVisualBasic)
            {
                string defaultNamespace = module.DefaultNamespace;

                if (defaultNamespace != null)
                {
                    // VB marks the default/root namespace with an asterisk
                    UsingNamespace("*" + defaultNamespace, module);
                }

                foreach (string assemblyName in module.LinkedAssembliesDebugInfo)
                {
                    UsingNamespace("&" + assemblyName, module);
                }

                foreach (UsedNamespaceOrType import in module.GetImports(Context))
                {
                    var importString = TryEncodeImport(import, null, isProjectLevel: true);
                    if (importString != null)
                    {
                        UsingNamespace(importString, method);
                    }
                }

                // VB current namespace -- VB appends the namespace of the container without prefixes
                UsingNamespace(GetOrCreateSerializedNamespaceName(method.ContainingNamespace), method);
            }
        }