예제 #1
0
        public IEnumerable <JsStatement> GetCodeAfterLastType(IEnumerable <JsType> types)
        {
            var scriptableAttributes = MetadataUtils.GetScriptableAttributes(_compilation.MainAssembly.AssemblyAttributes, _metadataImporter).ToList();

            if (scriptableAttributes.Count > 0)
            {
                return new[] { (JsStatement)JsExpression.Assign(JsExpression.Member(_linker.CurrentAssemblyExpression, "attr"), JsExpression.ArrayLiteral(scriptableAttributes.Select(a => MetadataUtils.ConstructAttribute(a, null, _compilation, _metadataImporter, _namer, _runtimeLibrary, _errorReporter)))) }
            }
            ;
            else
            {
                return(EmptyList <JsStatement> .Instance);
            }
        }
예제 #2
0
 public IEnumerable <JsStatement> GetStaticInitStatements(JsClass type)
 {
     return(!MetadataUtils.IsJsGeneric(type.CSharpTypeDefinition, _metadataImporter) && !MetadataUtils.IsResources(type.CSharpTypeDefinition, _attributeStore)
                      ? type.StaticInitStatements
                      : EmptyList <JsStatement> .Instance);
 }
예제 #3
0
 private string GetRoot(ITypeDefinition type)
 {
     return(string.IsNullOrEmpty(MetadataUtils.GetModuleName(type, _attributeStore)) ? "global" : "exports");
 }
예제 #4
0
        private TypeOOPEmulationPhase CreateTypeDefinitions(JsType type)
        {
            string name       = _metadataImporter.GetTypeSemantics(type.CSharpTypeDefinition).Name;
            bool   isGlobal   = string.IsNullOrEmpty(name);
            bool   isMixin    = MetadataUtils.IsMixin(type.CSharpTypeDefinition, _attributeStore);
            bool   export     = type.CSharpTypeDefinition.IsExternallyVisible();
            var    statements = new List <JsStatement>();

            statements.Add(JsStatement.Comment("//////////////////////////////////////////////////////////////////////////////" + Environment.NewLine + " " + type.CSharpTypeDefinition.FullName));

            string typevarName = _namer.GetTypeVariableName(name);

            if (type is JsClass)
            {
                var c = (JsClass)type;
                if (isGlobal)
                {
                    statements.AddRange(c.StaticMethods.Select(m => (JsStatement)JsExpression.Binary(ExpressionNodeType.Assign, JsExpression.Member(JsExpression.Identifier(GetRoot(type.CSharpTypeDefinition)), m.Name), m.Definition)));
                    export = false;
                }
                else if (isMixin)
                {
                    statements.AddRange(c.StaticMethods.Select(m => (JsStatement)JsExpression.Assign(MakeNestedMemberAccess(name + "." + m.Name), m.Definition)));
                    export = false;
                }
                else if (MetadataUtils.IsResources(c.CSharpTypeDefinition, _attributeStore))
                {
                    statements.Add(GenerateResourcesClass(c));
                }
                else
                {
                    var unnamedCtor = c.UnnamedConstructor ?? JsExpression.FunctionDefinition(new string[0], JsStatement.EmptyBlock);

                    if (MetadataUtils.IsJsGeneric(c.CSharpTypeDefinition, _metadataImporter))
                    {
                        var typeParameterNames = c.CSharpTypeDefinition.TypeParameters.Select(tp => _namer.GetTypeParameterName(tp)).ToList();
                        var stmts = new List <JsStatement> {
                            JsStatement.Var(InstantiatedGenericTypeVariableName, unnamedCtor)
                        };
                        AddClassMembers(c, InstantiatedGenericTypeVariableName, stmts);
                        stmts.AddRange(c.StaticInitStatements);
                        stmts.Add(JsStatement.Return(JsExpression.Identifier(InstantiatedGenericTypeVariableName)));
                        var replacer = new GenericSimplifier(c.CSharpTypeDefinition, typeParameterNames, JsExpression.Identifier(InstantiatedGenericTypeVariableName));
                        for (int i = 0; i < stmts.Count; i++)
                        {
                            stmts[i] = replacer.Process(stmts[i]);
                        }
                        statements.Add(JsStatement.Var(typevarName, JsExpression.FunctionDefinition(typeParameterNames, JsStatement.Block(stmts))));
                        statements.Add(JsExpression.Assign(JsExpression.Member(JsExpression.Identifier(typevarName), TypeName), JsExpression.String(_metadataImporter.GetTypeSemantics(c.CSharpTypeDefinition).Name)));
                        var args = new List <JsExpression> {
                            JsExpression.Identifier(typevarName), _linker.CurrentAssemblyExpression, JsExpression.Number(c.CSharpTypeDefinition.TypeParameterCount)
                        };
                        statements.Add(JsExpression.Invocation(JsExpression.Member(_systemScript, c.CSharpTypeDefinition.Kind == TypeKind.Interface ? InitGenericInterface : InitGenericClass), args));
                    }
                    else
                    {
                        statements.Add(JsStatement.Var(typevarName, unnamedCtor));
                        statements.Add(JsExpression.Assign(JsExpression.Member(JsExpression.Identifier(typevarName), TypeName), JsExpression.String(_metadataImporter.GetTypeSemantics(c.CSharpTypeDefinition).Name)));
                        AddClassMembers(c, typevarName, statements);
                    }
                }
            }
            else if (type is JsEnum)
            {
                var e = (JsEnum)type;
                statements.Add(JsStatement.Var(typevarName, JsExpression.FunctionDefinition(new string[0], JsStatement.EmptyBlock)));
                statements.Add(JsExpression.Assign(JsExpression.Member(JsExpression.Identifier(typevarName), TypeName), JsExpression.String(_metadataImporter.GetTypeSemantics(e.CSharpTypeDefinition).Name)));
            }

            if (export)
            {
                string root = GetRoot(type.CSharpTypeDefinition);
                statements.Add(JsExpression.Assign(MakeNestedMemberAccess(name, JsExpression.Identifier(root)), JsExpression.Identifier(typevarName)));
            }

            return(new TypeOOPEmulationPhase(null, statements));
        }
