public static Dictionary <Function, HashSet <string> > Analyze(JsStatement statement)
            {
                var obj = new LocalVariableGatherer();

                obj.VisitStatement(statement, obj._result[new Function()] = new HashSet <string>());
                return(obj._result);
            }
        public static JsStatement Process(JsStatement statement)
        {
            var locals  = LocalVariableGatherer.Analyze(statement);
            var globals = ImplicitGlobalsGatherer.Analyze(statement, locals);

            return(IdentifierMinifierRewriter.Process(statement, locals, globals, GenerateName));
        }
Example #3
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));
        }
Example #4
0
        public void GatheringIsCorrect()
        {
            var stmt    = JsStatement.EnsureBlock(JavaScriptParser.Parser.ParseStatement(@"
{
	var a;
	(function() {
		var b;
		c;
		function d(p1, p2) {
			e;
			b;
			var f;
		}
		for (var g = 1;;) {
			for (var h in x) {
			}
			for (i in x) {
			}
		}
	});
	try {
	}
	catch (ex) {
		(function() {
			ex;
		});
	}
	j;
}"));
            var locals  = LocalVariableGatherer.Analyze(stmt);
            var globals = ImplicitGlobalsGatherer.Analyze(stmt, locals, reportGlobalsAsUsedInAllParentScopes: true);
            var result  = new OutputRewriter(locals, globals).Process(stmt);

            string actual = OutputFormatter.Format(result);

            Assert.That(actual.Replace("\r\n", "\n"), Is.EqualTo(
                            @"{
	locals(a);
	globals(c, d, e, i, j, x);
	var a;
	(function() {
		locals(b, g, h);
		globals(c, d, e, i, x);
		var b;
		c;
		function d(p1, p2) {
			locals(f, p1, p2);
			globals(e);
			e;
			b;
			var f;
		}
		for (var g = 1;;) {
			for (var h in x) {
			}
			for (i in x) {
			}
		}
	});
	try {
	}
	catch (ex) {
		(function() {
			locals();
			globals();
			ex;
		});
	}
	j;
}
".Replace("\r\n", "\n")));
        }
Example #5
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);
            }