Esempio n. 1
0
 private static void VisitTopLevelType(
     Cci.TypeReferenceIndexer noPiaIndexer,
     Cci.INamespaceTypeDefinition type
     )
 {
     noPiaIndexer?.Visit((Cci.ITypeDefinition)type);
 }
Esempio n. 2
0
        private EmbeddedType EmbedType(
            NamedTypeSymbol namedType,
            bool fromImplements,
            SyntaxNode syntaxNodeOpt,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(namedType.IsDefinition);

            EmbeddedType embedded = new EmbeddedType(this, namedType);
            EmbeddedType cached   = EmbeddedTypesMap.GetOrAdd(namedType, embedded);

            bool isInterface = (namedType.IsInterface);

            if (isInterface && fromImplements)
            {
                // Note, we must use 'cached' here because we might drop 'embedded' below.
                cached.EmbedAllMembersOfImplementedInterface(syntaxNodeOpt, diagnostics);
            }

            if (embedded != cached)
            {
                return(cached);
            }

            // We do not expect this method to be called on a different thread once GetTypes is called.
            // Therefore, the following check can be as simple as:
            Debug.Assert(!IsFrozen, "Set of embedded types is frozen.");

            var noPiaIndexer = new Cci.TypeReferenceIndexer(new EmitContext(ModuleBeingBuilt, syntaxNodeOpt, diagnostics, metadataOnly: false, includePrivateMembers: true));

            // Make sure we embed all types referenced by the type declaration: implemented interfaces, etc.
            noPiaIndexer.VisitTypeDefinitionNoMembers(embedded);

            if (!isInterface)
            {
                Debug.Assert(namedType.TypeKind == TypeKind.Struct || namedType.TypeKind == TypeKind.Enum || namedType.TypeKind == TypeKind.Delegate);
                // For structures, enums and delegates we embed all members.

                if (namedType.TypeKind == TypeKind.Struct || namedType.TypeKind == TypeKind.Enum)
                {
                    // TODO: When building debug versions in the IDE, the compiler will insert some extra members
                    // that support ENC. These make no sense in local types, so we will skip them. We have to
                    // check for them explicitly or they will trip the member-validity check that follows.
                }

                foreach (FieldSymbol f in namedType.GetFieldsToEmit())
                {
                    EmbedField(embedded, f, syntaxNodeOpt, diagnostics);
                }

                foreach (MethodSymbol m in namedType.GetMethodsToEmit())
                {
                    if ((object)m != null)
                    {
                        EmbedMethod(embedded, m, syntaxNodeOpt, diagnostics);
                    }
                }

                // We also should embed properties and events, but we don't need to do this explicitly here
                // because accessors embed them automatically.
            }

            return(embedded);
        }
Esempio n. 3
0
        /// <summary>
        /// Returns all top-level (not nested) types defined in the module.
        /// </summary>
        public override IEnumerable <Cci.INamespaceTypeDefinition> GetTopLevelTypes(EmitContext context)
        {
            Cci.TypeReferenceIndexer typeReferenceIndexer = null;
            HashSet <string>         names;

            // First time through, we need to collect emitted names of all top level types.
            if (_namesOfTopLevelTypes == null)
            {
                names = new HashSet <string>();
            }
            else
            {
                names = null;
            }

            // First time through, we need to push things through TypeReferenceIndexer
            // to make sure we collect all to be embedded NoPia types and members.
            if (EmbeddedTypesManagerOpt != null && !EmbeddedTypesManagerOpt.IsFrozen)
            {
                typeReferenceIndexer = new Cci.TypeReferenceIndexer(context);
                Debug.Assert(names != null);

                // Run this reference indexer on the assembly- and module-level attributes first.
                // We'll run it on all other types below.
                // The purpose is to trigger Translate on all types.
                this.Dispatch(typeReferenceIndexer);
            }

            AddTopLevelType(names, _rootModuleType);
            VisitTopLevelType(typeReferenceIndexer, _rootModuleType);
            yield return(_rootModuleType);

            foreach (var type in this.GetAnonymousTypes(context))
            {
                AddTopLevelType(names, type);
                VisitTopLevelType(typeReferenceIndexer, type);
                yield return(type);
            }

            foreach (var type in this.GetTopLevelTypesCore(context))
            {
                AddTopLevelType(names, type);
                VisitTopLevelType(typeReferenceIndexer, type);
                yield return(type);
            }

            var privateImpl = this.PrivateImplClass;

            if (privateImpl != null)
            {
                AddTopLevelType(names, privateImpl);
                VisitTopLevelType(typeReferenceIndexer, privateImpl);
                yield return(privateImpl);
            }

            if (EmbeddedTypesManagerOpt != null)
            {
                foreach (var embedded in EmbeddedTypesManagerOpt.GetTypes(context.Diagnostics, names))
                {
                    AddTopLevelType(names, embedded);
                    yield return(embedded);
                }
            }

            if (names != null)
            {
                Debug.Assert(_namesOfTopLevelTypes == null);
                _namesOfTopLevelTypes = names;
            }
        }