diff --git a/docs/pages/pmd/userdocs/tools/ant.md b/docs/pages/pmd/userdocs/tools/ant.md index e01732c2c1..d1e6c1917d 100644 --- a/docs/pages/pmd/userdocs/tools/ant.md +++ b/docs/pages/pmd/userdocs/tools/ant.md @@ -204,7 +204,7 @@ accordingly and this rule won't be executed. The specific version of a language to be used is selected via the `sourceLanguage` nested element. Possible values are: - + diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 659241eeb9..125a043c62 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -42,6 +42,25 @@ useful. A short description how to use it is available under [Creating XML dump Any feedback about it, especially about your use cases, is highly appreciated. +#### Updated Apex Support + +* The Apex language support has been bumped to version 48 (Spring '20). All new language features are now properly + parsed and processed. + +#### CPD XML format + +The CPD XML output format has been enhanced to also report column information for found duplications +in addition to the line information. This allows to display the exact tokens, that are considered +duplicate. + +If a CPD language doesn't provide these exact information, then these additional attributes are omitted. + +Each `` element in the XML format now has 3 new attributes: + +* attribute `endLine` +* attribute `beginColumn` (if there is column information available) +* attribute `endColumn` (if there is column information available) + #### Modified Rules * The Java rule {% rule "java/errorprone/AvoidLiteralsInIfCondition" %} (`java-errorprone`) has a new property @@ -59,6 +78,8 @@ Any feedback about it, especially about your use cases, is highly appreciated. ### Fixed Issues +* apex + * [#2208](https://github.com/pmd/pmd/issues/2208): \[apex] ASTFormalComment should implement ApexNode<T> * core * [#2006](https://github.com/pmd/pmd/issues/2006): \[core] PMD should warn about multiple instances of the same rule in a ruleset * [#2161](https://github.com/pmd/pmd/issues/2161): \[core] ResourceLoader is deprecated and marked as internal but is exposed @@ -107,6 +128,11 @@ You can identify them with the `@InternalApi` annotation. You'll also get a depr * Constructors of {% jdoc core::RuleSetFactory %}, use factory methods from {% jdoc core::RulesetsFactoryUtils %} instead * {% jdoc core::RulesetsFactoryUtils#getRulesetFactory(core::PMDConfiguration, core::util.ResourceLoader) %} +* {% jdoc apex::lang.apex.ast.AbstractApexNode %} +* {% jdoc apex::lang.apex.ast.AbstractApexNodeBase %}, and the related `visit` +methods on {% jdoc apex::lang.apex.ast.ApexParserVisitor %} and its implementations. + Use {% jdoc apex::lang.apex.ast.ApexNode %} instead, now considers comments too. + ##### For removal * pmd-core @@ -151,6 +177,7 @@ You can identify them with the `@InternalApi` annotation. You'll also get a depr * [#2194](https://github.com/pmd/pmd/pull/2194): \[java] Fix odd logic in AvoidUsingHardCodedIPRule - [Egor Bredikhin](https://github.com/Egor18) * [#2195](https://github.com/pmd/pmd/pull/2195): \[modelica] Normalize invalid node ranges - [Anatoly Trosinenko](https://github.com/atrosinenko) * [#2199](https://github.com/pmd/pmd/pull/2199): \[modelica] Fix Javadoc tags - [Anatoly Trosinenko](https://github.com/atrosinenko) +* [#2225](https://github.com/pmd/pmd/pull/2225): \[core] CPD: report endLine / column informations for found duplications - [Maikel Steneker](https://github.com/maikelsteneker) {% endtocmaker %} diff --git a/pmd-apex-jorje/pom.xml b/pmd-apex-jorje/pom.xml index 71b4b5b9d0..786f80ce2b 100644 --- a/pmd-apex-jorje/pom.xml +++ b/pmd-apex-jorje/pom.xml @@ -12,7 +12,7 @@ - 2019-01-18-a041d7 + 2019-11-07-964d4a diff --git a/pmd-apex-jorje/repo/apex/apex-jorje-lsp-minimized/2019-01-18-a041d7/apex-jorje-lsp-minimized-2019-01-18-a041d7.jar b/pmd-apex-jorje/repo/apex/apex-jorje-lsp-minimized/2019-11-07-964d4a/apex-jorje-lsp-minimized-2019-11-07-964d4a.jar similarity index 55% rename from pmd-apex-jorje/repo/apex/apex-jorje-lsp-minimized/2019-01-18-a041d7/apex-jorje-lsp-minimized-2019-01-18-a041d7.jar rename to pmd-apex-jorje/repo/apex/apex-jorje-lsp-minimized/2019-11-07-964d4a/apex-jorje-lsp-minimized-2019-11-07-964d4a.jar index bb1964a604..e0c1863bc6 100644 Binary files a/pmd-apex-jorje/repo/apex/apex-jorje-lsp-minimized/2019-01-18-a041d7/apex-jorje-lsp-minimized-2019-01-18-a041d7.jar and b/pmd-apex-jorje/repo/apex/apex-jorje-lsp-minimized/2019-11-07-964d4a/apex-jorje-lsp-minimized-2019-11-07-964d4a.jar differ diff --git a/pmd-apex-jorje/repo/apex/apex-jorje-lsp-minimized/2019-01-18-a041d7/apex-jorje-lsp-minimized-2019-01-18-a041d7.pom b/pmd-apex-jorje/repo/apex/apex-jorje-lsp-minimized/2019-11-07-964d4a/apex-jorje-lsp-minimized-2019-11-07-964d4a.pom similarity index 74% rename from pmd-apex-jorje/repo/apex/apex-jorje-lsp-minimized/2019-01-18-a041d7/apex-jorje-lsp-minimized-2019-01-18-a041d7.pom rename to pmd-apex-jorje/repo/apex/apex-jorje-lsp-minimized/2019-11-07-964d4a/apex-jorje-lsp-minimized-2019-11-07-964d4a.pom index 5a0a59af5d..ee8110a921 100644 --- a/pmd-apex-jorje/repo/apex/apex-jorje-lsp-minimized/2019-01-18-a041d7/apex-jorje-lsp-minimized-2019-01-18-a041d7.pom +++ b/pmd-apex-jorje/repo/apex/apex-jorje-lsp-minimized/2019-11-07-964d4a/apex-jorje-lsp-minimized-2019-11-07-964d4a.pom @@ -1,9 +1,9 @@ - 4.0.0 apex apex-jorje-lsp-minimized - 2019-01-18-a041d7 + 2019-11-07-964d4a POM was created from install:install-file diff --git a/pmd-apex-jorje/repo/apex/apex-jorje-lsp-minimized/maven-metadata-local.xml b/pmd-apex-jorje/repo/apex/apex-jorje-lsp-minimized/maven-metadata-local.xml index 3bd7ba5668..4d46c52b43 100644 --- a/pmd-apex-jorje/repo/apex/apex-jorje-lsp-minimized/maven-metadata-local.xml +++ b/pmd-apex-jorje/repo/apex/apex-jorje-lsp-minimized/maven-metadata-local.xml @@ -3,10 +3,10 @@ apex apex-jorje-lsp-minimized - 2019-01-18-a041d7 + 2019-11-07-964d4a - 2019-01-18-a041d7 + 2019-11-07-964d4a - 20190118084525 + 20200117105703 diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/cpd/ApexTokenizer.java b/pmd-apex/src/main/java/net/sourceforge/pmd/cpd/ApexTokenizer.java index c872489c02..bb5f9b6cf1 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/cpd/ApexTokenizer.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/cpd/ApexTokenizer.java @@ -55,7 +55,8 @@ public class ApexTokenizer implements Tokenizer { if (!caseSensitive) { tokenText = tokenText.toLowerCase(Locale.ROOT); } - TokenEntry tokenEntry = new TokenEntry(tokenText, sourceCode.getFileName(), token.getLine()); + TokenEntry tokenEntry = new TokenEntry(tokenText, sourceCode.getFileName(), token.getLine(), + token.getCharPositionInLine(), token.getCharPositionInLine() + tokenText.length()); tokenEntries.add(tokenEntry); } token = lexer.nextToken(); diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageModule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageModule.java index 61c5dfe234..2ec8899f8a 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageModule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageModule.java @@ -7,6 +7,8 @@ package net.sourceforge.pmd.lang.apex; import net.sourceforge.pmd.lang.BaseLanguageModule; import net.sourceforge.pmd.lang.apex.rule.ApexRuleChainVisitor; +import apex.jorje.services.Version; + public class ApexLanguageModule extends BaseLanguageModule { public static final String NAME = "Apex"; @@ -15,6 +17,6 @@ public class ApexLanguageModule extends BaseLanguageModule { public ApexLanguageModule() { super(NAME, null, TERSE_NAME, ApexRuleChainVisitor.class, EXTENSIONS); - addVersion("45", new ApexHandler(), true); + addVersion(String.valueOf((int) Version.CURRENT.getExternal()), new ApexHandler(), true); } } diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTFormalComment.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTFormalComment.java index 97360e3fb5..d9ca521600 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTFormalComment.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTFormalComment.java @@ -4,12 +4,35 @@ package net.sourceforge.pmd.lang.apex.ast; -public class ASTFormalComment extends AbstractApexNodeBase { - private String token; +import org.antlr.runtime.Token; + +import net.sourceforge.pmd.lang.apex.ast.ASTFormalComment.AstComment; + +import apex.jorje.data.Location; +import apex.jorje.data.Locations; +import apex.jorje.semantic.ast.AstNode; +import apex.jorje.semantic.ast.context.Emitter; +import apex.jorje.semantic.ast.visitor.AstVisitor; +import apex.jorje.semantic.ast.visitor.Scope; +import apex.jorje.semantic.ast.visitor.ValidationScope; +import apex.jorje.semantic.symbol.resolver.SymbolResolver; +import apex.jorje.semantic.symbol.type.TypeInfo; +import apex.jorje.semantic.symbol.type.TypeInfos; + +public class ASTFormalComment extends AbstractApexNode { + + private final String image; + + ASTFormalComment(Token token) { + super(new AstComment(token)); + this.image = token.getText(); + } + + @Deprecated public ASTFormalComment(String token) { - super(ASTFormalComment.class); - this.token = token; + super(new AstComment(null)); + image = token; } @Override @@ -19,10 +42,48 @@ public class ASTFormalComment extends AbstractApexNodeBase { @Override public String getImage() { - return token; + return image; } public String getToken() { - return token; + return image; } + + + public static final class AstComment implements AstNode { + + private final Location loc; + + private AstComment(Token token) { + this.loc = token == null + ? Locations.NONE + : Locations.loc(token.getLine(), token.getCharPositionInLine() + 1); + } + + @Override + public Location getLoc() { + return loc; + } + + @Override + public void traverse(AstVisitor astVisitor, T t) { + // do nothing + } + + @Override + public void validate(SymbolResolver symbolResolver, ValidationScope validationScope) { + // do nothing + } + + @Override + public void emit(Emitter emitter) { + // do nothing + } + + @Override + public TypeInfo getDefiningType() { + return TypeInfos.VOID; + } + } + } diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AbstractApexNode.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AbstractApexNode.java index 93a8496361..9e5063b7df 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AbstractApexNode.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AbstractApexNode.java @@ -4,6 +4,7 @@ package net.sourceforge.pmd.lang.apex.ast; +import net.sourceforge.pmd.annotation.InternalApi; import net.sourceforge.pmd.lang.ast.SourceCodePositioner; import apex.jorje.data.Location; @@ -11,6 +12,11 @@ import apex.jorje.data.Locations; import apex.jorje.semantic.ast.AstNode; import apex.jorje.semantic.exception.UnexpectedCodePathException; +/** + * @deprecated Use {@link ApexNode} + */ +@Deprecated +@InternalApi public abstract class AbstractApexNode extends AbstractApexNodeBase implements ApexNode { protected final T node; @@ -20,6 +26,21 @@ public abstract class AbstractApexNode extends AbstractApexNo this.node = node; } + @Override + public ApexNode getChild(int index) { + return (ApexNode) super.getChild(index); + } + + @Override + public ApexNode getParent() { + return (ApexNode) super.getParent(); + } + + @Override + public Iterable> children() { + return (Iterable>) super.children(); + } + void calculateLineNumbers(SourceCodePositioner positioner) { if (!hasRealLoc()) { return; diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AbstractApexNodeBase.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AbstractApexNodeBase.java index 3599741d60..d3b2272668 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AbstractApexNodeBase.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AbstractApexNodeBase.java @@ -8,6 +8,10 @@ import net.sourceforge.pmd.lang.ast.AbstractNode; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.SourceCodePositioner; +/** + * @deprecated Use {@link ApexNode} + */ +@Deprecated public abstract class AbstractApexNodeBase extends AbstractNode { public AbstractApexNodeBase(Class klass) { diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexNode.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexNode.java index fc2c9097d4..e0b4ae004e 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexNode.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexNode.java @@ -8,13 +8,21 @@ import net.sourceforge.pmd.lang.ast.Node; import apex.jorje.semantic.ast.AstNode; +/** + * Root interface implemented by all Apex nodes. Apex nodes wrap a tree + * obtained from an external parser (Jorje). The underlying AST node is + * available with {@link #getNode()}. + * + * @param Type of the underlying Jorje node + */ public interface ApexNode extends Node { /** - * Accept the visitor. * + * Accept the visitor. */ Object jjtAccept(ApexParserVisitor visitor, Object data); + /** * Accept the visitor. * * @@ -24,8 +32,21 @@ public interface ApexNode extends Node { @Deprecated Object childrenAccept(ApexParserVisitor visitor, Object data); + /** * Get the underlying AST node. */ T getNode(); + + + @Override + Iterable> children(); + + + @Override + ApexNode getChild(int index); + + + @Override + ApexNode getParent(); } diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParserVisitor.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParserVisitor.java index b662e82865..2edcc668b7 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParserVisitor.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParserVisitor.java @@ -5,13 +5,13 @@ package net.sourceforge.pmd.lang.apex.ast; public interface ApexParserVisitor { + /** + * @deprecated Use {@link #visit(ApexNode, Object)}. That method + * also visits comments now. + */ + @Deprecated Object visit(AbstractApexNodeBase node, Object data); - /** - * @deprecated This visit method will be removed with PMD 7.0.0. Use {@link #visit(AbstractApexNodeBase, Object)} - * instead. This method would not visit all nodes, e.g. ASTFormalComment would not be covered. - */ - @Deprecated // will be removed with PMD 7.0.0 Object visit(ApexNode node, Object data); Object visit(ASTAnnotation node, Object data); diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParserVisitorAdapter.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParserVisitorAdapter.java index 1680151c23..eb58942e54 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParserVisitorAdapter.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParserVisitorAdapter.java @@ -5,463 +5,467 @@ package net.sourceforge.pmd.lang.apex.ast; public class ApexParserVisitorAdapter implements ApexParserVisitor { + + /** + * @deprecated Use {@link #visit(ApexNode, Object)}. That method + * also visits comments now. + */ + @Deprecated @Override public Object visit(AbstractApexNodeBase node, Object data) { return node.childrenAccept(this, data); } - /** - * @deprecated This visit method will be removed with PMD 7.0.0. Use {@link #visit(AbstractApexNodeBase, Object)} - * instead. This method would not visit all nodes, e.g. ASTFormalComment would not be covered. - */ - @Deprecated // will be removed with PMD 7.0.0 @Override public Object visit(ApexNode node, Object data) { - return visit((AbstractApexNodeBase) node, data); + for (ApexNode child : node.children()) { + child.jjtAccept(this, data); + } + return data; } @Override public Object visit(ASTMethod node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTUserClass node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTModifierNode node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTParameter node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTBlockStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTUserClassMethods node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTBridgeMethodCreator node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTReturnStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTLiteralExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTConstructorPreambleStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTUserInterface node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTUserEnum node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTFieldDeclaration node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTWhileLoopStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTTryCatchFinallyBlockStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTForLoopStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTIfElseBlockStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTIfBlockStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTForEachStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTField node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTBreakStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTThrowStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTDoLoopStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTTernaryExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTSoqlExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTBooleanExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTAnnotation node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTAnonymousClass node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTArrayLoadExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTArrayStoreExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTAssignmentExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTBinaryExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTBindExpressions node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTCatchBlockStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTClassRefExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTContinueStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTDmlDeleteStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTDmlInsertStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTDmlMergeStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTDmlUndeleteStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTDmlUpdateStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTDmlUpsertStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTExpressionStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTFieldDeclarationStatements node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTInstanceOfExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTJavaMethodCallExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTJavaVariableExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTMapEntryNode node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTMethodCallExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTModifierOrAnnotation node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNewListInitExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNewListLiteralExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNewMapInitExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNewMapLiteralExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNewObjectExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNewSetInitExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNewSetLiteralExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTPackageVersionExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTPostfixExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTPrefixExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTProperty node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTReferenceExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTRunAsBlockStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTSoslExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTStandardCondition node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTSuperMethodCallExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTSuperVariableExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTThisMethodCallExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTThisVariableExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTTriggerVariableExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTUserExceptionMethods node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTUserTrigger node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTVariableDeclaration node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTVariableDeclarationStatements node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTVariableExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTAnnotationParameter node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTCastExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTConstructorPreamble node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTIllegalStoreExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTMethodBlockStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTModifier node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTMultiStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNestedExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNestedStoreExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNewKeyValueObjectExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTStatementExecuted node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTFormalComment node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } } diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParserVisitorReducedAdapter.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParserVisitorReducedAdapter.java index 16d9329dd4..f989a95bde 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParserVisitorReducedAdapter.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParserVisitorReducedAdapter.java @@ -23,7 +23,7 @@ public class ApexParserVisitorReducedAdapter extends ApexParserVisitorAdapter { public Object visit(ASTUserClassOrInterface node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } } diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexTreeBuilder.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexTreeBuilder.java index 272715343c..084186cbfa 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexTreeBuilder.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexTreeBuilder.java @@ -288,7 +288,7 @@ public final class ApexTreeBuilder extends AstVisitor { if (parent != null) { ASTFormalComment comment = new ASTFormalComment(tokenLocation.token); comment.calculateLineNumbers(sourceCodePositioner, tokenLocation.index, - tokenLocation.index + tokenLocation.token.length()); + tokenLocation.index + tokenLocation.token.getText().length()); // move existing nodes so that we can insert the comment as the first node for (int i = parent.getNumChildren(); i > 0; i--) { @@ -354,7 +354,7 @@ public final class ApexTreeBuilder extends AstVisitor { if (token.getType() == ApexLexer.BLOCK_COMMENT) { // Filter only block comments starting with "/**" if (token.getText().startsWith("/**")) { - tokenLocations.add(new ApexDocTokenLocation(startIndex, token.getText())); + tokenLocations.add(new ApexDocTokenLocation(startIndex, token)); } } // TODO : Check other non-doc comments and tokens of type ApexLexer.EOL_COMMENT for "NOPMD" suppressions @@ -368,11 +368,11 @@ public final class ApexTreeBuilder extends AstVisitor { private static class ApexDocTokenLocation { int index; - String token; + Token token; ApexNode nearestNode; int nearestNodeDistance; - ApexDocTokenLocation(int index, String token) { + ApexDocTokenLocation(int index, Token token) { this.index = index; this.token = token; } diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/TestAccessEvaluator.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/TestAccessEvaluator.java index 9d8b7bd8cc..9e22af4e7b 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/TestAccessEvaluator.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/TestAccessEvaluator.java @@ -348,4 +348,9 @@ public class TestAccessEvaluator implements AccessEvaluator { public boolean useTestValueForAnonymousScriptLengthLimit() { return false; } + + @Override + public boolean hasNamespaceGuardedAccess(Namespace namespace, String arg1) { + return false; + } } diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/AbstractApexRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/AbstractApexRule.java index 488b1c44ba..253e9277af 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/AbstractApexRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/AbstractApexRule.java @@ -136,464 +136,468 @@ public abstract class AbstractApexRule extends AbstractRule } } + /** + * @deprecated Use {@link #visit(ApexNode, Object)}. That method + * also visits comments now. + */ + @Deprecated @Override public Object visit(AbstractApexNodeBase node, Object data) { node.childrenAccept(this, data); return null; } - /** - * @deprecated This visit method will be removed with PMD 7.0.0. Use {@link #visit(AbstractApexNodeBase, Object)} - * instead. This method would not visit all nodes, e.g. ASTFormalComment would not be covered. - */ - @Deprecated // will be removed with PMD 7.0.0 + @Override public Object visit(ApexNode node, Object data) { - return visit((AbstractApexNodeBase) node, data); + for (ApexNode child : node.children()) { + child.jjtAccept(this, data); + } + return data; } @Override public Object visit(ASTMethod node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTUserClass node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTModifierNode node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTParameter node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTBlockStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTUserClassMethods node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTBridgeMethodCreator node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTReturnStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTLiteralExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTConstructorPreambleStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTUserInterface node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTUserEnum node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTFieldDeclaration node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTWhileLoopStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTTryCatchFinallyBlockStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTForLoopStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTIfElseBlockStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTIfBlockStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTForEachStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTField node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTBreakStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTThrowStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTDoLoopStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTTernaryExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTSoqlExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTBooleanExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTAnnotation node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTAnonymousClass node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTArrayLoadExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTArrayStoreExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTAssignmentExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTBinaryExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTBindExpressions node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTCatchBlockStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTClassRefExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTContinueStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTDmlDeleteStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTDmlInsertStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTDmlMergeStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTDmlUndeleteStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTDmlUpdateStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTDmlUpsertStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTExpressionStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTFieldDeclarationStatements node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTInstanceOfExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTJavaMethodCallExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTJavaVariableExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTMapEntryNode node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTMethodCallExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTModifierOrAnnotation node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNewListInitExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNewListLiteralExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNewMapInitExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNewMapLiteralExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNewObjectExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNewSetInitExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNewSetLiteralExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTPackageVersionExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTPostfixExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTPrefixExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTProperty node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTReferenceExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTRunAsBlockStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTSoslExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTStandardCondition node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTSuperMethodCallExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTSuperVariableExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTThisMethodCallExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTThisVariableExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTTriggerVariableExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTUserExceptionMethods node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTUserTrigger node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTVariableDeclaration node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTVariableDeclarationStatements node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTVariableExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTAnnotationParameter node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTCastExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTConstructorPreamble node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTIllegalStoreExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTMethodBlockStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTModifier node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTMultiStatement node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNestedExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNestedStoreExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTNewKeyValueObjectExpression node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTStatementExecuted node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } @Override public Object visit(ASTFormalComment node, Object data) { - return visit((AbstractApexNodeBase) node, data); + return visit((ApexNode) node, data); } } diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AbstractNcssCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AbstractNcssCountRule.java index cd0701e48f..c7c0d4878e 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AbstractNcssCountRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AbstractNcssCountRule.java @@ -55,7 +55,7 @@ public abstract class AbstractNcssCountRule> extends Abstr private static class NcssVisitor extends ApexParserVisitorAdapter { @Override - public Object visit(AbstractApexNodeBase node, Object data) { + public Object visit(ApexNode node, Object data) { return countNodeChildren(node, data); } diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTest.java index b037920923..3f051e0a09 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTest.java @@ -4,7 +4,10 @@ package net.sourceforge.pmd.lang.apex.ast; +import static org.hamcrest.core.IsInstanceOf.instanceOf; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.io.File; @@ -107,6 +110,36 @@ public class ApexParserTest extends ApexParserTestBase { assertEquals("Wrong end line", 5, method2.getEndLine()); } + @Test + public void checkComments() { + + String code = "public /** Comment on Class */ class SimpleClass {\n" // line 1 + + " /** Comment on m1 */" + + " public void method1() {\n" // line 2 + + " }\n" // line 3 + + " public void method2() {\n" // line 4 + + " }\n" // line 5 + + "}\n"; // line 6 + + ApexNode root = parse(code); + + assertThat(root, instanceOf(ASTUserClass.class)); + ApexNode comment = root.getChild(0); + assertThat(comment, instanceOf(ASTFormalComment.class)); + + assertNotEquals(comment.getNode(), null); + assertThat(comment.getNode(), instanceOf(ASTFormalComment.AstComment.class)); + assertPosition(comment, 1, 9, 1, 31); + assertEquals("/** Comment on Class */", ((ASTFormalComment) comment).getToken()); + + ApexNode m1 = root.getChild(2); + assertThat(m1, instanceOf(ASTMethod.class)); + + ApexNode comment2 = m1.getChild(0); + assertThat(comment2, instanceOf(ASTFormalComment.class)); + assertEquals("/** Comment on m1 */", ((ASTFormalComment) comment2).getToken()); + } + @Test public void parsesRealWorldClasses() throws Exception { File directory = new File("src/test/resources"); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AbstractTokenizer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AbstractTokenizer.java index 7309fd2f4c..87c5acb924 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AbstractTokenizer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AbstractTokenizer.java @@ -58,8 +58,7 @@ public abstract class AbstractTokenizer implements Tokenizer { // if ( CPD.debugEnable ) { // System.out.println("Token added:" + token.toString()); // } - tokenEntries.add(new TokenEntry(token.toString(), tokens.getFileName(), lineNumber + 1)); - + tokenEntries.add(new TokenEntry(token.toString(), tokens.getFileName(), lineNumber + 1, loc - token.length(), loc - 1)); } } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Mark.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Mark.java index 6332d9fc32..a1b88be336 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Mark.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Mark.java @@ -6,6 +6,7 @@ package net.sourceforge.pmd.cpd; public class Mark implements Comparable { private TokenEntry token; + private TokenEntry endToken; private int lineCount; private SourceCode code; @@ -25,10 +26,28 @@ public class Mark implements Comparable { return this.token.getBeginLine(); } + /** + * The column number where this duplication begins. + * returns -1 if not available + * @return the begin column number + */ + public int getBeginColumn() { + return this.token.getBeginColumn(); // TODO Java 1.8 make optional + } + public int getEndLine() { return getBeginLine() + getLineCount() - 1; } + /** + * The column number where this duplication ends. + * returns -1 if not available + * @return the end column number + */ + public int getEndColumn() { + return this.endToken == null ? -1 : this.endToken.getEndColumn(); // TODO Java 1.8 make optional + } + public int getLineCount() { return this.lineCount; } @@ -37,6 +56,10 @@ public class Mark implements Comparable { this.lineCount = lineCount; } + public void setEndToken(TokenEntry endToken) { + this.endToken = endToken; + } + public String getSourceCodeSlice() { return this.code.getSlice(getBeginLine(), getEndLine()); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MatchAlgorithm.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MatchAlgorithm.java index 292802b044..fcf4b8ec8b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MatchAlgorithm.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MatchAlgorithm.java @@ -78,8 +78,10 @@ public class MatchAlgorithm { for (Mark mark : match) { TokenEntry token = mark.getToken(); int lineCount = tokens.getLineCount(token, match); + TokenEntry endToken = tokens.getEndToken(token, match); mark.setLineCount(lineCount); + mark.setEndToken(endToken); SourceCode sourceCode = source.get(token.getTokenSrcID()); mark.setSourceCode(sourceCode); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/TokenEntry.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/TokenEntry.java index 178f0e3ebe..7246dc6acf 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/TokenEntry.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/TokenEntry.java @@ -15,7 +15,9 @@ public class TokenEntry implements Comparable { public static final TokenEntry EOF = new TokenEntry(); private String tokenSrcID; - private int beginLine; + private final int beginLine; + private final int beginColumn; + private final int endColumn; private int index; private int identifier; private int hashCode; @@ -36,6 +38,9 @@ public class TokenEntry implements Comparable { private TokenEntry() { this.identifier = 0; this.tokenSrcID = "EOFMarker"; + this.beginLine = -1; + this.beginColumn = -1; + this.endColumn = -1; } /** @@ -45,9 +50,23 @@ public class TokenEntry implements Comparable { * @param beginLine the linenumber, 1-based. */ public TokenEntry(String image, String tokenSrcID, int beginLine) { + this(image, tokenSrcID, beginLine, -1, -1); + } + + /** + * Creates a new token entry with the given informations. + * @param image + * @param tokenSrcID + * @param beginLine the linenumber, 1-based. + * @param beginColumn the column number, 1-based + * @param endColumn the column number, 1-based + */ + public TokenEntry(String image, String tokenSrcID, int beginLine, int beginColumn, int endColumn) { setImage(image); this.tokenSrcID = tokenSrcID; this.beginLine = beginLine; + this.beginColumn = beginColumn; + this.endColumn = endColumn; this.index = TOKEN_COUNT.get().getAndIncrement(); } @@ -93,6 +112,24 @@ public class TokenEntry implements Comparable { return beginLine; } + /** + * The column number where this token begins. + * returns -1 if not available + * @return the begin column number + */ + public int getBeginColumn() { + return beginColumn; // TODO Java 1.8 make optional + } + + /** + * The column number where this token ends. + * returns -1 if not available + * @return the end column number + */ + public int getEndColumn() { + return endColumn; // TODO Java 1.8 make optional + } + public int getIdentifier() { return this.identifier; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java index 95b2be848a..f77ab6f229 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java @@ -28,8 +28,12 @@ public class Tokens { return tokens.size(); } + public TokenEntry getEndToken(TokenEntry mark, Match match) { + return get(mark.getIndex() + match.getTokenCount() - 1); + } + public int getLineCount(TokenEntry mark, Match match) { - TokenEntry endTok = get(mark.getIndex() + match.getTokenCount() - 1); + TokenEntry endTok = getEndToken(mark, match); if (endTok == TokenEntry.EOF) { endTok = get(mark.getIndex() + match.getTokenCount() - 2); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java index bea6819f9c..ab71d78bdf 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java @@ -117,9 +117,18 @@ public final class XMLRenderer implements Renderer, CPDRenderer { Mark mark; for (Iterator iterator = match.iterator(); iterator.hasNext();) { mark = iterator.next(); - Element file = doc.createElement("file"); + final Element file = doc.createElement("file"); file.setAttribute("line", String.valueOf(mark.getBeginLine())); file.setAttribute("path", mark.getFilename()); + file.setAttribute("endline", String.valueOf(mark.getEndLine())); + final int beginCol = mark.getBeginColumn(); + final int endCol = mark.getEndColumn(); + if (beginCol != -1) { + file.setAttribute("column", String.valueOf(beginCol)); + } + if (endCol != -1) { + file.setAttribute("endcolumn", String.valueOf(endCol)); + } duplication.appendChild(file); } return duplication; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java index 3310732cb0..4dc054e38a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java @@ -58,7 +58,7 @@ public abstract class AntlrTokenizer implements Tokenizer { } private void processToken(final Tokens tokenEntries, final String fileName, final AntlrToken token) { - final TokenEntry tokenEntry = new TokenEntry(token.getImage(), fileName, token.getBeginLine()); + final TokenEntry tokenEntry = new TokenEntry(token.getImage(), fileName, token.getBeginLine(), token.getBeginColumn() + 1, token.getEndColumn() + 1); tokenEntries.add(tokenEntry); } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/JavaCCTokenizer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/JavaCCTokenizer.java index 03adab05c5..0672b655f0 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/JavaCCTokenizer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/JavaCCTokenizer.java @@ -24,7 +24,7 @@ public abstract class JavaCCTokenizer implements Tokenizer { } protected TokenEntry processToken(Tokens tokenEntries, GenericToken currentToken, String filename) { - return new TokenEntry(currentToken.getImage(), filename, currentToken.getBeginLine()); + return new TokenEntry(currentToken.getImage(), filename, currentToken.getBeginLine(), currentToken.getBeginColumn(), currentToken.getEndColumn()); } @Override diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java index aebe05551f..4dcce59fbf 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java @@ -43,14 +43,14 @@ import net.sourceforge.pmd.lang.dfa.DataFlowNode; * method return an instance of this sub-interface. For example, * no JSP node should have a Java node as its child. Embedding nodes from * different languages will not be done via these methods, and conforming - * implementations should ensure, that every node returned by these methods + * implementations should ensure that every node returned by these methods * are indeed of the same type. Possibly, a type parameter will be added to * the Node interface in 7.0.0 to enforce it at compile-time. * *

