Ejemplo n.º 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);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        private void ImportMethods(TypeSymbol typeSymbol)
        {
            // NOTE: We do not import parameters for imported members.
            //       Parameters are used in the script model generation phase to populate
            //       symbol tables, which is not done for imported methods.

            TypeDefinition type = (TypeDefinition)typeSymbol.MetadataReference;

            foreach (MethodDefinition method in type.Methods)
            {
                if (method.IsSpecialName)
                {
                    continue;
                }

                if (method.IsPrivate || method.IsAssembly || method.IsFamilyAndAssembly)
                {
                    continue;
                }

                string methodName = method.Name;

                if (typeSymbol.GetMember(methodName) != null)
                {
                    // Ignore if its an overload since we don't care about parameters
                    // for imported methods, overloaded ctors don't matter.
                    // We just care about return values pretty much, and existence of the
                    // method.
                    continue;
                }

                TypeSymbol returnType = ResolveType(method.MethodReturnType.ReturnType);

                if (returnType == null)
                {
                    continue;
                }

                // skip symbol generation for members decorated with [ScriptIgnore]
                if (MetadataHelpers.IsIgnored(method))
                {
                    continue;
                }

                MethodSymbol methodSymbol = new MethodSymbol(
                    methodName,
                    typeSymbol,
                    returnType,
                    MetadataHelpers.IsExtensionMethod(method));

                if (MetadataHelpers.ShouldIgnoreMethodGeneratedTypeArguments(method))
                {
                    methodSymbol.IgnoreGeneratedTypeArguments = true;
                }

                methodSymbol.SetParseContext(method);
                ImportMemberDetails(methodSymbol, method, method);

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

                    foreach (GenericParameter genericParameter in method.GenericParameters)
                    {
                        GenericParameterSymbol arg =
                            new GenericParameterSymbol(genericParameter.Position, genericParameter.Name,
                                                       /* typeArgument */ false,
                                                       symbols.GlobalNamespace);
                        genericArguments.Add(arg);
                    }

                    methodSymbol.AddGenericArguments(genericArguments);
                }

                if (method.IsAbstract)
                {
                    // NOTE: We're ignoring the override scenario - it doesn't matter in terms
                    //       of the compilation and code generation
                    methodSymbol.SetImplementationState(SymbolImplementationFlags.Abstract);
                }

                if (MetadataHelpers.ShouldSkipFromScript(method))
                {
                    methodSymbol.SetSkipGeneration();
                }

                string transformedName = MetadataHelpers.GetTransformedName(method);

                if (string.IsNullOrEmpty(transformedName) == false)
                {
                    methodSymbol.SetTransformName(transformedName);
                }

                string scriptName = MetadataHelpers.GetScriptName(method, out _, out _);

                if (string.IsNullOrEmpty(scriptName) == false && !methodSymbol.IsTransformed)
                {
                    methodSymbol.SetTransformedName(scriptName);
                }

                string selector = MetadataHelpers.GetScriptMethodSelector(method);

                if (string.IsNullOrEmpty(selector) == false)
                {
                    methodSymbol.SetSelector(selector);
                }

                if (MetadataHelpers.ShouldTreatAsConditionalMethod(method, out ICollection <string> conditions))
                {
                    methodSymbol.SetConditions(conditions);
                }

                typeSymbol.AddMember(methodSymbol);
            }
        }
