diff --git a/src/NUglify.Tests/TestData/JS/Expected/Assignments/MultiVars.js b/src/NUglify.Tests/TestData/JS/Expected/Assignments/MultiVars.js index 41eae184..848129af 100644 --- a/src/NUglify.Tests/TestData/JS/Expected/Assignments/MultiVars.js +++ b/src/NUglify.Tests/TestData/JS/Expected/Assignments/MultiVars.js @@ -1 +1 @@ -var a="a",b="b",c,d="d",e,f,g;d&&(e="e");f="f",g="g" \ No newline at end of file +var a="a",b="b",c,d="d",e,f,g;d&&(e="e");f="f";g="g" \ No newline at end of file diff --git a/src/NUglify.Tests/TestData/JS/Expected/Bugs/Bug189.js b/src/NUglify.Tests/TestData/JS/Expected/Bugs/Bug189.js index ee5fcf3e..4097c06a 100644 --- a/src/NUglify.Tests/TestData/JS/Expected/Bugs/Bug189.js +++ b/src/NUglify.Tests/TestData/JS/Expected/Bugs/Bug189.js @@ -1,3 +1,4 @@ -let x = 1; // a comment +let x = 1 +// a comment // another comment -let y = 2; +let y = 2 diff --git a/src/NUglify.Tests/TestData/JS/Expected/Comments/EndWithImportantComment.js b/src/NUglify.Tests/TestData/JS/Expected/Comments/EndWithImportantComment.js index f3bde12f..25cb9e18 100644 --- a/src/NUglify.Tests/TestData/JS/Expected/Comments/EndWithImportantComment.js +++ b/src/NUglify.Tests/TestData/JS/Expected/Comments/EndWithImportantComment.js @@ -1,3 +1 @@ -/*! START OF BLOCK NOTICE -- we need to retain these comments in the output */ -var a=10; -/*! END OF BLOCK NOTICE */ +/*! START OF BLOCK NOTICE -- we need to retain these comments in the output */var a=10/*! END OF BLOCK NOTICE */ \ No newline at end of file diff --git a/src/NUglify.Tests/TestData/JS/Expected/Comments/ImportantComment.js b/src/NUglify.Tests/TestData/JS/Expected/Comments/ImportantComment.js index 784f1f62..4623444b 100644 --- a/src/NUglify.Tests/TestData/JS/Expected/Comments/ImportantComment.js +++ b/src/NUglify.Tests/TestData/JS/Expected/Comments/ImportantComment.js @@ -1,18 +1,6 @@ /*! * this is an example of an "important" comment * that we want to keep - */ -function foo(){ -/*! this too */ -}var a=12; -/*! - * this is another one, but it's between a couple var statements - */ -var b=13; -/** @preserve This is an important comment because of the @preserve token */ -/** + */function foo(){/*! this too */}var a=12/*! * this is another one, but it's between a couple var statements */;var b=13/** @preserve This is an important comment because of the @preserve token *//** ** @license And so is this, because of the @license token - */ -for(var ndx=0;ndx<10;++ndx) -/*! inside a block */ -; \ No newline at end of file + */;for(var ndx=0;ndx<10;++ndx)/*! inside a block */; \ No newline at end of file diff --git a/src/NUglify.Tests/TestData/JS/Expected/Comments/ImportantIgnore.js b/src/NUglify.Tests/TestData/JS/Expected/Comments/ImportantIgnore.js index 7e21def8..ee3fd3a0 100644 --- a/src/NUglify.Tests/TestData/JS/Expected/Comments/ImportantIgnore.js +++ b/src/NUglify.Tests/TestData/JS/Expected/Comments/ImportantIgnore.js @@ -1,7 +1,3 @@ -var p,i;if(location.hash)throw"hash exists";else alert("no hash");for(p in window)alert(p+" = "+window[p]);for(;;)if(window.timer)break;do{ -//! keep one -if(+new Date-1e6){ -//! keep two -break} -/*! keep three */ -}while(1);foo:for(i=0;i<100;++i)if(i%3)break foo \ No newline at end of file +var p,i;if(location.hash)throw"hash exists";else alert("no hash");for(p in window)alert(p+" = "+window[p]);for(;;)if(window.timer)break;do{//! keep one +if(+new Date-1e6){//! keep two +break}/*! keep three */}while(1);foo:for(i=0;i<100;++i)if(i%3)break foo \ No newline at end of file diff --git a/src/NUglify.Tests/TestData/JS/Expected/Comments/OnlyImportantComment.js b/src/NUglify.Tests/TestData/JS/Expected/Comments/OnlyImportantComment.js index 7a8bb275..13d7672a 100644 --- a/src/NUglify.Tests/TestData/JS/Expected/Comments/OnlyImportantComment.js +++ b/src/NUglify.Tests/TestData/JS/Expected/Comments/OnlyImportantComment.js @@ -1 +1 @@ -/*! Copyright 2010 by Contoso Corp. All rights reserved */ +/*! Copyright 2010 by Contoso Corp. All rights reserved */ \ No newline at end of file diff --git a/src/NUglify.Tests/TestData/JS/Expected/Comments/TwoImportantComments.js b/src/NUglify.Tests/TestData/JS/Expected/Comments/TwoImportantComments.js index b48a59f2..f3fabe83 100644 --- a/src/NUglify.Tests/TestData/JS/Expected/Comments/TwoImportantComments.js +++ b/src/NUglify.Tests/TestData/JS/Expected/Comments/TwoImportantComments.js @@ -1,3 +1 @@ -/*! First Important Comment */ -/*! Second Important Comment */ -var a=10 \ No newline at end of file +/*! First Important Comment *//*! Second Important Comment */var a=10 \ No newline at end of file diff --git a/src/NUglify.Tests/TestData/JS/Expected/Modules/ExportCombine.js b/src/NUglify.Tests/TestData/JS/Expected/Modules/ExportCombine.js index cfaeb0f0..2751ee14 100644 --- a/src/NUglify.Tests/TestData/JS/Expected/Modules/ExportCombine.js +++ b/src/NUglify.Tests/TestData/JS/Expected/Modules/ExportCombine.js @@ -1,3 +1,2 @@ //! start my implicit module -function n(n,t){return n+t}export function mul(n,t){return n*t}function t(n){return mul(n,n)}function i(n,t){if(t==0)return 1;for(var i=1;--t;)i=mul(i,n);return i}export const pi=3.1415927,negOne=-1;export var accumulator=0,foo="bar";export{n as sum,t as square,i as pow}; -//! end my implicit module +function n(n,t){return n+t}export function mul(n,t){return n*t}function t(n){return mul(n,n)}function i(n,t){if(t==0)return 1;for(var i=1;--t;)i=mul(i,n);return i}export const pi=3.1415927,negOne=-1;export var accumulator=0,foo="bar";export{n as sum,t as square,i as pow}//! end my implicit module diff --git a/src/NUglify.Tests/TestData/JS/Expected/Syntax/EmptyStatement.js b/src/NUglify.Tests/TestData/JS/Expected/Syntax/EmptyStatement.js index 6899b709..8d207989 100644 --- a/src/NUglify.Tests/TestData/JS/Expected/Syntax/EmptyStatement.js +++ b/src/NUglify.Tests/TestData/JS/Expected/Syntax/EmptyStatement.js @@ -1,3 +1 @@ -function foo(){for(var ndx=0;ndx<10;++ndx);}if(ndx) -/*! important */ -; \ No newline at end of file +function foo(){for(var ndx=0;ndx<10;++ndx);}if(ndx)/*! important */; \ No newline at end of file diff --git a/src/NUglify.Tests/TestData/JS/Input/Comments/ImportantComment.js b/src/NUglify.Tests/TestData/JS/Input/Comments/ImportantComment.js index 7e96be5a..8bd0c543 100644 --- a/src/NUglify.Tests/TestData/JS/Input/Comments/ImportantComment.js +++ b/src/NUglify.Tests/TestData/JS/Input/Comments/ImportantComment.js @@ -5,9 +5,7 @@ function foo() {/*! this too */} /* regular comment that will get stripped */ var a = 12; -/*! - * this is another one, but it's between a couple var statements - */ +/*! * this is another one, but it's between a couple var statements */ var b = 13; /** @preserve This is an important comment because of the @preserve token */ diff --git a/src/NUglify.Tests/TestData/JS/Input/Operators/Comma.js b/src/NUglify.Tests/TestData/JS/Input/Operators/Comma.js index 91afc860..583a7cbe 100644 --- a/src/NUglify.Tests/TestData/JS/Input/Operators/Comma.js +++ b/src/NUglify.Tests/TestData/JS/Input/Operators/Comma.js @@ -1,2 +1,20 @@ +function uxp_toggleElementVisibility_return(e) +{ + var o = e.style; + return 'none' === o.display + ? (o.display = '', 1) + : (o.display = 'none', 0); +} +// we need to keep those parens around the comma operator +// so that we continue to have two arguments, the second of +// which is a comma-operator expression. +var t = foo(bar, (ack,gag)); + +// the comma-operators in this var statement should be wrapped in parens to +// distinguish them from the var comma separators +var y = (t, foo, bar); + +// multiple commas, for op-prec sake +// because they are evaluated left-to-right, there should be no parens in this list z = a, b, c, document; diff --git a/src/NUglify/JavaScript/Comment.cs b/src/NUglify/JavaScript/Comment.cs index 6d444415..7f71a3c4 100644 --- a/src/NUglify/JavaScript/Comment.cs +++ b/src/NUglify/JavaScript/Comment.cs @@ -11,5 +11,6 @@ public class Comment { public SourceContext Context { get; set; } public bool IsImportant { get; set; } + public bool IsMultiLine { get; set; } } } \ No newline at end of file diff --git a/src/NUglify/JavaScript/JSParser.cs b/src/NUglify/JavaScript/JSParser.cs index 4e621a38..3179121d 100644 --- a/src/NUglify/JavaScript/JSParser.cs +++ b/src/NUglify/JavaScript/JSParser.cs @@ -749,10 +749,7 @@ AstNode ParseStatement(bool fSourceElement, bool skipComments = false) var comment = comments[0]; comments.RemoveAt(0); - if (!comment.IsImportant) - return new StandardComment(comment.Context); - - return new ImportantComment(comment.Context); + return new Syntax.Comment(comment.Context, comment.IsImportant, comment.IsMultiLine); } AstNode statement = null; @@ -3010,7 +3007,7 @@ private void ParseFunctionBody(BlockStatement body) }; } } - else if (!m_newModule && !(statement is ImportantComment || statement is StandardComment)) + else if (!m_newModule && !(statement is Syntax.Comment)) { // no longer considering constant wrappers possibleDirectivePrologue = false; @@ -5842,9 +5839,7 @@ void AppendComments(BlockStatement block) { // we have comments before the EOF. Add the comment(s) to the program. foreach (var comment in comments) - { - block.Append(comment.IsImportant ? new ImportantComment(comment.Context) : new StandardComment(comment.Context) as AstNode); - } + block.Append(new Syntax.Comment(comment.Context, comment.IsImportant, comment.IsMultiLine)); comments.Clear(); } @@ -5912,7 +5907,8 @@ private SourceContext ScanNextToken() comments.Add(new Comment { Context = nextToken.Clone(), - IsImportant = important + IsImportant = important, + IsMultiLine = nextToken.Is(JSToken.MultipleLineComment) }); } } diff --git a/src/NUglify/JavaScript/Syntax/ClassNode.cs b/src/NUglify/JavaScript/Syntax/ClassNode.cs index 932cc29a..08c59d99 100644 --- a/src/NUglify/JavaScript/Syntax/ClassNode.cs +++ b/src/NUglify/JavaScript/Syntax/ClassNode.cs @@ -99,10 +99,7 @@ public ClassNode(SourceContext context) public override void Accept(IVisitor visitor) { - if (visitor != null) - { - visitor.Visit(this); - } + visitor?.Visit(this); } public override IEnumerable Children diff --git a/src/NUglify/JavaScript/Syntax/Comment.cs b/src/NUglify/JavaScript/Syntax/Comment.cs new file mode 100644 index 00000000..233ab5f1 --- /dev/null +++ b/src/NUglify/JavaScript/Syntax/Comment.cs @@ -0,0 +1,27 @@ +using NUglify.JavaScript.Visitors; + +namespace NUglify.JavaScript.Syntax +{ + public class Comment : AstNode + { + // Indicates if this was a multiline comment (by syntax only, doesn't necessarily contain a \n) + public bool IsMultiLine { get; set; } + public bool IsImportant { get; set; } + public string Value { get; set; } + + // this is for determining if a node in a block AFTER a return/break/continue should be removed. We don't want to remove an important comment, so SAY it's a declaration. + public override bool IsDeclaration => true; + + public Comment(SourceContext context, bool isImportant, bool isMultiLine) : base(context) + { + IsImportant = isImportant; + IsMultiLine = isMultiLine; + Value = Context.Code; + } + + public override void Accept(IVisitor visitor) + { + visitor?.Visit(this); + } + } +} diff --git a/src/NUglify/JavaScript/Syntax/ImportantComment.cs b/src/NUglify/JavaScript/Syntax/ImportantComment.cs deleted file mode 100644 index d71df97b..00000000 --- a/src/NUglify/JavaScript/Syntax/ImportantComment.cs +++ /dev/null @@ -1,22 +0,0 @@ -using NUglify.JavaScript.Visitors; - -namespace NUglify.JavaScript.Syntax -{ - public class ImportantComment : AstNode - { - public string Comment { get; set; } - - // this is for determining if a node in a block AFTER a return/break/continue should be removed. We don't want to remove an important comment, so SAY it's a declaration. - public override bool IsDeclaration => true; - - public ImportantComment(SourceContext context) : base(context) - { - Comment = Context.Code; - } - - public override void Accept(IVisitor visitor) - { - visitor?.Visit(this); - } - } -} diff --git a/src/NUglify/JavaScript/Syntax/StandardComment.cs b/src/NUglify/JavaScript/Syntax/StandardComment.cs deleted file mode 100644 index cb649b3b..00000000 --- a/src/NUglify/JavaScript/Syntax/StandardComment.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Diagnostics; -using NUglify.JavaScript.Visitors; - -namespace NUglify.JavaScript.Syntax -{ - [DebuggerDisplay("{Comment}")] - public class StandardComment : AstNode - { - public string Comment { get; set; } - - // this is for determining if a node in a block AFTER a return/break/continue should be removed. We don't want to remove an important comment, so SAY it's a declaration. - public override bool IsDeclaration => true; - - public StandardComment(SourceContext context) : base(context) - { - Comment = Context.Code; - } - - public override void Accept(IVisitor visitor) - { - visitor?.Visit(this); - } - } -} diff --git a/src/NUglify/JavaScript/Visitors/AnalyzeNodeVisitor.cs b/src/NUglify/JavaScript/Visitors/AnalyzeNodeVisitor.cs index 264a68ac..3ff0e0f2 100644 --- a/src/NUglify/JavaScript/Visitors/AnalyzeNodeVisitor.cs +++ b/src/NUglify/JavaScript/Visitors/AnalyzeNodeVisitor.cs @@ -610,7 +610,7 @@ static AstNode FindLastStatement(BlockStatement node) // or important comments until we get the last statement var lastStatementIndex = node.Count - 1; while (lastStatementIndex >= 0 - && (node[lastStatementIndex] is FunctionObject || node[lastStatementIndex] is ImportantComment || node[lastStatementIndex] is StandardComment)) + && (node[lastStatementIndex] is FunctionObject || node[lastStatementIndex] is Syntax.Comment)) { --lastStatementIndex; } @@ -1565,7 +1565,7 @@ static int PreviousStatementIndex(BlockStatement node, AstNode child) // get the index of the statement before the last return // (skip over function decls and importand comments) var indexPrevious = node.IndexOf(child) - 1; - while (indexPrevious >= 0 && (node[indexPrevious] is FunctionObject || node[indexPrevious] is ImportantComment || node[indexPrevious] is StandardComment)) + while (indexPrevious >= 0 && (node[indexPrevious] is FunctionObject || node[indexPrevious] is Syntax.Comment)) { --indexPrevious; } diff --git a/src/NUglify/JavaScript/Visitors/BindingsVisitor.cs b/src/NUglify/JavaScript/Visitors/BindingsVisitor.cs index 4f81f7e7..e685baaa 100644 --- a/src/NUglify/JavaScript/Visitors/BindingsVisitor.cs +++ b/src/NUglify/JavaScript/Visitors/BindingsVisitor.cs @@ -386,12 +386,7 @@ public void Visit(IfStatement node) ReportError(node); } - public void Visit(StandardComment node) - { - ReportError(node); - } - - public void Visit(ImportantComment node) + public void Visit(Syntax.Comment node) { ReportError(node); } diff --git a/src/NUglify/JavaScript/Visitors/IVisitor.cs b/src/NUglify/JavaScript/Visitors/IVisitor.cs index 21d64735..1c0ac1ab 100644 --- a/src/NUglify/JavaScript/Visitors/IVisitor.cs +++ b/src/NUglify/JavaScript/Visitors/IVisitor.cs @@ -58,8 +58,7 @@ public interface IVisitor void Visit(GetterSetter node); void Visit(GroupingOperator node); void Visit(IfStatement node); - void Visit(StandardComment node); - void Visit(ImportantComment node); + void Visit(Syntax.Comment node); void Visit(ImportExportSpecifier node); void Visit(ImportStatement node); void Visit(InitializerNode node); diff --git a/src/NUglify/JavaScript/Visitors/JsonOutputVisitor.cs b/src/NUglify/JavaScript/Visitors/JsonOutputVisitor.cs index 793142ca..00f28140 100644 --- a/src/NUglify/JavaScript/Visitors/JsonOutputVisitor.cs +++ b/src/NUglify/JavaScript/Visitors/JsonOutputVisitor.cs @@ -549,12 +549,7 @@ public void Visit(IfStatement node) IsValid = false; } - public void Visit(StandardComment node) - { - // invalid! ignore - IsValid = false; - } - public void Visit(ImportantComment node) + public void Visit(Syntax.Comment node) { // invalid! ignore IsValid = false; diff --git a/src/NUglify/JavaScript/Visitors/MatchPropertiesVisitor.cs b/src/NUglify/JavaScript/Visitors/MatchPropertiesVisitor.cs index fb1aee46..ab109dee 100644 --- a/src/NUglify/JavaScript/Visitors/MatchPropertiesVisitor.cs +++ b/src/NUglify/JavaScript/Visitors/MatchPropertiesVisitor.cs @@ -311,11 +311,7 @@ public void Visit(IfStatement node) // not applicable; terminate } - public void Visit(StandardComment node) - { - // not applicable; terminate - } - public void Visit(ImportantComment node) + public void Visit(Syntax.Comment node) { // not applicable; terminate } diff --git a/src/NUglify/JavaScript/Visitors/NewParensVisitor.cs b/src/NUglify/JavaScript/Visitors/NewParensVisitor.cs index 831ac67c..f97a498c 100644 --- a/src/NUglify/JavaScript/Visitors/NewParensVisitor.cs +++ b/src/NUglify/JavaScript/Visitors/NewParensVisitor.cs @@ -194,12 +194,7 @@ public virtual void Visit(GroupingOperator node) // output parens ourselves. And don't bother recursing. } - public void Visit(StandardComment node) - { - // we're good? - } - - public void Visit(ImportantComment node) + public void Visit(Syntax.Comment node) { // we're good? } diff --git a/src/NUglify/JavaScript/Visitors/OutputVisitor.cs b/src/NUglify/JavaScript/Visitors/OutputVisitor.cs index d801a104..3e8b8b1f 100644 --- a/src/NUglify/JavaScript/Visitors/OutputVisitor.cs +++ b/src/NUglify/JavaScript/Visitors/OutputVisitor.cs @@ -602,12 +602,12 @@ public void Visit(BlockStatement node) { if (prevStatement != null) { - if (statement is StandardComment || statement is ImportantComment) + if (statement is Syntax.Comment) { // no need for a ; yet MarkSegment(prevStatement, null, prevStatement.TerminatingContext); } - else if (requiresSeparator.Query(prevNonCommentStatement)) + else if (requiresSeparator.Query(prevNonCommentStatement) && !(prevStatement is Syntax.Comment comment && !comment.IsMultiLine)) { OutputPossibleLineBreak(';'); MarkSegment(prevStatement, null, prevStatement.TerminatingContext); @@ -627,7 +627,7 @@ public void Visit(BlockStatement node) // MarkSegment(prevStatement, null, prevStatement.TerminatingContext); // } - if (!(statement is DirectivePrologue || statement is StandardComment || statement is ImportantComment)) + if (!(statement is DirectivePrologue || statement is Syntax.Comment)) { if (m_needsStrictDirective) { @@ -644,7 +644,7 @@ public void Visit(BlockStatement node) m_startOfStatement = true; statement.Accept(this); prevStatement = statement; - if (!(statement is StandardComment || statement is ImportantComment)) + if (!(statement is Syntax.Comment)) prevNonCommentStatement = statement; } } @@ -2088,7 +2088,7 @@ public void Visit(IfStatement node) m_startOfStatement = true; node.TrueBlock[0].Accept(this); - if (node.TrueBlock[0] is ImportantComment || node.TrueBlock[0] is StandardComment) + if (node.TrueBlock[0] is Syntax.Comment) { // the true-block only contained a single comment. // that's not a true statement, so terminate it with an empty-statement @@ -2151,79 +2151,7 @@ public void Visit(IfStatement node) } } - public void Visit(StandardComment node) - { - if (node == null) - return; - - if (settings.CommentMode != JsComment.All) - return; - - var symbol = StartSymbol(node); - - // make sure we force the comments to start on a new line, regardless - // of whether or not we are in multi- or single-line mode, and the statement after - // should also be on a new line. - // TODO: remember if we need a break or not? - BreakLine(true); - - node.Context.OutputLine = lineCount; - - // the output method assumes any text we send it's way doesn't contain any line feed - // characters. The comment however, may contain some. We don't want to count - // the entire comment as a single line, AND we want to normalize the line-feed characters, - // so lets process the comment line-by-line - var startIndex = 0; - var firstLF = node.Comment.IndexOfAny(LineFeedCharacters, startIndex); - if (firstLF < 0) - { - // no line-breaks at all! - Output(node.Comment); - } - else - { - // output the first segment -- from start to first line break - Output(node.Comment.Substring(0, firstLF)); - while (true) - { - // advance the next segment pointer - if (node.Comment[firstLF] == '\r' - && firstLF < node.Comment.Length - 1 - && node.Comment[firstLF + 1] == '\n') - { - startIndex = firstLF + 2; - } - else - { - startIndex = firstLF + 1; - } - - // force the line-break in the output - BreakLine(true); - - // look for the next line break - firstLF = node.Comment.IndexOfAny(LineFeedCharacters, startIndex); - - if (firstLF > startIndex) - { - // only output something if there was something before the next line break - Output(node.Comment.Substring(startIndex, firstLF - startIndex)); - } - else if (firstLF < 0) - { - // no more line-breaks -- output the last segment and break out of the loop - Output(node.Comment.Substring(startIndex)); - break; - } - } - } - - // force a line-break AFTER the important comment as well - BreakLine(true); - EndSymbol(symbol); - } - - public void Visit(ImportantComment node) + public void Visit(Syntax.Comment node) { if (node != null) { @@ -2239,22 +2167,26 @@ public void Visit(ImportantComment node) // the entire comment as a single line, AND we want to normalize the line-feed characters, // so lets process the comment line-by-line var startIndex = 0; - var firstLF = node.Comment.IndexOfAny(LineFeedCharacters, startIndex); + var firstLF = node.Value.IndexOfAny(LineFeedCharacters, startIndex); if (firstLF < 0) { // no line-breaks at all! - Output(node.Comment); + Output(node.Value); + + // force a line-break + if(!node.IsMultiLine) + BreakLine(true); } else { // output the first segment -- from start to first line break - Output(node.Comment.Substring(0, firstLF)); + Output(node.Value.Substring(0, firstLF)); while (true) { // advance the next segment pointer - if (node.Comment[firstLF] == '\r' - && firstLF < node.Comment.Length - 1 - && node.Comment[firstLF + 1] == '\n') + if (node.Value[firstLF] == '\r' + && firstLF < node.Value.Length - 1 + && node.Value[firstLF + 1] == '\n') { startIndex = firstLF + 2; } @@ -2267,24 +2199,23 @@ public void Visit(ImportantComment node) BreakLine(true); // look for the next line break - firstLF = node.Comment.IndexOfAny(LineFeedCharacters, startIndex); + firstLF = node.Value.IndexOfAny(LineFeedCharacters, startIndex); if (firstLF > startIndex) { // only output something if there was something before the next line break - Output(node.Comment.Substring(startIndex, firstLF - startIndex)); + Output(node.Value.Substring(startIndex, firstLF - startIndex)); } else if (firstLF < 0) { // no more line-breaks -- output the last segment and break out of the loop - Output(node.Comment.Substring(startIndex)); + Output(node.Value.Substring(startIndex)); break; } } + } - // force a line-break AFTER teh important comment as well - BreakLine(true); EndSymbol(symbol); } } @@ -4160,7 +4091,7 @@ void OutputBlock(BlockStatement block) { Indent(); NewLine(); - if (block[0] is ImportantComment || block[0] is StandardComment) + if (block[0] is Syntax.Comment) { // not a REAL statement, so follow the comment with a semicolon to // be the actual statement for this block. diff --git a/src/NUglify/JavaScript/Visitors/RemoveCommentsVisitor.cs b/src/NUglify/JavaScript/Visitors/RemoveCommentsVisitor.cs index f850f50b..56f079cc 100644 --- a/src/NUglify/JavaScript/Visitors/RemoveCommentsVisitor.cs +++ b/src/NUglify/JavaScript/Visitors/RemoveCommentsVisitor.cs @@ -24,19 +24,20 @@ public static void Apply(BlockStatement block, JSParser parser) block.Accept(visitor); } } - - public override void Visit(StandardComment node) + public override void Visit(BlockStatement node) { - if (parser.Settings.CommentMode == JsComment.All) - return; - - node.Parent.ReplaceChild(node, null); - node.Parent = null; + if (node != null) + { + // iterate backwards as we are likely to remove nodes + for (var ndx = node.Count - 1; ndx >= 0; --ndx) + node[ndx].Accept(this); + } } - public override void Visit(ImportantComment node) + + public override void Visit(Syntax.Comment node) { - if (parser.Settings.CommentMode == JsComment.None) + if (parser.Settings.CommentMode != JsComment.None && (parser.Settings.CommentMode != JsComment.Important || node.IsImportant)) return; node.Parent.ReplaceChild(node, null); diff --git a/src/NUglify/JavaScript/Visitors/ReorderScopeVisitor.cs b/src/NUglify/JavaScript/Visitors/ReorderScopeVisitor.cs index 031d45cd..6346e5c2 100644 --- a/src/NUglify/JavaScript/Visitors/ReorderScopeVisitor.cs +++ b/src/NUglify/JavaScript/Visitors/ReorderScopeVisitor.cs @@ -101,7 +101,7 @@ public static void Apply(BlockStatement block, JSParser parser) // Make sure that we skip over any remaining comments and directive prologues. // we do NOT want to insert anything between the start of the scope and any directive prologues. - while (insertAt < block.Count && (block[insertAt] is DirectivePrologue || block[insertAt] is ImportantComment || block[insertAt] is StandardComment)) + while (insertAt < block.Count && (block[insertAt] is DirectivePrologue || block[insertAt] is Syntax.Comment)) { ++insertAt; } @@ -158,7 +158,7 @@ public static void Apply(BlockStatement block, JSParser parser) static int RelocateDirectivePrologue(BlockStatement block, int insertAt, DirectivePrologue directivePrologue) { // skip over any comments - while (insertAt < block.Count && (block[insertAt] is ImportantComment || block[insertAt] is StandardComment)) + while (insertAt < block.Count && (block[insertAt] is Syntax.Comment)) ++insertAt; // if the one we want to insert is already at this spot, then we're good to go @@ -595,7 +595,7 @@ public override void Visit(BlockStatement node) { // walk backwards until we find the last non-comment statement var ndxLast = node.Count - 1; - while (ndxLast >= 0 && (node[ndxLast] is ImportantComment || node[ndxLast] is StandardComment)) + while (ndxLast >= 0 && (node[ndxLast] is Syntax.Comment)) --ndxLast; // if the last non-comment statement isn't the first.... diff --git a/src/NUglify/JavaScript/Visitors/RequiresSeparatorVisitor.cs b/src/NUglify/JavaScript/Visitors/RequiresSeparatorVisitor.cs index 08f59489..72555bcb 100644 --- a/src/NUglify/JavaScript/Visitors/RequiresSeparatorVisitor.cs +++ b/src/NUglify/JavaScript/Visitors/RequiresSeparatorVisitor.cs @@ -415,13 +415,7 @@ public void Visit(IfStatement node) } } - public void Visit(StandardComment node) - { - if (node != null) - DoesRequire = false; - } - - public void Visit(ImportantComment node) + public void Visit(Syntax.Comment node) { if (node != null) DoesRequire = false; diff --git a/src/NUglify/JavaScript/Visitors/ResolutionVisitor.cs b/src/NUglify/JavaScript/Visitors/ResolutionVisitor.cs index 47299d77..1ccb0bda 100644 --- a/src/NUglify/JavaScript/Visitors/ResolutionVisitor.cs +++ b/src/NUglify/JavaScript/Visitors/ResolutionVisitor.cs @@ -1309,12 +1309,8 @@ public void Visit(IfStatement node) } } - public void Visit(StandardComment node) - { - // nothing to do - } - public void Visit(ImportantComment node) + public void Visit(Syntax.Comment node) { // nothing to do } diff --git a/src/NUglify/JavaScript/Visitors/StatementStartVisitor.cs b/src/NUglify/JavaScript/Visitors/StatementStartVisitor.cs index 1797131d..d8f7be5d 100644 --- a/src/NUglify/JavaScript/Visitors/StatementStartVisitor.cs +++ b/src/NUglify/JavaScript/Visitors/StatementStartVisitor.cs @@ -279,12 +279,7 @@ public void Visit(IfStatement node) // starts with an 'if', so we don't care } - public void Visit(StandardComment node) - { - // comment, so we need to keep going - } - - public void Visit(ImportantComment node) + public void Visit(Syntax.Comment node) { // comment, so we need to keep going } diff --git a/src/NUglify/JavaScript/Visitors/TreeVisitor.cs b/src/NUglify/JavaScript/Visitors/TreeVisitor.cs index 5077c9af..cd06d84c 100644 --- a/src/NUglify/JavaScript/Visitors/TreeVisitor.cs +++ b/src/NUglify/JavaScript/Visitors/TreeVisitor.cs @@ -84,9 +84,7 @@ public virtual void Visit(BlockStatement node) { if (node != null) { - // Prevent enumeration modification - var nodeChildren = node.Children.ToArray(); - foreach (var statement in nodeChildren) + foreach (var statement in node.Children) statement?.Accept(this); } } @@ -424,11 +422,7 @@ public virtual void Visit(IfStatement node) } } - public virtual void Visit(StandardComment node) - { - // no children - } - public virtual void Visit(ImportantComment node) + public virtual void Visit(Syntax.Comment node) { // no children }