Пример #1
0
 public JsCatchClause(string identifier, JsStatement body)
 {
     if (identifier == null) throw new ArgumentNullException("identifier");
     if (body == null) throw new ArgumentNullException("body");
     Identifier = identifier;
     Body = JsBlockStatement.MakeBlock(body);
 }
		public JsSwitchSection(IEnumerable<JsExpression> values, JsStatement body) {
			if (values == null) throw new ArgumentNullException("values");
			if (body == null) throw new ArgumentNullException("body");
			Values = values.AsReadOnly();
			if (Values.Count == 0) throw new ArgumentException("Values cannot be empty", "values");
			Body = JsStatement.EnsureBlock(body);
		}
Пример #3
0
        public void Add(JsStatement statement)
        {
            if (Substates.Any())
                throw new Exception("Cannot add a statement to a state that contains substates");

            InternalAdd(statement);
        }
Пример #4
0
		private bool IsNextStatementReachable(JsStatement current) {
			while (current is JsBlockStatement) {
				var block = (JsBlockStatement)current;
				if (block.Statements.Count == 0)
					return true;
				current = block.Statements[block.Statements.Count - 1];
			}
			var ifst = current as JsIfStatement;
			if (ifst != null) {
				return ifst.Else == null || ifst.Then.Statements.Count == 0 || ifst.Else.Statements.Count == 0 || IsNextStatementReachable(ifst.Then.Statements[ifst.Then.Statements.Count - 1]) || IsNextStatementReachable(ifst.Else.Statements[ifst.Else.Statements.Count - 1]);
			}

			return !(current is JsReturnStatement || current is JsGotoStatement || current is JsGotoStateStatement || current is JsThrowStatement || current is JsBreakStatement || current is JsContinueStatement);
		}
		public void CanAnalyzeStatements() {
			var asm = Common.CreateMockAssembly();
			var t1 = Common.CreateMockTypeDefinition("Type", asm);
			var t2 = Common.CreateMockTypeDefinition("Type", asm);
			var t3 = Common.CreateMockTypeDefinition("Type", asm);

			var ast = new JsStatement[] {
				new JsIfStatement(JsExpression.Member(new JsTypeReferenceExpression(t1), "X"), new JsBlockStatement(
					new JsExpressionStatement(JsExpression.Add(new JsTypeReferenceExpression(t2), new JsTypeReferenceExpression(t3)))
				),
				null),
				new JsExpressionStatement(JsExpression.Add(JsExpression.Number(1), new JsTypeReferenceExpression(t1))),
			};
			
			var refs = TypeReferenceFinder.Analyze(ast);
			Assert.That(refs, Has.Count.EqualTo(3));
			Assert.That(refs.Contains(t1));
			Assert.That(refs.Contains(t2));
			Assert.That(refs.Contains(t3));
		}
Пример #6
0
        public bool TryUnwrapJsniStatement(ExpressionStatementSyntax statement, out JsStatement result)
        {
            var expression = statement.Expression;
            if (expression is InvocationExpressionSyntax)
            {
                var jsniInvocation = (InvocationExpressionSyntax)expression;
                var symbolInfo = Context.Instance.Compilation.GetSemanticModel(expression.SyntaxTree).GetSymbolInfo(jsniInvocation);
                var method = (IMethodSymbol)symbolInfo.Symbol;
                var arguments = jsniInvocation.ArgumentList.Arguments.Select(x => (JsExpression)x.Accept(transformer)).ToArray();

                if (symbolInfo.Symbol == null)
                {
                    var classText = statement.FirstAncestorOrSelf<ClassDeclarationSyntax>().NormalizeWhitespace().ToString();
                    var diagnostics = transformer.model.GetDiagnostics().Select(x => x.ToString()).ToArray();
                }

                if (method.ReducedFrom != null && !method.ReducedFrom.Equals(method))
                {
                    method = method.ReducedFrom;
                    var target = (JsExpression)jsniInvocation.Expression.Accept(transformer);
                    var methodTarget = target is JsMemberReferenceExpression ? ((JsMemberReferenceExpression)target).Target : target;
                    arguments = new[] { methodTarget }.Concat(arguments).ToArray();
                }

                if (method != null && Equals(method.ContainingType, Context.Instance.JsniType))
                {
                    switch (method.Name)
                    {
                        case "forin":
                            var target = arguments[0];
                            var invocation = (JsInvocationExpression)arguments[1];
                            var function = (JsFunction)invocation.Arguments[1];
                            result = Js.ForIn(function.Parameters[0].Name, target).Body(function.Body);
                            return true;
                    }
                }
            }
            result = null;
            return false;
        }
