diff --git a/pmd-visualforce/etc/grammar/VfParser.jjt b/pmd-visualforce/etc/grammar/VfParser.jjt index 2c98f612ca..cf17d312d4 100644 --- a/pmd-visualforce/etc/grammar/VfParser.jjt +++ b/pmd-visualforce/etc/grammar/VfParser.jjt @@ -82,6 +82,8 @@ PARSER_END(VfParser) | <#TEXT_IN_EL: (~["}", "'", "\""])+ > | <#CLOSEBRACE: ("}")> | <#DOT: "." > +| <#COMMNT_START: "/*" > +| <#COMMNT_END: "*/" > } @@ -161,12 +163,14 @@ PARSER_END(VfParser) TOKEN : { - )? > : AttrValueBetweenSingleQuotesState + > : InlineCommentStateSQ +| )? > : AttrValueBetweenSingleQuotesState } TOKEN : -{ - )? > : AttrValueBetweenDoubleQuotesState +{ + > : InlineCommentStateDQ +| )? > : AttrValueBetweenDoubleQuotesState } TOKEN : @@ -176,7 +180,7 @@ PARSER_END(VfParser) TOKEN : { - : InlineCommentStateScript + > : InlineCommentStateScript | )? > : HtmlScriptContentState } @@ -260,10 +264,23 @@ PARSER_END(VfParser) TOKEN : { - < COMMENT_CLOSE_SCRIPT: ("*/" ) > : ElInScriptState + < COMMENT_CLOSE_SCRIPT: () > : ElInScriptState | < COMMENT_INNER_TEXT_SCRIPT: (~[]) > } + TOKEN : +{ + < COMMENT_CLOSE_SQ: () > : ElAttribTagStateSQ +| < COMMENT_INNER_TEXT_SQ: (~[]) > +} + + + TOKEN : +{ + < COMMENT_CLOSE_DQ: () > : ElAttribTagStateDQ +| < COMMENT_INNER_TEXT_DQ: (~[]) > +} + TOKEN : { " > : AfterTagState @@ -409,7 +426,10 @@ void Expression() : {} { ConditionalExpression() [ AssignmentOperator() Expression() ] -| InlineCommentExpression() ( ConditionalExpression() | InlineCommentExpression() )* +| CommentExpression() ( ConditionalExpression() | CommentExpression() )* +| ELDQCommentExpression() ( ConditionalExpression() | ELDQCommentExpression() )* +| ELSQCommentExpression() ( ConditionalExpression() | ELSQCommentExpression() )* + } void AssignmentOperator() #void : @@ -492,7 +512,25 @@ void PrimaryExpression() #void : PrimaryPrefix() ( LOOKAHEAD(2) PrimarySuffix() )* } -void InlineCommentExpression() : +void ELSQCommentExpression() #CommentExpression : +{ + StringBuffer content = new StringBuffer(); + Token t; +} +{ + ( t = { content.append(t.image); })* { jjtThis.setImage(content.toString()); } +} + +void ELDQCommentExpression() #CommentExpression : +{ + StringBuffer content = new StringBuffer(); + Token t; +} +{ + ( t = { content.append(t.image); })* { jjtThis.setImage(content.toString()); } +} + +void CommentExpression() : { StringBuffer content = new StringBuffer(); Token t; diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/VfParserVisitorAdapter.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/VfParserVisitorAdapter.java index b60b979111..4e2560647d 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/VfParserVisitorAdapter.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/VfParserVisitorAdapter.java @@ -90,7 +90,7 @@ public class VfParserVisitorAdapter implements VfParserVisitor { } @Override - public Object visit(ASTInlineCommentExpression node, Object data) { + public Object visit(ASTCommentExpression node, Object data) { return visit((VfNode) node, data); } } diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/rule/AbstractVfRule.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/rule/AbstractVfRule.java index 6ed7a384dc..fd8f15a194 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/rule/AbstractVfRule.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/rule/AbstractVfRule.java @@ -28,7 +28,7 @@ import net.sourceforge.pmd.lang.vf.ast.ASTElement; import net.sourceforge.pmd.lang.vf.ast.ASTExpression; import net.sourceforge.pmd.lang.vf.ast.ASTHtmlScript; import net.sourceforge.pmd.lang.vf.ast.ASTIdentifier; -import net.sourceforge.pmd.lang.vf.ast.ASTInlineCommentExpression; +import net.sourceforge.pmd.lang.vf.ast.ASTCommentExpression; import net.sourceforge.pmd.lang.vf.ast.ASTLiteral; import net.sourceforge.pmd.lang.vf.ast.ASTText; import net.sourceforge.pmd.lang.vf.ast.VfNode; @@ -133,7 +133,7 @@ public abstract class AbstractVfRule extends AbstractRule implements VfParserVis return visit((VfNode) node, data); } - public Object visit(ASTInlineCommentExpression node, Object data) { + public Object visit(ASTCommentExpression node, Object data) { return visit((VfNode) node, data); } } diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfDocStyleTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfDocStyleTest.java index 2962610166..41242d7a0f 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfDocStyleTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/vf/ast/VfDocStyleTest.java @@ -151,6 +151,53 @@ public class VfDocStyleTest extends AbstractVfNodesTest { ASTText text = script.getFirstChildOfType(ASTText.class); assertEquals("Correct script content expected!", "Script!", text.getImage()); } + + /** + * Test parsing of EL in attribute of an element. + */ + @Test + public void testELInTagValue() { + Set elememts = getNodes(ASTElement.class, TEST_EL_IN_TAG_ATTRIBUTE); + assertEquals("One element expected!", 1, elememts.size()); + ASTElement element = elememts.iterator().next(); + ASTAttributeValue attribute = element.getFirstDescendantOfType(ASTAttributeValue.class); + ASTIdentifier id = attribute.getFirstDescendantOfType(ASTIdentifier.class); + assertEquals("Correct identifier expected", "foo", id.getImage()); + + } + + /** + * Test parsing of EL in attribute of an element that also has a comment. + */ + @Test + public void testELInTagValueWithCommentDQ() { + Set elememts = getNodes(ASTElement.class, TEST_EL_IN_TAG_ATTRIBUTE_WITH_COMMENT); + assertEquals("One element expected!", 1, elememts.size()); + ASTElement element = elememts.iterator().next(); + ASTElExpression elExpr = element.getFirstDescendantOfType(ASTElExpression.class); + ASTIdentifier id = elExpr.getFirstDescendantOfType(ASTIdentifier.class); + assertEquals("Correct identifier expected", "init", id.getImage()); + ASTCommentExpression comment = elExpr.getFirstDescendantOfType(ASTCommentExpression.class); + assertEquals("Correct comment expected!", "comment here", comment.getImage()); + + } + + + /** + * Test parsing of EL in attribute of an element that also has a comment. + */ + @Test + public void testELInTagValueWithCommentSQ() { + Set elememts = getNodes(ASTElement.class, TEST_EL_IN_TAG_ATTRIBUTE_WITH_COMMENT_SQ); + assertEquals("One element expected!", 1, elememts.size()); + ASTElement element = elememts.iterator().next(); + ASTElExpression elExpr = element.getFirstDescendantOfType(ASTElExpression.class); + ASTIdentifier id = elExpr.getFirstDescendantOfType(ASTIdentifier.class); + assertEquals("Correct identifier expected", "init", id.getImage()); + ASTCommentExpression comment = elExpr.getFirstDescendantOfType(ASTCommentExpression.class); + assertEquals("Correct comment expected!", "comment here", comment.getImage()); + + } /** @@ -167,7 +214,6 @@ public class VfDocStyleTest extends AbstractVfNodesTest { ASTIdentifier id = el.getFirstDescendantOfType(ASTIdentifier.class); assertEquals("Correct EL content expected!", "elInScript", id.getImage()); } - /** * Test parsing of inline comment in EL. @@ -180,13 +226,12 @@ public class VfDocStyleTest extends AbstractVfNodesTest { ASTText text = script.getFirstChildOfType(ASTText.class); assertEquals("Correct script content expected!", "vartext=", text.getImage()); ASTElExpression el = script.getFirstChildOfType(ASTElExpression.class); - List comments = el.findDescendantsOfType(ASTInlineCommentExpression.class); - assertEquals("Correct comment size expected!", 2, comments.size()); + List comments = el.findDescendantsOfType(ASTCommentExpression.class); + assertEquals("Correct comment size expected!", 2, comments.size()); ASTIdentifier id = el.getFirstDescendantOfType(ASTIdentifier.class); assertEquals("Correct EL content expected!", "elInScript", id.getImage()); } - - + /** * Test parsing of quoted EL in HTML <script> element. */ @@ -196,7 +241,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { assertEquals("One script expected!", 1, scripts.size()); ASTHtmlScript script = scripts.iterator().next(); ASTText text = script.getFirstChildOfType(ASTText.class); - assertEquals("Correct script content expected!", "vartext='textHere", text.getImage()); + assertEquals("Correct script content expected!", "vartext='textHere", text.getImage()); ASTElExpression el = script.getFirstChildOfType(ASTElExpression.class); ASTIdentifier id = el.getFirstDescendantOfType(ASTIdentifier.class); assertEquals("Correct EL content expected!", "elInScript", id.getImage()); @@ -653,7 +698,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest { assertEquals("One attribute expected!", 1, attributes.size()); Iterator iterator = attributes.iterator(); ASTAttributeValue attr = iterator.next(); - ASTIdentifier id = attr.getFirstDescendantOfType(ASTIdentifier.class); + ASTIdentifier id = attr.getFirstDescendantOfType(ASTIdentifier.class); assertEquals("Expected to detect proper value for EL in attribute!", "something", id.getImage()); } @@ -672,7 +717,11 @@ public class VfDocStyleTest extends AbstractVfNodesTest { private static final String TEST_ATTRIBUTE_VALUE_CONTAINING_HASH = " foo "; private static final String TEST_HTML_SCRIPT = ""; - + + private static final String TEST_EL_IN_TAG_ATTRIBUTE = "text"; + private static final String TEST_EL_IN_TAG_ATTRIBUTE_WITH_COMMENT = "text"; + private static final String TEST_EL_IN_TAG_ATTRIBUTE_WITH_COMMENT_SQ = "text"; + private static final String TEST_EL_IN_HTML_SCRIPT = ""; private static final String TEST_EL_IN_HTML_SCRIPT_WITH_COMMENT = "";