Beispiel #1
0
 public object VisitTypeReferenceExpression(JsTypeReferenceExpression expression, bool parenthesized)
 {
     if (!_allowIntermediates)
     {
         throw new NotSupportedException("TypeReferenceExpressions should not occur in the output stage");
     }
     _cb.Append("{").Append(expression.Type.Name).Append("}");
     return(null);
 }
 public ScriptSharpOOPEmulator(ICompilation compilation, IScriptSharpMetadataImporter metadataImporter, IRuntimeLibrary runtimeLibrary, INamer namer, IErrorReporter errorReporter)
 {
     _metadataImporter = metadataImporter;
     _runtimeLibrary   = runtimeLibrary;
     _namer            = namer;
     _errorReporter    = errorReporter;
     _compilation      = compilation;
     _systemType       = new JsTypeReferenceExpression(_compilation.FindType(KnownTypeCode.Type).GetDefinition());
 }
            public override JsExpression VisitTypeReferenceExpression(JsTypeReferenceExpression expression, object data)
            {
                var          parts  = expression.TypeName.Split('.');
                JsExpression result = JsExpression.Identifier(parts[0]);

                for (int i = 1; i < parts.Length; i++)
                {
                    result = JsExpression.MemberAccess(result, parts[i]);
                }
                return(result);
            }
 public MockRuntimeLibrary()
 {
     GetScriptType = (t, c) => {
                         if (t.TypeParameterCount > 0 && !(t is ParameterizedType) && c == TypeContext.TypeOf) {
                             // This handles open generic types ( typeof(C<,>) )
                             var def = t.GetDefinition();
                             return new JsTypeReferenceExpression(def.ParentAssembly, def.FullName);
                         }
                         else if (t is ArrayType) {
                             return JsExpression.Invocation(JsExpression.Identifier("$Array"), GetScriptType(((ArrayType)t).ElementType, TypeContext.GenericArgument));
                         }
                         else if (t is ParameterizedType) {
                             var pt = (ParameterizedType)t;
                             var def = pt.GetDefinition();
                             return JsExpression.Invocation(JsExpression.Identifier("$InstantiateGenericType"), new[] { new JsTypeReferenceExpression(def.ParentAssembly, t.Name) }.Concat(pt.TypeArguments.Select(a => GetScriptType(a, TypeContext.GenericArgument))));
                         }
                         else if (t is ITypeDefinition) {
                             var td = (ITypeDefinition)t;
                             var jsref = new JsTypeReferenceExpression(td.ParentAssembly, t.Name);
                             if (td.TypeParameterCount > 0)
                                 return JsExpression.Invocation(JsExpression.Identifier("$InstantiateGenericType"), new[] { jsref }.Concat(td.TypeParameters.Select(p => GetScriptType(p, TypeContext.GenericArgument))));
                             else {
                                 return jsref;
                             }
                         }
                         else if (t is ITypeParameter) {
                             return JsExpression.Identifier("$" + ((ITypeParameter)t).Name);
                         }
                         else {
                             throw new ArgumentException("Unsupported type + " + t.ToString());
                         }
                     };
     TypeIs                   = (e, s, t)     => JsExpression.Invocation(JsExpression.Identifier("$TypeIs"), e, GetScriptType(t, TypeContext.CastTarget));
     TryDowncast              = (e, s, d)     => JsExpression.Invocation(JsExpression.Identifier("$TryCast"), e, GetScriptType(d, TypeContext.CastTarget));
     Downcast                 = (e, s, d)     => JsExpression.Invocation(JsExpression.Identifier("$Cast"), e, GetScriptType(d, TypeContext.CastTarget));
     Upcast                   = (e, s, d)     => JsExpression.Invocation(JsExpression.Identifier("$Upcast"), e, GetScriptType(d, TypeContext.CastTarget));
     ReferenceEquals          = (a, b)        => JsExpression.Invocation(JsExpression.Identifier("$ReferenceEquals"), a, b);
     ReferenceNotEquals       = (a, b)        => JsExpression.Invocation(JsExpression.Identifier("$ReferenceNotEquals"), a, b);
     InstantiateGenericMethod = (m, a)        => JsExpression.Invocation(JsExpression.Identifier("$InstantiateGenericMethod"), new[] { m }.Concat(a.Select(x => GetScriptType(x, TypeContext.GenericArgument))));
     MakeException            = (e)           => JsExpression.Invocation(JsExpression.Identifier("$MakeException"), e);
     IntegerDivision          = (n, d)        => JsExpression.Invocation(JsExpression.Identifier("$IntDiv"), n, d);
     FloatToInt               = (e)           => JsExpression.Invocation(JsExpression.Identifier("$Truncate"), e);
     Coalesce                 = (a, b)        => JsExpression.Invocation(JsExpression.Identifier("$Coalesce"), a, b);
     Lift                     = (e)           => JsExpression.Invocation(JsExpression.Identifier("$Lift"), e);
     FromNullable             = (e)           => JsExpression.Invocation(JsExpression.Identifier("$FromNullable"), e);
     LiftedBooleanAnd         = (a, b)        => JsExpression.Invocation(JsExpression.Identifier("$LiftedBooleanAnd"), a, b);
     LiftedBooleanOr          = (a, b)        => JsExpression.Invocation(JsExpression.Identifier("$LiftedBooleanOr"), a, b);
     Bind                     = (f, t)        => JsExpression.Invocation(JsExpression.Identifier("$Bind"), f, t);
     Default                  = (t)           => JsExpression.Invocation(JsExpression.Identifier("$Default"), GetScriptType(t, TypeContext.GetDefaultValue));
     CreateArray              = (s)           => JsExpression.Invocation(JsExpression.Identifier("$CreateArray"), s);
     CloneDelegate            = (e, s, t)     => JsExpression.Invocation(JsExpression.Identifier("$CloneDelegate"), e);
     CallBase                 = (t, n, ta, a) => JsExpression.Invocation(JsExpression.Identifier("$CallBase"), new[] { GetScriptType(t, TypeContext.Instantiation), JsExpression.String(n), JsExpression.ArrayLiteral(ta.Select(x => GetScriptType(x, TypeContext.GenericArgument))), JsExpression.ArrayLiteral(a) });
     BindBaseCall             = (t, n, ta, a) => JsExpression.Invocation(JsExpression.Identifier("$BindBaseCall"), new[] { GetScriptType(t, TypeContext.Instantiation), JsExpression.String(n), JsExpression.ArrayLiteral(ta.Select(x => GetScriptType(x, TypeContext.GenericArgument))), a });
 }
        public object VisitTypeReferenceExpression(JsTypeReferenceExpression expression, bool parenthesized)
        {
            if (!_allowIntermediates)
            {
                throw new NotSupportedException("TypeReferenceExpressions should not occur in the output stage");
            }
            int    lastDot = expression.TypeName.LastIndexOf('.');
            string name    = (lastDot >= 0 ? expression.TypeName.Substring(lastDot + 1) : expression.TypeName);

            _cb.Append("{").Append(name).Append("}");
            return(null);
        }