Пример #7
0
            public static IList <JsStatement> Process(IMetadataImporter metadataImporter, INamer namer, ICompilation compilation, IList <JsStatement> statements)
            {
                var usedSymbols        = UsedSymbolsGatherer.Analyze(statements);
                var importer           = new ImportVisitor(metadataImporter, namer, compilation.MainAssembly, usedSymbols);
                var body               = statements.Select(s => importer.VisitStatement(s, null)).ToList();
                var moduleDependencies = importer._moduleAliases.Concat(MetadataUtils.GetAdditionalDependencies(compilation.MainAssembly));

                if (MetadataUtils.IsAsyncModule(compilation.MainAssembly))
                {
                    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);
            }
 public void ContinueStatementIsCorrectlyOutput()
 {
     AssertCorrect(JsStatement.Continue(), "continue;");
     AssertCorrect(JsStatement.Continue("someLabel"), "continue someLabel;");
 }
Пример #9
0
 public static JsFunctionDefinitionExpression FunctionDefinition(IEnumerable <string> parameterNames, JsStatement body, string name = null)
 {
     return(new JsFunctionDefinitionExpression(parameterNames, body, name));
 }
 public void BlockStatementsAreCorrectlyOutput()
 {
     AssertCorrect(JsStatement.Block(new JsStatement[0]), "{}");
     AssertCorrect(JsStatement.Block(new JsStatement[] { JsExpression.Identifier("X") }), "{X;}");
     AssertCorrect(JsStatement.Block(new JsStatement[] { JsExpression.Identifier("X"), JsExpression.Identifier("Y") }), "{X;Y;}");
 }
        public void ForStatementsAreCorrectlyOutput()
        {
            AssertCorrect(JsStatement.For(JsStatement.Var("i", JsExpression.Number(0)),
                                          JsExpression.Lesser(JsExpression.Identifier("i"), JsExpression.Number(10)),
                                          JsExpression.PostfixPlusPlus(JsExpression.Identifier("i")),
                                          JsStatement.EmptyBlock),
                          "for(var i=0;i<10;i++){}");

            AssertCorrect(JsStatement.For(JsExpression.Assign(JsExpression.Identifier("i"), JsExpression.Number(0)),
                                          JsExpression.Lesser(JsExpression.Identifier("i"), JsExpression.Number(10)),
                                          JsExpression.PostfixPlusPlus(JsExpression.Identifier("i")),
                                          JsStatement.EmptyBlock),
                          "for(i=0;i<10;i++){}");

            AssertCorrect(JsStatement.For(JsStatement.Var(JsStatement.Declaration("i", JsExpression.Number(0)), JsStatement.Declaration("j", JsExpression.Number(1))),
                                          JsExpression.Lesser(JsExpression.Identifier("i"), JsExpression.Number(10)),
                                          JsExpression.Comma(JsExpression.PostfixPlusPlus(JsExpression.Identifier("i")), JsExpression.PostfixPlusPlus(JsExpression.Identifier("j"))),
                                          JsStatement.EmptyBlock),
                          "for(var i=0,j=1;i<10;i++,j++){}");

            AssertCorrect(JsStatement.For(JsStatement.Empty, null, null, JsStatement.EmptyBlock), "for(;;){}");
        }
        private static JsExpression ConstructConstructorInfo(IMethod constructor, ICompilation compilation, IMetadataImporter metadataImporter, INamer namer, IRuntimeLibrary runtimeLibrary, IErrorReporter errorReporter, Func <IType, JsExpression> instantiateType, bool includeDeclaringType)
        {
            var properties = GetCommonMemberInfoProperties(constructor, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType);

            var sem = metadataImporter.GetConstructorSemantics(constructor);

            if (sem.Type == ConstructorScriptSemantics.ImplType.NotUsableFromScript)
            {
                errorReporter.Message(Messages._7200, constructor.FullName);
                return(JsExpression.Null);
            }
            properties.Add(new JsObjectLiteralProperty("type", JsExpression.Number((int)MemberTypes.Constructor)));
            properties.Add(new JsObjectLiteralProperty("params", JsExpression.ArrayLiteral(constructor.Parameters.Select(p => instantiateType(p.Type)))));
            if (sem.Type == ConstructorScriptSemantics.ImplType.NamedConstructor || sem.Type == ConstructorScriptSemantics.ImplType.StaticMethod)
            {
                properties.Add(new JsObjectLiteralProperty("sname", JsExpression.String(sem.Name)));
            }
            if (sem.Type == ConstructorScriptSemantics.ImplType.StaticMethod)
            {
                properties.Add(new JsObjectLiteralProperty("sm", JsExpression.True));
            }
            if ((sem.Type == ConstructorScriptSemantics.ImplType.UnnamedConstructor || sem.Type == ConstructorScriptSemantics.ImplType.NamedConstructor || sem.Type == ConstructorScriptSemantics.ImplType.StaticMethod) && sem.ExpandParams)
            {
                properties.Add(new JsObjectLiteralProperty("exp", JsExpression.True));
            }
            if (sem.Type == ConstructorScriptSemantics.ImplType.Json || sem.Type == ConstructorScriptSemantics.ImplType.InlineCode)
            {
                var usedNames  = new HashSet <string>();
                var parameters = new List <IVariable>();
                var variables  = new Dictionary <IVariable, VariableData>();
                IList <ResolveResult> constructorParameters = null;
                IList <ResolveResult> initializerStatements = null;
                if (sem.Type == ConstructorScriptSemantics.ImplType.Json && constructor.DeclaringType.Kind == TypeKind.Anonymous)
                {
                    initializerStatements = new List <ResolveResult>();
                    foreach (var p in constructor.DeclaringType.GetProperties())
                    {
                        string paramName = MakeCamelCase(p.Name);
                        string name      = namer.GetVariableName(paramName, usedNames);
                        usedNames.Add(name);
                        var variable = new SimpleVariable(p.ReturnType, paramName, DomRegion.Empty);
                        parameters.Add(variable);
                        variables.Add(variable, new VariableData(name, null, false));
                        initializerStatements.Add(new OperatorResolveResult(p.ReturnType, ExpressionType.Assign, new MemberResolveResult(new InitializedObjectResolveResult(constructor.DeclaringType), p), new LocalResolveResult(variable)));
                    }
                }
                else
                {
                    constructorParameters = new List <ResolveResult>();
                    foreach (var p in constructor.Parameters)
                    {
                        string name = namer.GetVariableName(p.Name, usedNames);
                        usedNames.Add(name);
                        var variable = new SimpleVariable(p.Type, p.Name, DomRegion.Empty);
                        parameters.Add(variable);
                        variables.Add(variable, new VariableData(name, null, false));
                        constructorParameters.Add(new LocalResolveResult(variable));
                    }
                }
                var compileResult = CompileConstructorInvocation(constructor, initializerStatements, constructor.DeclaringTypeDefinition, constructor, constructorParameters, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, variables, usedNames);
                var definition    = JsExpression.FunctionDefinition(parameters.Select(p => variables[p].Name), JsStatement.Block(compileResult.AdditionalStatements.Concat(new[] { JsStatement.Return(compileResult.Expression) })));
                properties.Add(new JsObjectLiteralProperty("def", definition));
            }
            return(JsExpression.ObjectLiteral(properties));
        }
        private void AssertCorrect(JsStatement stmt, string expected)
        {
            var actual = OutputFormatter.FormatMinified(stmt);

            Assert.That(actual.Replace("\r\n", "\n"), Is.EqualTo(expected.Replace("\r\n", "\n")));
        }
