Ejemplo n.º 1
0
        public static JsStatement Process(JsStatement statement)
        {
            var locals  = LocalVariableGatherer.Analyze(statement);
            var globals = ImplicitGlobalsGatherer.Analyze(statement, locals, reportGlobalsAsUsedInAllParentScopes: true);
            var renames = IdentifierRenameMapBuilder.Analyze(statement, locals, globals, GenerateName);

            return(IdentifierRenamer.Process(statement, renames));
        }
Ejemplo n.º 2
0
            public static IList <JsStatement> Process(IMetadataImporter metadataImporter, INamer namer, IAttributeStore attributeStore, ICompilation compilation, IList <JsStatement> statements)
            {
                var locals          = LocalVariableGatherer.Analyze(statements);
                var globals         = ImplicitGlobalsGatherer.Analyze(statements, locals, reportGlobalsAsUsedInAllParentScopes: false);
                var introducedNames = IntroducedNamesGatherer.Analyze(statements, metadataImporter, attributeStore, compilation.MainAssembly);
                var renameMap       = RenameMapBuilder.BuildMap(statements, locals, globals, introducedNames, namer);

                var usedSymbols = new HashSet <string>();

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

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

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

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

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

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

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

                return(body);
            }