/// <summary> /// Replaces property getter with an encoder method /// </summary> internal static void AddEncoderMethodToPropertyGet(ref string jsCode, string propertyFullName, string encoderMethodName) { string encodingMethod = encoderMethodName + _JSMethodStart + _JSMethodEnd; int index = 0; TextRange position; do { // Find property position position = JSParser.FindPropertyGetterRange(ref jsCode, propertyFullName, index); // There is no more property if (position.Start == -1) { break; } // Next search index = position.Start; if (position.End > -1) { // Set next searching position index = position.Start + encodingMethod.Length; // first remove previous value, then add new method jsCode = jsCode.Remove(position.Start, position.End - position.Start); jsCode = jsCode.Insert(position.Start, encodingMethod); } }while (index != -1); }
/// <summary> /// Enclose method first parameter with an encoder method /// </summary> public static void AddEncoderMethodToMethodFirstParameter(ref string jsCode, string methodFullName, string encoderMethodName) { string encodingMethod = encoderMethodName + _JSMethodStart; int index = 0; TextRange position; do { // Find property position position = JSParser.FindMethodFirstParameterRange(ref jsCode, methodFullName, index); // There is no more property if (position.Start == -1) { break; } // Next search index = position.Start; if (position.End >= 0) { // Set next searching position index = position.End + encodingMethod.Length; // We should add method end then add method name jsCode = jsCode.Insert(position.End, _JSMethodEnd); jsCode = jsCode.Insert(position.Start, encodingMethod); } }while (index != -1); }
/// <summary> /// Replaces property getter with an encoder method /// </summary> internal static void ReplacePropertyGetCommand(ref string jsCode, string propertyFullName, string replacemntCommand) { int index = 0; TextRange position; do { // Find property position position = JSParser.FindPropertyGetterRange(ref jsCode, propertyFullName, index); // There is no more property if (position.Start == -1) { break; } // Next search index = position.Start; if (position.End > -1) { // Set next searching position index = position.Start + replacemntCommand.Length; // first remove previous value, then add new method jsCode = jsCode.Remove(position.Start, position.End - position.Start); jsCode = jsCode.Insert(position.Start, replacemntCommand); } }while (index != -1); }
/// <summary> /// Iterates over all the code in the JavaScript file to get a list of all the functions declared in that file. /// </summary> internal List <FunctionMapEntry> ParseSourceCode(StreamReader sourceCodeStreamReader) { if (sourceCodeStreamReader == null) { return(null); } string sourceCode = sourceCodeStreamReader.ReadToEnd(); sourceCodeStreamReader.Close(); JSParser jsParser = new JSParser(); // We just want the AST, don't let AjaxMin do any optimizations CodeSettings codeSettings = new CodeSettings { MinifyCode = false }; Block block = jsParser.Parse(sourceCode, codeSettings); FunctionFinderVisitor functionFinderVisitor = new FunctionFinderVisitor(); functionFinderVisitor.Visit(block); // Sort in descending order by start position functionFinderVisitor.FunctionMap.Sort((x, y) => y.StartSourcePosition.CompareTo(x.StartSourcePosition)); return(functionFinderVisitor.FunctionMap); }
public DirectivePrologue(string value, Context context, JSParser parser) : base(value, PrimitiveType.String, context, parser) { // this is a "use strict" directive if the source context is EXACTLY "use strict" // don't consider the quotes so it can be " or ' delimiters UseStrict = string.CompareOrdinal(Context.Code, 1, "use strict", 0, 10) == 0; }
public AspNetBlockNode(Context context, JSParser parser, string aspNetBlockText, bool blockTerminatedByExplicitSemicolon) : base(context, parser) { this.aspNetBlockText = aspNetBlockText; this.blockTerminatedByExplicitSemicolon = blockTerminatedByExplicitSemicolon; }
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; } }
/// <summary> /// Enclose property setter with an encoder method /// </summary> public static void ReplacePropertySetCommand(ref string jsCode, string propertyFullName, string replacemntCommand) { int index = 0; TextRange position; do { // Find property position position = JSParser.FindPropertySetterRange(ref jsCode, propertyFullName, index); // There is no more property if (position.Start == -1) { break; } // Next search index = position.Start; if (position.End > -1) { // Set next searching position index = position.Start + replacemntCommand.Length; // remove the original command jsCode = jsCode.Remove(position.Start, position.End - position.Start); // insert the new command jsCode = jsCode.Insert(position.Start, replacemntCommand); } }while (index != -1); }
internal static void EvalString(string inputString, ref mdr.DValue result, mdr.DFunction callerFunction = null, mdr.DObject callerContext = null, mdr.DObject thisArg = null) { var funcMetadata = JSParser.ParseScript(inputString).Expression.Metadata; var func = new mdr.DFunction(funcMetadata, null); var tempCallFrame = new mdr.CallFrame(); bool isDirectEval = callerContext != null; if (isDirectEval) { //function will behave as if it was the caller Debug.Assert(thisArg != null && callerFunction != null && callerContext != null, "Invalid situation! Direct eval call must have thisArg, callerFunction, callerContext set"); funcMetadata.Scope.IsProgram = false; funcMetadata.Scope.IsEvalFunction = true; funcMetadata.ParentFunction = (JSFunctionMetadata)callerFunction.Metadata; tempCallFrame.CallerContext = callerContext; tempCallFrame.This = thisArg; } else { //This will behave just like a program code tempCallFrame.CallerContext = mdr.Runtime.Instance.GlobalContext; tempCallFrame.This = (mdr.Runtime.Instance.GlobalContext); } //TODO: find a way to assign a name to this //funcMetadata.Name += "_eval"; //After we know the ParentFunction tempCallFrame.Function = func; tempCallFrame.Signature = mdr.DFunctionSignature.EmptySignature; func.Call(ref tempCallFrame); result.Set(ref tempCallFrame.Return); }
public static Expression CombineWithComma(IndexSpan span, JSParser parser, Expression operand1, Expression operand2) { var comma = new CommaOperator(parser.EncodeSpan(span)); List <Expression> res = new List <Expression>(); CommaOperator left = operand1 as CommaOperator; CommaOperator right = operand2 as CommaOperator; if (left != null) { res.AddRange(left.Expressions); } else { res.Add(operand1); } if (right != null) { res.AddRange(right.Expressions); } else { res.Add(operand2); } comma.Expressions = res.ToArray(); return(comma); }
/// <summary> /// Crunched JS string passed to it, returning crunched string. /// The Errors property will be set with any errors found during the minification process. /// </summary> /// <param name="source">source Javascript</param> /// <param name="codeSettings">code minification settings</param> /// <returns>minified Javascript</returns> public string MinifyJavaScript(string source, CodeSettings codeSettings) { // default is an empty string string crunched = string.Empty; // reset the errors builder m_errors = new List <string>(); // create the parser from the source string. // pass null for the assumed globals array JSParser parser = new JSParser(source); // hook the engine error event parser.CompilerError += OnJavaScriptError; try { // parse the input Block scriptBlock = parser.Parse(codeSettings); if (scriptBlock != null) { // we'll return the crunched code crunched = scriptBlock.ToCode(); } } catch (Exception e) { m_errors.Add(e.ToString()); } return(crunched); }
public object Eval(string scriptCode) { object ret = null; try { this.SetParent((ScriptObject)engine.globalScope.GetObject()); StackFrame sf = new StackFrame(this, null, new object[0], this); engine.Globals.ScopeStack.Push(sf); Context context = new Context(new DocumentContext("eval code", engine), ((IConvertible)scriptCode).ToString()); JSParser p = new JSParser(context); Block b = p.ParseEvalBody(); AST a = b.PartiallyEvaluate(); Completion result = (Completion)a.Evaluate(); ret = ((Completion)result).value; } finally { engine.Globals.ScopeStack.Pop(); } return(ret); }
public ParameterDeclaration(Context context, JSParser parser, string identifier, int position) { m_name = identifier; m_context = (context != null ? context : new Context(parser)); FunctionScope functionScope = parser != null ? parser.ScopeStack.Peek() as FunctionScope : null; if (functionScope != null) { if (!functionScope.NameTable.ContainsKey(m_name)) { m_field = functionScope.AddNewArgumentField(m_name); m_field.OriginalContext = m_context; m_field.Position = position; } } else { // parameters should only be under a function scope m_context.HandleError( JSError.DuplicateName, m_name, true ); } }
/// <summary> /// Iterates over all the code in the JavaScript file to get a list of all the functions declared in that file. /// </summary> internal IReadOnlyList <FunctionMapEntry> ParseSourceCode(StreamReader sourceCodeStreamReader, SourceMap sourceMap) { if (sourceCodeStreamReader == null) { return(null); } string sourceCode = sourceCodeStreamReader.ReadToEnd(); sourceCodeStreamReader.Close(); JSParser jsParser = new JSParser(); // We just want the AST, don't let AjaxMin do any optimizations CodeSettings codeSettings = new CodeSettings { MinifyCode = false }; Block block = jsParser.Parse(sourceCode, codeSettings); FunctionFinderVisitor functionFinderVisitor = new FunctionFinderVisitor(sourceMap); functionFinderVisitor.Visit(block); // Sort in descending order by start position. This allows the first result found in a linear search to be the "closest function to the [consumer's] source position". // // ATTN: It may be possible to do this with an ascending order sort, followed by a series of binary searches on rows & columns. // Our current profiles show the memory pressure being a bigger issue than the stack lookup, so I'm leaving this for now. functionFinderVisitor.FunctionMap.Sort((x, y) => y.StartSourcePosition.CompareTo(x.StartSourcePosition)); return(functionFinderVisitor.FunctionMap); }
public void ReplacementFallbacksJS() { // reuse the same parser object var parser = new JSParser(); // default should leave tokens intact var settings = new CodeSettings(); settings.ReplacementTokensApplyDefaults(new Dictionary <string, string> { { "my.token", "\"Now he's done it!\"" }, { "num_token", "123" }, { "my-json", "{\"a\": 1, \"b\": 2, \"c\": [ 1, 2, 3 ] }" }, }); settings.ReplacementFallbacks.Add("zero", "0"); var actual = Parse(parser, settings, "var a = %MissingToken:zero%;"); Assert.AreEqual("var a=0", actual); actual = Parse(parser, settings, "var b = %MissingToken:ack% + 0;"); Assert.AreEqual("var b=+0", actual); actual = Parse(parser, settings, "var c = %MissingToken:% + 0;"); Assert.AreEqual("var c=+0", actual); actual = Parse(parser, settings, "var d = %MissingToken:%;debugger;throw 'why?';"); Assert.AreEqual("var d=;throw\"why?\";", actual); }
private static JsAst ParseCode(string code) { var parser = new JSParser(code); var ast = parser.Parse(new CodeSettings()); return(ast); }
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 } }
/// <summary> /// Produces a code minifiction of JS assets by using NUglify Minifier /// </summary> /// <param name="assets">Set of JS assets</param> /// <returns>Set of JS assets with minified text content</returns> public override IList <IAsset> Minify(IList <IAsset> assets) { if (assets == null) { throw new ArgumentNullException( nameof(assets), string.Format(CoreStrings.Common_ArgumentIsNull, nameof(assets)) ); } if (assets.Count == 0) { return(assets); } var assetsToProcessing = assets.Where(a => a.IsScript && !a.Minified).ToList(); if (assetsToProcessing.Count == 0) { return(assets); } var jsParser = new JSParser { Settings = _jsParserConfiguration }; foreach (var asset in assetsToProcessing) { InnerMinify(asset, jsParser); } return(assets); }
public ParameterDeclaration(Context context, JSParser parser, string identifier) { m_name = identifier; m_context = (context != null ? context : new Context(parser)); FunctionScope functionScope = parser != null?parser.ScopeStack.Peek() as FunctionScope : null; if (functionScope != null) { if (functionScope.NameTable.ContainsKey(m_name)) { //Only happens if there is another parameter declarations with the same name m_context.HandleError(JSError.DuplicateName, m_name, true); } else { m_field = functionScope.AddNewArgumentField(m_name); m_field.OriginalContext = m_context; } } else { // parameters should only be under a function scope m_context.HandleError( JSError.DuplicateName, m_name, true ); } }
public string BuildBundleContent(Bundle bundle, BundleContext context, IEnumerable <BundleFile> files) { var content = new StringBuilder(); foreach (var fileInfo in files) { var contents = new StringBuilder(Read(fileInfo)); //a regular expersion to get catch blocks const string pattern = @"\bcatch\b(\s*)*\((?<errVariable>([^)])*)\)(\s*)*\{(?<blockContent>([^{}])*(\{([^}])*\})*([^}])*)\}"; var regex = new Regex(pattern); var matches = regex.Matches(contents.ToString()); for (var i = matches.Count - 1; i >= 0; i--) //from end to start! (to avoid loss index) { var match = matches[i]; //catch( errVariable ) var errVariable = match.Groups["errVariable"].ToString(); //start index of catch block var blockContentIndex = match.Groups["blockContent"].Index; var hasContent = match.Groups["blockContent"].Length > 2; contents.Insert(blockContentIndex, string.Format("if(customErrorLogging)customErrorLogging({0}){1}", errVariable, hasContent ? ";" : "")); } var parser = new JSParser(contents.ToString()); var bundleValue = parser.Parse(parser.Settings).ToCode(); content.Append(bundleValue); content.AppendLine(";"); } return(content.ToString()); }
public void SourceDirectiveJS() { string source; using (var reader = new StreamReader(Path.Combine(s_inputFolder, @"SourceDirective.js"))) { source = reader.ReadToEnd(); } var errors = new List <Tuple <string, int, int> > { new Tuple <string, int, int>("foo.js", 12, 3), new Tuple <string, int, int>("foo.js", 12, 7), new Tuple <string, int, int>("fargo.htm", 5, 44), new Tuple <string, int, int>("fargo.htm", 5, 48), }; var errorCount = 0; var parser = new JSParser(); parser.CompilerError += (sender, ea) => { Assert.IsTrue(errors.Count > errorCount, "too many errors"); Assert.AreEqual(errors[errorCount].Item1, ea.Error.File, "file path"); Assert.AreEqual(errors[errorCount].Item2, ea.Error.StartLine, "line number"); Assert.AreEqual(errors[errorCount].Item3, ea.Error.StartColumn, "column number"); ++errorCount; }; var block = parser.Parse(source, new CodeSettings()); Assert.AreEqual(errors.Count, errorCount, "errors found"); }
public static Expression CombineWithComma(IndexSpan span, JSParser parser, Expression operand1, Expression operand2) { var comma = new CommaOperator(parser.EncodeSpan(span)); List<Expression> res = new List<Expression>(); CommaOperator left = operand1 as CommaOperator; CommaOperator right = operand2 as CommaOperator; if (left != null) { res.AddRange(left.Expressions); } else { res.Add(operand1); } if (right != null) { res.AddRange(right.Expressions); } else { res.Add(operand2); } comma.Expressions = res.ToArray(); return comma; }
static Block ParseJavaScript(IAsset asset) { var source = asset.OpenStream().ReadToEnd(); var parser = new JSParser(source); return(parser.Parse(new CodeSettings())); }
public static void Prepare(IJsProjectEntry entry, TextReader sourceUnit) { var parser = new JSParser(sourceUnit.ReadToEnd()); var ast = parser.Parse(new CodeSettings()); entry.UpdateTree(ast, null); }
public void ReplacementStringsJS() { // reuse the same parser object var parser = new JSParser(); // default should leave tokens intact var settings = new CodeSettings(); var source = "var a = 'He said, %My.Token:foo%'"; var actual = Parse(parser, settings, source); Assert.AreEqual("var a=\"He said, %My.Token:foo%\"", actual); settings.ReplacementTokensApplyDefaults(new Dictionary <string, string> { { "my.token", "\"Now he's done it!\"" }, { "num_token", "123" }, { "my-json", "{\"a\": 1, \"b\": 2, \"c\": [ 1, 2, 3 ] }" }, }); settings.ReplacementFallbacks.Add("zero", "0"); actual = Parse(parser, settings, source); Assert.AreEqual("var a='He said, \"Now he\\'s done it!\"'", actual); actual = Parse(parser, settings, "var b = '%Num_Token%';"); Assert.AreEqual("var b=\"123\"", actual); actual = Parse(parser, settings, "var c = '%My-JSON%';"); Assert.AreEqual("var c='{\"a\": 1, \"b\": 2, \"c\": [ 1, 2, 3 ] }'", actual); }
/// <summary> /// Produces code minifiction of JS content by using /// Microsoft Ajax JS Minifier /// </summary> /// <param name="content">JS content</param> /// <param name="isInlineCode">Flag whether the content is inline code</param> /// <param name="encoding">Text encoding</param> /// <returns>Minification result</returns> public CodeMinificationResult Minify(string content, bool isInlineCode, Encoding encoding) { if (string.IsNullOrWhiteSpace(content)) { return(new CodeMinificationResult(string.Empty)); } string newContent; var errorReporter = new MsAjaxJsErrorReporter(); var errors = new List <MinificationErrorInfo>(); var warnings = new List <MinificationErrorInfo>(); var jsParserConfiguration = isInlineCode ? GetInlineJsParserSettings() : GetEmbeddedJsParserSettings(); var jsParser = new JSParser { Settings = jsParserConfiguration }; jsParser.CompilerError += errorReporter.JsMinificationErrorHandler; try { var stringBuilder = new StringBuilder(); using (var stringWriter = new StringWriter(stringBuilder, CultureInfo.InvariantCulture)) { Block block = jsParser.Parse(content); if (block != null) { if (jsParserConfiguration.Format == JavaScriptFormat.JSON) { // Use a JSON output visitor if (!JSONOutputVisitor.Apply(stringWriter, block, jsParserConfiguration)) { errors.Add(new MinificationErrorInfo(MsAjaxStrings.ErrorMessage_InvalidJsonOutput)); } } else { // Use normal output visitor OutputVisitor.Apply(stringWriter, block, jsParserConfiguration); } } } newContent = stringBuilder.ToString(); } finally { jsParser.CompilerError -= errorReporter.JsMinificationErrorHandler; } errors.AddRange(errorReporter.Errors); warnings.AddRange(errorReporter.Warnings); return(new CodeMinificationResult(newContent, errors, warnings)); }
private void InnerMinify(IAsset asset, JSParser jsParser) { string newContent; string assetUrl = asset.Url; var documentContext = new DocumentContext(asset.Content) { FileContext = assetUrl }; jsParser.CompilerError += ParserErrorHandler; try { var stringBuilder = new StringBuilder(); using (var stringWriter = new StringWriter(stringBuilder, CultureInfo.InvariantCulture)) { Block block = jsParser.Parse(documentContext); if (block != null) { if (_jsParserConfiguration.Format == JavaScriptFormat.JSON) { // Use a JSON output visitor if (!JSONOutputVisitor.Apply(stringWriter, block, _jsParserConfiguration)) { throw new MicrosoftAjaxParsingException(Strings.Minifiers_InvalidJsonOutput); } } else { // Use normal output visitor OutputVisitor.Apply(stringWriter, block, _jsParserConfiguration); } } } newContent = stringBuilder.ToString(); } catch (MicrosoftAjaxParsingException e) { throw new AssetMinificationException( string.Format(CoreStrings.Minifiers_MinificationSyntaxError, CODE_TYPE, assetUrl, MINIFIER_NAME, e.Message), e); } catch (Exception e) { throw new AssetMinificationException( string.Format(CoreStrings.Minifiers_MinificationFailed, CODE_TYPE, assetUrl, MINIFIER_NAME, e.Message), e); } finally { jsParser.CompilerError -= ParserErrorHandler; } asset.Content = newContent; asset.Minified = true; }
public Switch(Context context, JSParser parser, AstNode expression, AstNodeList cases) : base(context, parser) { m_expression = expression; m_cases = cases; if (m_expression != null) m_expression.Parent = this; if (m_cases != null) m_cases.Parent = this; }
public void TestAnonymousFunctionIsRecognizedAsFunction() { string code = "function () { }"; LookAheadLangParser textParser = LookAheadLangParser.CreateJavascriptParser(TestUtil.GetTextStream(code)); var parser = new JSParser(textParser); Assert.IsTrue(parser.NextIsFunction()); }
/// <summary> /// Create parser instance /// </summary> protected virtual JSParser CreateParser() { var parser = new JSParser(); parser.Settings.IgnoreAllErrors = true; parser.Settings.MinifyCode = true; return(parser); }
/// <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; SnLog.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); }
void Txt_parseClick(object sender, EventArgs e) { var engine = new JSParser(); var result = engine.Parse(txt_input.Text); if(result.IsSome) { var sb = new System.Text.StringBuilder(); foreach(var s in result.Value) s.ToString(sb, " ", ""); txt_output.Text = sb.ToString(); } else { txt_output.Text = "Can't parse input."; } }
public List<TokenResultItem> AnalyzeFile(string fileContents, string path, string name) { List<TokenResultItem> tris = new List<TokenResultItem>(); JSParser jsp = new JSParser(); if (jsp.ParseText(fileContents, name, path)) { foreach (TokenResultItem tri in jsp.Tokens) { tris.Add(tri); } } return tris; }
public ImportantComment(Context context, JSParser parser) : base(context, parser) { if (parser != null && parser.Settings.OutputMode == OutputMode.SingleLine) { // if we are in single-line mode, we want to replace all CRLF pairs // with just the LF to save output bytes. Comment = Context.Code.Replace("\r\n", "\n"); } else { // multi-line mode, just leave it as-is Comment = Context.Code; } }
public ImportantComment(Context context, JSParser parser) : base(context, parser) { if (parser != null && parser.Settings.OutputMode == OutputMode.SingleLine) { // if we are in single-line mode, we want to replace all CRLF pairs // with just the LF to save output bytes. And then add another LF at // the end so we start whatever follows the important comment on a new line m_comment = Context.Code.Replace("\r\n", "\n") + '\n'; } else { // multi-line mode, just leave it as-is m_comment = Context.Code; } }
public static Edit[] GetEditsAfterKeystroke(string code, int position, char ch, FormattingOptions options = null) { using (new DebugTimer("FormatKeyStroke")) { if (ch == ';' || ch == '}') { var ast = new JSParser(code).Parse(new CodeSettings() { AllowShebangLine = true }); var visitor = new RangeVisitor(ch, position, ast); ast.Walk(visitor); if (visitor.Span != default(IndexSpan)) { return FilterRange( visitor.Span.Start, visitor.Span.End, GetEdits(code, options, ast) ); } } return new Edit[0]; } }
public DebuggerNode(Context context, JSParser parser) : base(context, parser) { }
protected ConditionalCompilationStatement(Context context, JSParser parser) : base(context, parser) { }
private static JsAst ParseCode(string code) { var parser = new JSParser(code); var ast = parser.Parse(new CodeSettings()); return ast; }
private JsAst ParseOneFile(JsAst ast, JSParser parser) { if (parser != null) { try { ast = parser.Parse(_codeSettings); } catch (Exception e) { if (e.IsCriticalException()) { throw; } Debug.Assert(false, String.Format("Failure in JavaScript parser: {0}", e.ToString())); } } return ast; }
public bool CanExecuteText(string text) { var errorSink = new ReplErrorSink(text); var parser = new JSParser(text, errorSink); parser.Parse(new CodeSettings()); return !errorSink.Unterminated; }
public ThisLiteral(Context context, JSParser parser) : base(context, parser) { }
public GetterSetter(String identifier, bool isGetter, EncodedSpan span, JSParser parser) : base(identifier, span) { IsGetter = isGetter; }
private static List<Edit> GetEdits(string code, FormattingOptions options, bool onEnter = false) { var ast = new JSParser(code).Parse(new CodeSettings() { AllowShebangLine = true }); return GetEdits(code, options, ast, onEnter); }
private static string FormatCode(string code, int position, char ch, FormattingOptions options) { var ast = new JSParser(code).Parse(new CodeSettings()); var edits = Formatter.GetEditsAfterKeystroke(code, position, ch, options); return ApplyEdits(code, edits); }
public ParameterDeclaration(Context context, JSParser parser) : base(context, parser) { }
private static string FormatCode(string code, FormattingOptions options) { var ast = new JSParser(code).Parse(new CodeSettings()); var edits = Formatter.GetEditsForDocument(code, options); return ApplyEdits(code, edits); }
internal static TextSpan? GetDataTipSpan(IWpfTextView wpfTextView, TextSpan selection) { // Adjust the span to expression boundaries. var snapshot = wpfTextView.TextSnapshot; var start = LineAndColumnNumberToSnapshotPoint(snapshot, selection.iStartLine, selection.iStartIndex); var end = LineAndColumnNumberToSnapshotPoint(snapshot, selection.iEndLine, selection.iEndIndex); // If this is a zero-length span (which it usually is, unless there's selection), adjust it // to cover one char to the right, since an empty span at the beginning of the expression does // not count as belonging to that expression; if (start == end && start.Position != snapshot.Length) { end += 1; } var snapshotSpan = new SnapshotSpan(start, end); var trackingSpan = snapshot.CreateTrackingSpan(snapshotSpan.Span, SpanTrackingMode.EdgeExclusive); var rep = new ReverseExpressionParser(snapshot, wpfTextView.TextBuffer, trackingSpan); var exprSpan = rep.GetExpressionRange(forCompletion: false); if (exprSpan == null) { return null; } // Check whether this is an expression with side effects - if it does, we don't want to show a data tip for it. string text = exprSpan.Value.GetText(); var ast = new JSParser(text).Parse(new CodeSettings()); var sideEffectsDetectingVisitor = new SideEffectsDetectingVisitor(); ast.Walk(sideEffectsDetectingVisitor); if (sideEffectsDetectingVisitor.HasSideEffects) { return null; } TextSpan dataTipSpan; SnapshotPointToLineAndColumnNumber(exprSpan.Value.Start, out dataTipSpan.iStartLine, out dataTipSpan.iStartIndex); SnapshotPointToLineAndColumnNumber(exprSpan.Value.End, out dataTipSpan.iEndLine, out dataTipSpan.iEndIndex); return dataTipSpan; }
private static string FormatEnter(string code, int start, int end, FormattingOptions options) { var ast = new JSParser(code).Parse(new CodeSettings()); var edits = Formatter.GetEditsAfterEnter(code, start, end, options); return ApplyEdits(code, edits); }
public TypeOfNode(Context context, JSParser parser, AstNode operand) : base(context, parser, operand, JSToken.TypeOf) { }
public ConditionalCompilationElse(Context context, JSParser parser) : base(context, parser) { }
/// <summary> /// Returns a minified version of a given JavaScript. /// </summary> /// <param name="resource">JavaScript to be minified</param> /// <returns>Minified JavaScript</returns> public string Minify(string resource) { if (String.IsNullOrEmpty(resource)) { return resource; } // Reset error minificationError = null; canRecover = true; try { JSParser parser = new JSParser(resource); parser.CompilerError += parser_CompilerError; // Parse the resource Block scriptBlock = parser.Parse(null); // Get minified code if no error occurs or parser was able to recover if ((scriptBlock != null) && ((minificationError == null) || ((minificationError != null) && canRecover))) { resource = scriptBlock.ToCode(); } } catch (JScriptException ex) { minificationError = ex; canRecover = false; } if (minificationError != null) { if (LogMinifierParseError) { // Log exception to event log if allowed EventLogProvider.LogException("JS Compression", "MINIFYJS", minificationError); } if (!canRecover) { // Add error info in front of non-minified resource resource += "\r\n\r\n// Minification failed (line " + minificationError.Line.ToString() + "): " + minificationError.Message; } } return resource; }
public VoidNode(Context context, JSParser parser, AstNode operand) : base(context, parser, operand, JSToken.Void) { }
/// <summary> /// Returns a minified version of a given JavaScript. /// </summary> /// <param name="resource">JavaScript to be minified</param> /// <returns>Minified JavaScript</returns> public string Minify(string resource) { try { JSParser parser = new JSParser(resource, new string[0]); // Parse the resource string parsed = parser.Parse(null).ToCode(); if (!String.IsNullOrEmpty(parsed)) { resource = parsed; } } catch (Exception ex) { // Parse throws null reference exception on some ocasions EventLogProvider.LogException("JS Compression", "MINIFYJS", ex); resource = "// Minification failed: " + ex.Message + "\r\n\r\n" + resource; } return resource; }