Пример #14
0
        public bool Compile(CompilerOptions options)
        {
            string intermediateAssemblyFile = Path.GetTempFileName(), intermediateDocFile = Path.GetTempFileName();
            var    actualOut = Console.Out;
            var    er = new ErrorReporterWrapper(_errorReporter, actualOut);

            try {
                Console.SetOut(new StringWriter());                     // I don't trust the third-party libs to not generate spurious random messages, so make sure that any of those messages are suppressed.

                var settings = MapSettings(options, intermediateAssemblyFile, intermediateDocFile, er);
                if (er.HasErrors)
                {
                    return(false);
                }

                if (!options.AlreadyCompiled)
                {
                    // Compile the assembly
                    var ctx = new CompilerContext(settings, new ConvertingReportPrinter(er));
                    var d   = new Mono.CSharp.Driver(ctx);
                    d.Compile();
                    if (er.HasErrors)
                    {
                        return(false);
                    }
                }

                var references = LoadReferences(settings.AssemblyReferences, er);
                if (references == null)
                {
                    return(false);
                }

                PreparedCompilation compilation = PreparedCompilation.CreateCompilation(settings.AssemblyName, options.SourceFiles.Select(f => new SimpleSourceFile(f, settings.Encoding)), references.Select(r => r.Item1), options.DefineConstants, LoadResources(options.EmbeddedResources));

                IMethod entryPoint = FindEntryPoint(options, er, compilation);

                var container = new WindsorContainer();
                foreach (var plugin in TopologicalSortPlugins(references).Reverse())
                {
                    RegisterPlugin(container, plugin);
                }

                var attributeStore = new AttributeStore(compilation.Compilation, er);

                container.Register(Component.For <IErrorReporter>().Instance(er),
                                   Component.For <CompilerOptions>().Instance(options),
                                   Component.For <IAttributeStore>().Instance(attributeStore),
                                   Component.For <ICompilation>().Instance(compilation.Compilation),
                                   Component.For <ICompiler>().ImplementedBy <Compiler.Compiler>()
                                   );

                InitializeAttributeStore(attributeStore, container, compilation.Compilation);

                container.Resolve <IMetadataImporter>().Prepare(compilation.Compilation.GetAllTypeDefinitions());

                var compiledTypes = container.Resolve <ICompiler>().Compile(compilation);

                foreach (var rewriter in container.ResolveAll <IJSTypeSystemRewriter>())
                {
                    compiledTypes = rewriter.Rewrite(compiledTypes);
                }

                var invoker = new OOPEmulatorInvoker(container.Resolve <IOOPEmulator>(), container.Resolve <IMetadataImporter>(), container.Resolve <IErrorReporter>());

                var js = invoker.Process(compiledTypes.ToList(), entryPoint);
                js = container.Resolve <ILinker>().Process(js);

                if (er.HasErrors)
                {
                    return(false);
                }

                string outputAssemblyPath = !string.IsNullOrEmpty(options.OutputAssemblyPath) ? options.OutputAssemblyPath : Path.ChangeExtension(options.SourceFiles[0], ".dll");
                string outputScriptPath   = !string.IsNullOrEmpty(options.OutputScriptPath)   ? options.OutputScriptPath   : Path.ChangeExtension(options.SourceFiles[0], ".js");

                if (!options.AlreadyCompiled)
                {
                    try {
                        File.Copy(intermediateAssemblyFile, outputAssemblyPath, true);
                    }
                    catch (IOException ex) {
                        er.Region = DomRegion.Empty;
                        er.Message(Messages._7950, ex.Message);
                        return(false);
                    }
                    if (!string.IsNullOrEmpty(options.DocumentationFile))
                    {
                        try {
                            File.Copy(intermediateDocFile, options.DocumentationFile, true);
                        }
                        catch (IOException ex) {
                            er.Region = DomRegion.Empty;
                            er.Message(Messages._7952, ex.Message);
                            return(false);
                        }
                    }
                }

                if (options.MinimizeScript)
                {
                    js = ((JsBlockStatement)Minifier.Process(JsStatement.Block(js))).Statements;
                }

                string script = options.MinimizeScript ? OutputFormatter.FormatMinified(js) : OutputFormatter.Format(js);
                try {
                    File.WriteAllText(outputScriptPath, script, settings.Encoding);
                }
                catch (IOException ex) {
                    er.Region = DomRegion.Empty;
                    er.Message(Messages._7951, ex.Message);
                    return(false);
                }
                return(true);
            }
            catch (Exception ex) {
                er.Region = DomRegion.Empty;
                er.InternalError(ex.ToString());
                return(false);
            }
            finally {
                if (!options.AlreadyCompiled)
                {
                    try { File.Delete(intermediateAssemblyFile); } catch {}
                    try { File.Delete(intermediateDocFile); } catch {}
                }
                if (actualOut != null)
                {
                    Console.SetOut(actualOut);
                }
            }
        }
        public static JsExpression ConstructAttribute(IAttribute attr, ITypeDefinition currentType, ICompilation compilation, IMetadataImporter metadataImporter, INamer namer, IRuntimeLibrary runtimeLibrary, IErrorReporter errorReporter)
        {
            errorReporter.Region = attr.Region;
            var initializerStatements = attr.NamedArguments.Select(a => new OperatorResolveResult(a.Key.ReturnType, ExpressionType.Assign, new MemberResolveResult(new InitializedObjectResolveResult(attr.AttributeType), a.Key), a.Value)).ToList <ResolveResult>();
            var constructorResult     = CompileConstructorInvocation(attr.Constructor, initializerStatements, currentType, null, attr.PositionalArguments, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, null, null);

            if (constructorResult.AdditionalStatements.Count > 0)
            {
                return(JsExpression.Invocation(JsExpression.FunctionDefinition(new string[0], JsStatement.Block(constructorResult.AdditionalStatements.Concat(new[] { JsStatement.Return(constructorResult.Expression) })))));
            }
            else
            {
                return(constructorResult.Expression);
            }
        }