예제 #5
0
        private JsExpression GetBaseClass(ITypeDefinition type)
        {
            var csBase = type.DirectBaseTypes.SingleOrDefault(b => b.Kind == TypeKind.Class);

            if (csBase == null || csBase.IsKnownType(KnownTypeCode.Object) || csBase.IsKnownType(KnownTypeCode.ValueType) || MetadataUtils.IsImported(csBase.GetDefinition(), _attributeStore) && MetadataUtils.IsSerializable(csBase.GetDefinition(), _attributeStore))
            {
                return(null);
            }
            return(_runtimeLibrary.InstantiateType(csBase, new DefaultRuntimeContext(type, _metadataImporter, _errorReporter, _namer)));
        }
예제 #6
0
        private void AddClassMembers(JsClass c, string typevarName, List <JsStatement> stmts)
        {
            if (c.NamedConstructors.Count > 0)
            {
                stmts.AddRange(c.NamedConstructors.Select(m => (JsStatement)JsExpression.Assign(JsExpression.Member(JsExpression.Identifier(typevarName), m.Name), m.Definition)));
            }

            var  defaultConstructor = Saltarelle.Compiler.Utils.SelfParameterize(c.CSharpTypeDefinition).GetConstructors().SingleOrDefault(x => x.Parameters.Count == 0 && x.IsPublic);
            bool hasCreateInstance  = false;

            if (defaultConstructor != null)
            {
                var sem = _metadataImporter.GetConstructorSemantics(defaultConstructor);
                if (sem.Type != ConstructorScriptSemantics.ImplType.UnnamedConstructor && sem.Type != ConstructorScriptSemantics.ImplType.NotUsableFromScript)
                {
                    var createInstance = MetadataUtils.CompileConstructorInvocation(defaultConstructor, null, c.CSharpTypeDefinition, null, EmptyList <ResolveResult> .Instance, _compilation, _metadataImporter, _namer, _runtimeLibrary, _errorReporter, null, null);
                    stmts.Add(JsExpression.Assign(
                                  JsExpression.Member(JsExpression.Identifier(typevarName), "createInstance"),
                                  JsExpression.FunctionDefinition(new string[0], JsStatement.Block(createInstance.AdditionalStatements.Concat(new[] { JsStatement.Return(createInstance.Expression) })))));
                    hasCreateInstance = true;
                }
            }

            if (c.CSharpTypeDefinition.Kind == TypeKind.Struct)
            {
                stmts.Add(JsExpression.Assign(JsExpression.Member(JsExpression.Identifier(typevarName), "getDefaultValue"), hasCreateInstance ? JsExpression.Member(JsExpression.Identifier(typevarName), "createInstance") : JsExpression.FunctionDefinition(EmptyList <string> .Instance, JsStatement.Return(JsExpression.New(JsExpression.Identifier(typevarName))))));

                if (_metadataImporter.GetTypeSemantics(c.CSharpTypeDefinition).Type == TypeScriptSemantics.ImplType.MutableValueType)
                {
                    stmts.Add(JsExpression.Assign(JsExpression.Member(JsExpression.Identifier(typevarName), "$clone"), GenerateStructCloneMethod(c.CSharpTypeDefinition, typevarName, hasCreateInstance)));
                }
            }

            stmts.AddRange(c.StaticMethods.Select(m => (JsStatement)JsExpression.Assign(JsExpression.Member(JsExpression.Identifier(typevarName), m.Name), RewriteMethod(m))));

            if (MetadataUtils.IsSerializable(c.CSharpTypeDefinition, _attributeStore))
            {
                string typeCheckCode = MetadataUtils.GetSerializableTypeCheckCode(c.CSharpTypeDefinition, _attributeStore);
                if (!string.IsNullOrEmpty(typeCheckCode))
                {
                    var oldReg = _errorReporter.Region;
                    _errorReporter.Region = c.CSharpTypeDefinition.Attributes.Single(a => a.AttributeType.FullName == typeof(SerializableAttribute).FullName).Region;
                    var method = MetadataUtils.CreateTypeCheckMethod(Saltarelle.Compiler.Utils.SelfParameterize(c.CSharpTypeDefinition), _compilation);

                    var errors = new List <string>();
                    var tokens = InlineCodeMethodCompiler.Tokenize(method, typeCheckCode, errors.Add);
                    if (errors.Count == 0)
                    {
                        var context = new DefaultRuntimeContext(c.CSharpTypeDefinition, _metadataImporter, _errorReporter, _namer);
                        var result  = InlineCodeMethodCompiler.CompileExpressionInlineCodeMethodInvocation(method, tokens, JsExpression.Identifier("obj"), new JsExpression[0],
                                                                                                           n => {
                            var type = ReflectionHelper.ParseReflectionName(n).Resolve(_compilation);
                            if (type.Kind == TypeKind.Unknown)
                            {
                                errors.Add("Unknown type '" + n + "' specified in inline implementation");
                                return(JsExpression.Null);
                            }
                            return(_runtimeLibrary.InstantiateType(type, context));
                        },
                                                                                                           t => _runtimeLibrary.InstantiateTypeForUseAsTypeArgumentInInlineCode(t, context),
                                                                                                           errors.Add);

                        stmts.Add(JsExpression.Assign(
                                      JsExpression.Member(JsExpression.Identifier(typevarName), "isInstanceOfType"),
                                      JsExpression.FunctionDefinition(new[] { "obj" }, JsStatement.Return(result))));

                        foreach (var e in errors)
                        {
                            _errorReporter.Message(Messages._7157, c.CSharpTypeDefinition.FullName, e);
                        }
                    }
                    _errorReporter.Region = oldReg;
                }
            }

            if (MetadataUtils.IsJsGeneric(c.CSharpTypeDefinition, _metadataImporter))
            {
                var args = new List <JsExpression> {
                    JsExpression.Identifier(typevarName),
                    new JsTypeReferenceExpression(c.CSharpTypeDefinition), JsExpression.ArrayLiteral(c.CSharpTypeDefinition.TypeParameters.Select(tp => JsExpression.Identifier(_namer.GetTypeParameterName(tp)))),
                    CreateInstanceMembers(c, typevarName),
                };
                if (c.CSharpTypeDefinition.Kind != TypeKind.Interface)
                {
                    args.Add(JsExpression.FunctionDefinition(new string[0], JsStatement.Return(GetBaseClass(c.CSharpTypeDefinition) ?? JsExpression.Null)));
                }
                args.Add(JsExpression.FunctionDefinition(new string[0], JsStatement.Return(JsExpression.ArrayLiteral(GetImplementedInterfaces(c.CSharpTypeDefinition)))));
                stmts.Add(JsExpression.Invocation(JsExpression.Member(_systemScript, c.CSharpTypeDefinition.Kind == TypeKind.Interface ? RegisterGenericInterfaceInstance : RegisterGenericClassInstance), args));
                if (c.CSharpTypeDefinition.Kind == TypeKind.Class && c.NamedConstructors.Count > 0)
                {
                    stmts.Add(AssignNamedConstructorPrototypes(c, JsExpression.Identifier(typevarName)));
                }
                if (c.CSharpTypeDefinition.Kind == TypeKind.Struct)
                {
                    stmts.Add(JsExpression.Assign(JsExpression.Member(JsExpression.Identifier(typevarName), "__class"), JsExpression.False));
                }
                var metadata = GetMetadataDescriptor(c.CSharpTypeDefinition, true);
                if (metadata != null)
                {
                    stmts.Add(JsExpression.Invocation(JsExpression.Member(_systemScript, SetMetadata), JsExpression.Identifier(typevarName), metadata));
                }
            }
        }
