コード例 #1
0
        private void ImportType(MetadataSource mdSource, TypeDefinition type, bool inScriptCoreAssembly, bool inApplicationAssembly,
                                ScriptReference dependency, TypeSymbol outerType = null)
        {
            if (!type.IsPublic && !type.IsNestedPublic && dependency?.InternalesVisible == false)
            {
                return;
            }

            if (inScriptCoreAssembly && MetadataHelpers.ShouldImportScriptCoreType(type) == false)
            {
                return;
            }

            string name          = outerType is TypeSymbol ? $"{outerType.Name}${type.Name}" : type.Name;
            string namespaceName = outerType is TypeSymbol ? outerType.Namespace : type.Namespace;

            bool   dummy;
            string scriptName = MetadataHelpers.GetScriptName(type, out dummy, out dummy);

            NamespaceSymbol namespaceSymbol = symbols.GetNamespace(namespaceName);
            TypeSymbol      typeSymbol      = null;

            if (type.IsInterface)
            {
                typeSymbol = new InterfaceSymbol(name, namespaceSymbol);
            }
            else if (MetadataHelpers.IsEnum(type))
            {
                // NOTE: We don't care about the flags bit on imported enums
                //       because this is only consumed by the generation logic.
                typeSymbol = new EnumerationSymbol(name, namespaceSymbol, /* flags */ false);

                if (MetadataHelpers.ShouldUseEnumNames(type))
                {
                    ((EnumerationSymbol)typeSymbol).SetNamedValues();
                }
                else if (MetadataHelpers.ShouldUseEnumValues(type))
                {
                    ((EnumerationSymbol)typeSymbol).SetNumericValues();
                }
            }
            else if (MetadataHelpers.IsDelegate(type))
            {
                typeSymbol = new DelegateSymbol(name, namespaceSymbol);
                typeSymbol.SetTransformedName("Function");
                typeSymbol.SetIgnoreGenerics();
                typeSymbol.SetIgnoreNamespace();
            }
            else
            {
                if (MetadataHelpers.ShouldTreatAsRecordType(type))
                {
                    typeSymbol = new RecordSymbol(name, namespaceSymbol);
                    typeSymbol.SetTransformedName(nameof(Object));
                }
                else
                {
                    typeSymbol = new ClassSymbol(name, namespaceSymbol);
                }
            }

            if (typeSymbol != null)
            {
                if (MetadataHelpers.ShouldIgnoreGenerics(type, out var useGenericName))
                {
                    typeSymbol.SetIgnoreGenerics(useGenericName);
                }

                if (type.HasGenericParameters)
                {
                    List <GenericParameterSymbol> genericArguments = new List <GenericParameterSymbol>();

                    foreach (GenericParameter genericParameter in type.GenericParameters)
                    {
                        GenericParameterSymbol arg =
                            new GenericParameterSymbol(genericParameter.Position, genericParameter.Name, true, symbols.GlobalNamespace);

                        genericArguments.Add(arg);
                    }

                    typeSymbol.AddGenericParameters(genericArguments);
                }

                string dependencyName = MetadataHelpers.GetScriptDependencyName(type, out string dependencyIdentifier);

                if (dependencyName != null)
                {
                    dependency = ScriptReferenceProvider.Instance.GetReference(dependencyName, dependencyIdentifier);
                }

                if (!inApplicationAssembly)
                {
                    typeSymbol.SetImported(dependency);
                }

                typeSymbol.SetMetadataToken(type, inScriptCoreAssembly);

                bool ignoreNamespace = MetadataHelpers.ShouldIgnoreNamespace(type);

                if (ignoreNamespace || dependency == null || string.IsNullOrEmpty(dependency.Identifier))
                {
                    typeSymbol.SetIgnoreNamespace();
                }
                else
                {
                    typeSymbol.ScriptNamespace = dependency.Identifier;
                }

                //todo: improve the logic here to support private/protected access modifiers for nested classes
                typeSymbol.IsPublic   = type.IsPublic;
                typeSymbol.IsInternal = type.IsNotPublic;

                if (string.IsNullOrEmpty(scriptName) == false)
                {
                    typeSymbol.SetTransformedName(scriptName);
                }

                SetArrayTypeMetadata(type, typeSymbol, scriptName);

                typeSymbol.SetSource(dependency);
                namespaceSymbol.AddType(typeSymbol);
                importedTypes.Add(typeSymbol);

                if (outerType is TypeSymbol)
                {
                    outerType.AddType(typeSymbol);
                }

                if (type.HasNestedTypes)
                {
                    foreach (TypeDefinition nestedType in type.NestedTypes)
                    {
                        ImportType(mdSource, nestedType, inScriptCoreAssembly, inApplicationAssembly, dependency, typeSymbol);
                    }
                }
            }
        }