Пример #16
0
        public override async Task <bool> WriteStatementAsync(ScriptScopeContext scope, JsStatement statement, CancellationToken token)
        {
            var page = scope.PageResult;

            if (statement is JsExpressionStatement exprStatement)
            {
                var value = exprStatement.Expression.Evaluate(scope);
                if (value != null && !ReferenceEquals(value, JsNull.Value) && value != StopExecution.Value && value != IgnoreResult.Value)
                {
                    var strValue = page.Format.EncodeValue(value);
                    if (!string.IsNullOrEmpty(strValue))
                    {
                        var bytes = strValue.ToUtf8Bytes();
                        await scope.OutputStream.WriteAsync(bytes, token).ConfigAwait();
                    }
                    await scope.OutputStream.WriteAsync(JsTokenUtils.NewLineUtf8, token).ConfigAwait();
                }
            }
            else if (statement is JsFilterExpressionStatement filterStatement)
            {
                await page.WritePageFragmentAsync(scope, filterStatement.FilterExpression, token).ConfigAwait();

                if (!page.Context.RemoveNewLineAfterFiltersNamed.Contains(filterStatement.FilterExpression.LastFilterName))
                {
                    await scope.OutputStream.WriteAsync(JsTokenUtils.NewLineUtf8, token).ConfigAwait();
                }
            }
            else if (statement is JsBlockStatement blockStatement)
            {
                await page.WriteStatementsAsync(scope, blockStatement.Statements, token).ConfigAwait();
            }
            else if (statement is JsPageBlockFragmentStatement pageFragmentStatement)
            {
                await page.WritePageFragmentAsync(scope, pageFragmentStatement.Block, token).ConfigAwait();
            }
            else
            {
                return(false);
            }

            return(true);
        }