예제 #7
0
        private JsExpression GenerateStructCloneMethod(ITypeDefinition type, string typevarName, bool hasCreateInstance)
        {
            var stmts = new List <JsStatement>()
            {
                JsStatement.Var("r", hasCreateInstance ? (JsExpression)JsExpression.Invocation(JsExpression.Member(JsExpression.Identifier(typevarName), "createInstance")) : JsExpression.New(JsExpression.Identifier(typevarName)))
            };
            var o = JsExpression.Identifier("o");
            var r = JsExpression.Identifier("r");

            foreach (var f in type.Fields.Where(f => !f.IsStatic))
            {
                var sem = _metadataImporter.GetFieldSemantics(f);
                if (sem.Type == FieldScriptSemantics.ImplType.Field)
                {
                    var          def   = f.ReturnType.GetDefinition();
                    JsExpression value = JsExpression.Member(o, sem.Name);
                    if (def != null && def.Kind == TypeKind.Struct && _metadataImporter.GetTypeSemantics(def).Type == TypeScriptSemantics.ImplType.MutableValueType)
                    {
                        value = _runtimeLibrary.CloneValueType(value, f.ReturnType, new DefaultRuntimeContext(type, _metadataImporter, _errorReporter, _namer));
                    }
                    stmts.Add(JsExpression.Assign(JsExpression.Member(r, sem.Name), value));
                }
            }

            foreach (var p in type.Properties.Where(p => !p.IsStatic))
            {
                var sem = _metadataImporter.GetPropertySemantics(p);

                if ((sem.Type == PropertyScriptSemantics.ImplType.GetAndSetMethods && MetadataUtils.IsAutoProperty(p) == true) || sem.Type == PropertyScriptSemantics.ImplType.Field)
                {
                    var          def       = p.ReturnType.GetDefinition();
                    var          fieldName = sem.Type == PropertyScriptSemantics.ImplType.GetAndSetMethods ? _metadataImporter.GetAutoPropertyBackingFieldName(p) : sem.FieldName;
                    JsExpression value     = JsExpression.Member(o, fieldName);
                    if (def != null && def.Kind == TypeKind.Struct && _metadataImporter.GetTypeSemantics(def).Type == TypeScriptSemantics.ImplType.MutableValueType)
                    {
                        value = _runtimeLibrary.CloneValueType(value, p.ReturnType, new DefaultRuntimeContext(type, _metadataImporter, _errorReporter, _namer));
                    }
                    stmts.Add(JsExpression.Assign(JsExpression.Member(r, fieldName), value));
                }
            }

            foreach (var e in type.Events.Where(e => !e.IsStatic && MetadataUtils.IsAutoEvent(e) == true))
            {
                var sem = _metadataImporter.GetEventSemantics(e);

                if (sem.Type == EventScriptSemantics.ImplType.AddAndRemoveMethods)
                {
                    var          def       = e.ReturnType.GetDefinition();
                    var          fieldName = _metadataImporter.GetAutoEventBackingFieldName(e);
                    JsExpression value     = JsExpression.Member(o, fieldName);
                    if (def != null && def.Kind == TypeKind.Struct && _metadataImporter.GetTypeSemantics(def).Type == TypeScriptSemantics.ImplType.MutableValueType)
                    {
                        value = _runtimeLibrary.CloneValueType(value, e.ReturnType, new DefaultRuntimeContext(type, _metadataImporter, _errorReporter, _namer));
                    }
                    stmts.Add(JsExpression.Assign(JsExpression.Member(r, fieldName), value));
                }
            }
            stmts.Add(JsStatement.Return(r));
            return(JsExpression.FunctionDefinition(new[] { "o" }, JsStatement.Block(stmts)));
        }