Ejemplo n.º 3
0
        private TypeSymbol ResolveType(TypeReference type, TypeSymbol parentSymbol = null)
        {
            int arrayDimensions = 0;

            while (type is ArrayType arrayType)
            {
                arrayDimensions++;
                type = arrayType.ElementType;
            }

            GenericInstanceType genericType = type as GenericInstanceType;

            if (genericType != null)
            {
                type = genericType.ElementType;
            }
            string name = ProcessNestedTypeName(type);

            if (string.CompareOrdinal(name, MscorlibTypeNames.System_ValueType) == 0)
            {
                // Ignore this type - it is the base class for enums, and other primitive types
                // but we don't import it since it is not useful in script
                return(null);
            }

            TypeSymbol typeSymbol;

            if (type is GenericParameter genericParameter)
            {
                typeSymbol = new GenericParameterSymbol(genericParameter.Position, genericParameter.Name,
                                                        genericParameter.Owner.GenericParameterType == GenericParameterType.Type,
                                                        symbols.GlobalNamespace);
                if (parentSymbol != null)
                {
                    ((GenericParameterSymbol)typeSymbol).Owner = parentSymbol;
                }
            }
            else
            {
                typeSymbol = (TypeSymbol)((ISymbolTable)symbols).FindSymbol(name, null, SymbolFilter.Types);

                if (typeSymbol == null)
                {
                    //TODO: Improve this error and provide context as to what type is missing from where
                    errorHandler.ReportMissingReferenceError(name);
                    resolveError = true;
                }
            }

            if (genericType != null)
            {
                List <TypeSymbol> typeArgs = new List <TypeSymbol>();

                foreach (TypeReference argTypeRef in genericType.GenericArguments)
                {
                    TypeSymbol argType = ResolveType(argTypeRef, typeSymbol);
                    typeArgs.Add(argType);
                }

                typeSymbol = symbols.CreateGenericTypeSymbol(typeSymbol, typeArgs);
                Debug.Assert(typeSymbol != null);
            }

            if (arrayDimensions != 0)
            {
                for (int i = 0; i < arrayDimensions; i++)
                {
                    typeSymbol = symbols.CreateArrayTypeSymbol(typeSymbol);
                }
            }

            return(typeSymbol);
        }
Ejemplo n.º 4
0
        private TypeSymbol ResolveType(TypeReference type)
        {
            int arrayDimensions = 0;

            while (type is ArrayType)
            {
                arrayDimensions++;
                type = ((ArrayType)type).ElementType;
            }

            GenericInstanceType genericType = type as GenericInstanceType;

            if (genericType != null)
            {
                type = genericType.ElementType;
            }

            string name = type.FullName;

            if (String.CompareOrdinal(name, "System.ValueType") == 0)
            {
                // Ignore this type - it is the base class for enums, and other primitive types
                // but we don't import it since it is not useful in script
                return(null);
            }

            TypeSymbol typeSymbol;

            GenericParameter genericParameter = type as GenericParameter;

            if (genericParameter != null)
            {
                typeSymbol = new GenericParameterSymbol(genericParameter.Position, genericParameter.Name,
                                                        (genericParameter.Owner.GenericParameterType == GenericParameterType.Type),
                                                        _symbols.GlobalNamespace);
            }
            else
            {
                typeSymbol = (TypeSymbol)((ISymbolTable)_symbols).FindSymbol(name, null, SymbolFilter.Types);
                if (typeSymbol == null)
                {
                    _errorHandler.ReportError("Unable to resolve referenced type '" + name +
                                              "'. Make sure all needed assemblies have been explicitly referenced.",
                                              String.Empty);
                    _resolveError = true;
                }
            }

            if (genericType != null)
            {
                List <TypeSymbol> typeArgs = new List <TypeSymbol>();

                foreach (TypeReference argTypeRef in genericType.GenericArguments)
                {
                    TypeSymbol argType = ResolveType(argTypeRef);
                    typeArgs.Add(argType);
                }

                typeSymbol = _symbols.CreateGenericTypeSymbol(typeSymbol, typeArgs);
                Debug.Assert(typeSymbol != null);
            }

            if (arrayDimensions != 0)
            {
                for (int i = 0; i < arrayDimensions; i++)
                {
                    typeSymbol = _symbols.CreateArrayTypeSymbol(typeSymbol);
                }
            }

            return(typeSymbol);
        }