Пример #17
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));
        }
Пример #18
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));
                }
            }
        }
Пример #19
0
 private JsExpression RewriteMethod(JsMethod method)
 {
     return(method.TypeParameterNames.Count == 0 ? method.Definition : JsExpression.FunctionDefinition(method.TypeParameterNames, JsStatement.Return(method.Definition)));
 }
        private static JsExpression ConstructMemberInfo(IMember m, ICompilation compilation, IMetadataImporter metadataImporter, INamer namer, IRuntimeLibrary runtimeLibrary, IErrorReporter errorReporter, Func <IType, JsExpression> instantiateType, bool includeDeclaringType, MethodScriptSemantics semanticsIfAccessor)
        {
            if (m is IMethod && ((IMethod)m).IsConstructor)
            {
                return(ConstructConstructorInfo((IMethod)m, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType));
            }

            var properties = GetCommonMemberInfoProperties(m, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType);

            if (m.IsStatic)
            {
                properties.Add(new JsObjectLiteralProperty("isStatic", JsExpression.True));
            }

            if (m is IMethod)
            {
                var method = (IMethod)m;
                var sem    = semanticsIfAccessor ?? metadataImporter.GetMethodSemantics(method);
                if (sem.Type != MethodScriptSemantics.ImplType.NormalMethod && sem.Type != MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument && sem.Type != MethodScriptSemantics.ImplType.InlineCode)
                {
                    errorReporter.Message(Messages._7201, m.FullName, "method");
                    return(JsExpression.Null);
                }
                if ((sem.Type == MethodScriptSemantics.ImplType.NormalMethod || sem.Type == MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument) && sem.ExpandParams)
                {
                    properties.Add(new JsObjectLiteralProperty("exp", JsExpression.True));
                }

                properties.Add(new JsObjectLiteralProperty("type", JsExpression.Number((int)MemberTypes.Method)));
                if (sem.Type == MethodScriptSemantics.ImplType.InlineCode)
                {
                    var usedNames  = new HashSet <string>();
                    var parameters = new List <IVariable>();
                    var variables  = new Dictionary <IVariable, VariableData>();
                    var arguments  = new List <ResolveResult>();
                    foreach (var p in method.Parameters)
                    {
                        string name = namer.GetVariableName(p.Name, usedNames);
                        usedNames.Add(name);
                        var variable = new SimpleVariable(p.Type, p.Name, DomRegion.Empty);
                        parameters.Add(variable);
                        variables.Add(variable, new VariableData(name, null, false));
                        arguments.Add(new LocalResolveResult(variable));
                    }
                    var tokens = InlineCodeMethodCompiler.Tokenize(method, sem.LiteralCode, _ => {});

                    var compileResult = Compile(CreateMethodInvocationResolveResult(method, method.IsStatic ? (ResolveResult) new TypeResolveResult(method.DeclaringType) : new ThisResolveResult(method.DeclaringType), arguments), method.DeclaringTypeDefinition, method, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, true, variables, usedNames);
                    var definition    = JsExpression.FunctionDefinition(parameters.Select(p => variables[p].Name), JsStatement.Block(compileResult.AdditionalStatements.Concat(new[] { JsStatement.Return(compileResult.Expression) })));

                    if (tokens.Any(t => t.Type == InlineCodeToken.TokenType.TypeParameter && t.OwnerType == SymbolKind.Method))
                    {
                        definition = JsExpression.FunctionDefinition(method.TypeParameters.Select(namer.GetTypeParameterName), JsStatement.Return(definition));
                        properties.Add(new JsObjectLiteralProperty("tpcount", JsExpression.Number(method.TypeParameters.Count)));
                    }
                    properties.Add(new JsObjectLiteralProperty("def", definition));
                }
                else
                {
                    if (IsJsGeneric(method, metadataImporter))
                    {
                        properties.Add(new JsObjectLiteralProperty("tpcount", JsExpression.Number(method.TypeParameters.Count)));
                    }
                    if (sem.Type == MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument)
                    {
                        properties.Add(new JsObjectLiteralProperty("sm", JsExpression.True));
                    }
                    properties.Add(new JsObjectLiteralProperty("sname", JsExpression.String(sem.Name)));
                }
                properties.Add(new JsObjectLiteralProperty("returnType", instantiateType(method.ReturnType)));
                properties.Add(new JsObjectLiteralProperty("params", JsExpression.ArrayLiteral(method.Parameters.Select(p => instantiateType(p.Type)))));
            }
            else if (m is IField)
            {
                var field = (IField)m;
                var sem   = metadataImporter.GetFieldSemantics(field);
                if (sem.Type != FieldScriptSemantics.ImplType.Field)
                {
                    errorReporter.Message(Messages._7201, m.FullName, "field");
                    return(JsExpression.Null);
                }
                properties.Add(new JsObjectLiteralProperty("type", JsExpression.Number((int)MemberTypes.Field)));
                properties.Add(new JsObjectLiteralProperty("returnType", instantiateType(field.ReturnType)));
                properties.Add(new JsObjectLiteralProperty("sname", JsExpression.String(sem.Name)));
            }
            else if (m is IProperty)
            {
                var prop = (IProperty)m;
                var sem  = metadataImporter.GetPropertySemantics(prop);
                properties.Add(new JsObjectLiteralProperty("type", JsExpression.Number((int)MemberTypes.Property)));
                properties.Add(new JsObjectLiteralProperty("returnType", instantiateType(prop.ReturnType)));
                if (prop.Parameters.Count > 0)
                {
                    properties.Add(new JsObjectLiteralProperty("params", JsExpression.ArrayLiteral(prop.Parameters.Select(p => instantiateType(p.Type)))));
                }

                switch (sem.Type)
                {
                case PropertyScriptSemantics.ImplType.GetAndSetMethods:
                    if (sem.GetMethod != null && sem.GetMethod.Type != MethodScriptSemantics.ImplType.NormalMethod && sem.GetMethod.Type != MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument && sem.GetMethod.Type != MethodScriptSemantics.ImplType.InlineCode)
                    {
                        errorReporter.Message(Messages._7202, m.FullName, "property", "getter");
                        return(JsExpression.Null);
                    }
                    if (sem.SetMethod != null && sem.SetMethod.Type != MethodScriptSemantics.ImplType.NormalMethod && sem.SetMethod.Type != MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument && sem.SetMethod.Type != MethodScriptSemantics.ImplType.InlineCode)
                    {
                        errorReporter.Message(Messages._7202, m.FullName, "property", "setter");
                        return(JsExpression.Null);
                    }
                    if (sem.GetMethod != null)
                    {
                        properties.Add(new JsObjectLiteralProperty("getter", ConstructMemberInfo(prop.Getter, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType, sem.GetMethod)));
                    }
                    if (sem.SetMethod != null)
                    {
                        properties.Add(new JsObjectLiteralProperty("setter", ConstructMemberInfo(prop.Setter, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType, sem.SetMethod)));
                    }
                    break;

                case PropertyScriptSemantics.ImplType.Field:
                    if (prop.CanGet)
                    {
                        properties.Add(new JsObjectLiteralProperty("getter", ConstructFieldPropertyAccessor(prop.Getter, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, sem.FieldName, instantiateType, isGetter: true, includeDeclaringType: includeDeclaringType)));
                    }
                    if (prop.CanSet)
                    {
                        properties.Add(new JsObjectLiteralProperty("setter", ConstructFieldPropertyAccessor(prop.Setter, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, sem.FieldName, instantiateType, isGetter: false, includeDeclaringType: includeDeclaringType)));
                    }
                    properties.Add(new JsObjectLiteralProperty("fname", JsExpression.String(sem.FieldName)));
                    break;

                default:
                    errorReporter.Message(Messages._7201, m.FullName, "property");
                    return(JsExpression.Null);
                }
            }
            else if (m is IEvent)
            {
                var evt = (IEvent)m;
                var sem = metadataImporter.GetEventSemantics(evt);
                if (sem.Type != EventScriptSemantics.ImplType.AddAndRemoveMethods)
                {
                    errorReporter.Message(Messages._7201, m.FullName, "event");
                    return(JsExpression.Null);
                }
                if (sem.AddMethod.Type != MethodScriptSemantics.ImplType.NormalMethod && sem.AddMethod.Type != MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument && sem.AddMethod.Type != MethodScriptSemantics.ImplType.InlineCode)
                {
                    errorReporter.Message(Messages._7202, m.FullName, "event", "add accessor");
                    return(JsExpression.Null);
                }
                if (sem.RemoveMethod.Type != MethodScriptSemantics.ImplType.NormalMethod && sem.RemoveMethod.Type != MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument && sem.RemoveMethod.Type != MethodScriptSemantics.ImplType.InlineCode)
                {
                    errorReporter.Message(Messages._7202, m.FullName, "event", "remove accessor");
                    return(JsExpression.Null);
                }

                properties.Add(new JsObjectLiteralProperty("type", JsExpression.Number((int)MemberTypes.Event)));
                properties.Add(new JsObjectLiteralProperty("adder", ConstructMemberInfo(evt.AddAccessor, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType, sem.AddMethod)));
                properties.Add(new JsObjectLiteralProperty("remover", ConstructMemberInfo(evt.RemoveAccessor, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType, sem.RemoveMethod)));
            }
            else
            {
                throw new ArgumentException("Invalid member " + m);
            }

            return(JsExpression.ObjectLiteral(properties));
        }