예제 #8
0
 private IEnumerable <JsExpression> GetImplementedInterfaces(ITypeDefinition type)
 {
     return(type.GetAllBaseTypes().Where(t => t.Kind == TypeKind.Interface && !t.Equals(type) && MetadataUtils.DoesTypeObeyTypeSystem(t.GetDefinition(), _attributeStore)).Select(t => _runtimeLibrary.InstantiateType(t, new DefaultRuntimeContext(type, _metadataImporter, _errorReporter, _namer))));
 }
예제 #9
0
        private JsExpression GetMetadataDescriptor(ITypeDefinition type, bool isGenericSpecialization)
        {
            var properties           = new List <JsObjectLiteralProperty>();
            var scriptableAttributes = MetadataUtils.GetScriptableAttributes(type.Attributes, _metadataImporter).ToList();

            if (scriptableAttributes.Count != 0)
            {
                properties.Add(new JsObjectLiteralProperty("attr", JsExpression.ArrayLiteral(scriptableAttributes.Select(a => MetadataUtils.ConstructAttribute(a, type, _compilation, _metadataImporter, _namer, _runtimeLibrary, _errorReporter)))));
            }
            if (type.Kind == TypeKind.Interface && MetadataUtils.IsJsGeneric(type, _metadataImporter) && type.TypeParameters != null && type.TypeParameters.Any(typeParameter => typeParameter.Variance != VarianceModifier.Invariant))
            {
                properties.Add(new JsObjectLiteralProperty("variance", JsExpression.ArrayLiteral(type.TypeParameters.Select(typeParameter => JsExpression.Number(ConvertVarianceToInt(typeParameter.Variance))))));
            }
            if (type.Kind == TypeKind.Class || type.Kind == TypeKind.Interface)
            {
                var members = type.Members.Where(m => MetadataUtils.IsReflectable(m, _attributeStore))
                              .OrderBy(m => m, MemberOrderer.Instance)
                              .Select(m => {
                    _errorReporter.Region = m.Region;
                    return(MetadataUtils.ConstructMemberInfo(m, _compilation, _metadataImporter, _namer, _runtimeLibrary, _errorReporter, t => _runtimeLibrary.InstantiateType(t, isGenericSpecialization ? _genericSpecializationReflectionRuntimeContext : _defaultReflectionRuntimeContext), includeDeclaringType: false));
                })
                              .ToList();
                if (members.Count > 0)
                {
                    properties.Add(new JsObjectLiteralProperty("members", JsExpression.ArrayLiteral(members)));
                }

                var aua = _attributeStore.AttributesFor(type).GetAttribute <AttributeUsageAttribute>();
                if (aua != null)
                {
                    if (!aua.Inherited)
                    {
                        properties.Add(new JsObjectLiteralProperty("attrNoInherit", JsExpression.True));
                    }
                    if (aua.AllowMultiple)
                    {
                        properties.Add(new JsObjectLiteralProperty("attrAllowMultiple", JsExpression.True));
                    }
                }
            }
            if (type.Kind == TypeKind.Enum && _attributeStore.AttributesFor(type).HasAttribute <FlagsAttribute>())
            {
                properties.Add(new JsObjectLiteralProperty("enumFlags", JsExpression.True));
            }

            return(properties.Count > 0 ? JsExpression.ObjectLiteral(properties) : null);
        }