A number of methods are deprecated and will be removed in 7.0.0. * Most of them are implementation details that clutter this API and * make implementation more difficult. Some methods prefixed with {@code jjt} - * have a more conventional counterpart (e.g. {@link #getParent()} and + * have a more conventional counterpart (e.g. {@link #jjtGetParent()} and * {@link #getParent()}) that should be preferred. */ public interface Node { diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkTest.java index 5f2e1c6915..5e0b0ed42c 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkTest.java @@ -29,6 +29,34 @@ public class MarkTest { assertEquals(beginLine, mark.getBeginLine()); assertEquals(lineCount, mark.getLineCount()); assertEquals(beginLine + lineCount - 1, mark.getEndLine()); + assertEquals(-1, mark.getBeginColumn()); + assertEquals(-1, mark.getEndColumn()); + assertEquals(codeFragment, mark.getSourceCodeSlice()); + } + + @Test + public void testColumns() { + final String filename = "/var/Foo.java"; + final int beginLine = 1; + final int beginColumn = 2; + final int endColumn = 3; + final TokenEntry token = new TokenEntry("public", "/var/Foo.java", 1, beginColumn, 0); + final TokenEntry endToken = new TokenEntry("}", "/var/Foo.java", 5, 0, endColumn); + + final Mark mark = new Mark(token); + final int lineCount = 10; + mark.setLineCount(lineCount); + mark.setEndToken(endToken); + final String codeFragment = "code fragment"; + mark.setSourceCode(new SourceCode(new StringCodeLoader(codeFragment))); + + assertEquals(token, mark.getToken()); + assertEquals(filename, mark.getFilename()); + assertEquals(beginLine, mark.getBeginLine()); + assertEquals(lineCount, mark.getLineCount()); + assertEquals(beginLine + lineCount - 1, mark.getEndLine()); + assertEquals(beginColumn, mark.getBeginColumn()); + assertEquals(endColumn, mark.getEndColumn()); assertEquals(codeFragment, mark.getSourceCodeSlice()); } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/TokenEntryTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/TokenEntryTest.java index d3e1042ae8..e66a27fb1e 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/TokenEntryTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/TokenEntryTest.java @@ -17,6 +17,19 @@ public class TokenEntryTest { assertEquals(1, mark.getBeginLine()); assertEquals("/var/Foo.java", mark.getTokenSrcID()); assertEquals(0, mark.getIndex()); + assertEquals(-1, mark.getBeginColumn()); + assertEquals(-1, mark.getEndColumn()); + } + + @Test + public void testColumns() { + TokenEntry.clearImages(); + TokenEntry mark = new TokenEntry("public", "/var/Foo.java", 1, 2, 3); + assertEquals(1, mark.getBeginLine()); + assertEquals("/var/Foo.java", mark.getTokenSrcID()); + assertEquals(0, mark.getIndex()); + assertEquals(2, mark.getBeginColumn()); + assertEquals(3, mark.getEndColumn()); } public static junit.framework.Test suite() { diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/XMLRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/XMLRendererTest.java index c6307b735a..22eca255a7 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/XMLRendererTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/XMLRendererTest.java @@ -78,6 +78,9 @@ public class XMLRendererTest { if (file != null) { assertEquals("1", file.getAttributes().getNamedItem("line").getNodeValue()); assertEquals("/var/Foo.java", file.getAttributes().getNamedItem("path").getNodeValue()); + assertEquals("6", file.getAttributes().getNamedItem("endline").getNodeValue()); + assertEquals(null, file.getAttributes().getNamedItem("column")); + assertEquals(null, file.getAttributes().getNamedItem("endcolumn")); file = file.getNextSibling(); while (file != null && file.getNodeType() != Node.ELEMENT_NODE) { file = file.getNextSibling(); @@ -85,6 +88,9 @@ public class XMLRendererTest { } if (file != null) { assertEquals("73", file.getAttributes().getNamedItem("line").getNodeValue()); + assertEquals("78", file.getAttributes().getNamedItem("endline").getNodeValue()); + assertEquals(null, file.getAttributes().getNamedItem("column")); + assertEquals(null, file.getAttributes().getNamedItem("endcolumn")); } assertEquals(1, doc.getElementsByTagName("codefragment").getLength()); assertEquals(codeFragment, doc.getElementsByTagName("codefragment").item(0).getTextContent()); @@ -126,6 +132,54 @@ public class XMLRendererTest { } } + @Test + public void testWithOneDuplicationWithColumns() throws IOException { + CPDRenderer renderer = new XMLRenderer(); + List list = new ArrayList<>(); + int lineCount = 6; + String codeFragment = "code\nfragment"; + Mark mark1 = createMark("public", "/var/Foo.java", 1, lineCount, codeFragment, 2, 3); + Mark mark2 = createMark("stuff", "/var/Foo.java", 73, lineCount, codeFragment, 4, 5); + Match match = new Match(75, mark1, mark2); + + list.add(match); + StringWriter sw = new StringWriter(); + renderer.render(list.iterator(), sw); + String report = sw.toString(); + try { + Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder() + .parse(new ByteArrayInputStream(report.getBytes(ENCODING))); + NodeList dupes = doc.getElementsByTagName("duplication"); + assertEquals(1, dupes.getLength()); + Node file = dupes.item(0).getFirstChild(); + while (file != null && file.getNodeType() != Node.ELEMENT_NODE) { + file = file.getNextSibling(); + } + if (file != null) { + assertEquals("1", file.getAttributes().getNamedItem("line").getNodeValue()); + assertEquals("/var/Foo.java", file.getAttributes().getNamedItem("path").getNodeValue()); + assertEquals("6", file.getAttributes().getNamedItem("endline").getNodeValue()); + assertEquals("2", file.getAttributes().getNamedItem("column").getNodeValue()); + assertEquals("3", file.getAttributes().getNamedItem("endcolumn").getNodeValue()); + file = file.getNextSibling(); + while (file != null && file.getNodeType() != Node.ELEMENT_NODE) { + file = file.getNextSibling(); + } + } + if (file != null) { + assertEquals("73", file.getAttributes().getNamedItem("line").getNodeValue()); + assertEquals("78", file.getAttributes().getNamedItem("endline").getNodeValue()); + assertEquals("4", file.getAttributes().getNamedItem("column").getNodeValue()); + assertEquals("5", file.getAttributes().getNamedItem("endcolumn").getNodeValue()); + } + assertEquals(1, doc.getElementsByTagName("codefragment").getLength()); + assertEquals(codeFragment, doc.getElementsByTagName("codefragment").item(0).getTextContent()); + } catch (Exception e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } + @Test public void testRendererEncodedPath() throws IOException { CPDRenderer renderer = new XMLRenderer(); @@ -135,7 +189,7 @@ public class XMLRendererTest { Mark mark2 = createMark("void", "/var/F 0) { tokenEntries.add(new TokenEntry(String.valueOf(currentToken.kind), sourceCode.getFileName(), - currentToken.beginLine)); + currentToken.beginLine, currentToken.beginColumn, currentToken.endColumn)); currentToken = (Token) tokenMgr.getNextToken(); } } catch (IOException e) { diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/cpd/PLSQLTokenizer.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/cpd/PLSQLTokenizer.java index b44122309b..40126ce624 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/cpd/PLSQLTokenizer.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/cpd/PLSQLTokenizer.java @@ -68,7 +68,8 @@ public class PLSQLTokenizer extends JavaCCTokenizer { image = String.valueOf(plsqlToken.kind); } - return new TokenEntry(image, fileName, currentToken.getBeginLine()); + return new TokenEntry(image, fileName, currentToken.getBeginLine(), + currentToken.getBeginColumn(), currentToken.getEndColumn()); } @Override diff --git a/pmd-scala/src/main/java/net/sourceforge/pmd/cpd/ScalaTokenizer.java b/pmd-scala/src/main/java/net/sourceforge/pmd/cpd/ScalaTokenizer.java index 7706e48d31..94c48abdc2 100644 --- a/pmd-scala/src/main/java/net/sourceforge/pmd/cpd/ScalaTokenizer.java +++ b/pmd-scala/src/main/java/net/sourceforge/pmd/cpd/ScalaTokenizer.java @@ -17,6 +17,7 @@ import net.sourceforge.pmd.lang.scala.ScalaLanguageModule; import scala.collection.Iterator; import scala.meta.Dialect; import scala.meta.inputs.Input; +import scala.meta.inputs.Position; import scala.meta.internal.tokenizers.ScalametaTokenizer; import scala.meta.tokens.Token; @@ -74,7 +75,9 @@ public class ScalaTokenizer implements Tokenizer { Token token; while ((token = filter.getNextToken()) != null) { String tokenText = token.text() != null ? token.text() : token.name(); - TokenEntry cpdToken = new TokenEntry(tokenText, filename, token.pos().startLine()); + Position tokenPosition = token.pos(); + TokenEntry cpdToken = new TokenEntry(tokenText, filename, tokenPosition.startLine(), + tokenPosition.startColumn(), tokenPosition.endColumn()); tokenEntries.add(cpdToken); } } finally { diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/cpd/VfTokenizer.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/cpd/VfTokenizer.java index 9ddce331de..13febc7b90 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/cpd/VfTokenizer.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/cpd/VfTokenizer.java @@ -34,7 +34,7 @@ public class VfTokenizer implements Tokenizer { while (currentToken.image.length() > 0) { tokenEntries.add(new TokenEntry(String.valueOf(currentToken.kind), sourceCode.getFileName(), - currentToken.beginLine)); + currentToken.beginLine, currentToken.beginColumn, currentToken.endColumn)); currentToken = (Token) tokenMgr.getNextToken(); } } catch (IOException e) {