Пример #21
0
 public static JsLabeledStatement Label(string label, JsStatement statement)
 {
     return(new JsLabeledStatement(label, statement));
 }
Пример #22
0
 public static JsFunction Body(this JsFunction function, JsStatement statement)
 {
     function.Body.Aggregate(statement);
     return(function);
 }
 public void CommentsAreIgnored()
 {
     AssertCorrect(JsStatement.Comment("Line 1"), "");
 }
Пример #24
0
 public static JsIfStatement If(JsExpression condition, JsStatement ifTrue, JsStatement ifFalse = null)
 {
     return(new JsIfStatement(condition, ifTrue, ifFalse));
 }
 public void VariableDeclarationStatementsAreCorrectlyOutput()
 {
     AssertCorrect(JsStatement.Var(new[] { JsStatement.Declaration("i", null) }), "var i;");
     AssertCorrect(JsStatement.Var(new[] { JsStatement.Declaration("i", null), JsStatement.Declaration("j", null) }), "var i,j;");
     AssertCorrect(JsStatement.Var(new[] { JsStatement.Declaration("i", JsExpression.Number(0)) }), "var i=0;");
     AssertCorrect(JsStatement.Var(new[] { JsStatement.Declaration("i", JsExpression.Number(0)), JsStatement.Declaration("j", JsExpression.Number(1)) }), "var i=0,j=1;");
     AssertCorrect(JsStatement.Var(new[] { JsStatement.Declaration("i", JsExpression.Number(0)), JsStatement.Declaration("j", null) }), "var i=0,j;");
 }