예제 #10
0
        private JsExpression GetFieldHashCode(IField field)
        {
            var impl = _metadataImporter.GetFieldSemantics(field);

            if (impl.Type != FieldScriptSemantics.ImplType.Field)
            {
                return(null);
            }

            IType        type          = NullableType.GetUnderlyingType(field.Type);
            bool         needNullCheck = field.Type.IsReferenceType != false || field.Type.IsKnownType(KnownTypeCode.NullableOfT) || type.Kind == TypeKind.Enum && MetadataUtils.IsNamedValues(field.Type.GetDefinition(), _attributeStore);
            JsExpression member        = JsExpression.Member(JsExpression.This, impl.Name);

            JsExpression result = JsExpression.Invocation(JsExpression.Member(_systemScript, "getHashCode"), member);

            if (needNullCheck)
            {
                result = JsExpression.Conditional(member, result, JsExpression.Number(0));
            }

            if (type.Kind == TypeKind.Enum && !MetadataUtils.IsNamedValues(type.GetDefinition(), _attributeStore))
            {
                result = needNullCheck ? JsExpression.LogicalOr(member, JsExpression.Number(0)) : member;
            }
            else if (type is ITypeDefinition)
            {
                switch (((ITypeDefinition)type).KnownTypeCode)
                {
                case KnownTypeCode.Boolean:
                    result = JsExpression.Conditional(member, JsExpression.Number(1), JsExpression.Number(0));
                    break;

                case KnownTypeCode.Byte:
                case KnownTypeCode.SByte:
                case KnownTypeCode.Char:
                case KnownTypeCode.Int16:
                case KnownTypeCode.UInt16:
                case KnownTypeCode.Int32:
                case KnownTypeCode.UInt32:
                case KnownTypeCode.Int64:
                case KnownTypeCode.UInt64:
                case KnownTypeCode.Decimal:
                case KnownTypeCode.Single:
                case KnownTypeCode.Double:
                    result = needNullCheck ? JsExpression.LogicalOr(member, JsExpression.Number(0)) : member;
                    break;
                }
            }

            return(result);
        }