Beispiel #6
0
        public OOPEmulator(ICompilation compilation, IMetadataImporter metadataImporter, IRuntimeLibrary runtimeLibrary, INamer namer, IErrorReporter errorReporter)
        {
            _compilation  = compilation;
            _systemScript = new JsTypeReferenceExpression(compilation.FindType(new FullTypeName("System.Script")).GetDefinition());
            _systemObject = new JsTypeReferenceExpression(compilation.FindType(KnownTypeCode.Object).GetDefinition());

            _metadataImporter = metadataImporter;
            _runtimeLibrary   = runtimeLibrary;
            _namer            = namer;
            _errorReporter    = errorReporter;
            _defaultReflectionRuntimeContext = new ReflectionRuntimeContext(false, _systemObject, _namer);
            _genericSpecializationReflectionRuntimeContext = new ReflectionRuntimeContext(true, _systemObject, _namer);
        }
Beispiel #7
0
            public override JsExpression VisitTypeReferenceExpression(JsTypeReferenceExpression expression, object data)
            {
                var sem = _metadataImporter.GetTypeSemantics(expression.Type);

                if (sem.Type != TypeScriptSemantics.ImplType.NormalType)
                {
                    throw new ArgumentException("The type " + expression.Type.FullName + " appears in the output stage but is not a normal type.");
                }

                if (IsLocalReference(expression.Type))
                {
                    if (string.IsNullOrEmpty(sem.Name))
                    {
                        return(JsExpression.Identifier("exports"));                             // Referencing a [GlobalMethods] type. Since it was not handled in the member expression, we must be in a module, which means that the function should exist on the exports object.
                    }
                    // For types in our own assembly, we can use the $TYPE variable in the pattern "var $TYPE = function() {} ... Type.registerClass(global, 'The.Name', $TYPE)"
                    return(JsExpression.Identifier(_namer.GetTypeVariableName(_metadataImporter.GetTypeSemantics(expression.Type).Name)));
                }

                string moduleName = GetTypeModuleName(expression.Type);

                var          parts = sem.Name.Split('.');
                JsExpression result;

                if (moduleName != null)
                {
                    result = JsExpression.Identifier(GetModuleAlias(moduleName));
                    if (!string.IsNullOrEmpty(sem.Name))                        // Test for [GlobalMethods] types.
                    {
                        result = JsExpression.Member(result, parts[0]);
                    }
                }
                else
                {
                    result = JsExpression.Identifier(parts[0]);
                }

                for (int i = 1; i < parts.Length; i++)
                {
                    result = JsExpression.Member(result, parts[i]);
                }
                return(result);
            }