Пример #26
0
 public static JsForInStatement Body(this JsForInStatement forInStatement, JsStatement statement)
 {
     forInStatement.Body = statement;
     return(forInStatement);
 }
 public void BreakStatementIsCorrectlyOutput()
 {
     AssertCorrect(JsStatement.Break(), "break;");
     AssertCorrect(JsStatement.Break("someLabel"), "break someLabel;");
 }
Пример #28
0
 public static JsForStatement Body(this JsForStatement forStatement, JsStatement body)
 {
     forStatement.Body = body;
     return(forStatement);
 }
 public void WhileStatementIsCorrectlyOutput()
 {
     AssertCorrect(JsStatement.While(JsExpression.True, JsStatement.Block(JsStatement.Var("x", JsExpression.Number(0)))),
                   "while(true){var x=0;}");
 }
Пример #30
0
 internal void InternalAdd(JsStatement statement)
 {
     ((List<JsStatement>)Statements).Add(statement);        
 }
Пример #31
0
 public JsLabeledStatement(string label, JsStatement statement)
 {
     Label     = label;
     Statement = statement;
 }
		private void AssertCorrect(JsStatement stmt, string expected) {
			var actual = OutputFormatter.Format(stmt);
			Assert.That(actual.Replace("\r\n", "\n"), Is.EqualTo(expected.Replace("\r\n", "\n")));
		}