예제 #11
0
        public JsExpression TryDowncast(JsExpression expression, IType sourceType, IType targetType, IRuntimeContext context)
        {
            JsExpression jsTarget = CompileImportedTypeCheckCode(targetType, ref expression, context, false);

            if (jsTarget == null)
            {
                var def = targetType.GetDefinition();
                if (def != null && (!MetadataUtils.DoesTypeObeyTypeSystem(def, _attributeStore) || (MetadataUtils.IsSerializable(def, _attributeStore) && string.IsNullOrEmpty(MetadataUtils.GetSerializableTypeCheckCode(def, _attributeStore)))))
                {
                    _errorReporter.Message(Messages._7702, targetType.FullName);
                    return(JsExpression.Null);
                }

                jsTarget = GetCastTarget(sourceType, targetType, context);
            }

            if (jsTarget == null || IsSystemObjectReference(jsTarget))
            {
                return(expression);
            }

            return(JsExpression.Invocation(JsExpression.Member(CreateTypeReferenceExpression(_systemScript), "safeCast"), expression, jsTarget));
        }
예제 #12
0
        public JsExpression TypeIs(JsExpression expression, IType sourceType, IType targetType, IRuntimeContext context)
        {
            var importedCheck = CompileImportedTypeCheckCode(targetType, ref expression, context, true);

            if (importedCheck != null)
            {
                return(importedCheck);
            }

            var def = targetType.GetDefinition();

            if (def != null && (!MetadataUtils.DoesTypeObeyTypeSystem(def, _attributeStore) || (MetadataUtils.IsSerializable(def, _attributeStore) && string.IsNullOrEmpty(MetadataUtils.GetSerializableTypeCheckCode(def, _attributeStore)))))
            {
                _errorReporter.Message(Messages._7701, targetType.FullName);
                return(JsExpression.Null);
            }

            var jsTarget = GetCastTarget(sourceType, targetType, context);

            if (jsTarget == null || IsSystemObjectReference(jsTarget))
            {
                return(ReferenceNotEquals(expression, JsExpression.Null, context));
            }
            return(JsExpression.Invocation(JsExpression.Member(CreateTypeReferenceExpression(_systemScript), "isInstanceOfType"), expression, jsTarget));
        }