Beispiel #8
0
            public override JsExpression VisitTypeReferenceExpression(JsTypeReferenceExpression expression, IList <string> data)
            {
                var sem = _metadataImporter.GetTypeSemantics(expression.Type);

                if (sem.Type != TypeScriptSemantics.ImplType.NormalType && sem.Type != TypeScriptSemantics.ImplType.MutableValueType)
                {
                    throw new ArgumentException("The type " + expression.Type.FullName + " appears in the output stage but is not a normal type.");
                }

                if (!IsLocalReference(expression.Type, _mainAssembly, _mainModuleName, _attributeStore))                        // Types in our own assembly will not clash with anything because we use the type variable (or the 'exports' object in case of global methods).
                {
                    string moduleName = GetTypeModuleName(expression.Type, _attributeStore);
                    if (moduleName == null)                             // Imported modules will never clash with anything because we handle that elsewhere
                    {
                        var parts = sem.Name.Split('.');
                        data.Add(parts[0]);
                    }
                }

                return(expression);
            }
        public IList<JsStatement> Rewrite(IEnumerable<JsType> types, ICompilation compilation)
        {
            var netSystemType = compilation.FindType(KnownTypeCode.Type).GetDefinition();
            var systemType = new JsTypeReferenceExpression(netSystemType.ParentAssembly, _metadataImporter.GetTypeSemantics(netSystemType).Name);

            var result = new List<JsStatement>();

            var orderedTypes = types.OrderBy(t => t.Name).ToList();
            string currentNs = "";
            foreach (var t in orderedTypes) {
                try {
                    var globalMethodsPrefix = _metadataImporter.GetGlobalMethodsPrefix(t.CSharpTypeDefinition);

                    string ns = GetNamespace(t.Name);
                    if (ns != currentNs && globalMethodsPrefix == null) {
                        result.Add(new JsExpressionStatement(JsExpression.Invocation(JsExpression.MemberAccess(systemType, RegisterNamespace), JsExpression.String(ns))));
                        currentNs = ns;
                    }
                    result.Add(new JsComment("//////////////////////////////////////////////////////////////////////////////" + Environment.NewLine + " " + t.Name));

                    var typeRef = new JsTypeReferenceExpression(compilation.MainAssembly, t.Name);
                    if (t is JsClass) {
                        var c = (JsClass)t;
                        if (globalMethodsPrefix != null) {
                            if (globalMethodsPrefix == "") {
                                result.AddRange(c.StaticMethods.Select(m => new JsExpressionStatement(JsExpression.Binary(ExpressionNodeType.Assign, JsExpression.MemberAccess(JsExpression.Identifier("window"), m.Name), m.Definition))));
                            }
                            else {
                                result.AddRange(c.StaticMethods.Select(m => new JsExpressionStatement(JsExpression.Assign(MakeNestedMemberAccess(globalMethodsPrefix + "." + m.Name), m.Definition))));
                            }
                        }
                        else if (_metadataImporter.IsResources(t.CSharpTypeDefinition)) {
                            result.Add(GenerateResourcesClass(c));
                        }
                        else {
                            var unnamedCtor = c.UnnamedConstructor ?? JsExpression.FunctionDefinition(new string[0], JsBlockStatement.EmptyStatement);

                            if (c.TypeArgumentNames.Count == 0) {
                                result.Add(new JsExpressionStatement(JsExpression.Assign(typeRef, unnamedCtor)));
                                AddClassMembers(c, typeRef, compilation, result);
                            }
                            else {
                                var stmts = new List<JsStatement> { new JsVariableDeclarationStatement(InstantiatedGenericTypeVariableName, unnamedCtor) };
                                AddClassMembers(c, JsExpression.Identifier(InstantiatedGenericTypeVariableName), compilation, stmts);
                                stmts.AddRange(c.StaticInitStatements);
                                stmts.Add(new JsReturnStatement(JsExpression.Identifier(InstantiatedGenericTypeVariableName)));
                                result.Add(new JsExpressionStatement(JsExpression.Assign(typeRef, JsExpression.FunctionDefinition(c.TypeArgumentNames, new JsBlockStatement(stmts)))));
                                result.Add(new JsExpressionStatement(JsExpression.Invocation(JsExpression.MemberAccess(typeRef, c.ClassType == JsClass.ClassTypeEnum.Interface ? RegisterGenericInterface : RegisterGenericClass), JsExpression.String(c.Name), JsExpression.Number(c.TypeArgumentNames.Count))));
                            }
                        }
                    }
                    else if (t is JsEnum) {
                        var e = (JsEnum)t;
                        bool flags = GetAttributePositionalArgs(t.CSharpTypeDefinition, FlagsAttribute, "System") != null;
                        result.Add(new JsExpressionStatement(JsExpression.Assign(typeRef, JsExpression.FunctionDefinition(new string[0], JsBlockStatement.EmptyStatement))));
                        result.Add(new JsExpressionStatement(JsExpression.Assign(JsExpression.MemberAccess(typeRef, Prototype), JsExpression.ObjectLiteral(e.Values.Select(v => new JsObjectLiteralProperty(v.Name, (_metadataImporter.IsNamedValues(t.CSharpTypeDefinition) ? JsExpression.String(v.Name) : JsExpression.Number(v.Value))))))));
                        result.Add(new JsExpressionStatement(JsExpression.Invocation(JsExpression.MemberAccess(typeRef, RegisterEnum), JsExpression.String(t.Name), JsExpression.Boolean(flags))));
                    }
                }
                catch (Exception ex) {
                    _errorReporter.Region = t.CSharpTypeDefinition.Region;
                    _errorReporter.InternalError(ex, "Error formatting type " + t.CSharpTypeDefinition.FullName);
                }
            }

            var typesToRegister = orderedTypes.OfType<JsClass>()
                                        .Where(c =>    c.TypeArgumentNames.Count == 0
                                                    && _metadataImporter.GetGlobalMethodsPrefix(c.CSharpTypeDefinition) == null
                                                    && !_metadataImporter.IsResources(c.CSharpTypeDefinition))
                                        .ToList();

            result.AddRange(TopologicalSortTypesByInheritance(typesToRegister)
                            .Select(c => {
                                             try {
                                                 var typeRef = new JsTypeReferenceExpression(compilation.MainAssembly, c.Name);
                                                 if (c.ClassType == JsClass.ClassTypeEnum.Interface) {
                                                     return JsExpression.Invocation(JsExpression.MemberAccess(typeRef, RegisterInterface), JsExpression.String(c.Name), JsExpression.ArrayLiteral(c.ImplementedInterfaces));
                                                 }
                                                 else {
                                                     return CreateRegisterClassCall(JsExpression.String(c.Name), c.BaseClass, c.ImplementedInterfaces, typeRef);
                                                 }
                                             }
                                             catch (Exception ex) {
                                                 _errorReporter.Region = c.CSharpTypeDefinition.Region;
                                                 _errorReporter.InternalError(ex, "Error formatting type " + c.CSharpTypeDefinition.FullName);
                                                 return JsExpression.Number(0);
                                             }
                                         })
                            .Select(expr => new JsExpressionStatement(expr)));
            result.AddRange(orderedTypes.OfType<JsClass>().Where(c => c.TypeArgumentNames.Count == 0 && !_metadataImporter.IsResources(c.CSharpTypeDefinition)).SelectMany(t => t.StaticInitStatements));

            return result;
        }
        public IList <JsStatement> Rewrite(IEnumerable <JsType> types, ICompilation compilation)
        {
            var netSystemType = compilation.FindType(KnownTypeCode.Type).GetDefinition();
            var systemType    = new JsTypeReferenceExpression(netSystemType.ParentAssembly, _metadataImporter.GetTypeSemantics(netSystemType).Name);

            var result = new List <JsStatement>();

            var    orderedTypes = OrderByNamespace(types, t => t.Name).ToList();
            string currentNs    = "";

            foreach (var t in orderedTypes)
            {
                try {
                    var globalMethodsPrefix = _metadataImporter.GetGlobalMethodsPrefix(t.CSharpTypeDefinition);

                    string ns = GetNamespace(t.Name);
                    if (ns != currentNs && globalMethodsPrefix == null)
                    {
                        result.Add(new JsExpressionStatement(JsExpression.Invocation(JsExpression.MemberAccess(systemType, RegisterNamespace), JsExpression.String(ns))));
                        currentNs = ns;
                    }
                    result.Add(new JsComment("//////////////////////////////////////////////////////////////////////////////" + Environment.NewLine + " " + t.CSharpTypeDefinition.FullName));

                    var typeRef = new JsTypeReferenceExpression(compilation.MainAssembly, t.Name);
                    if (t is JsClass)
                    {
                        var c = (JsClass)t;
                        if (globalMethodsPrefix != null)
                        {
                            if (globalMethodsPrefix == "")
                            {
                                result.AddRange(c.StaticMethods.Select(m => new JsExpressionStatement(JsExpression.Binary(ExpressionNodeType.Assign, JsExpression.MemberAccess(JsExpression.Identifier("window"), m.Name), m.Definition))));
                            }
                            else
                            {
                                result.AddRange(c.StaticMethods.Select(m => new JsExpressionStatement(JsExpression.Assign(MakeNestedMemberAccess(globalMethodsPrefix + "." + m.Name), m.Definition))));
                            }
                        }
                        else if (_metadataImporter.IsResources(t.CSharpTypeDefinition))
                        {
                            result.Add(GenerateResourcesClass(c));
                        }
                        else
                        {
                            var unnamedCtor = c.UnnamedConstructor ?? JsExpression.FunctionDefinition(new string[0], JsBlockStatement.EmptyStatement);

                            if (c.TypeArgumentNames.Count == 0)
                            {
                                result.Add(new JsExpressionStatement(JsExpression.Assign(typeRef, unnamedCtor)));
                                AddClassMembers(c, typeRef, compilation, result);
                            }
                            else
                            {
                                var stmts = new List <JsStatement> {
                                    new JsVariableDeclarationStatement(InstantiatedGenericTypeVariableName, unnamedCtor)
                                };
                                AddClassMembers(c, JsExpression.Identifier(InstantiatedGenericTypeVariableName), compilation, stmts);
                                stmts.AddRange(c.StaticInitStatements);
                                stmts.Add(new JsReturnStatement(JsExpression.Identifier(InstantiatedGenericTypeVariableName)));
                                result.Add(new JsExpressionStatement(JsExpression.Assign(typeRef, JsExpression.FunctionDefinition(c.TypeArgumentNames, new JsBlockStatement(stmts)))));
                                result.Add(new JsExpressionStatement(JsExpression.Invocation(JsExpression.MemberAccess(typeRef, c.ClassType == JsClass.ClassTypeEnum.Interface ? RegisterGenericInterface : RegisterGenericClass), JsExpression.String(c.Name), JsExpression.Number(c.TypeArgumentNames.Count))));
                            }
                        }
                    }
                    else if (t is JsEnum)
                    {
                        var  e     = (JsEnum)t;
                        bool flags = GetAttributePositionalArgs(t.CSharpTypeDefinition, FlagsAttribute, "System") != null;
                        result.Add(new JsExpressionStatement(JsExpression.Assign(typeRef, JsExpression.FunctionDefinition(new string[0], JsBlockStatement.EmptyStatement))));
                        result.Add(new JsExpressionStatement(JsExpression.Assign(JsExpression.MemberAccess(typeRef, Prototype), JsExpression.ObjectLiteral(e.Values.Select(v => new JsObjectLiteralProperty(v.Name, (_metadataImporter.IsNamedValues(t.CSharpTypeDefinition) ? JsExpression.String(v.Name) : JsExpression.Number(v.Value))))))));
                        result.Add(new JsExpressionStatement(JsExpression.Invocation(JsExpression.MemberAccess(typeRef, RegisterEnum), JsExpression.String(t.Name), JsExpression.Boolean(flags))));
                    }
                }
                catch (Exception ex) {
                    _errorReporter.Region = t.CSharpTypeDefinition.Region;
                    _errorReporter.InternalError(ex, "Error formatting type " + t.CSharpTypeDefinition.FullName);
                }
            }

            var typesToRegister = orderedTypes.OfType <JsClass>()
                                  .Where(c => c.TypeArgumentNames.Count == 0 &&
                                         _metadataImporter.GetGlobalMethodsPrefix(c.CSharpTypeDefinition) == null &&
                                         !_metadataImporter.IsResources(c.CSharpTypeDefinition))
                                  .ToList();

            result.AddRange(TopologicalSortTypesByInheritance(typesToRegister)
                            .Select(c => {
                try {
                    var typeRef = new JsTypeReferenceExpression(compilation.MainAssembly, c.Name);
                    if (c.ClassType == JsClass.ClassTypeEnum.Interface)
                    {
                        return(JsExpression.Invocation(JsExpression.MemberAccess(typeRef, RegisterInterface), JsExpression.String(c.Name), JsExpression.ArrayLiteral(c.ImplementedInterfaces)));
                    }
                    else
                    {
                        return(CreateRegisterClassCall(JsExpression.String(c.Name), c.BaseClass, c.ImplementedInterfaces, typeRef));
                    }
                }
                catch (Exception ex) {
                    _errorReporter.Region = c.CSharpTypeDefinition.Region;
                    _errorReporter.InternalError(ex, "Error formatting type " + c.CSharpTypeDefinition.FullName);
                    return(JsExpression.Number(0));
                }
            })
                            .Select(expr => new JsExpressionStatement(expr)));
            result.AddRange(orderedTypes.OfType <JsClass>().Where(c => c.TypeArgumentNames.Count == 0 && !_metadataImporter.IsResources(c.CSharpTypeDefinition)).SelectMany(t => t.StaticInitStatements));

            return(result);
        }
Beispiel #11
0
 public override JsExpression VisitTypeReferenceExpression(JsTypeReferenceExpression expression, HashSet <ITypeDefinition> data)
 {
     data.Add(expression.Type);
     return(base.VisitTypeReferenceExpression(expression, data));
 }
 public virtual JsExpression VisitTypeReferenceExpression(JsTypeReferenceExpression expression, TData data)
 {
     return(expression);
 }