Пример #33
0
		private JsBlockStatement ProcessAsyncMethod(JsBlockStatement statement, string stateMachineMethodName, string doFinallyBlocksVariableName, JsVariableDeclaration taskCompletionSource, Func<JsExpression, JsExpression> makeSetResult, Func<JsExpression, JsExpression> makeSetException, Func<JsExpression> getTask, Func<JsExpression, JsExpression, JsExpression> bindToContext) {
			_stateMachineMethodName = stateMachineMethodName;
			_doFinallyBlocksVariableName = doFinallyBlocksVariableName;
			_makeSetResult = taskCompletionSource != null ? makeSetResult : null;
			_needDoFinallyBlocksVariable = new HasAwaitInsideTryWithFinallyVisitor().Analyze(statement);

			var result = Process(statement, isIteratorBlock: false, isAsync: true);
			var hoistResult = VariableHoistingVisitor.Process(result);

			string catchVariable = _allocateTempVariable();

			JsStatement body;
			if (taskCompletionSource != null && (statement.Statements.Count == 0 || IsNextStatementReachable(statement.Statements[statement.Statements.Count - 1]))) {	// If we return the task, and if we risk falling out of the original method, we need to add a setResult call.
				body = JsStatement.Block(hoistResult.Item1.Statements.Concat(new JsStatement[] { makeSetResult(null) }));
			}
			else {
				body = hoistResult.Item1;
			}

			if (taskCompletionSource != null)
				body = JsStatement.Try(body, JsStatement.Catch(catchVariable, JsStatement.Block(makeSetException(JsExpression.Identifier(catchVariable)))), null);

			IEnumerable<JsVariableDeclaration> declarations = new[] { JsStatement.Declaration(_stateVariableName, JsExpression.Number(0)) };
			if (taskCompletionSource != null)
				declarations = declarations.Concat(new[] { taskCompletionSource });
			declarations = declarations.Concat(hoistResult.Item2.Select(v => JsStatement.Declaration(v, null)));

			if (_needDoFinallyBlocksVariable)
				body = JsStatement.Block(new[] { JsStatement.Var(_doFinallyBlocksVariableName, JsExpression.True) }.Concat(body is JsBlockStatement ? ((JsBlockStatement)body).Statements : (IEnumerable<JsStatement>)new[] { body }));

			var stateMachine = JsExpression.FunctionDefinition(new string[0], body);
			var boundStateMachine = UsesThisVisitor.Analyze(stateMachine.Body) ? bindToContext(stateMachine, JsExpression.This) : stateMachine;
			
			IEnumerable<JsStatement> stmts = new JsStatement[] { JsStatement.Var(declarations),
			                                                     JsStatement.Var(stateMachineMethodName, boundStateMachine),
			                                                     JsExpression.Invocation(JsExpression.Identifier(stateMachineMethodName))
			                                                   };
			if (taskCompletionSource != null)
				stmts = stmts.Concat(new[] { JsStatement.Return(getTask()) });

			return JsStatement.Block(stmts);
		}
Пример #34
0
 public object VisitStatement(JsStatement statement, bool addNewline)
 {
     return(statement.Accept(this, addNewline));
 }
Пример #35
0
 public static JsSwitchSection Statement(this JsSwitchSection section, JsStatement statement)
 {
     section.Statements.Add(statement);
     return(section);
 }
Пример #36
0
 public JsStatement Process(JsStatement stmt)
 {
     return(VisitStatement(stmt, null));
 }
 protected void AssertCorrect(JsStatement stmt, string expected)
 {
     var actual = OutputFormatter.Format(stmt, allowIntermediates: true);
     Assert.That(actual.Replace("\r\n", "\n"), Is.EqualTo(expected.Replace("\r\n", "\n")));
 }
Пример #38
0
 public static JsDoWhileStatement DoWhile(JsExpression condition, JsStatement statement)
 {
     return(new JsDoWhileStatement(condition, statement));
 }
Пример #39
0
 public static void If(this JsBlockStatement blockStatement, JsExpression condition, JsStatement ifTrue, JsStatement ifFalse = null)
 {
     blockStatement.Add(If(condition, ifTrue, ifFalse));
 }
Пример #40
0
 public void Add(JsStatement statement)
 {
     statements.Add(statement);
 }