Ejemplo n.º 5
0
        private void ImportType(MetadataSource mdSource, TypeDefinition type, bool inScriptCoreAssembly, string scriptNamespace)
        {
            if (type.IsPublic == false)
            {
                return;
            }
            if (inScriptCoreAssembly && (MetadataHelpers.ShouldImportScriptCoreType(type) == false))
            {
                return;
            }

            string name          = type.Name;
            string namespaceName = 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");
            }
            else
            {
                if (MetadataHelpers.ShouldTreatAsRecordType(type))
                {
                    typeSymbol = new RecordSymbol(name, namespaceSymbol);
                    typeSymbol.SetTransformedName("Object");
                }
                else
                {
                    typeSymbol = new ClassSymbol(name, namespaceSymbol);

                    string extendee;
                    if (MetadataHelpers.IsScriptExtension(type, out extendee))
                    {
                        ((ClassSymbol)typeSymbol).SetExtenderClass(extendee);
                    }

                    if (String.CompareOrdinal(scriptName, "Array") == 0)
                    {
                        typeSymbol.SetArray();
                    }
                }
            }

            if (typeSymbol != null)
            {
                if (type.HasGenericParameters)
                {
                    List <GenericParameterSymbol> genericArguments = new List <GenericParameterSymbol>();
                    foreach (GenericParameter genericParameter in type.GenericParameters)
                    {
                        GenericParameterSymbol arg =
                            new GenericParameterSymbol(genericParameter.Position, genericParameter.Name,
                                                       /* typeArgument */ true,
                                                       _symbols.GlobalNamespace);
                        genericArguments.Add(arg);
                    }

                    typeSymbol.AddGenericParameters(genericArguments);
                }

                ScriptReference dependency = null;
                string          dependencyIdentifier;
                string          dependencyName = MetadataHelpers.GetScriptDependencyName(type, out dependencyIdentifier);
                if (dependencyName != null)
                {
                    dependency      = new ScriptReference(dependencyName, dependencyIdentifier);
                    scriptNamespace = dependency.Identifier;
                }

                typeSymbol.SetImported(dependency);
                typeSymbol.SetMetadataToken(type, inScriptCoreAssembly);

                bool ignoreNamespace = MetadataHelpers.ShouldIgnoreNamespace(type);
                if (ignoreNamespace || String.IsNullOrEmpty(scriptNamespace))
                {
                    typeSymbol.SetIgnoreNamespace();
                }
                else
                {
                    typeSymbol.ScriptNamespace = scriptNamespace;
                }
                typeSymbol.SetPublic();

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

                namespaceSymbol.AddType(typeSymbol);
                _importedTypes.Add(typeSymbol);
            }
        }
Ejemplo n.º 6
0
        private void ImportType(MetadataSource mdSource, TypeDefinition type, bool inScriptCoreAssembly, string assemblyScriptNamespace, string assemblyScriptName)
        {
            if (type.IsPublic == false)
            {
                return;
            }
            if (inScriptCoreAssembly && (MetadataHelpers.ShouldImportScriptCoreType(type) == false))
            {
                return;
            }

            string name            = type.Name;
            string namespaceName   = type.Namespace;
            string scriptNamespace = MetadataHelpers.GetScriptNamespace(type);
            string scriptName      = MetadataHelpers.GetScriptName(type);

            if (String.IsNullOrEmpty(scriptNamespace) && (String.IsNullOrEmpty(assemblyScriptNamespace) == false))
            {
                scriptNamespace = assemblyScriptNamespace;
            }

            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");
            }
            else
            {
                if (MetadataHelpers.ShouldTreatAsRecordType(type))
                {
                    typeSymbol = new RecordSymbol(name, namespaceSymbol);
                }
                else
                {
                    typeSymbol = new ClassSymbol(name, namespaceSymbol);

                    string mixinRoot;
                    if (MetadataHelpers.ShouldGlobalizeMembers(type, out mixinRoot))
                    {
                        ((ClassSymbol)typeSymbol).SetGlobalMethods(mixinRoot);
                    }
                }
            }

            if (typeSymbol != null)
            {
                if (type.HasGenericParameters)
                {
                    List <GenericParameterSymbol> genericArguments = new List <GenericParameterSymbol>();
                    foreach (GenericParameter genericParameter in type.GenericParameters)
                    {
                        GenericParameterSymbol arg =
                            new GenericParameterSymbol(genericParameter.Position, genericParameter.Name,
                                                       /* typeArgument */ true,
                                                       _symbols.GlobalNamespace);
                        genericArguments.Add(arg);
                    }

                    typeSymbol.AddGenericParameters(genericArguments);
                }

                typeSymbol.SetImported(assemblyScriptName);
                typeSymbol.SetMetadataToken(type, inScriptCoreAssembly);

                bool ignoreNamespace = MetadataHelpers.ShouldIgnoreNamespace(type);
                if (ignoreNamespace)
                {
                    typeSymbol.SetIgnoreNamespace();
                }
                typeSymbol.SetPublic();

                if (String.IsNullOrEmpty(scriptNamespace) == false)
                {
                    typeSymbol.ScriptNamespace = scriptNamespace;
                }

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

                namespaceSymbol.AddType(typeSymbol);
                _importedTypes.Add(typeSymbol);
            }
        }