public void ASpaceIsInsertedBetweenBinaryAndUnaryPlusAndMinusToAvoidParseAsIncrementOrDecrement() { AssertCorrect(JsExpression.Binary(ExpressionNodeType.Add, JsExpression.Identifier("a"), JsExpression.Unary(ExpressionNodeType.Positive, JsExpression.Identifier("b"))), "a+ +b"); AssertCorrect(JsExpression.Binary(ExpressionNodeType.Subtract, JsExpression.Identifier("a"), JsExpression.Unary(ExpressionNodeType.Negate, JsExpression.Identifier("b"))), "a- -b"); AssertCorrect(JsExpression.Binary(ExpressionNodeType.Subtract, JsExpression.Identifier("a"), JsExpression.Unary(ExpressionNodeType.Positive, JsExpression.Identifier("b"))), "a-+b"); AssertCorrect(JsExpression.Binary(ExpressionNodeType.Add, JsExpression.Identifier("a"), JsExpression.Unary(ExpressionNodeType.Negate, JsExpression.Identifier("b"))), "a+-b"); }
public void ClassWithSameNameAsVariable2() { var someAsm = Common.CreateMockAssembly(); var actual = Process(new JsStatement[] { JsStatement.Function("f", new[] { "x" }, JsStatement.Block( JsStatement.Var("y", JsExpression.Number(0)), JsExpression.FunctionDefinition(new string[0], JsExpression.Binary(ExpressionNodeType.Add, JsExpression.Member(new JsTypeReferenceExpression(Common.CreateMockTypeDefinition("x", someAsm)), "a"), JsExpression.Member(new JsTypeReferenceExpression(Common.CreateMockTypeDefinition("y", someAsm)), "a")) ), JsExpression.FunctionDefinition(new string[0], JsStatement.Block( JsStatement.Var("z", JsExpression.Binary(ExpressionNodeType.Add, JsExpression.Identifier("x"), JsExpression.Identifier("y"))) )) )) }, new[] { Common.CreateMockAssembly(), someAsm }, new MockMetadataImporter { GetTypeSemantics = t => TypeScriptSemantics.NormalType(t.Name) }, namer: new Namer()); AssertCorrect(actual, @"(function() { 'use strict'; var $asm = {}; function f(x1) { var y1 = 0; (function() { x.a + y.a; }); (function() { var z = x1 + y1; }); } })(); "); }
public void AssignmentIsNotParenthesizedInsideConstructorArgumentList() { AssertCorrect(JsExpression.ArrayLiteral( JsExpression.Binary(ExpressionNodeType.Assign, JsExpression.Number(1), JsExpression.Number(2) ) ), "[1 = 2]"); }
public void ExpressionNodeTypeIsNotParenthesizedWhenUsedAsBinaryArgument() { AssertCorrect(JsExpression.Binary(ExpressionNodeType.Multiply, JsExpression.Unary(ExpressionNodeType.Negate, JsExpression.Identifier("X") ), JsExpression.Number(1) ), "-X * 1"); }
public void IndexingWorks() { AssertCorrect(JsExpression.Binary(ExpressionNodeType.Index, JsExpression.Binary(ExpressionNodeType.Index, JsExpression.Number(1), JsExpression.Number(2) ), JsExpression.Number(3) ), "1[2][3]"); }
public void CommaIsNotParenthesizedInsideIndexing() { AssertCorrect(JsExpression.Binary(ExpressionNodeType.Index, JsExpression.Number(1), JsExpression.Comma( JsExpression.Number(2), JsExpression.Number(3) ) ), "1[2, 3]"); }
public void CommaIsParenthesizedAsAssignmentValue() { AssertCorrect(JsExpression.Binary(ExpressionNodeType.Assign, JsExpression.Number(1), JsExpression.Comma( JsExpression.Number(2), JsExpression.Number(3) ) ), "1 = (2, 3)"); }
public void ImportingImportedTypeFromOwnAssemblyWorks() { var asm = CreateMockAssembly(); var type = CreateMockType("MyImportedType", asm); var actual = Process(new JsStatement[] { new JsReturnStatement(JsExpression.Binary(ExpressionNodeType.Add, JsExpression.Member(new JsTypeReferenceExpression(type), "x"), JsExpression.Number(1))) }, mainAssembly: asm, metadata: new MockScriptSharpMetadataImporter { GetTypeSemantics = t => TypeScriptSemantics.NormalType("$" + t.FullName), IsImported = t => ReferenceEquals(t, type) }); AssertCorrect(actual, "return $MyImportedType.x + 1;\n"); }
public void ConditionalIsNotDoublyParenthesized() { AssertCorrect(JsExpression.Binary(ExpressionNodeType.Add, JsExpression.Number(1), JsExpression.Conditional( JsExpression.Number(2), JsExpression.Number(3), JsExpression.Number(4) ) ), "1 + (2 ? 3 : 4)"); }
public void Works() { var asm = new Mock <IAssembly>(MockBehavior.Strict); var actual = Process(new JsStatement[] { new JsExpressionStatement(new JsTypeReferenceExpression(asm.Object, "GlobalType")), new JsReturnStatement(JsExpression.Binary(ExpressionNodeType.Add, JsExpression.MemberAccess(new JsTypeReferenceExpression(asm.Object, "Global.NestedNamespace.InnerNamespace.Type"), "x"), JsExpression.Number(1))) }); Assert.That(actual.Replace("\r\n", "\n"), Is.EqualTo( @"GlobalType; return Global.NestedNamespace.InnerNamespace.Type.x + 1; ".Replace("\r\n", "\n"))); }
public void ImportingTypesFromGlobalNamespaceWorks() { var otherAsm = CreateMockAssembly(); var actual = Process(new JsStatement[] { new JsExpressionStatement(new JsTypeReferenceExpression(CreateMockType("GlobalType", otherAsm))), new JsReturnStatement(JsExpression.Binary(ExpressionNodeType.Add, JsExpression.Member(new JsTypeReferenceExpression(CreateMockType("Global.NestedNamespace.InnerNamespace.Type", otherAsm)), "x"), JsExpression.Number(1))) }, metadata: new MockScriptSharpMetadataImporter { GetTypeSemantics = t => TypeScriptSemantics.NormalType(string.Join(".", t.FullName.Split('.').Select(x => "$" + x))) }); AssertCorrect(actual, @"$GlobalType; return $Global.$NestedNamespace.$InnerNamespace.$Type.x + 1; "); }
public void BinaryOperatorsAreCorrectlyOutput() { var operators = new Dictionary <ExpressionNodeType, string> { { ExpressionNodeType.LogicalAnd, "{0}&&{1}" }, { ExpressionNodeType.LogicalOr, "{0}||{1}" }, { ExpressionNodeType.NotEqual, "{0}!={1}" }, { ExpressionNodeType.LesserOrEqual, "{0}<={1}" }, { ExpressionNodeType.GreaterOrEqual, "{0}>={1}" }, { ExpressionNodeType.Lesser, "{0}<{1}" }, { ExpressionNodeType.Greater, "{0}>{1}" }, { ExpressionNodeType.Equal, "{0}=={1}" }, { ExpressionNodeType.Subtract, "{0}-{1}" }, { ExpressionNodeType.Add, "{0}+{1}" }, { ExpressionNodeType.Modulo, "{0}%{1}" }, { ExpressionNodeType.Divide, "{0}/{1}" }, { ExpressionNodeType.Multiply, "{0}*{1}" }, { ExpressionNodeType.BitwiseAnd, "{0}&{1}" }, { ExpressionNodeType.BitwiseOr, "{0}|{1}" }, { ExpressionNodeType.BitwiseXor, "{0}^{1}" }, { ExpressionNodeType.Same, "{0}==={1}" }, { ExpressionNodeType.NotSame, "{0}!=={1}" }, { ExpressionNodeType.LeftShift, "{0}<<{1}" }, { ExpressionNodeType.RightShiftSigned, "{0}>>{1}" }, { ExpressionNodeType.RightShiftUnsigned, "{0}>>>{1}" }, { ExpressionNodeType.InstanceOf, "{0} instanceof {1}" }, { ExpressionNodeType.In, "{0} in {1}" }, { ExpressionNodeType.Index, "{0}[{1}]" }, { ExpressionNodeType.Assign, "{0}={1}" }, { ExpressionNodeType.MultiplyAssign, "{0}*={1}" }, { ExpressionNodeType.DivideAssign, "{0}/={1}" }, { ExpressionNodeType.ModuloAssign, "{0}%={1}" }, { ExpressionNodeType.AddAssign, "{0}+={1}" }, { ExpressionNodeType.SubtractAssign, "{0}-={1}" }, { ExpressionNodeType.LeftShiftAssign, "{0}<<={1}" }, { ExpressionNodeType.RightShiftSignedAssign, "{0}>>={1}" }, { ExpressionNodeType.RightShiftUnsignedAssign, "{0}>>>={1}" }, { ExpressionNodeType.BitwiseAndAssign, "{0}&={1}" }, { ExpressionNodeType.BitwiseOrAssign, "{0}|={1}" }, { ExpressionNodeType.BitwiseXorAssign, "{0}^={1}" }, }; for (var oper = ExpressionNodeType.BinaryFirst; oper <= ExpressionNodeType.BinaryLast; oper++) { Assert.That(operators.ContainsKey(oper), string.Format("Unexpected operator {0}", oper)); var expr = JsExpression.Binary(oper, JsExpression.Identifier("a"), JsExpression.Identifier("b")); AssertCorrect(expr, string.Format(operators[oper], "a", "b")); } }
public void ImportingImportedTypeFromOwnAssemblyWorks() { var asm = Common.CreateMockAssembly(); var type = Common.CreateMockTypeDefinition("MyImportedType", asm, attributes: new Expression <Func <Attribute> >[] { () => new ImportedAttribute() }); var actual = Process(new JsStatement[] { new JsReturnStatement(JsExpression.Binary(ExpressionNodeType.Add, JsExpression.Member(new JsTypeReferenceExpression(type), "x"), JsExpression.Number(1))) }, asm, metadata: new MockMetadataImporter { GetTypeSemantics = t => TypeScriptSemantics.NormalType("$" + t.FullName) }); AssertCorrect(actual, @"(function() { return $MyImportedType.x + 1; })(); "); }
public void ImportingTypeFromOwnAssemblyUsesTheTypeVariable() { var asm = Common.CreateMockAssembly(); var type = Common.CreateMockTypeDefinition("GlobalType", asm); var actual = Process(new JsStatement[] { new JsExpressionStatement(new JsTypeReferenceExpression(type)), new JsReturnStatement(JsExpression.Binary(ExpressionNodeType.Add, JsExpression.Member(new JsTypeReferenceExpression(Common.CreateMockTypeDefinition("Global.NestedNamespace.InnerNamespace.Type", asm)), "x"), JsExpression.Number(1))) }, asm, new MockMetadataImporter { GetTypeSemantics = t => TypeScriptSemantics.NormalType(string.Join(".", t.FullName.Split('.').Select(x => "$" + x))) }); AssertCorrect(actual, @"(function() { $$GlobalType; return $$Global_$NestedNamespace_$InnerNamespace_$Type.x + 1; })(); "); }
public void ImportingTypeFromOwnAssemblyButOtherModuleNameResultsInARequire() { var asm = Common.CreateMockAssembly(attributes: new Expression <Func <Attribute> >[] { () => new ModuleNameAttribute("main-module") }); var type = Common.CreateMockTypeDefinition("GlobalType", asm, attributes: new Expression <Func <Attribute> >[] { () => new ModuleNameAttribute("some-module") }); var actual = Process(new JsStatement[] { new JsExpressionStatement(new JsTypeReferenceExpression(type)), new JsReturnStatement(JsExpression.Binary(ExpressionNodeType.Add, JsExpression.Member(new JsTypeReferenceExpression(Common.CreateMockTypeDefinition("Global.NestedNamespace.InnerNamespace.Type", asm, attributes: new Expression <Func <Attribute> >[] { () => new ModuleNameAttribute("some-module") })), "x"), JsExpression.Number(1))) }, asm, metadata: new MockMetadataImporter { GetTypeSemantics = t => TypeScriptSemantics.NormalType(string.Join(".", t.FullName.Split('.').Select(x => "$" + x))) }); AssertCorrect(actual, @"require('mscorlib'); var $somemodule = require('some-module'); $somemodule.$GlobalType; return $somemodule.$Global.$NestedNamespace.$InnerNamespace.$Type.x + 1; "); }
public void MultiplicationInConditionalIsParenthesized() { AssertCorrect(JsExpression.Conditional( JsExpression.Binary(ExpressionNodeType.Multiply, JsExpression.Number(1), JsExpression.Number(2) ), JsExpression.Binary(ExpressionNodeType.Multiply, JsExpression.Number(3), JsExpression.Number(4) ), JsExpression.Binary(ExpressionNodeType.Multiply, JsExpression.Number(5), JsExpression.Number(6) ) ), "((1 * 2) ? (3 * 4) : (5 * 6))"); }
public void ImportingTypesFromGlobalNamespaceWorks() { var otherAsm = Common.CreateMockAssembly(); var actual = Process(new JsStatement[] { new JsTypeReferenceExpression(Common.CreateMockTypeDefinition("GlobalType", otherAsm)), JsStatement.Return(JsExpression.Binary(ExpressionNodeType.Add, JsExpression.Member(new JsTypeReferenceExpression(Common.CreateMockTypeDefinition("Global.NestedNamespace.InnerNamespace.Type", otherAsm)), "x"), JsExpression.Number(1))) }, new[] { Common.CreateMockAssembly(), otherAsm }, new MockMetadataImporter { GetTypeSemantics = t => TypeScriptSemantics.NormalType(string.Join(".", t.FullName.Split('.').Select(x => "$" + x))) }); AssertCorrect(actual, @"(function() { 'use strict'; var $asm = {}; $GlobalType; return $Global.$NestedNamespace.$InnerNamespace.$Type.x + 1; })(); "); }
public void LeftToRightAssociativityWorksForExpressionNodeTypes() { AssertCorrect(JsExpression.Binary(ExpressionNodeType.Subtract, JsExpression.Binary(ExpressionNodeType.Subtract, JsExpression.Number(1), JsExpression.Number(2) ), JsExpression.Number(3) ), "1 - 2 - 3"); AssertCorrect(JsExpression.Binary(ExpressionNodeType.Subtract, JsExpression.Number(1), JsExpression.Binary(ExpressionNodeType.Subtract, JsExpression.Number(2), JsExpression.Number(3) ) ), "1 - (2 - 3)"); }
public void AsyncModuleWithoutReferencesWorks() { var asm = Common.CreateMockAssembly(new Expression <Func <Attribute> >[] { () => new AsyncModuleAttribute() }); var type = Common.CreateMockTypeDefinition("GlobalType", asm); var actual = Process(new JsStatement[] { new JsExpressionStatement(new JsTypeReferenceExpression(type)), new JsExpressionStatement(JsExpression.Binary(ExpressionNodeType.Add, JsExpression.Member(new JsTypeReferenceExpression(Common.CreateMockTypeDefinition("Global.NestedNamespace.InnerNamespace.Type", asm)), "x"), JsExpression.Number(1))), }, asm, metadata: new MockMetadataImporter { GetTypeSemantics = t => TypeScriptSemantics.NormalType(string.Join(".", t.FullName.Split('.').Select(x => "$" + x))) }); AssertCorrect(actual, @"define(['mscorlib'], function($_) { var exports = {}; $$GlobalType; $$Global_$NestedNamespace_$InnerNamespace_$Type.x + 1; return exports; }); "); }
public void RightToLeftAssociativityWorksForExpressionNodeTypes() { AssertCorrect(JsExpression.Binary(ExpressionNodeType.Assign, JsExpression.Number(1), JsExpression.Binary(ExpressionNodeType.Assign, JsExpression.Number(2), JsExpression.Number(3) ) ), "1 = 2 = 3"); AssertCorrect(JsExpression.Binary(ExpressionNodeType.Assign, JsExpression.Binary(ExpressionNodeType.Assign, JsExpression.Number(1), JsExpression.Number(2) ), JsExpression.Number(3) ), "(1 = 2) = 3"); }
public void MultiplyHasHigherPrecedenceThanAdd() { AssertCorrect(JsExpression.Binary(ExpressionNodeType.Add, JsExpression.Binary(ExpressionNodeType.Multiply, JsExpression.Number(1), JsExpression.Number(2) ), JsExpression.Number(3) ), "1 * 2 + 3"); AssertCorrect(JsExpression.Binary(ExpressionNodeType.Add, JsExpression.Number(1), JsExpression.Binary(ExpressionNodeType.Multiply, JsExpression.Number(2), JsExpression.Number(3) ) ), "1 + 2 * 3"); AssertCorrect(JsExpression.Binary(ExpressionNodeType.Multiply, JsExpression.Binary(ExpressionNodeType.Add, JsExpression.Number(1), JsExpression.Number(2) ), JsExpression.Number(3) ), "(1 + 2) * 3"); AssertCorrect(JsExpression.Binary(ExpressionNodeType.Multiply, JsExpression.Number(1), JsExpression.Binary(ExpressionNodeType.Add, JsExpression.Number(2), JsExpression.Number(3) ) ), "1 * (2 + 3)"); }
public IList <JsStatement> Process(IEnumerable <JsType> types, IMethod entryPoint) { var result = new List <JsStatement>(); var orderedTypes = OrderByNamespace(types, t => _metadataImporter.GetTypeSemantics(t.CSharpTypeDefinition).Name).ToList(); foreach (var t in orderedTypes) { try { string name = _metadataImporter.GetTypeSemantics(t.CSharpTypeDefinition).Name; bool isGlobal = string.IsNullOrEmpty(name); bool isMixin = MetadataUtils.IsMixin(t.CSharpTypeDefinition); result.Add(new JsComment("//////////////////////////////////////////////////////////////////////////////" + Environment.NewLine + " " + t.CSharpTypeDefinition.FullName)); var typeRef = JsExpression.Identifier(_namer.GetTypeVariableName(name)); if (t is JsClass) { var c = (JsClass)t; if (isGlobal) { result.AddRange(c.StaticMethods.Select(m => new JsExpressionStatement(JsExpression.Binary(ExpressionNodeType.Assign, JsExpression.Member(GetRoot(t.CSharpTypeDefinition, exportNonPublic: true), m.Name), m.Definition)))); } else if (isMixin) { result.AddRange(c.StaticMethods.Select(m => new JsExpressionStatement(JsExpression.Assign(MakeNestedMemberAccess(name + "." + m.Name), m.Definition)))); } else if (MetadataUtils.IsResources(c.CSharpTypeDefinition)) { result.Add(GenerateResourcesClass(c)); } else { var unnamedCtor = c.UnnamedConstructor ?? JsExpression.FunctionDefinition(new string[0], JsBlockStatement.EmptyStatement); if (MetadataUtils.IsJsGeneric(c.CSharpTypeDefinition, _metadataImporter)) { var typeParameterNames = c.CSharpTypeDefinition.TypeParameters.Select(tp => _namer.GetTypeParameterName(tp)).ToList(); var stmts = new List <JsStatement> { new JsVariableDeclarationStatement(InstantiatedGenericTypeVariableName, unnamedCtor) }; AddClassMembers(c, JsExpression.Identifier(InstantiatedGenericTypeVariableName), stmts); stmts.AddRange(c.StaticInitStatements); stmts.Add(new JsReturnStatement(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]); } result.Add(new JsVariableDeclarationStatement(typeRef.Name, JsExpression.FunctionDefinition(typeParameterNames, new JsBlockStatement(stmts)))); var args = new List <JsExpression> { GetRoot(t.CSharpTypeDefinition), JsExpression.String(name), typeRef, JsExpression.Number(c.CSharpTypeDefinition.TypeParameterCount) }; var metadata = GetMetadataDescriptor(t.CSharpTypeDefinition, false); if (metadata != null) { args.Add(metadata); } result.Add(new JsExpressionStatement(JsExpression.Invocation(JsExpression.Member(_systemScript, c.CSharpTypeDefinition.Kind == TypeKind.Interface ? RegisterGenericInterface : RegisterGenericClass), args))); } else { result.Add(new JsVariableDeclarationStatement(typeRef.Name, unnamedCtor)); AddClassMembers(c, typeRef, result); } } } else if (t is JsEnum) { var e = (JsEnum)t; result.Add(new JsVariableDeclarationStatement(typeRef.Name, JsExpression.FunctionDefinition(new string[0], JsBlockStatement.EmptyStatement))); var values = new List <JsObjectLiteralProperty>(); foreach (var v in e.CSharpTypeDefinition.Fields) { if (v.ConstantValue != null) { var sem = _metadataImporter.GetFieldSemantics(v); if (sem.Type == FieldScriptSemantics.ImplType.Field) { values.Add(new JsObjectLiteralProperty(sem.Name, JsExpression.Number(Convert.ToDouble(v.ConstantValue)))); } else if (sem.Type == FieldScriptSemantics.ImplType.Constant && sem.Name != null) { values.Add(new JsObjectLiteralProperty(sem.Name, sem.Value is string?JsExpression.String((string)sem.Value) : JsExpression.Number(Convert.ToDouble(sem.Value)))); } } else { _errorReporter.Region = v.Region; _errorReporter.InternalError("Enum field " + v.FullName + " is not constant."); } } result.Add(new JsExpressionStatement(JsExpression.Assign(JsExpression.Member(typeRef, Prototype), JsExpression.ObjectLiteral(values)))); } } catch (Exception ex) { _errorReporter.Region = t.CSharpTypeDefinition.Region; _errorReporter.InternalError(ex, "Error formatting type " + t.CSharpTypeDefinition.FullName); } } var typesToRegister = orderedTypes .Where(c => !(c is JsClass && MetadataUtils.IsJsGeneric(c.CSharpTypeDefinition, _metadataImporter)) && !string.IsNullOrEmpty(_metadataImporter.GetTypeSemantics(c.CSharpTypeDefinition).Name) && (!MetadataUtils.IsResources(c.CSharpTypeDefinition) || c.CSharpTypeDefinition.IsExternallyVisible()) && // Resources classes are only exported if they are public. !MetadataUtils.IsMixin(c.CSharpTypeDefinition)) .ToList(); result.AddRange(TopologicalSortTypesByInheritance(typesToRegister) .Select(c => { try { string name = _metadataImporter.GetTypeSemantics(c.CSharpTypeDefinition).Name; if (c.CSharpTypeDefinition.Kind == TypeKind.Enum) { return(CreateRegisterEnumCall(c.CSharpTypeDefinition, name, JsExpression.Identifier(_namer.GetTypeVariableName(name)))); } if (MetadataUtils.IsResources(c.CSharpTypeDefinition)) { return(JsExpression.Invocation(JsExpression.Member(_systemScript, RegisterType), GetRoot(c.CSharpTypeDefinition), JsExpression.String(name), JsExpression.Identifier(_namer.GetTypeVariableName(name)))); } if (c.CSharpTypeDefinition.Kind == TypeKind.Interface) { return(CreateRegisterInterfaceCall(c.CSharpTypeDefinition, name, JsExpression.Identifier(_namer.GetTypeVariableName(name)), GetImplementedInterfaces(c.CSharpTypeDefinition.GetDefinition()).ToList())); } else { return(CreateRegisterClassCall(c.CSharpTypeDefinition, name, JsExpression.Identifier(_namer.GetTypeVariableName(name)), GetBaseClass(c.CSharpTypeDefinition), GetImplementedInterfaces(c.CSharpTypeDefinition).ToList())); } } 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(GetStaticInitializationOrder(orderedTypes.OfType <JsClass>(), 1) .Where(c => !MetadataUtils.IsJsGeneric(c.CSharpTypeDefinition, _metadataImporter) && !MetadataUtils.IsResources(c.CSharpTypeDefinition)) .SelectMany(c => c.StaticInitStatements)); if (entryPoint != null) { if (entryPoint.Parameters.Count > 0) { _errorReporter.Region = entryPoint.Region; _errorReporter.Message(Messages._7800, entryPoint.FullName); } else { var sem = _metadataImporter.GetMethodSemantics(entryPoint); if (sem.Type != MethodScriptSemantics.ImplType.NormalMethod) { _errorReporter.Region = entryPoint.Region; _errorReporter.Message(Messages._7801, entryPoint.FullName); } else { result.Add(new JsExpressionStatement(JsExpression.Invocation(JsExpression.Member(new JsTypeReferenceExpression(entryPoint.DeclaringTypeDefinition), sem.Name)))); } } } 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); }
public IList <JsStatement> Process(IEnumerable <JsType> types, IMethod entryPoint) { var result = new List <JsStatement>(); var orderedTypes = OrderByNamespace(types, t => _metadataImporter.GetTypeSemantics(t.CSharpTypeDefinition).Name).ToList(); var exportedNamespacesByRoot = new Dictionary <string, HashSet <string> >(); foreach (var t in orderedTypes) { try { string name = _metadataImporter.GetTypeSemantics(t.CSharpTypeDefinition).Name; bool isGlobal = string.IsNullOrEmpty(name); bool isMixin = MetadataUtils.IsMixin(t.CSharpTypeDefinition); bool export = t.CSharpTypeDefinition.IsExternallyVisible(); result.Add(JsStatement.Comment("//////////////////////////////////////////////////////////////////////////////" + Environment.NewLine + " " + t.CSharpTypeDefinition.FullName)); string typevarName = _namer.GetTypeVariableName(name); if (t is JsClass) { var c = (JsClass)t; if (isGlobal) { result.AddRange(c.StaticMethods.Select(m => (JsStatement)JsExpression.Binary(ExpressionNodeType.Assign, JsExpression.Member(JsExpression.Identifier(GetRoot(t.CSharpTypeDefinition)), m.Name), m.Definition))); export = false; } else if (isMixin) { result.AddRange(c.StaticMethods.Select(m => (JsStatement)JsExpression.Assign(MakeNestedMemberAccess(name + "." + m.Name), m.Definition))); export = false; } else if (MetadataUtils.IsResources(c.CSharpTypeDefinition)) { result.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]); } result.Add(JsStatement.Var(typevarName, JsExpression.FunctionDefinition(typeParameterNames, JsStatement.Block(stmts)))); result.Add(JsExpression.Assign(JsExpression.Member(JsExpression.Identifier(typevarName), TypeName), JsExpression.String(_metadataImporter.GetTypeSemantics(c.CSharpTypeDefinition).Name))); var args = new List <JsExpression> { JsExpression.Identifier(typevarName), JsExpression.Number(c.CSharpTypeDefinition.TypeParameterCount) }; result.Add(JsExpression.Invocation(JsExpression.Member(_systemScript, c.CSharpTypeDefinition.Kind == TypeKind.Interface ? InitGenericInterface : InitGenericClass), args)); } else { result.Add(JsStatement.Var(typevarName, unnamedCtor)); result.Add(JsExpression.Assign(JsExpression.Member(JsExpression.Identifier(typevarName), TypeName), JsExpression.String(_metadataImporter.GetTypeSemantics(c.CSharpTypeDefinition).Name))); AddClassMembers(c, typevarName, result); } } } else if (t is JsEnum) { var e = (JsEnum)t; result.Add(JsStatement.Var(typevarName, JsExpression.FunctionDefinition(new string[0], JsStatement.EmptyBlock))); result.Add(JsExpression.Assign(JsExpression.Member(JsExpression.Identifier(typevarName), TypeName), JsExpression.String(_metadataImporter.GetTypeSemantics(e.CSharpTypeDefinition).Name))); } if (export) { string root = GetRoot(t.CSharpTypeDefinition); var split = SplitIntoNamespaceAndName(name); if (!string.IsNullOrEmpty(split.Item1)) { HashSet <string> hs; if (!exportedNamespacesByRoot.TryGetValue(root, out hs)) { hs = exportedNamespacesByRoot[root] = new HashSet <string>(); } hs.Add(split.Item1); } result.Add(JsExpression.Assign(MakeNestedMemberAccess(name, JsExpression.Identifier(root)), JsExpression.Identifier(typevarName))); } } catch (Exception ex) { _errorReporter.Region = t.CSharpTypeDefinition.Region; _errorReporter.InternalError(ex, "Error formatting type " + t.CSharpTypeDefinition.FullName); } } result.InsertRange(0, exportedNamespacesByRoot.OrderBy(x => x.Key).SelectMany(x => CreateNamespaces(JsExpression.Identifier(x.Key), x.Value)).ToList()); var typesToRegister = TopologicalSortTypesByInheritance(orderedTypes) .Where(c => !(c is JsClass && MetadataUtils.IsJsGeneric(c.CSharpTypeDefinition, _metadataImporter)) && !string.IsNullOrEmpty(_metadataImporter.GetTypeSemantics(c.CSharpTypeDefinition).Name) && !MetadataUtils.IsResources(c.CSharpTypeDefinition) && !MetadataUtils.IsMixin(c.CSharpTypeDefinition)) .ToList(); foreach (var t in typesToRegister) { try { string name = _metadataImporter.GetTypeSemantics(t.CSharpTypeDefinition).Name; string typevarName = _namer.GetTypeVariableName(name); if (t.CSharpTypeDefinition.Kind == TypeKind.Enum) { result.Add(CreateInitEnumCall((JsEnum)t, typevarName)); } else { var c = (JsClass)t; if (t.CSharpTypeDefinition.Kind == TypeKind.Interface) { result.Add(CreateInitInterfaceCall(c, typevarName, GetImplementedInterfaces(t.CSharpTypeDefinition.GetDefinition()).ToList())); } else { result.Add(CreateInitClassCall(c, typevarName, GetBaseClass(t.CSharpTypeDefinition), GetImplementedInterfaces(t.CSharpTypeDefinition).ToList())); if (c.NamedConstructors.Count > 0) { result.Add(AssignNamedConstructorPrototypes(c, JsExpression.Identifier(_namer.GetTypeVariableName(name)))); } } } } catch (Exception ex) { _errorReporter.Region = t.CSharpTypeDefinition.Region; _errorReporter.InternalError(ex, "Error formatting type " + t.CSharpTypeDefinition.FullName); } } foreach (var t in orderedTypes) { var metadata = GetMetadataDescriptor(t.CSharpTypeDefinition, false); if (metadata != null) { result.Add(JsExpression.Invocation(JsExpression.Member(_systemScript, SetMetadata), JsExpression.Identifier(_namer.GetTypeVariableName(_metadataImporter.GetTypeSemantics(t.CSharpTypeDefinition).Name)), metadata)); } } result.AddRange(GetStaticInitializationOrder(orderedTypes.OfType <JsClass>(), 1) .Where(c => !MetadataUtils.IsJsGeneric(c.CSharpTypeDefinition, _metadataImporter) && !MetadataUtils.IsResources(c.CSharpTypeDefinition)) .SelectMany(c => c.StaticInitStatements)); if (entryPoint != null) { if (entryPoint.Parameters.Count > 0) { _errorReporter.Region = entryPoint.Region; _errorReporter.Message(Messages._7800, entryPoint.FullName); } else { var sem = _metadataImporter.GetMethodSemantics(entryPoint); if (sem.Type != MethodScriptSemantics.ImplType.NormalMethod) { _errorReporter.Region = entryPoint.Region; _errorReporter.Message(Messages._7801, entryPoint.FullName); } else { result.Add(JsExpression.Invocation(JsExpression.Member(new JsTypeReferenceExpression(entryPoint.DeclaringTypeDefinition), sem.Name))); } } } return(result); }
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)); }
public virtual JsExpression VisitBinaryExpression(JsBinaryExpression expression, TData data) { var left = VisitExpression(expression.Left, data); var right = VisitExpression(expression.Right, data); return(ReferenceEquals(left, expression.Left) && ReferenceEquals(right, expression.Right) ? expression : JsExpression.Binary(expression.NodeType, left, right)); }
public void TheOverallStructureIsCorrect() { AssertCorrect( @"//////////////////////////////////////////////////////////////////////////////// // OuterNamespace.InnerNamespace.SomeEnum var $OuterNamespace_InnerNamespace_SomeEnum = function() { }; $OuterNamespace_InnerNamespace_SomeEnum.prototype = { Value1: 1, Value2: 2, Value3: 3 }; {Type}.registerEnum(global, 'OuterNamespace.InnerNamespace.SomeEnum', $OuterNamespace_InnerNamespace_SomeEnum, false); //////////////////////////////////////////////////////////////////////////////// // OuterNamespace.InnerNamespace.SomeType var $OuterNamespace_InnerNamespace_SomeType = function() { this.a = 0; }; $OuterNamespace_InnerNamespace_SomeType.prototype = { method1: function(x) { return x; }, method2: function(x, y) { return x + y; } }; $OuterNamespace_InnerNamespace_SomeType.staticMethod = function() { }; //////////////////////////////////////////////////////////////////////////////// // OuterNamespace.InnerNamespace.SomeType2 var $OuterNamespace_InnerNamespace_SomeType2 = function() { this.b = 0; }; $OuterNamespace_InnerNamespace_SomeType2.prototype = { method1: function(x) { return x; } }; $OuterNamespace_InnerNamespace_SomeType2.otherStaticMethod = function() { }; //////////////////////////////////////////////////////////////////////////////// // OuterNamespace.InnerNamespace2.OtherInterface var $OuterNamespace_InnerNamespace2_OtherInterface = function() { }; $OuterNamespace_InnerNamespace2_OtherInterface.prototype = { interfaceMethod: null }; //////////////////////////////////////////////////////////////////////////////// // OuterNamespace.InnerNamespace2.OtherType var $OuterNamespace_InnerNamespace2_OtherType = function() { }; $OuterNamespace_InnerNamespace2_OtherType.prototype = { method1: function(x) { return x; } }; {Type}.registerClass(global, 'OuterNamespace.InnerNamespace.SomeType', $OuterNamespace_InnerNamespace_SomeType); {Type}.registerClass(global, 'OuterNamespace.InnerNamespace.SomeType2', $OuterNamespace_InnerNamespace_SomeType2); {Type}.registerInterface(global, 'OuterNamespace.InnerNamespace2.OtherInterface', $OuterNamespace_InnerNamespace2_OtherInterface, []); {Type}.registerClass(global, 'OuterNamespace.InnerNamespace2.OtherType', $OuterNamespace_InnerNamespace2_OtherType, {SomeType2}); y = 1; x = 1; ", new JsClass(CreateMockTypeDefinition("OuterNamespace.InnerNamespace.SomeType"), JsClass.ClassTypeEnum.Class, null, null, null) { UnnamedConstructor = JsExpression.FunctionDefinition(new string[0], new JsExpressionStatement(JsExpression.Assign(JsExpression.Member(JsExpression.This, "a"), JsExpression.Number(0)))), InstanceMethods = { new JsMethod(CreateMockMethod("Method1"), "method1", null, JsExpression.FunctionDefinition(new[] { "x" }, new JsReturnStatement(JsExpression.Identifier("x")))), new JsMethod(CreateMockMethod("Method2"), "method2", null, JsExpression.FunctionDefinition(new[] { "x", "y"}, new JsReturnStatement(JsExpression.Binary(ExpressionNodeType.Add, JsExpression.Identifier("x"), JsExpression.Identifier("y"))))) }, StaticMethods = { new JsMethod(CreateMockMethod("StaticMethod"), "staticMethod", null, JsExpression.FunctionDefinition(new string[0], JsBlockStatement.EmptyStatement)) }, }, new JsClass(CreateMockTypeDefinition("OuterNamespace.InnerNamespace.SomeType2"), JsClass.ClassTypeEnum.Class, null, null, null) { UnnamedConstructor = JsExpression.FunctionDefinition(new string[0], new JsExpressionStatement(JsExpression.Assign(JsExpression.Member(JsExpression.This, "b"), JsExpression.Number(0)))), InstanceMethods = { new JsMethod(CreateMockMethod("Method1"), "method1", null, JsExpression.FunctionDefinition(new[] { "x" }, new JsReturnStatement(JsExpression.Identifier("x")))) }, StaticMethods = { new JsMethod(CreateMockMethod("OtherStaticMethod"), "otherStaticMethod", null, JsExpression.FunctionDefinition(new string[0], JsBlockStatement.EmptyStatement)) }, StaticInitStatements = { new JsExpressionStatement(JsExpression.Assign(JsExpression.Identifier("y"), JsExpression.Number(1))) } }, new JsEnum(CreateMockTypeDefinition("OuterNamespace.InnerNamespace.SomeEnum"), new[] { new JsEnumValue("Value1", 1), new JsEnumValue("Value2", 2), new JsEnumValue("Value3", 3), }), new JsClass(CreateMockTypeDefinition("OuterNamespace.InnerNamespace2.OtherType"), JsClass.ClassTypeEnum.Class, null, new JsTypeReferenceExpression(Common.CreateMockType("OuterNamespace.InnerNamespace.SomeType2")), null) { UnnamedConstructor = JsExpression.FunctionDefinition(new string[0], JsBlockStatement.EmptyStatement), InstanceMethods = { new JsMethod(CreateMockMethod("Method1"), "method1", null, JsExpression.FunctionDefinition(new[] { "x" }, new JsReturnStatement(JsExpression.Identifier("x")))), }, StaticInitStatements = { new JsExpressionStatement(JsExpression.Assign(JsExpression.Identifier("x"), JsExpression.Number(1))) } }, new JsClass(CreateMockTypeDefinition("OuterNamespace.InnerNamespace2.OtherInterface"), JsClass.ClassTypeEnum.Interface, null, null, null) { UnnamedConstructor = JsExpression.FunctionDefinition(new string[0], JsBlockStatement.EmptyStatement), InstanceMethods = { new JsMethod(CreateMockMethod("InterfaceMethod"), "interfaceMethod", null, null) }, StaticInitStatements = {} }); }
public IList <JsStatement> Process(IEnumerable <JsType> types, ICompilation compilation, IMethod entryPoint) { var result = new List <JsStatement>(); var orderedTypes = OrderByNamespace(types, t => _metadataImporter.GetTypeSemantics(t.CSharpTypeDefinition).Name).ToList(); foreach (var t in orderedTypes) { try { string name = _metadataImporter.GetTypeSemantics(t.CSharpTypeDefinition).Name; bool isGlobal = string.IsNullOrEmpty(name); bool isMixin = _metadataImporter.IsMixin(t.CSharpTypeDefinition); result.Add(new JsComment("//////////////////////////////////////////////////////////////////////////////" + Environment.NewLine + " " + t.CSharpTypeDefinition.FullName)); var typeRef = JsExpression.Identifier(_namer.GetTypeVariableName(name)); if (t is JsClass) { var c = (JsClass)t; if (isGlobal) { result.AddRange(c.StaticMethods.Select(m => new JsExpressionStatement(JsExpression.Binary(ExpressionNodeType.Assign, JsExpression.Member(GetRoot(t.CSharpTypeDefinition, exportNonPublic: true), m.Name), m.Definition)))); } else if (isMixin) { result.AddRange(c.StaticMethods.Select(m => new JsExpressionStatement(JsExpression.Assign(MakeNestedMemberAccess(name + "." + 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 JsVariableDeclarationStatement(typeRef.Name, 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 JsVariableDeclarationStatement(typeRef.Name, JsExpression.FunctionDefinition(c.TypeArgumentNames, new JsBlockStatement(stmts)))); result.Add(new JsExpressionStatement(JsExpression.Invocation(JsExpression.Member(_systemType, c.ClassType == JsClass.ClassTypeEnum.Interface ? RegisterGenericInterface : RegisterGenericClass), GetRoot(t.CSharpTypeDefinition), JsExpression.String(name), typeRef, 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 JsVariableDeclarationStatement(typeRef.Name, JsExpression.FunctionDefinition(new string[0], JsBlockStatement.EmptyStatement))); result.Add(new JsExpressionStatement(JsExpression.Assign(JsExpression.Member(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.Member(_systemType, RegisterEnum), GetRoot(t.CSharpTypeDefinition), JsExpression.String(name), typeRef, 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 && !string.IsNullOrEmpty(_metadataImporter.GetTypeSemantics(c.CSharpTypeDefinition).Name) && (!_metadataImporter.IsResources(c.CSharpTypeDefinition) || Utils.IsPublic(c.CSharpTypeDefinition)) && // Resources classes are only exported if they are public. !_metadataImporter.IsMixin(c.CSharpTypeDefinition)) .ToList(); result.AddRange(TopologicalSortTypesByInheritance(typesToRegister) .Select(c => { try { string name = _metadataImporter.GetTypeSemantics(c.CSharpTypeDefinition).Name; if (_metadataImporter.IsResources(c.CSharpTypeDefinition)) { return(JsExpression.Invocation(JsExpression.Member(_systemType, RegisterType), GetRoot(c.CSharpTypeDefinition), JsExpression.String(name), JsExpression.Identifier(_namer.GetTypeVariableName(name)))); } if (c.ClassType == JsClass.ClassTypeEnum.Interface) { return(JsExpression.Invocation(JsExpression.Member(_systemType, RegisterInterface), GetRoot(c.CSharpTypeDefinition), JsExpression.String(name), JsExpression.Identifier(_namer.GetTypeVariableName(name)), JsExpression.ArrayLiteral(c.ImplementedInterfaces))); } else { return(CreateRegisterClassCall(GetRoot(c.CSharpTypeDefinition), name, JsExpression.Identifier(_namer.GetTypeVariableName(name)), c.BaseClass, c.ImplementedInterfaces)); } } 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)); if (entryPoint != null) { if (entryPoint.Parameters.Count > 0) { _errorReporter.Region = entryPoint.Region; _errorReporter.Message(7800, entryPoint.FullName); } else { var sem = _metadataImporter.GetMethodSemantics(entryPoint); if (sem.Type != MethodScriptSemantics.ImplType.NormalMethod) { _errorReporter.Region = entryPoint.Region; _errorReporter.Message(7801, entryPoint.FullName); } else { result.Add(new JsExpressionStatement(JsExpression.Invocation(JsExpression.Member(new JsTypeReferenceExpression(entryPoint.DeclaringTypeDefinition), sem.Name)))); } } } return(result); }