public string Compile(IEnumerable<string> files) { var blocks = new List<Block>(); // ReSharper disable once LoopCanBeConvertedToQuery foreach (string file in files) { var parser = new JSParser(File.ReadAllText(file)) { FileContext = file }; var block = parser.Parse(new CodeSettings { EvalTreatment = EvalTreatment.MakeImmediateSafe, PreserveImportantComments = false }); if (block != null) { blocks.Add(block); } } Block fst = blocks[0]; for (int i = 1; i < blocks.Count; i++) { fst.Append(blocks[i]); } string sequenceCode = fst.ToCode(); var minifier = new Minifier(); string compiled = minifier.MinifyJavaScript( sequenceCode, new CodeSettings { EvalTreatment = EvalTreatment.MakeImmediateSafe, PreserveImportantComments = false }); return compiled; }
public SwitchCase(Context context, JSParser parser, AstNode caseValue, Block statements) : base(context, parser) { m_caseValue = caseValue; if (caseValue != null) { caseValue.Parent = this; } if (statements != null) { if (statements.Count == 1) { // if there is only one item in the block // and that one item IS a block... Block block = statements[0] as Block; if (block != null) { // then we can skip the intermediary block because all it // does is add braces around the block, which aren't needed statements = block; } } } m_statements = statements; if (statements != null) { statements.Parent = this; } }
protected UnaryOperator(Context context, JSParser parser, AstNode operand, JSToken operatorToken) : base(context, parser) { Operand = operand; OperatorToken = operatorToken; if (Operand != null) Operand.Parent = this; }
private ReorderScopeVisitor(JSParser parser) { // save the mods we care about m_moveVarStatements = parser.Settings.ReorderScopeDeclarations && parser.Settings.IsModificationAllowed(TreeModifications.CombineVarStatementsToTopOfScope); m_moveFunctionDecls = parser.Settings.ReorderScopeDeclarations && parser.Settings.IsModificationAllowed(TreeModifications.MoveFunctionToTopOfScope); m_combineAdjacentVars = parser.Settings.IsModificationAllowed(TreeModifications.CombineVarStatements); }
public ObjectLiteral(Context context, JSParser parser, ObjectLiteralField[] keys, AstNode[] values) : base(context, parser) { // the length of keys and values should be identical. // if either is null, or if the lengths don't match, we ignore both! if (keys == null || values == null || keys.Length != values.Length) { // allocate EMPTY arrays so we don't have to keep checking for nulls m_keys = new ObjectLiteralField[0]; m_values = new AstNode[0]; } else { // copy the arrays m_keys = keys; m_values = values; // make sure the parents are set properly foreach (AstNode astNode in keys) { astNode.Parent = this; } foreach (AstNode astNode in values) { astNode.Parent = this; } // because we don't ensure that the arrays are the same length, we'll need to // check for the minimum length every time we iterate over them } }
public ConstantWrapper(Object value, PrimitiveType primitiveType, Context context, JSParser parser) : base(context, parser) { PrimitiveType = primitiveType; // force numerics to be of type double Value = (primitiveType == PrimitiveType.Number ? System.Convert.ToDouble(value, CultureInfo.InvariantCulture) : value); }
string InsertModulePathIntoDefineCall(string moduleScript, string modulePath) { var parser = new JSParser(moduleScript); var sourceTree = parser.Parse(new CodeSettings()); sourceTree.Accept(new ModulePathInserter(modulePath)); return sourceTree.ToCode(); }
public DoWhile(Context context, JSParser parser, AstNode body, AstNode condition) : base(context, parser) { Body = ForceToBlock(body); Condition = condition; if (Body != null) Body.Parent = this; if (Condition != null) Condition.Parent = this; }
public Switch(Context context, JSParser parser, AstNode expression, AstNodeList cases) : base(context, parser) { Expression = expression; Cases = cases; if (Expression != null) Expression.Parent = this; if (Cases != null) Cases.Parent = this; }
public static bool JavaScriptContainsTopLevelVariable(string javaScriptSource, string variableName) { var parser = new JSParser(javaScriptSource); var tree = parser.Parse(new CodeSettings()); var finder = new TopLevelVariableFinder(variableName); tree.Accept(finder); return finder.found; }
internal FunctionScope(ActivationObject parent, bool isExpression, JSParser parser) : base(parent, parser) { if (isExpression) { // parent scopes automatically reference enclosed function expressions AddReference(Parent); } }
public Member(Context context, JSParser parser, AstNode rootObject, string memberName, Context idContext) : base(context, parser) { Name = memberName; NameContext = idContext; Root = rootObject; if (Root != null) Root.Parent = this; }
public WithNode(Context context, JSParser parser, AstNode obj, AstNode body) : base(context, parser) { m_withObject = obj; Body = ForceToBlock(body); if (m_withObject != null) { m_withObject.Parent = this; } if (Body != null) { Body.Parent = this; } }
public ConditionalCompilationElseIf(Context context, JSParser parser, AstNode condition) : base(context, parser) { Condition = condition; if (Condition != null) { Condition.Parent = this; } }
/// <summary> /// In addition to combining, also minifies the given Javascript. /// </summary> /// <returns>The combined and minified Javascript code for this bundle.</returns> public override string Combine() { var source = base.Combine(); var result = string.Empty; var errorLines = string.Empty; var hasError = false; try { var jsParser = new JSParser(source); var settings = new CodeSettings() { CombineDuplicateLiterals = true, OutputMode = OutputMode.SingleLine, RemoveUnneededCode = true, TermSemicolons = false, PreserveImportantComments = false, }; jsParser.CompilerError += delegate(object sender, JScriptExceptionEventArgs args) { // The 0 severity means errors. // We can safely ignore the rest. if (args.Error.Severity == 0) { hasError = true; errorLines += string.Format("\r\n/* Javascript parse error when processing the bundle.\r\nStart: line {0} column {1}, end: line {2} column {3}.\r\nError message: {4} */", args.Error.StartLine, args.Error.StartColumn, args.Error.EndLine, args.Error.EndColumn, args.Error.Message); } }; jsParser.UndefinedReference += delegate(object sender, UndefinedReferenceEventArgs args) { // Let's just ignore undefined references. }; var block = jsParser.Parse(settings); result = block.ToCode(); } catch (Exception exc) { hasError = true; Logger.WriteException(exc); } // If there were errors, use the non-minified version and append the errors to the bottom, // so that the portal builder can debug it. if (hasError) result = source + "\r\n\r\n" + errorLines; return result; }
public Conditional(Context context, JSParser parser, AstNode condition, AstNode trueExpression, AstNode falseExpression) : base(context, parser) { Condition = condition; TrueExpression = trueExpression; FalseExpression = falseExpression; if (condition != null) condition.Parent = this; if (trueExpression != null) trueExpression.Parent = this; if (falseExpression != null) falseExpression.Parent = this; }
public ForIn(Context context, JSParser parser, AstNode var, AstNode collection, AstNode body) : base(context, parser) { Variable = var; Collection = collection; Body = ForceToBlock(body); if (Body != null) Body.Parent = this; if (Variable != null) Variable.Parent = this; if (Collection != null) Collection.Parent = this; }
public IfNode(Context context, JSParser parser, AstNode condition, AstNode trueBranch, AstNode falseBranch) : base(context, parser) { Condition = condition; TrueBlock = ForceToBlock(trueBranch); FalseBlock = ForceToBlock(falseBranch); // make sure the parent element is set if (Condition != null) Condition.Parent = this; if (TrueBlock != null) TrueBlock.Parent = this; if (FalseBlock != null) FalseBlock.Parent = this; }
public static void Apply(Block block, JSParser parser) { // create a new instance of the visitor and apply it to the block var visitor = new ReorderScopeVisitor(parser); block.Accept(visitor); // get the first insertion point. Make sure that we skip over any comments and directive prologues. // we do NOT want to insert anything between the start of the scope and any directive prologues. int insertAt = 0; while (insertAt < block.Count && (block[insertAt].IsDirectivePrologue || block[insertAt] is ImportantComment)) { ++insertAt; } // first, we want to move all function declarations to the top of this block if (visitor.m_functionDeclarations != null) { foreach (var funcDecl in visitor.m_functionDeclarations) { insertAt = RelocateFunction(block, insertAt, funcDecl); } } // special case: if there is only one var statement in the entire scope, // then just leave it alone because we will only add bytes by moving it around, // or be byte-neutral at best (no initializers and not in a for-statement). if (visitor.m_varStatements != null && visitor.m_varStatements.Count > 1) { // then we want to move all variable declarations after to the top (after the functions) foreach (var varStatement in visitor.m_varStatements) { insertAt = RelocateVar(block, insertAt, varStatement); } } // then we want to do the same thing for all child functions (declarations AND other) if (visitor.m_functionDeclarations != null) { foreach (var funcDecl in visitor.m_functionDeclarations) { Apply(funcDecl.Body, parser); } } if (visitor.m_functionExpressions != null) { foreach (var funcExpr in visitor.m_functionExpressions) { Apply(funcExpr.Body, parser); } } }
public LabeledStatement(Context context, JSParser parser, string label, int nestCount, AstNode statement) : base(context, parser) { m_label = label; m_statement = statement; m_nestCount = nestCount; if (m_statement != null) { m_statement.Parent = this; } }
public ForNode(Context context, JSParser parser, AstNode initializer, AstNode condition, AstNode increment, AstNode body) : base(context, parser) { Initializer = initializer; Condition = condition; Incrementer = increment; Body = ForceToBlock(body); if (Body != null) Body.Parent = this; if (Incrementer != null) Incrementer.Parent = this; if (Condition != null) Condition.Parent = this; if (Initializer != null) Initializer.Parent = this; }
public TryNode(Context context, JSParser parser, AstNode tryBlock, string catchVarName, Context catchVarContext, AstNode catchBlock, AstNode finallyBlock) : base(context, parser) { CatchVarName = catchVarName; TryBlock = ForceToBlock(tryBlock); CatchBlock = ForceToBlock(catchBlock); FinallyBlock = ForceToBlock(finallyBlock); if (TryBlock != null) { TryBlock.Parent = this; } if (CatchBlock != null) { CatchBlock.Parent = this; } if (FinallyBlock != null) { FinallyBlock.Parent = this; } CatchVarContext = catchVarContext; }
public static string InsertModulePathIntoDefineCall(string moduleScript, string modulePath) { var inserter = new ModulePathInserter(); var parser = new JSParser(moduleScript); var sourceTree = parser.Parse(new CodeSettings { MinifyCode = false }); sourceTree.Accept(inserter); if (inserter.insertionIndex > 0) { return moduleScript.Insert(inserter.insertionIndex, "\"" + modulePath + "\","); } else { return moduleScript; } }
public CallNode(Context context, JSParser parser, AstNode function, AstNodeList args, bool inBrackets) : base(context, parser) { m_func = function; m_args = args; m_inBrackets = inBrackets; if (m_func != null) { m_func.Parent = this; } if (m_args != null) { m_args.Parent = this; } }
internal GlobalScope(JSParser parser) : base(null, parser) { // define the Global object's properties, and methods m_globalObject = new GlobalObject( GlobalObjectInstance.GlobalObject, new string[] { "Infinity", "NaN", "undefined", "window", "Image", "Math", "XMLHttpRequest", "DOMParser", "Worker" }, new string[] { "decodeURI", "decodeURIComponent", "encodeURI", "encodeURIComponent", "escape", "eval", "importScripts", "isNaN", "isFinite", "parseFloat", "parseInt", "unescape", "ActiveXObject", "Array", "Boolean", "Date", "Error", "Function", "Number", "Object", "RegExp", "String", "HTMLElement" } ); // define the Window object's properties, and methods m_windowObject = new GlobalObject( GlobalObjectInstance.WindowObject, new string[] { "applicationCache", "clientInformation", "clipboardData", "closed", "document", "event", "external", "frameElement", "frames", "history", "length", "localStorage", "location", "name", "navigator", "opener", "parent", "screen", "self", "sessionStorage", "status", "top" }, new string[] { "addEventListener", "alert", "attachEvent", "blur", "clearInterval", "clearTimeout", "close", "confirm", "createPopup", "detachEvent", "dispatchEvent", "execScript", "focus", "getComputedStyle", "getSelection", "moveBy", "moveTo", "navigate", "open", "postMessage", "prompt", "removeEventListener", "resizeBy", "resizeTo", "scroll", "scrollBy", "scrollTo", "setActive", "setInterval", "setTimeout", "showModalDialog", "showModelessDialog" } ); }
private bool m_useStrict; //= false; #endregion Fields #region Constructors protected ActivationObject(ActivationObject parent, JSParser parser) { m_parent = parent; m_nameTable = new Dictionary<string, JSVariableField>(); m_fieldTable = new List<JSVariableField>(); m_childScopes = new List<ActivationObject>(); Verboten = new Dictionary<JSVariableField, JSVariableField>(32); m_isKnownAtCompileTime = true; m_parser = parser; // if our parent is a scope.... if (parent != null) { // add us to the parent's list of child scopes parent.m_childScopes.Add(this); // if the parent is strict, so are we UseStrict = parent.UseStrict; } }
public override CombinedFileResult Parse(params string[] files) { var combined = CombineFiles(files); var settings = new CodeSettings { }; var parser = new JSParser(combined); var block = parser.Parse(settings); var result = block.ToCode(); var key = GenerateKey(result); return new CombinedFileResult { Content = result, Key = key, }; }
Block ParseJavaScript(string source) { this.ErrorList = new List<ContextError>(); JSParser jSParser = new JSParser(); jSParser.CompilerError += new EventHandler<ContextErrorEventArgs>(this.OnJavaScriptError); try { var block = jSParser.Parse(source, CodeSettings); return block; } catch (Exception ex) { this.ErrorList.Add(new ContextError { Severity = 0, //File = this.FileName, Message = ex.Message }); throw; } }
static void Main(string[] args) { var input = File.ReadAllText("input.js"); Console.WriteLine("--- Raw ---"); Console.WriteLine(input); Console.WriteLine("\r\n"); Console.WriteLine("--- Minified ---"); Console.WriteLine(new Minifier().MinifyJavaScript(input)); Console.WriteLine("\r\n"); Console.WriteLine("--- AST ---"); var parser = new JSParser(); parser.CompilerError += (_, ea) => Console.WriteLine(ea.Error); var functions = parser.Parse(input); var functionContext = parser.Parse("var functionContext = {};"); new ObjectLiteralVisitor(functions).Visit(functionContext); OutputVisitor.Apply(Console.Out, functionContext, new CodeSettings() { MinifyCode = false, OutputMode = OutputMode.MultipleLines }); }
protected Expression(Context context, JSParser parser) : base(context, parser) { }