예제 #13
0
        private JsExpression GetCastTarget(IType type, IRuntimeContext context)
        {
            var def = type.GetDefinition();

            if (type.Kind == TypeKind.Enum)
            {
                var underlying = MetadataUtils.IsNamedValues(def, _attributeStore) ? _compilation.FindType(KnownTypeCode.String) : def.EnumUnderlyingType;
                return(CreateTypeReferenceExpression(underlying.GetDefinition()));
            }

            if (def != null)
            {
                if (MetadataUtils.IsSerializable(def, _attributeStore) && string.IsNullOrEmpty(MetadataUtils.GetSerializableTypeCheckCode(def, _attributeStore)))
                {
                    return(null);
                }
                if (!MetadataUtils.DoesTypeObeyTypeSystem(def, _attributeStore))
                {
                    return(null);
                }
            }

            return(GetScriptType(type, TypeContext.GetScriptType, context));
        }
예제 #14
0
        private JsExpression GetTypeDefinitionScriptType(ITypeDefinition type, TypeContext context)
        {
            var sem = _metadataImporter.GetTypeSemantics(type);

            if (sem.Type == TypeScriptSemantics.ImplType.NotUsableFromScript)
            {
                _errorReporter.Message(Saltarelle.Compiler.Messages._7522, type.FullName);
                return(JsExpression.Null);
            }

            if (context != TypeContext.GetScriptType && context != TypeContext.TypeOf && !MetadataUtils.DoesTypeObeyTypeSystem(type, _attributeStore))
            {
                return(CreateTypeReferenceExpression(KnownTypeReference.Object));
            }
            else if (MetadataUtils.IsSerializable(type, _attributeStore) && !MetadataUtils.DoesTypeObeyTypeSystem(type, _attributeStore))
            {
                return(CreateTypeReferenceExpression(KnownTypeReference.Object));
            }
            else
            {
                return(CreateTypeReferenceExpression(type));
            }
        }
예제 #15
0
            public static IList <JsStatement> Process(IMetadataImporter metadataImporter, INamer namer, IAttributeStore attributeStore, ICompilation compilation, IList <JsStatement> statements)
            {
                var locals          = LocalVariableGatherer.Analyze(statements);
                var globals         = ImplicitGlobalsGatherer.Analyze(statements, locals, reportGlobalsAsUsedInAllParentScopes: false);
                var introducedNames = IntroducedNamesGatherer.Analyze(statements, metadataImporter, attributeStore, compilation.MainAssembly);
                var renameMap       = RenameMapBuilder.BuildMap(statements, locals, globals, introducedNames, namer);

                var usedSymbols = new HashSet <string>();

                foreach (var sym in         locals.Values.SelectMany(v => v)                            // Declared locals.
                         .Concat(globals.Values.SelectMany(v => v))                                     // Implicitly declared globals.
                         .Concat(renameMap.Values.SelectMany(v => v.Values))                            // Locals created during preparing rename.
                         .Concat(introducedNames.Values.SelectMany(v => v))                             // All global types used.
                         )
                {
                    usedSymbols.Add(sym);
                }

                statements = IdentifierRenamer.Process(statements, renameMap).ToList();

                bool isModule = MetadataUtils.GetModuleName(compilation.MainAssembly, attributeStore) != null || MetadataUtils.IsAsyncModule(compilation.MainAssembly, attributeStore);
                var  importer = new ImportVisitor(metadataImporter, namer, attributeStore, compilation.MainAssembly, usedSymbols, JsExpression.Identifier(isModule ? "exports" : "$asm"));

                var body = (!isModule ? new[] { JsStatement.Var("$asm", JsExpression.ObjectLiteral()) } : new JsStatement[0]).Concat(statements.Select(s => importer.VisitStatement(s, null))).ToList();
                var moduleDependencies = importer._moduleAliases.Concat(MetadataUtils.GetAdditionalDependencies(compilation.MainAssembly, attributeStore));

                if (MetadataUtils.IsAsyncModule(compilation.MainAssembly, attributeStore))
                {
                    body.InsertRange(0, new[] { JsStatement.UseStrict, JsStatement.Var("exports", JsExpression.ObjectLiteral()) });
                    body.Add(JsStatement.Return(JsExpression.Identifier("exports")));

                    var pairs = new[] { new KeyValuePair <string, string>("mscorlib", namer.GetVariableName("_", usedSymbols)) }
                    .Concat(moduleDependencies.OrderBy(x => x.Key))
                    .ToList();

                    body = new List <JsStatement> {
                        JsExpression.Invocation(
                            JsExpression.Identifier("define"),
                            JsExpression.ArrayLiteral(pairs.Select(p => JsExpression.String(p.Key))),
                            JsExpression.FunctionDefinition(
                                pairs.Select(p => p.Value),
                                JsStatement.Block(body)
                                )
                            )
                    };
                }
                else if (moduleDependencies.Any())
                {
                    // If we require any module, we require mscorlib. This should work even if we are a leaf module that doesn't include any other module because our parent script will do the mscorlib require for us.
                    body.InsertRange(0, new[] { JsStatement.UseStrict, JsExpression.Invocation(JsExpression.Identifier("require"), JsExpression.String("mscorlib")) }
                                     .Concat(moduleDependencies
                                             .OrderBy(x => x.Key).OrderBy(x => x.Key)
                                             .Select(x => JsStatement.Var(
                                                         x.Value,
                                                         JsExpression.Invocation(
                                                             JsExpression.Identifier("require"),
                                                             JsExpression.String(x.Key))))
                                             .ToList()));
                }
                else
                {
                    body.Insert(0, JsStatement.UseStrict);
                    body = new List <JsStatement> {
                        JsExpression.Invocation(JsExpression.FunctionDefinition(new string[0], JsStatement.Block(body)))
                    };
                }

                return(body);
            }