From fe5f0daef923cbec7a3ad87a50e960e19fef42ca Mon Sep 17 00:00:00 2001 From: Anand Date: Sat, 1 Apr 2017 19:48:00 -0700 Subject: [PATCH 0001/2019] merge --- .../lang/plsql/ast/InlinePragmaProcError.pls | 34 +++++++------- .../pmd/lang/plsql/ast/IsOfType.pls | 44 +++++++++---------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/InlinePragmaProcError.pls b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/InlinePragmaProcError.pls index a362cfe50c1..93985c69099 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/InlinePragmaProcError.pls +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/InlinePragmaProcError.pls @@ -1,17 +1,17 @@ -create or replace package inline_praqma_error is - -end; -/ - -create or replace package body inline_praqma_error is - procedure do_transaction(p_input_token in varchar(200)) is - - begin - PRAGMA AUTONOMOUS_TRANSACTION; - bno74.log_hentglass_request(p_hentglass_request - ,v_logging_req_seq_no); - COMMIT; - end do_transaction; - -end inline_praqma_error; -/ +create or replace package inline_praqma_error is + +end; +/ + +create or replace package body inline_praqma_error is + procedure do_transaction(p_input_token in varchar(200)) is + + begin + PRAGMA AUTONOMOUS_TRANSACTION; + bno74.log_hentglass_request(p_hentglass_request + ,v_logging_req_seq_no); + COMMIT; + end do_transaction; + +end inline_praqma_error; +/ diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/IsOfType.pls b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/IsOfType.pls index c536a73f456..6806a042143 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/IsOfType.pls +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/IsOfType.pls @@ -1,23 +1,23 @@ -PROCEDURE IsOfType ( -inChannelID IN number, -inOperID IN number, -inClientId IN number, -ioFPOobj IN FPO_OBJ, -inPackageIDout IN number, -inStatusId IN number) -is -loFPOGE_OBJ FPOGE_OBJ; -BEGIN - -IF ioFPOobj IS OF (FPOGE_OBJ) THEN -loFPOGE_OBJ:=treat(ioFPOobj AS FPOGE_OBJ); -end if; - -IF ioFPOobj IS NOT OF TYPE (ONLY FPOGE_OBJ) THEN -loFPOGE_OBJ:=treat(ioFPOobj AS FPOGE_OBJ); -end if; - -loFPOGE_OBJ:=SELECT A FROM persons p WHERE IS OF TYPE (employee_t); -loFPOGE_OBJ:=SELECT A FROM persons p WHERE IS NOT OF TYPE (ONLY employee_t, other_t); - +PROCEDURE IsOfType ( +inChannelID IN number, +inOperID IN number, +inClientId IN number, +ioFPOobj IN FPO_OBJ, +inPackageIDout IN number, +inStatusId IN number) +is +loFPOGE_OBJ FPOGE_OBJ; +BEGIN + +IF ioFPOobj IS OF (FPOGE_OBJ) THEN +loFPOGE_OBJ:=treat(ioFPOobj AS FPOGE_OBJ); +end if; + +IF ioFPOobj IS NOT OF TYPE (ONLY FPOGE_OBJ) THEN +loFPOGE_OBJ:=treat(ioFPOobj AS FPOGE_OBJ); +end if; + +loFPOGE_OBJ:=SELECT A FROM persons p WHERE IS OF TYPE (employee_t); +loFPOGE_OBJ:=SELECT A FROM persons p WHERE IS NOT OF TYPE (ONLY employee_t, other_t); + end; \ No newline at end of file From 9aa8bfaa41bc95573a4480fb07936d3380ae121d Mon Sep 17 00:00:00 2001 From: Anand Date: Mon, 3 Apr 2017 00:16:04 -0700 Subject: [PATCH 0002/2019] Add rule preventing the use of non existent annotations in apex --- .../AvoidNonExistentAnnotationsRule.java | 88 +++++++++++++++++++ .../main/resources/rulesets/apex/ruleset.xml | 9 ++ .../main/resources/rulesets/apex/style.xml | 20 +++++ .../lang/apex/rule/style/StyleRulesTest.java | 1 + .../style/xml/AvoidNonExistentAnnotations.xml | 55 ++++++++++++ pmd-test/pom.xml | 5 ++ 6 files changed, 178 insertions(+) create mode 100644 pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/style/AvoidNonExistentAnnotationsRule.java create mode 100644 pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/style/xml/AvoidNonExistentAnnotations.xml diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/style/AvoidNonExistentAnnotationsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/style/AvoidNonExistentAnnotationsRule.java new file mode 100644 index 00000000000..f4477807108 --- /dev/null +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/style/AvoidNonExistentAnnotationsRule.java @@ -0,0 +1,88 @@ +package net.sourceforge.pmd.lang.apex.rule.style; + +import java.util.*; + +import net.sourceforge.pmd.lang.apex.ast.*; +import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule; + +import apex.jorje.semantic.ast.compilation.*; +import apex.jorje.semantic.ast.member.*; +import apex.jorje.semantic.ast.modifier.Annotation; +import apex.jorje.semantic.ast.modifier.ModifierNode; +import apex.jorje.semantic.symbol.type.*; + +/** + * Apex supported non existent annotations for legacy reasons. + * In the future, use of such non-existent annotations could result in broken apex code that will not copile. + * This will prevent users of garbage annotations from being able to use legitimate annotations added to apex in the future. + * + * @author a.subramanian + */ +public class AvoidNonExistentAnnotationsRule extends AbstractApexRule { + + private static final Set supportedApexAnnotations = getSupportedApexAnnotations(); + + @Override + public Object visit(final ASTUserClass node, final Object data) { + final UserClass userClass = node.getNode(); + checkForNonExistentAnnotation(node, userClass.getModifiers(), data); + return super.visit(node, data); + } + + @Override + public final Object visit(ASTUserInterface node, final Object data) { + final UserInterface userInterface = node.getNode(); + checkForNonExistentAnnotation(node, userInterface.getModifiers(), data); + return super.visit(node, data); + } + + @Override + public Object visit(final ASTUserEnum node, final Object data) { + final UserEnum userEnum = node.getNode(); + checkForNonExistentAnnotation(node, userEnum.getModifiers(), data); + return super.visit(node, data); + } + + @Override + public Object visit(final ASTMethod node, final Object data) { + final Method method = node.getNode(); + return checkForNonExistentAnnotation(node, method.getModifiersNode(), data); + } + + @Override + public Object visit(final ASTProperty node, final Object data) { + final Property property = node.getNode(); + return checkForNonExistentAnnotation(node, property.getModifiersNode(), data); + } + + @Override + public Object visit(final ASTField node, final Object data) { + final Field field = node.getNode(); + return checkForNonExistentAnnotation(node, field.getModifiers(), data); + } + + private Object checkForNonExistentAnnotation(final AbstractApexNode node, final ModifierNode modifierNode, final Object data) { + for (final Annotation annotation : modifierNode.getModifiers().getAnnotations()) { + if (!supportedApexAnnotations.contains(annotation.getType())) { + addViolationWithMessage(data, node, "Use of non existent annotations will lead to broken Apex code which will not compile in the future."); + } + } + return data; + } + + private static Set getSupportedApexAnnotations() { + final java.lang.reflect.Field[] fields = AnnotationTypeInfos.class.getFields(); + final Set annotationTypeInfos = new HashSet<>(); + for (final java.lang.reflect.Field field : fields) { + if (field.getType().isAssignableFrom(StandardAnnotationTypeInfo.class)) { + field.setAccessible(true); + try { + annotationTypeInfos.add((StandardAnnotationTypeInfo) field.get(null)); + } catch (final Exception illegalAccessException) { + continue; + } + } + } + return annotationTypeInfos; + } +} diff --git a/pmd-apex/src/main/resources/rulesets/apex/ruleset.xml b/pmd-apex/src/main/resources/rulesets/apex/ruleset.xml index 768ecd89942..f056dab2053 100644 --- a/pmd-apex/src/main/resources/rulesets/apex/ruleset.xml +++ b/pmd-apex/src/main/resources/rulesets/apex/ruleset.xml @@ -131,6 +131,15 @@ + + 3 + + + + + + + 3 diff --git a/pmd-apex/src/main/resources/rulesets/apex/style.xml b/pmd-apex/src/main/resources/rulesets/apex/style.xml index 3fa03f0adc6..455f497d061 100644 --- a/pmd-apex/src/main/resources/rulesets/apex/style.xml +++ b/pmd-apex/src/main/resources/rulesets/apex/style.xml @@ -132,4 +132,24 @@ Many interfaces (e.g. Batch) required global modifiers in the past but don't req + + + Apex supported non existent annotations for legacy reasons. + In the future, use of such non-existent annotations could result in broken apex code that will not copile. + This will prevent users of garbage annotations from being able to use legitimate annotations added to apex in the future. + + 3 + + + + diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/style/StyleRulesTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/style/StyleRulesTest.java index f16234d462a..2a95346bde9 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/style/StyleRulesTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/style/StyleRulesTest.java @@ -14,6 +14,7 @@ public class StyleRulesTest extends SimpleAggregatorTst { public void setUp() { addRule(RULESET, "AvoidGlobalModifier"); addRule(RULESET, "AvoidLogicInTrigger"); + addRule(RULESET, "AvoidNonExistentAnnotations"); addRule(RULESET, "ClassNamingConventions"); addRule(RULESET, "MethodNamingConventions"); addRule(RULESET, "VariableNamingConventions"); diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/style/xml/AvoidNonExistentAnnotations.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/style/xml/AvoidNonExistentAnnotations.xml new file mode 100644 index 00000000000..e252db3663a --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/style/xml/AvoidNonExistentAnnotations.xml @@ -0,0 +1,55 @@ + + + + + + Class with nonexistent annotation + 1 + + + + + Interface with nonexistent annotation + 1 + + + + + Method with non existent annotation + 1 + + + + + Property with non existent annotation + 1 + + + + + Field with non existent annotation + 1 + + + diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 5be06af8cde..1a68c7dc3ab 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -34,5 +34,10 @@ 1.10.19 test + + apex + apex-jorje-ide + 1.0-sfdc-187-SNAPSHOT-55042bfc2e + From 4e0dd619b6b771a9fe39c32a409c91bbd7da4829 Mon Sep 17 00:00:00 2001 From: Anand Date: Mon, 3 Apr 2017 00:17:48 -0700 Subject: [PATCH 0003/2019] Remove dependency from pmd test --- pmd-test/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 1a68c7dc3ab..5be06af8cde 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -34,10 +34,5 @@ 1.10.19 test - - apex - apex-jorje-ide - 1.0-sfdc-187-SNAPSHOT-55042bfc2e - From cc9edda0491a0e17585a481b493b471a5015c50e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20So=CC=88semann?= Date: Thu, 6 Apr 2017 15:27:02 +0200 Subject: [PATCH 0004/2019] Add custom rule property for Codacy.com plus minor adjustments --- .../main/resources/rulesets/apex/ruleset.xml | 238 +++++++++++++----- 1 file changed, 173 insertions(+), 65 deletions(-) diff --git a/pmd-apex/src/main/resources/rulesets/apex/ruleset.xml b/pmd-apex/src/main/resources/rulesets/apex/ruleset.xml index 768ecd89942..1b1a8ac12a1 100644 --- a/pmd-apex/src/main/resources/rulesets/apex/ruleset.xml +++ b/pmd-apex/src/main/resources/rulesets/apex/ruleset.xml @@ -1,93 +1,121 @@ + Default ruleset used by the Code Climate Engine for Salesforce.com Apex + - 3 + 2 - + + + + - 3 + 2 - + + + + - 3 + 2 - + + + + - 3 + 2 - + + + + - 3 + 2 - + + + + - 3 + 2 - + + + + - 3 + 2 - + + + + - 3 + 2 - + + + + - 3 + 2 - + + + @@ -95,233 +123,313 @@ + - 3 + 2 - + + + + - 3 + 2 - + + + + + + - 3 + 2 - + + + + - 3 + 2 - + + + - + 3 - + + + + 3 - + + + + 3 - + + + + 3 - + + + - + + + 3 - + + + + 3 - + + + + + - 3 + 1 - + + + + - 3 + 1 - + + + + - 3 + 1 - + + + + - 3 + 1 - + + + + - 3 + 1 - + + + + - 3 + 1 - + + + + - 3 + 1 - + + + + - 3 + 1 - + + + + - 3 + 1 - + + + + - 3 + 1 - + + + - + + - 3 + 1 - + + + + + - 3 + 2 - + + + + - 3 + 2 - + + + + - 3 + 2 - + + + + - 3 + 2 - + + + + \ No newline at end of file From 9d0c4d2c8e04e783f4e0c45017c0a09f7b74f3cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20So=CC=88semann?= Date: Thu, 20 Apr 2017 11:46:40 +0200 Subject: [PATCH 0005/2019] Define new Codacy.com specific property for Apex rulesets --- .../net/sourceforge/pmd/lang/apex/rule/AbstractApexRule.java | 2 ++ 1 file changed, 2 insertions(+) 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 b51210428b3..bad1f3b63ad 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 @@ -96,6 +96,7 @@ import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.rule.AbstractRule; import net.sourceforge.pmd.lang.rule.ImmutableLanguage; +import net.sourceforge.pmd.lang.rule.properties.IntegerProperty; import net.sourceforge.pmd.renderers.CodeClimateRule; public abstract class AbstractApexRule extends AbstractRule @@ -106,6 +107,7 @@ public AbstractApexRule() { definePropertyDescriptor(CODECLIMATE_CATEGORIES); definePropertyDescriptor(CODECLIMATE_REMEDIATION_MULTIPLIER); definePropertyDescriptor(CODECLIMATE_BLOCK_HIGHLIGHTING); + definePropertyDescriptor(new IntegerProperty("codacy_minutes_to_fix", "Codacy.com Time to fix in minutes", Integer.MIN_VALUE, Integer.MAX_VALUE, 5, 1.0f)); } @Override From a575910cdda9d5264277002449b05b44ee5d44e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20So=CC=88semann?= Date: Fri, 21 Apr 2017 11:26:20 +0200 Subject: [PATCH 0006/2019] Made CODACY_TIME_TO_FIX property static final --- .../net/sourceforge/pmd/lang/apex/rule/AbstractApexRule.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 bad1f3b63ad..b13b0c82086 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 @@ -101,13 +101,16 @@ public abstract class AbstractApexRule extends AbstractRule implements ApexParserVisitor, ImmutableLanguage, CodeClimateRule { + + private static final IntegerProperty CODACY_TIME_TO_FIX = new IntegerProperty("codacy_minutes_to_fix", + "Codacy.com Time to fix in minutes", Integer.MIN_VALUE, Integer.MAX_VALUE, 5, 1.0f); public AbstractApexRule() { super.setLanguage(LanguageRegistry.getLanguage(ApexLanguageModule.NAME)); definePropertyDescriptor(CODECLIMATE_CATEGORIES); definePropertyDescriptor(CODECLIMATE_REMEDIATION_MULTIPLIER); definePropertyDescriptor(CODECLIMATE_BLOCK_HIGHLIGHTING); - definePropertyDescriptor(new IntegerProperty("codacy_minutes_to_fix", "Codacy.com Time to fix in minutes", Integer.MIN_VALUE, Integer.MAX_VALUE, 5, 1.0f)); + definePropertyDescriptor(CODACY_TIME_TO_FIX); } @Override From 0096700a664d70da741925479a98420741fdc04c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20So=CC=88semann?= Date: Fri, 21 Apr 2017 17:17:44 +0200 Subject: [PATCH 0007/2019] https://github.com/pmd/pmd/pull/329#discussion_r112703324 --- .../sourceforge/pmd/lang/apex/rule/AbstractApexRule.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 b13b0c82086..78d8be1522f 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 @@ -102,15 +102,15 @@ public abstract class AbstractApexRule extends AbstractRule implements ApexParserVisitor, ImmutableLanguage, CodeClimateRule { - private static final IntegerProperty CODACY_TIME_TO_FIX = new IntegerProperty("codacy_minutes_to_fix", - "Codacy.com Time to fix in minutes", Integer.MIN_VALUE, Integer.MAX_VALUE, 5, 1.0f); + private static final IntegerProperty CODACY_MINUTES_TO_FIX = new IntegerProperty("codacy_minutes_to_fix", + "Codacy.com Time to fix in minutes", 0, Integer.MAX_VALUE, 5, 1.0f); public AbstractApexRule() { super.setLanguage(LanguageRegistry.getLanguage(ApexLanguageModule.NAME)); definePropertyDescriptor(CODECLIMATE_CATEGORIES); definePropertyDescriptor(CODECLIMATE_REMEDIATION_MULTIPLIER); definePropertyDescriptor(CODECLIMATE_BLOCK_HIGHLIGHTING); - definePropertyDescriptor(CODACY_TIME_TO_FIX); + definePropertyDescriptor(CODACY_MINUTES_TO_FIX); } @Override From b3046de6eeacf14c36443521d990c694f6255b8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20So=CC=88semann?= Date: Mon, 24 Apr 2017 11:54:10 +0200 Subject: [PATCH 0008/2019] Fix Checkstyle issues --- .../sourceforge/pmd/lang/apex/rule/AbstractApexRule.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 78d8be1522f..9e6ef74e035 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 @@ -101,9 +101,9 @@ public abstract class AbstractApexRule extends AbstractRule implements ApexParserVisitor, ImmutableLanguage, CodeClimateRule { - - private static final IntegerProperty CODACY_MINUTES_TO_FIX = new IntegerProperty("codacy_minutes_to_fix", - "Codacy.com Time to fix in minutes", 0, Integer.MAX_VALUE, 5, 1.0f); + + private static final IntegerProperty CODACY_MINUTES_TO_FIX = new IntegerProperty("codacy_minutes_to_fix", + "Codacy.com Time to fix in minutes", 0, Integer.MAX_VALUE, 5, 1.0f); public AbstractApexRule() { super.setLanguage(LanguageRegistry.getLanguage(ApexLanguageModule.NAME)); From b97462fa24f3690d94919c53e915c62df9bebb55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20So=CC=88semann?= Date: Mon, 24 Apr 2017 12:22:23 +0200 Subject: [PATCH 0009/2019] Make Time to fix property work for XPath rules --- .../net/sourceforge/pmd/lang/apex/rule/AbstractApexRule.java | 2 +- .../java/net/sourceforge/pmd/lang/apex/rule/ApexXPathRule.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) 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 9e6ef74e035..cedb30ae7c4 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 @@ -102,7 +102,7 @@ public abstract class AbstractApexRule extends AbstractRule implements ApexParserVisitor, ImmutableLanguage, CodeClimateRule { - private static final IntegerProperty CODACY_MINUTES_TO_FIX = new IntegerProperty("codacy_minutes_to_fix", + public static final IntegerProperty CODACY_MINUTES_TO_FIX = new IntegerProperty("codacy_minutes_to_fix", "Codacy.com Time to fix in minutes", 0, Integer.MAX_VALUE, 5, 1.0f); public AbstractApexRule() { diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/ApexXPathRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/ApexXPathRule.java index ea86f815fe2..85eec0a3bfe 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/ApexXPathRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/ApexXPathRule.java @@ -18,6 +18,7 @@ public ApexXPathRule() { definePropertyDescriptor(CODECLIMATE_CATEGORIES); definePropertyDescriptor(CODECLIMATE_REMEDIATION_MULTIPLIER); definePropertyDescriptor(CODECLIMATE_BLOCK_HIGHLIGHTING); + definePropertyDescriptor(AbstractApexRule.CODACY_MINUTES_TO_FIX); } @Override From 76b9b393689d4d5a2e3ecce2fc78ffca524e8f0d Mon Sep 17 00:00:00 2001 From: oowekyala Date: Sat, 12 Aug 2017 18:37:09 +0200 Subject: [PATCH 0010/2019] Separated multifile analysis from metrics --- .../net/sourceforge/pmd/RuleSetWriter.java | 2 +- .../sourceforge/pmd/SourceCodeProcessor.java | 8 + .../sourceforge/pmd/benchmark/Benchmark.java | 17 ++- .../lang/AbstractLanguageVersionHandler.java | 5 + .../pmd/lang/LanguageVersionHandler.java | 9 ++ .../pmd/lang/rule/AbstractRule.java | 4 +- .../pmd/lang/java/AbstractJavaHandler.java | 11 ++ .../ast/ASTClassOrInterfaceDeclaration.java | 2 +- .../java/ast/ASTConstructorDeclaration.java | 2 +- .../lang/java/ast/ASTFieldDeclaration.java | 2 +- .../lang/java/ast/ASTMethodDeclaration.java | 2 +- .../ASTMethodOrConstructorDeclaration.java | 2 +- .../pmd/lang/java/ast/JavaQualifiedName.java | 22 ++- .../lang/java/metrics/AbstractJavaMetric.java | 27 +--- .../lang/java/metrics/JavaMetricsFacade.java | 12 -- .../lang/java/metrics/JavaMetricsVisitor.java | 27 +--- .../metrics/JavaMetricsVisitorFacade.java | 3 +- .../metrics/impl/AbstractJavaClassMetric.java | 4 +- .../lang/java/metrics/impl/NoamMetric.java | 6 +- .../lang/java/metrics/impl/NopaMetric.java | 4 +- .../pmd/lang/java/metrics/impl/WocMetric.java | 6 +- .../metrics/signature/JavaFieldSigMask.java | 39 ----- .../signature/JavaOperationSigMask.java | 68 --------- .../pmd/lang/java/multifile/ClassMirror.java | 61 ++++++++ .../{metrics => multifile}/ClassStats.java | 71 +++++---- .../lang/java/multifile/MultifileFacade.java | 42 ++++++ .../java/multifile/MultifileFacadeBacker.java | 26 ++++ .../lang/java/multifile/MultifileVisitor.java | 52 +++++++ .../multifile/MultifileVisitorFacade.java | 22 +++ .../{metrics => multifile}/PackageStats.java | 24 +-- .../ProjectMirror.java} | 19 ++- .../multifile/signature/JavaFieldSigMask.java | 97 ++++++++++++ .../signature/JavaFieldSignature.java | 12 +- .../signature/JavaOperationSigMask.java | 111 ++++++++++++++ .../signature/JavaOperationSignature.java | 12 +- .../signature/JavaSigMask.java | 24 ++- .../signature/JavaSignature.java | 2 +- .../java/metrics/JavaMetricsVisitorTest.java | 111 -------------- .../java/metrics/ProjectMemoizerTest.java | 10 +- .../pmd/lang/java/metrics/SigMaskTest.java | 20 +-- .../pmd/lang/java/metrics/SignatureTest.java | 10 +- .../lang/java/multifile/ClassStatsTest.java | 79 ++++++++++ .../multifile/JavaMultifileVisitorTest.java | 93 ++++++++++++ .../PackageStatsTest.java | 13 +- .../testdata/MultifileVisitorTestData.java | 75 ++++++++++ .../testdata/SignatureCountTestData.java | 140 ++++++++++++++++++ 46 files changed, 1025 insertions(+), 385 deletions(-) delete mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaFieldSigMask.java delete mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaOperationSigMask.java create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ClassMirror.java rename pmd-java/src/main/java/net/sourceforge/pmd/lang/java/{metrics => multifile}/ClassStats.java (68%) create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileFacade.java create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileFacadeBacker.java create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileVisitor.java create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileVisitorFacade.java rename pmd-java/src/main/java/net/sourceforge/pmd/lang/java/{metrics => multifile}/PackageStats.java (84%) rename pmd-java/src/main/java/net/sourceforge/pmd/lang/java/{metrics/JavaSignatureMatcher.java => multifile/ProjectMirror.java} (66%) create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaFieldSigMask.java rename pmd-java/src/main/java/net/sourceforge/pmd/lang/java/{metrics => multifile}/signature/JavaFieldSignature.java (85%) create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaOperationSigMask.java rename pmd-java/src/main/java/net/sourceforge/pmd/lang/java/{metrics => multifile}/signature/JavaOperationSignature.java (95%) rename pmd-java/src/main/java/net/sourceforge/pmd/lang/java/{metrics => multifile}/signature/JavaSigMask.java (68%) rename pmd-java/src/main/java/net/sourceforge/pmd/lang/java/{metrics => multifile}/signature/JavaSignature.java (96%) delete mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitorTest.java create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/ClassStatsTest.java create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/JavaMultifileVisitorTest.java rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/{metrics => multifile}/PackageStatsTest.java (84%) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/testdata/MultifileVisitorTestData.java create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/testdata/SignatureCountTestData.java diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetWriter.java b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetWriter.java index aa2edbc67ee..80ea5d6f79f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetWriter.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetWriter.java @@ -195,7 +195,7 @@ private Element createRuleElement(Rule rule) { return createSingleRuleElement(rule instanceof ImmutableLanguage ? null : rule.getLanguage(), rule.getMinimumLanguageVersion(), rule.getMaximumLanguageVersion(), rule.isDeprecated(), rule.getName(), rule.getSince(), null, rule.getMessage(), rule.getExternalInfoUrl(), - rule.getRuleClass(), rule.usesDFA(), rule.usesTypeResolution(), rule.usesMetrics(), + rule.getRuleClass(), rule.usesDFA(), rule.usesTypeResolution(), rule.usesMultifile(), rule.getDescription(), rule.getPriority(), rule.getPropertyDescriptors(), rule.getPropertiesByPropertyDescriptor(), rule.getExamples()); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/SourceCodeProcessor.java b/pmd-core/src/main/java/net/sourceforge/pmd/SourceCodeProcessor.java index e361f742093..91ff2769f26 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/SourceCodeProcessor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/SourceCodeProcessor.java @@ -167,6 +167,13 @@ private void usesMetrics(LanguageVersion languageVersion, Node rootNode, RuleSet } } + private void multifileAnalysis(Node rootNode, LanguageVersionHandler languageVersionHandler) { + long start = System.nanoTime(); + languageVersionHandler.getMultifileFacade().start(rootNode); + long end = System.nanoTime(); + Benchmarker.mark(Benchmark.Multifile, end - start, 0); + } + private void processSource(Reader sourceCode, RuleSets ruleSets, RuleContext ctx) { LanguageVersion languageVersion = ctx.getLanguageVersion(); LanguageVersionHandler languageVersionHandler = languageVersion.getLanguageVersionHandler(); @@ -177,6 +184,7 @@ private void processSource(Reader sourceCode, RuleSets ruleSets, RuleContext ctx Language language = languageVersion.getLanguage(); usesDFA(languageVersion, rootNode, ruleSets, language); usesTypeResolution(languageVersion, rootNode, ruleSets, language); + multifileAnalysis(rootNode, languageVersionHandler); usesMetrics(languageVersion, rootNode, ruleSets, language); List acus = Collections.singletonList(rootNode); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmark.java b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmark.java index ac37b993e59..8674abd1c18 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmark.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmark.java @@ -17,14 +17,15 @@ public enum Benchmark { SymbolTable(5, "Symbol table"), DFA(6, "DFA"), TypeResolution(7, "Type resolution"), - MetricsVisitor(8, "Metrics"), - RuleChainVisit(9, "RuleChain visit"), - Reporting(10, "Reporting"), - RuleTotal(11, "Rule total"), - RuleChainTotal(12, "Rule chain rule total"), - MeasuredTotal(13, "Measured total"), - NonMeasuredTotal(14, "Non-measured total"), - TotalPMD(15, "Total PMD"); + Multifile(8, "Multifile analysis"), + MetricsVisitor(9, "Metrics"), + RuleChainVisit(10, "RuleChain visit"), + Reporting(11, "Reporting"), + RuleTotal(12, "Rule total"), + RuleChainTotal(13, "Rule chain rule total"), + MeasuredTotal(14, "Measured total"), + NonMeasuredTotal(15, "Non-measured total"), + TotalPMD(16, "Total PMD"); public final int index; public final String name; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/AbstractLanguageVersionHandler.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/AbstractLanguageVersionHandler.java index 948f2c7cb9f..0d78c42dcc6 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/AbstractLanguageVersionHandler.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/AbstractLanguageVersionHandler.java @@ -60,6 +60,11 @@ public VisitorStarter getDumpFacade(final Writer writer, final String prefix, fi return VisitorStarter.DUMMY; } + @Override + public VisitorStarter getMultifileFacade() { + return VisitorStarter.DUMMY; + } + @Override public DFAGraphRule getDFAGraphRule() { return null; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionHandler.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionHandler.java index 238e711a665..7208da4619f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionHandler.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionHandler.java @@ -95,5 +95,14 @@ public interface LanguageVersionHandler { */ VisitorStarter getDumpFacade(Writer writer, String prefix, boolean recurse); + + /** + * Gets the visitor that performs multifile data gathering. + * + * @return The visitor starter + */ + VisitorStarter getMultifileFacade(); + + DFAGraphRule getDFAGraphRule(); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java index 0eba4fc1d59..c7b946c7b56 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java @@ -527,8 +527,8 @@ public Rule deepCopy() { if (usesTypeResolution()) { rule.setUsesTypeResolution(); } - if (usesMetrics()) { - rule.setUsesMetrics(); + if (usesMultifile()) { + rule.setUsesMultifile(); } rule.setDescription(getDescription()); for (final String example : getExamples()) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/AbstractJavaHandler.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/AbstractJavaHandler.java index 2b591f8e225..49913071908 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/AbstractJavaHandler.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/AbstractJavaHandler.java @@ -20,6 +20,7 @@ import net.sourceforge.pmd.lang.java.dfa.DataFlowFacade; import net.sourceforge.pmd.lang.java.dfa.JavaDFAGraphRule; import net.sourceforge.pmd.lang.java.metrics.JavaMetricsVisitorFacade; +import net.sourceforge.pmd.lang.java.multifile.MultifileVisitorFacade; import net.sourceforge.pmd.lang.java.rule.JavaRuleViolationFactory; import net.sourceforge.pmd.lang.java.symboltable.SymbolFacade; import net.sourceforge.pmd.lang.java.typeresolution.TypeResolutionFacade; @@ -116,6 +117,16 @@ public void start(Node rootNode) { }; } + @Override + public VisitorStarter getMultifileFacade() { + return new VisitorStarter() { + @Override + public void start(Node rootNode) { + new MultifileVisitorFacade().initializeWith((ASTCompilationUnit) rootNode); + } + }; + } + @Override public DFAGraphRule getDFAGraphRule() { return new JavaDFAGraphRule(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclaration.java index 9e09fe341c3..f6606831595 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclaration.java @@ -50,7 +50,7 @@ public void setInterface() { public JavaQualifiedName getQualifiedName() { if (qualifiedName == null) { if (isNested()) { - ASTClassOrInterfaceDeclaration parent = this.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class); + ASTAnyTypeDeclaration parent = this.getFirstParentOfType(ASTAnyTypeDeclaration.class); JavaQualifiedName parentQN = parent.getQualifiedName(); qualifiedName = JavaQualifiedName.ofNestedClass(parentQN, this.getImage()); return qualifiedName; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java index 666f75bbdfe..dd598a3668f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java @@ -5,7 +5,7 @@ package net.sourceforge.pmd.lang.java.ast; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSignature; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature; public class ASTConstructorDeclaration extends AbstractJavaAccessNode implements ASTMethodOrConstructorDeclaration { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java index 82c8eb37c6d..4cc365d1475 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java @@ -6,7 +6,7 @@ package net.sourceforge.pmd.lang.java.ast; import net.sourceforge.pmd.lang.ast.SignedNode; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaFieldSignature; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSignature; public class ASTFieldDeclaration extends AbstractJavaAccessTypeNode implements Dimensionable, SignedNode { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java index f9e93ac83ad..9c9f2309bcf 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java @@ -7,7 +7,7 @@ import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.dfa.DFAGraphMethod; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSignature; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature; public class ASTMethodDeclaration extends AbstractJavaAccessNode implements DFAGraphMethod, ASTMethodOrConstructorDeclaration { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodOrConstructorDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodOrConstructorDeclaration.java index b141d01e2b3..58d79bdeac9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodOrConstructorDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodOrConstructorDeclaration.java @@ -5,7 +5,7 @@ package net.sourceforge.pmd.lang.java.ast; import net.sourceforge.pmd.lang.ast.SignedNode; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSignature; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature; /** * @author Clément Fournier diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaQualifiedName.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaQualifiedName.java index 843fb567e8d..b105ad6cc82 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaQualifiedName.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaQualifiedName.java @@ -63,7 +63,7 @@ private JavaQualifiedName() { } - /** Factorises the functionality of makeOperationof() */ + /** Factorises the functionality of ofOperation() */ private static JavaQualifiedName ofOperation(JavaQualifiedName parent, String opName, ASTFormalParameters params) { JavaQualifiedName qname = new JavaQualifiedName(); @@ -115,11 +115,27 @@ private static JavaQualifiedName ofOperation(JavaQualifiedName parent, String op } - // Might be useful with type resolution + /** + * Gets the qualified name of a class. + * + * @param clazz Class object + * + * @return The qualified name of the class, or null if the class is null + */ public static JavaQualifiedName ofClass(Class clazz) { - throw new UnsupportedOperationException(); + if (clazz == null) { + return null; + } + + String name = clazz.getName(); + if (name.indexOf('.') < 0) { + name = '.' + name; + } + + return ofString(name); } + /** * Parses a qualified name given in the format defined for this implementation. The format * is specified by a regex pattern (see {@link JavaQualifiedName#FORMAT}). Examples: diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/AbstractJavaMetric.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/AbstractJavaMetric.java index 9c6809bbcde..b287e0400e3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/AbstractJavaMetric.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/AbstractJavaMetric.java @@ -4,18 +4,12 @@ package net.sourceforge.pmd.lang.java.metrics; -import java.util.ArrayList; -import java.util.List; - import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration; -import net.sourceforge.pmd.lang.java.ast.JavaQualifiedName; import net.sourceforge.pmd.lang.metrics.AbstractMetric; /** - * Base class for metrics. Metric objects encapsulate the computational logic required to compute a metric from a - * PackageStats and node. They're stateless. + * Base class for metrics. Metric objects encapsulate the computational logic required to compute a metric from a node. * * @param Type of node the metric can be computed on * @@ -23,23 +17,4 @@ */ public abstract class AbstractJavaMetric extends AbstractMetric { - - protected List findAllCalls(ASTMethodOrConstructorDeclaration node) { - List result = new ArrayList<>(); - // TODO:cf findAllCalls - // Needs TypeRes - // Find the qualified names of all methods called in that method's block - return result; - } - - - /** - * Gives access to a signature matcher to metrics. They can use it to perform signature matching. - * - * @return A signature matcher - */ - protected static JavaSignatureMatcher getSignatureMatcher() { - return JavaMetrics.getFacade().getTopLevelPackageStats(); - } - } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsFacade.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsFacade.java index ce79002be34..26cf94d6830 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsFacade.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsFacade.java @@ -16,27 +16,15 @@ */ class JavaMetricsFacade extends AbstractMetricsFacade { - private final PackageStats topLevelPackageStats = new PackageStats(); private final JavaProjectMemoizer memoizer = new JavaProjectMemoizer(); /** Resets the entire data structure. Used for tests. */ void reset() { - topLevelPackageStats.reset(); memoizer.reset(); } - /** - * Gets the top level package stats of this façade. - * - * @return The top level package stats - */ - PackageStats getTopLevelPackageStats() { - return topLevelPackageStats; - } - - @Override public JavaProjectMemoizer getLanguageSpecificProjectMemoizer() { return memoizer; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitor.java index 107c19ea3db..c6b637e87e8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitor.java @@ -4,28 +4,21 @@ package net.sourceforge.pmd.lang.java.metrics; -import java.util.Stack; - import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration; -import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration; import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorReducedAdapter; /** - * Visitor for the metrics framework, that fills a {@link PackageStats} object with the signatures of operations and - * fields it encounters. + * Visitor for the metrics framework, that creates the memoizers. * * @author Clément Fournier */ class JavaMetricsVisitor extends JavaParserVisitorReducedAdapter { - private final Stack stack = new Stack<>(); - private final PackageStats toplevel; private final JavaProjectMemoizer memoizer; - JavaMetricsVisitor(PackageStats toplevel, JavaProjectMemoizer memoizer) { - this.toplevel = toplevel; + JavaMetricsVisitor(JavaProjectMemoizer memoizer) { this.memoizer = memoizer; } @@ -33,28 +26,14 @@ class JavaMetricsVisitor extends JavaParserVisitorReducedAdapter { @Override public Object visit(ASTAnyTypeDeclaration node, Object data) { memoizer.addClassMemoizer(node.getQualifiedName()); - - stack.push(toplevel.getClassStats(node.getQualifiedName(), true)); - super.visit(node, data); - stack.pop(); - - return data; + return super.visit(node, data); } @Override public Object visit(ASTMethodOrConstructorDeclaration node, Object data) { memoizer.addOperationMemoizer(node.getQualifiedName()); - - stack.peek().addOperation(node.getQualifiedName().getOperation(), node.getSignature()); return super.visit(node, data); } - - @Override - public Object visit(ASTFieldDeclaration node, Object data) { - stack.peek().addField(node.getVariableName(), node.getSignature()); - return data; // end recursion - } - } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitorFacade.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitorFacade.java index 9ae8ea0501f..4c4f6d4b205 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitorFacade.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitorFacade.java @@ -16,8 +16,7 @@ public class JavaMetricsVisitorFacade extends JavaParserVisitorAdapter { public void initializeWith(ASTCompilationUnit rootNode) { JavaMetricsFacade facade = JavaMetrics.getFacade(); - JavaMetricsVisitor visitor = new JavaMetricsVisitor(facade.getTopLevelPackageStats(), - facade.getLanguageSpecificProjectMemoizer()); + JavaMetricsVisitor visitor = new JavaMetricsVisitor(facade.getLanguageSpecificProjectMemoizer()); rootNode.jjtAccept(visitor, null); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/AbstractJavaClassMetric.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/AbstractJavaClassMetric.java index 045b7a8759c..1f471c37bf5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/AbstractJavaClassMetric.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/AbstractJavaClassMetric.java @@ -15,8 +15,8 @@ import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration; import net.sourceforge.pmd.lang.java.metrics.AbstractJavaMetric; import net.sourceforge.pmd.lang.java.metrics.api.JavaClassMetric; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaFieldSigMask; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSigMask; /** * Base class for class metrics. diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/NoamMetric.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/NoamMetric.java index c94237d35c2..057e74a2b08 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/NoamMetric.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/NoamMetric.java @@ -6,9 +6,9 @@ import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration.TypeKind; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSigMask; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSignature.Role; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaSignature.Visibility; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature.Role; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaSignature.Visibility; import net.sourceforge.pmd.lang.metrics.MetricOptions; /** diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/NopaMetric.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/NopaMetric.java index e19fa2761b4..9dc5d140987 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/NopaMetric.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/NopaMetric.java @@ -6,8 +6,8 @@ import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration.TypeKind; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaFieldSigMask; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaSignature.Visibility; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaSignature.Visibility; import net.sourceforge.pmd.lang.metrics.MetricOptions; /** diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/WocMetric.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/WocMetric.java index b3be183fdf1..c42f258e72f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/WocMetric.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/impl/WocMetric.java @@ -6,9 +6,9 @@ import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration.TypeKind; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSigMask; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSignature.Role; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaSignature.Visibility; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature.Role; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaSignature.Visibility; import net.sourceforge.pmd.lang.metrics.MetricOptions; /** diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaFieldSigMask.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaFieldSigMask.java deleted file mode 100644 index b3844825ad9..00000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaFieldSigMask.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.metrics.signature; - -/** - * Signature mask for a field. Newly created masks cover any field. - * - * @author Clément Fournier - */ -public final class JavaFieldSigMask extends JavaSigMask { - - private boolean coverFinal = true; - private boolean coverStatic = true; - - - public JavaFieldSigMask() { - super(); - } - - - /** Include final fields?. */ - public void coverFinal(boolean coverFinal) { - this.coverFinal = coverFinal; - } - - - /** Include static fields?. */ - public void coverStatic(boolean coverStatic) { - this.coverStatic = coverStatic; - } - - - @Override - public boolean covers(JavaFieldSignature sig) { - return super.covers(sig) && (coverFinal || !sig.isFinal) && (coverStatic || !sig.isStatic); - } -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaOperationSigMask.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaOperationSigMask.java deleted file mode 100644 index 4dbe77025ef..00000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaOperationSigMask.java +++ /dev/null @@ -1,68 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.metrics.signature; - -import java.util.Arrays; -import java.util.EnumSet; -import java.util.Set; - -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSignature.Role; - -/** - * Signature mask for an operation. Newly created masks cover any operation that is not abstract. - * - * @author Clément Fournier - */ -public final class JavaOperationSigMask extends JavaSigMask { - - private Set roleMask = EnumSet.allOf(Role.class); - private boolean coverAbstract = false; - - - /** - * Sets the mask to cover all roles. - */ - public void coverAllRoles() { - roleMask.addAll(Arrays.asList(JavaOperationSignature.Role.values())); - } - - - /** - * Restricts the roles covered by the mask to the parameters. - * - * @param roles The roles to cover - */ - public void restrictRolesTo(JavaOperationSignature.Role... roles) { - roleMask.clear(); - roleMask.addAll(Arrays.asList(roles)); - } - - - /** - * Forbid all mentioned roles. - * - * @param roles The roles to forbid - */ - public void forbid(JavaOperationSignature.Role... roles) { - roleMask.removeAll(Arrays.asList(roles)); - } - - - /** - * Forbid all mentioned visibilities. - * - * @param coverAbstract The visibilities to forbid - */ - public void coverAbstract(boolean coverAbstract) { - this.coverAbstract = coverAbstract; - } - - - @Override - public boolean covers(JavaOperationSignature sig) { - return super.covers(sig) && roleMask.contains(sig.role) && (coverAbstract - || !sig.isAbstract); - } -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ClassMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ClassMirror.java new file mode 100644 index 00000000000..0211ba37ea8 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ClassMirror.java @@ -0,0 +1,61 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.multifile; + +import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSigMask; + +/** + * Represents a class for signature matching. + * + * TODO:cf count signatures + * + * @author Clément Fournier + */ +public interface ClassMirror { + + /** + * Returns true if the signature of the operation designated by the qualified name is covered by the mask. + * + * @param opName The operation to test + * @param sigMask The signature mask to use + * + * @return True if the signature of the operation designated by the qualified name is covered by the mask + */ + boolean hasMatchingSig(String opName, JavaOperationSigMask sigMask); + + + /** + * Returns true if the signature of the field designated by its name and the qualified name of its class is covered + * by the mask. + * + * @param fieldName The name of the field + * @param sigMask The signature mask to use + * + * @return True if the signature of the field is covered by the mask + */ + boolean hasMatchingSig(String fieldName, JavaFieldSigMask sigMask); + + + /** + * Returns the number of operations matching the signature mask in the class. + * + * @param sigMask Signature mask + * + * @return The number of operations matching the signature mask + */ + int countMatchingOpSigs(JavaOperationSigMask sigMask); + + + /** + * Returns the number of fields matching the signature mask in the class. + * + * @param sigMask Signature mask + * + * @return The number of fields matching the signature mask + */ + int countMatchingFieldSigs(JavaFieldSigMask sigMask); + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/ClassStats.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ClassStats.java similarity index 68% rename from pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/ClassStats.java rename to pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ClassStats.java index 902bfa22424..525c419905a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/ClassStats.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ClassStats.java @@ -2,18 +2,19 @@ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ -package net.sourceforge.pmd.lang.java.metrics; +package net.sourceforge.pmd.lang.java.multifile; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import net.sourceforge.pmd.lang.java.ast.JavaQualifiedName; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaFieldSigMask; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaFieldSignature; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSigMask; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSignature; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSignature; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature; /** * Statistics about a class, enum, interface, or annotation. Stores information about the contained members and their @@ -26,7 +27,7 @@ * * @author Clément Fournier */ -/* default */ class ClassStats { +final class ClassStats implements ClassMirror { private Map> operations = new HashMap<>(); private Map> fields = new HashMap<>(); @@ -57,7 +58,7 @@ * * @return The new ClassStats or the one that was found. Can return null if createIfNotFound is unset */ - /* default */ ClassStats getNestedClassStats(String className, boolean createIfNotFound) { + ClassStats getNestedClassStats(String className, boolean createIfNotFound) { if (createIfNotFound && !nestedClasses.containsKey(className)) { nestedClasses.put(className, new ClassStats()); } @@ -71,7 +72,7 @@ * @param name The name of the operation * @param sig The signature of the operation */ - /* default */ void addOperation(String name, JavaOperationSignature sig) { + void addOperation(String name, JavaOperationSignature sig) { if (!operations.containsKey(sig)) { operations.put(sig, new HashSet()); } @@ -85,7 +86,7 @@ * @param name The name of the field * @param sig The signature of the field */ - /* default */ void addField(String name, JavaFieldSignature sig) { + void addField(String name, JavaFieldSignature sig) { if (!fields.containsKey(sig)) { fields.put(sig, new HashSet()); } @@ -93,16 +94,8 @@ } - /** - * Checks whether the class declares an operation by the name given which is covered by the signature mask. - * - * @param name The name of the operation to look for - * @param mask The mask covering accepted signatures - * - * @return True if the class declares an operation by the name given which is covered by the signature mask, false - * otherwise - */ - /* default */ boolean hasMatchingSig(String name, JavaOperationSigMask mask) { + @Override + public boolean hasMatchingSig(String name, JavaOperationSigMask mask) { // Indexing on signatures optimises this type of request for (JavaOperationSignature sig : operations.keySet()) { if (mask.covers(sig)) { @@ -115,16 +108,8 @@ } - /** - * Checks whether the class declares a field by the name given which is covered by the signature mask. - * - * @param name The name of the field to look for - * @param mask The mask covering accepted signatures - * - * @return True if the class declares a field by the name given which is covered by the signature mask, false - * otherwise - */ - /* default */ boolean hasMatchingSig(String name, JavaFieldSigMask mask) { + @Override + public boolean hasMatchingSig(String name, JavaFieldSigMask mask) { for (JavaFieldSignature sig : fields.keySet()) { if (mask.covers(sig)) { if (fields.get(sig).contains(name)) { @@ -135,4 +120,32 @@ return false; } + + @Override + public int countMatchingOpSigs(JavaOperationSigMask sigMask) { + int sum = 0; + + for (Entry> e : operations.entrySet()) { + if (sigMask.covers(e.getKey())) { + sum += e.getValue().size(); + } + } + + return sum; + } + + + @Override + public int countMatchingFieldSigs(JavaFieldSigMask sigMask) { + int sum = 0; + + for (Entry> e : fields.entrySet()) { + if (sigMask.covers(e.getKey())) { + sum += e.getValue().size(); + } + } + + return sum; + } + } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileFacade.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileFacade.java new file mode 100644 index 00000000000..6d5845535e1 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileFacade.java @@ -0,0 +1,42 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.multifile; + +/** + * Facade class for multi-file analysis. Stores an instance of a ProjectMirror. + * + * @author Clément Fournier + */ +public class MultifileFacade { + + private static final MultifileFacadeBacker FACADE = new MultifileFacadeBacker(); + + + private MultifileFacade() { + + } + + /** Resets the entire data structure. Used for tests. */ + static void reset() { + FACADE.reset(); + } + + + /** + * Gets the ProjectMirror instance representing the currently analysed project. + * + * @return The project mirror + */ + public static ProjectMirror getProjectMirror() { + return FACADE.getTopLevelPackageStats(); + } + + + static PackageStats getTopLevelPackageStats() { + return FACADE.getTopLevelPackageStats(); + } + + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileFacadeBacker.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileFacadeBacker.java new file mode 100644 index 00000000000..c582f2d357b --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileFacadeBacker.java @@ -0,0 +1,26 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.multifile; + +/** + * @author Clément Fournier + */ +class MultifileFacadeBacker { + + + private final PackageStats topLevelPackageStats = new PackageStats(); + + + /** Resets the data structure. Used for tests. */ + void reset() { + topLevelPackageStats.reset(); + } + + + PackageStats getTopLevelPackageStats() { + return topLevelPackageStats; + } + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileVisitor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileVisitor.java new file mode 100644 index 00000000000..e90eb44f969 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileVisitor.java @@ -0,0 +1,52 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.multifile; + +import java.util.Stack; + +import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration; +import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorReducedAdapter; + +/** + * @author Clément Fournier + */ +public class MultifileVisitor extends JavaParserVisitorReducedAdapter { + + private final Stack stack = new Stack<>(); + private final PackageStats toplevel; + + + MultifileVisitor(PackageStats toplevel) { + this.toplevel = toplevel; + } + + + @Override + public Object visit(ASTAnyTypeDeclaration node, Object data) { + stack.push(toplevel.getClassStats(node.getQualifiedName(), true)); + super.visit(node, data); + stack.pop(); + + return data; + } + + + @Override + public Object visit(ASTMethodOrConstructorDeclaration node, Object data) { + stack.peek().addOperation(node.getQualifiedName().getOperation(), node.getSignature()); + return super.visit(node, data); + } + + + @Override + public Object visit(ASTFieldDeclaration node, Object data) { + stack.peek().addField(node.getVariableName(), node.getSignature()); + return data; // end recursion + } + + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileVisitorFacade.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileVisitorFacade.java new file mode 100644 index 00000000000..6153848e8de --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileVisitorFacade.java @@ -0,0 +1,22 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.multifile; + +import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; +import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter; + +/** + * @author Clément Fournier + */ +public class MultifileVisitorFacade extends JavaParserVisitorAdapter { + + public void initializeWith(ASTCompilationUnit rootNode) { + PackageStats projectMirror = MultifileFacade.getTopLevelPackageStats(); + MultifileVisitor visitor = new MultifileVisitor(projectMirror); + rootNode.jjtAccept(visitor, null); + } + + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/PackageStats.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/PackageStats.java similarity index 84% rename from pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/PackageStats.java rename to pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/PackageStats.java index f89bc3e8849..98db954aad9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/PackageStats.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/PackageStats.java @@ -2,25 +2,25 @@ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ -package net.sourceforge.pmd.lang.java.metrics; +package net.sourceforge.pmd.lang.java.multifile; import java.util.HashMap; import java.util.Map; import net.sourceforge.pmd.lang.java.ast.JavaQualifiedName; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaFieldSigMask; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSigMask; /** * Statistics about a package. This recursive data structure mirrors the package structure of the analysed project and - * stores information about the classes and subpackages it contains. This object provides signature matching - * utilities to metrics. + * stores information about the classes and subpackages it contains. This object provides signature matching utilities + * to metrics. * * @author Clément Fournier * @see ClassStats */ -public final class PackageStats implements JavaSignatureMatcher { +final class PackageStats implements ProjectMirror { private final Map subPackages = new HashMap<>(); private final Map classes = new HashMap<>(); @@ -60,11 +60,11 @@ public final class PackageStats implements JavaSignatureMatcher { } String topClassName = qname.getClasses()[0]; - if (createIfNotFound && classes.get(topClassName) == null) { - classes.put(topClassName, new ClassStats()); + if (createIfNotFound && container.classes.get(topClassName) == null) { + container.classes.put(topClassName, new ClassStats()); } - ClassStats next = classes.get(topClassName); + ClassStats next = container.classes.get(topClassName); if (next == null) { return null; @@ -125,4 +125,10 @@ public boolean hasMatchingSig(JavaQualifiedName qname, String fieldName, JavaFie return clazz != null && clazz.hasMatchingSig(fieldName, sigMask); } + + @Override + public ClassMirror getClassMirror(JavaQualifiedName className) { + return getClassStats(className, false); + } + } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaSignatureMatcher.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ProjectMirror.java similarity index 66% rename from pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaSignatureMatcher.java rename to pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ProjectMirror.java index 25dbe29028f..b237bee5827 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaSignatureMatcher.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ProjectMirror.java @@ -2,18 +2,18 @@ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ -package net.sourceforge.pmd.lang.java.metrics; +package net.sourceforge.pmd.lang.java.multifile; import net.sourceforge.pmd.lang.java.ast.JavaQualifiedName; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaFieldSigMask; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSigMask; /** - * Gathers the methods that PackageStats should make available to metrics during the computation. + * Represents the analysed project to provide all rules with info about other classes. * * @author Clément Fournier */ -public interface JavaSignatureMatcher { +public interface ProjectMirror { /** * Returns true if the signature of the operation designated by the qualified name is covered by the mask. @@ -39,4 +39,13 @@ public interface JavaSignatureMatcher { boolean hasMatchingSig(JavaQualifiedName qname, String fieldName, JavaFieldSigMask sigMask); + /** + * Gets the class mirror corresponding to the qualified name. + * + * @param className The qualified name of the class. + * + * @return The class mirror + */ + ClassMirror getClassMirror(JavaQualifiedName className); + } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaFieldSigMask.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaFieldSigMask.java new file mode 100644 index 00000000000..fa4323fd6bb --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaFieldSigMask.java @@ -0,0 +1,97 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.multifile.signature; + +import net.sourceforge.pmd.lang.java.multifile.signature.JavaSignature.Visibility; + +/** + * Signature mask for a field. Newly created masks cover any field. + * + * @author Clément Fournier + */ +public final class JavaFieldSigMask extends JavaSigMask { + + private boolean coverFinal = true; + private boolean coverStatic = true; + + + /** + * Creates a field mask covering any field. + */ + public JavaFieldSigMask() { + // everything's initialized + } + + + /** + * Sets the mask to cover final fields. + * + * @return this + */ + public JavaFieldSigMask coverFinal() { + this.coverFinal = true; + return this; + } + + + /** + * Forbid final fields. + * + * @return this + */ + public JavaFieldSigMask forbidFinal() { + coverFinal = false; + return this; + } + + + /** + * Sets the mask to cover static fields. + * + * @return this + */ + public JavaFieldSigMask coverStatic() { + this.coverStatic = true; + return this; + } + + + /** + * Forbid abstract operations. + * + * @return this + */ + public JavaFieldSigMask forbidStatic() { + coverStatic = false; + return this; + } + + + @Override + public JavaFieldSigMask coverAllVisibilities() { + super.coverAllVisibilities(); + return this; + } + + + @Override + public JavaFieldSigMask restrictVisibilitiesTo(Visibility... visibilities) { + super.restrictVisibilitiesTo(visibilities); + return this; + } + + + @Override + public JavaFieldSigMask forbid(Visibility... visibilities) { + super.forbid(visibilities); + return this; + } + + + @Override + public boolean covers(JavaFieldSignature sig) { + return super.covers(sig) && (coverFinal || !sig.isFinal) && (coverStatic || !sig.isStatic); + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaFieldSignature.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaFieldSignature.java similarity index 85% rename from pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaFieldSignature.java rename to pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaFieldSignature.java index 4f1144fe8ae..83b8f1bd2fa 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaFieldSignature.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaFieldSignature.java @@ -2,7 +2,7 @@ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ -package net.sourceforge.pmd.lang.java.metrics.signature; +package net.sourceforge.pmd.lang.java.multifile.signature; import java.util.HashMap; import java.util.Map; @@ -29,6 +29,16 @@ private JavaFieldSignature(Visibility visibility, boolean isStatic, boolean isFi } + @Override + public String toString() { + return "JavaFieldSignature{" + + "isStatic=" + isStatic + + ", isFinal=" + isFinal + + ", visibility=" + visibility + + '}'; + } + + @Override public boolean equals(Object o) { return this == o; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaOperationSigMask.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaOperationSigMask.java new file mode 100644 index 00000000000..8c19af404bc --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaOperationSigMask.java @@ -0,0 +1,111 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.multifile.signature; + +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Set; + +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature.Role; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaSignature.Visibility; + +/** + * Signature mask for an operation. Newly created masks cover any operation that is not abstract. + * + * @author Clément Fournier + */ +public final class JavaOperationSigMask extends JavaSigMask { + + private Set roleMask = EnumSet.allOf(Role.class); + private boolean coverAbstract = false; + + + /** + * Creates an operation sig mask that covers any non-abstract operation. + */ + public JavaOperationSigMask() { + // everything's initialized + } + + + /** + * Sets the mask to cover all roles. + */ + public JavaOperationSigMask coverAllRoles() { + roleMask.addAll(Arrays.asList(JavaOperationSignature.Role.values())); + return this; + } + + + /** + * Restricts the roles covered by the mask to the parameters. + * + * @param roles The roles to cover + */ + public JavaOperationSigMask restrictRolesTo(JavaOperationSignature.Role... roles) { + roleMask.clear(); + roleMask.addAll(Arrays.asList(roles)); + return this; + } + + + /** + * Forbid all mentioned roles. + * + * @param roles The roles to forbid + */ + public JavaOperationSigMask forbid(JavaOperationSignature.Role... roles) { + roleMask.removeAll(Arrays.asList(roles)); + return this; + } + + + /** + * Sets the mask to cover abstract operations. + */ + public JavaOperationSigMask coverAbstract() { + this.coverAbstract = true; + return this; + } + + + /** + * Forbid abstract operations. + * + * @return this + */ + public JavaOperationSigMask forbidAbstract() { + coverAbstract = false; + return this; + } + + + @Override + public JavaOperationSigMask coverAllVisibilities() { + super.coverAllVisibilities(); + return this; + } + + + @Override + public JavaOperationSigMask restrictVisibilitiesTo(Visibility... visibilities) { + super.restrictVisibilitiesTo(visibilities); + return this; + } + + + @Override + public JavaOperationSigMask forbid(Visibility... visibilities) { + super.forbid(visibilities); + return this; + } + + + @Override + public boolean covers(JavaOperationSignature sig) { + return super.covers(sig) && roleMask.contains(sig.role) && (coverAbstract + || !sig.isAbstract); + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaOperationSignature.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaOperationSignature.java similarity index 95% rename from pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaOperationSignature.java rename to pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaOperationSignature.java index 2a6d615d8e0..75bbf6e3fd1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaOperationSignature.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaOperationSignature.java @@ -2,7 +2,7 @@ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ -package net.sourceforge.pmd.lang.java.metrics.signature; +package net.sourceforge.pmd.lang.java.multifile.signature; import java.util.HashMap; import java.util.List; @@ -53,6 +53,16 @@ public int hashCode() { } + @Override + public String toString() { + return "JavaOperationSignature{" + + "role=" + role + + ", isAbstract=" + isAbstract + + ", visibility=" + visibility + + '}'; + } + + /** Used internally by the pooler. */ private static int code(Visibility visibility, Role role, boolean isAbstract) { return visibility.hashCode() * 31 + role.hashCode() * 2 + (isAbstract ? 1 : 0); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaSigMask.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaSigMask.java similarity index 68% rename from pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaSigMask.java rename to pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaSigMask.java index cc50cf8f505..32fc2dcbd9a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaSigMask.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaSigMask.java @@ -2,13 +2,13 @@ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ -package net.sourceforge.pmd.lang.java.metrics.signature; +package net.sourceforge.pmd.lang.java.multifile.signature; import java.util.Arrays; import java.util.EnumSet; import java.util.Set; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaSignature.Visibility; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaSignature.Visibility; import net.sourceforge.pmd.lang.metrics.SigMask; /** @@ -24,11 +24,19 @@ public abstract class JavaSigMask> implements SigMask private Set visMask = EnumSet.allOf(Visibility.class); + protected JavaSigMask() { + + } + + /** * Sets the mask to cover all visibilities. + * + * @return this */ - public void coverAllVisibilities() { + public JavaSigMask coverAllVisibilities() { visMask.addAll(Arrays.asList(JavaSignature.Visibility.values())); + return this; } @@ -36,10 +44,13 @@ public void coverAllVisibilities() { * Restricts the visibilities covered by the mask to the parameters. * * @param visibilities The visibilities to cover + * + * @return this */ - public void restrictVisibilitiesTo(JavaSignature.Visibility... visibilities) { + public JavaSigMask restrictVisibilitiesTo(JavaSignature.Visibility... visibilities) { visMask.clear(); visMask.addAll(Arrays.asList(visibilities)); + return this; } @@ -47,9 +58,12 @@ public void restrictVisibilitiesTo(JavaSignature.Visibility... visibilities) { * Forbid all mentioned visibilities. * * @param visibilities The visibilities to forbid + * + * @return this */ - public void forbid(JavaSignature.Visibility... visibilities) { + public JavaSigMask forbid(JavaSignature.Visibility... visibilities) { visMask.removeAll(Arrays.asList(visibilities)); + return this; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaSignature.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaSignature.java similarity index 96% rename from pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaSignature.java rename to pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaSignature.java index 093a611461e..c3dd860493b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/signature/JavaSignature.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaSignature.java @@ -2,7 +2,7 @@ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ -package net.sourceforge.pmd.lang.java.metrics.signature; +package net.sourceforge.pmd.lang.java.multifile.signature; import net.sourceforge.pmd.lang.ast.SignedNode; import net.sourceforge.pmd.lang.java.ast.AccessNode; diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitorTest.java deleted file mode 100644 index 7807515397f..00000000000 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitorTest.java +++ /dev/null @@ -1,111 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.metrics; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -import net.sourceforge.pmd.lang.LanguageVersionHandler; -import net.sourceforge.pmd.lang.java.ParserTstUtil; -import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; -import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; -import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter; -import net.sourceforge.pmd.lang.java.ast.JavaQualifiedName; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaFieldSigMask; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSigMask; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSignature.Role; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaSignature.Visibility; -import net.sourceforge.pmd.lang.java.metrics.testdata.MetricsVisitorTestData; - -/** - * Tests of the metrics visitor. - * - * @author Clément Fournier - */ -public class JavaMetricsVisitorTest { - - - @Test - public void testPackageStatsNotNull() { - assertNotNull(JavaMetrics.getFacade().getTopLevelPackageStats()); - } - - - @Test - public void testOperationsAreThere() { - ASTCompilationUnit acu = parseAndVisitForClass(MetricsVisitorTestData.class); - - final JavaSignatureMatcher toplevel = JavaMetrics.getFacade().getTopLevelPackageStats(); - - final JavaOperationSigMask opMask = new JavaOperationSigMask(); - - // We could parse qnames from string but probably simpler to do that - acu.jjtAccept(new JavaParserVisitorAdapter() { - @Override - public Object visit(ASTMethodDeclaration node, Object data) { - assertTrue(toplevel.hasMatchingSig(node.getQualifiedName(), opMask)); - return data; - } - }, null); - } - - - @Test - public void testFieldsAreThere() { - parseAndVisitForClass(MetricsVisitorTestData.class); - - - final JavaSignatureMatcher toplevel = JavaMetrics.getFacade().getTopLevelPackageStats(); - - final JavaFieldSigMask fieldSigMask = new JavaFieldSigMask(); - - JavaQualifiedName clazz = JavaQualifiedName.ofString("net.sourceforge.pmd.lang.java" - + ".metrics.testdata" - + ".MetricsVisitorTestData"); - String[] fieldNames = {"x", "y", "z", "t"}; - Visibility[] visibilities = {Visibility.PUBLIC, Visibility.PRIVATE, Visibility.PROTECTED, Visibility.PACKAGE}; - - for (int i = 0; i < fieldNames.length; i++) { - fieldSigMask.restrictVisibilitiesTo(visibilities[i]); - assertTrue(toplevel.hasMatchingSig(clazz, fieldNames[i], fieldSigMask)); - } - } - - - // this test is probably useless, SignatureTest and SigMaskTest already ensure signatures and sigmask have no - // problem - @Test - public void testStaticOperationsSig() { - parseAndVisitForClass(MetricsVisitorTestData.class); - - final JavaSignatureMatcher toplevel = JavaMetrics.getFacade().getTopLevelPackageStats(); - - final JavaOperationSigMask operationSigMask = new JavaOperationSigMask(); - operationSigMask.restrictRolesTo(Role.STATIC); - - JavaQualifiedName q1 = JavaQualifiedName.ofString("net.sourceforge.pmd.lang.java" - + ".metrics.testdata" - + ".MetricsVisitorTestData#mystatic1()"); - - assertTrue(toplevel.hasMatchingSig(q1, operationSigMask)); - - operationSigMask.coverAllRoles(); - operationSigMask.forbid(Role.STATIC); - - assertFalse(toplevel.hasMatchingSig(q1, operationSigMask)); - } - - - static ASTCompilationUnit parseAndVisitForClass(Class clazz) { - ASTCompilationUnit acu = ParserTstUtil.parseJavaDefaultVersion(clazz); - LanguageVersionHandler handler = ParserTstUtil.getDefaultLanguageVersionHandler(); - handler.getTypeResolutionFacade(JavaMetricsVisitorTest.class.getClassLoader()).start(acu); - handler.getMetricsVisitorFacade().start(acu); - return acu; - } -} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/ProjectMemoizerTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/ProjectMemoizerTest.java index 5c8d16374f2..e92b0028d5c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/ProjectMemoizerTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/ProjectMemoizerTest.java @@ -4,7 +4,7 @@ package net.sourceforge.pmd.lang.java.metrics; -import static net.sourceforge.pmd.lang.java.metrics.JavaMetricsVisitorTest.parseAndVisitForClass; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; @@ -14,6 +14,7 @@ import org.junit.Test; +import net.sourceforge.pmd.lang.java.ParserTstUtil; import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration; @@ -48,6 +49,7 @@ public void memoizationTest() { @Test public void forceMemoizationTest() { + ASTCompilationUnit acu = parseAndVisitForClass(MetricsVisitorTestData.class); List reference = visitWith(acu, true); @@ -90,6 +92,12 @@ public Object visit(ASTAnyTypeDeclaration node, Object data) { } + static ASTCompilationUnit parseAndVisitForClass(Class clazz) { + ASTCompilationUnit acu = ParserTstUtil.parseJavaDefaultVersion(clazz); + ParserTstUtil.getDefaultLanguageVersionHandler().getMetricsVisitorFacade().start(acu); + return acu; + } + private class RandomOperationMetric extends AbstractJavaOperationMetric { private Random random = new Random(); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/SigMaskTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/SigMaskTest.java index 279c9ed55c7..ac730d87c4a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/SigMaskTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/SigMaskTest.java @@ -16,12 +16,12 @@ import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaFieldSigMask; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaFieldSignature; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSigMask; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSignature; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSignature.Role; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaSignature.Visibility; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSignature; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature.Role; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaSignature.Visibility; import net.sourceforge.pmd.lang.metrics.SigMask; /** @@ -108,7 +108,7 @@ public void testEmptyFieldMask() { public void testFinalFields() { List nodes = getOrderedNodes(ASTFieldDeclaration.class, TEST_FIELDS); JavaFieldSigMask mask = new JavaFieldSigMask(); - mask.coverFinal(false); + mask.forbidFinal(); for (ASTFieldDeclaration node : nodes) { if (node.isFinal()) { @@ -123,7 +123,7 @@ public void testFinalFields() { public void testStaticFields() { List nodes = getOrderedNodes(ASTFieldDeclaration.class, TEST_FIELDS); JavaFieldSigMask mask = new JavaFieldSigMask(); - mask.coverStatic(false); + mask.forbidStatic(); for (ASTFieldDeclaration node : nodes) { if (node.isStatic()) { @@ -188,7 +188,7 @@ public void testOperationVisibility() { TEST_OPERATIONS); JavaOperationSigMask mask = new JavaOperationSigMask(); - mask.coverAbstract(true); + mask.coverAbstract(); mask.restrictVisibilitiesTo(Visibility.PUBLIC); @@ -237,7 +237,7 @@ public void testOperationRoles() { TEST_OPERATIONS); JavaOperationSigMask mask = new JavaOperationSigMask(); mask.restrictRolesTo(Role.STATIC); - mask.coverAbstract(true); + mask.coverAbstract(); for (ASTMethodOrConstructorDeclaration node : nodes) { if (node.isStatic()) { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/SignatureTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/SignatureTest.java index 47bb966fe83..dab6aa719ec 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/SignatureTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/SignatureTest.java @@ -20,13 +20,13 @@ import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration; import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaFieldSignature; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSignature; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSignature.Role; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaSignature; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaSignature.Visibility; import net.sourceforge.pmd.lang.java.metrics.testdata.GetterDetection; import net.sourceforge.pmd.lang.java.metrics.testdata.SetterDetection; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSignature; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature.Role; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaSignature; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaSignature.Visibility; /** * Test class for {@link JavaSignature} and its subclasses. diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/ClassStatsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/ClassStatsTest.java new file mode 100644 index 00000000000..1b91154fd28 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/ClassStatsTest.java @@ -0,0 +1,79 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.multifile; + + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +import net.sourceforge.pmd.lang.java.ast.JavaQualifiedName; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature.Role; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaSignature.Visibility; +import net.sourceforge.pmd.lang.java.multifile.testdata.SignatureCountTestData; + +/** + * @author Clément Fournier + */ +public class ClassStatsTest { + + @Before + public void resetMultifile() { + MultifileFacade.reset(); + } + + + @Test + public void testCountOpSigs() { + + JavaMultifileVisitorTest.parseAndVisitForClass(SignatureCountTestData.class); + + final ProjectMirror toplevel = MultifileFacade.getProjectMirror(); + + final ClassMirror classMirror = toplevel.getClassMirror(JavaQualifiedName.ofClass(SignatureCountTestData.class)); + + final JavaOperationSigMask opSigMask = new JavaOperationSigMask().coverAbstract(); + opSigMask.restrictRolesTo(Role.STATIC); + + assertEquals(4, classMirror.countMatchingOpSigs(opSigMask)); + assertEquals(2, classMirror.countMatchingOpSigs(opSigMask.restrictVisibilitiesTo(Visibility.PRIVATE))); + assertEquals(2, classMirror.countMatchingOpSigs(opSigMask.restrictVisibilitiesTo(Visibility.PUBLIC))); + + opSigMask.restrictRolesTo(Role.METHOD).coverAllVisibilities(); + + assertEquals(6, classMirror.countMatchingOpSigs(opSigMask)); + assertEquals(1, classMirror.countMatchingOpSigs(opSigMask.restrictVisibilitiesTo(Visibility.PUBLIC))); + assertEquals(1, classMirror.countMatchingOpSigs(opSigMask.restrictVisibilitiesTo(Visibility.PRIVATE))); + assertEquals(4, classMirror.countMatchingOpSigs(opSigMask.restrictVisibilitiesTo(Visibility.PROTECTED))); + assertEquals(2, classMirror.countMatchingOpSigs(opSigMask.forbidAbstract())); + + opSigMask.restrictRolesTo(Role.GETTER_OR_SETTER).coverAllVisibilities(); + + assertEquals(8, classMirror.countMatchingOpSigs(opSigMask)); + assertEquals(4, classMirror.countMatchingOpSigs(opSigMask.restrictVisibilitiesTo(Visibility.PACKAGE))); + assertEquals(4, classMirror.countMatchingOpSigs(opSigMask.restrictVisibilitiesTo(Visibility.PUBLIC))); + + opSigMask.restrictRolesTo(Role.CONSTRUCTOR).coverAllVisibilities(); + + assertEquals(3, classMirror.countMatchingOpSigs(opSigMask)); + assertEquals(3, classMirror.countMatchingOpSigs(opSigMask.restrictVisibilitiesTo(Visibility.PUBLIC))); + + + JavaFieldSigMask fieldSigMask = new JavaFieldSigMask(); + + assertEquals(6, classMirror.countMatchingFieldSigs(fieldSigMask)); + assertEquals(3, classMirror.countMatchingFieldSigs(fieldSigMask.restrictVisibilitiesTo(Visibility.PUBLIC))); + assertEquals(1, classMirror.countMatchingFieldSigs(fieldSigMask.restrictVisibilitiesTo(Visibility.PROTECTED))); + assertEquals(2, classMirror.countMatchingFieldSigs(fieldSigMask.restrictVisibilitiesTo(Visibility.PRIVATE))); + assertEquals(0, classMirror.countMatchingFieldSigs(fieldSigMask.restrictVisibilitiesTo(Visibility.PRIVATE).forbidFinal())); + + + } + + +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/JavaMultifileVisitorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/JavaMultifileVisitorTest.java new file mode 100644 index 00000000000..9228e816830 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/JavaMultifileVisitorTest.java @@ -0,0 +1,93 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.multifile; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Test; + +import net.sourceforge.pmd.lang.LanguageVersionHandler; +import net.sourceforge.pmd.lang.java.ParserTstUtil; +import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; +import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; +import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter; +import net.sourceforge.pmd.lang.java.ast.JavaQualifiedName; +import net.sourceforge.pmd.lang.java.metrics.testdata.MetricsVisitorTestData; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature.Role; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaSignature.Visibility; +import net.sourceforge.pmd.lang.java.multifile.testdata.MultifileVisitorTestData; + +/** + * Tests of the metrics visitor. + * + * @author Clément Fournier + */ +public class JavaMultifileVisitorTest { + + + @Test + public void testPackageStatsNotNull() { + assertNotNull(MultifileFacade.getProjectMirror()); + } + + + @After + public void resetMultifile() { + MultifileFacade.reset(); + } + + + @Test + public void testOperationsAreThere() { + ASTCompilationUnit acu = parseAndVisitForClass(MultifileVisitorTestData.class); + + final ProjectMirror toplevel = MultifileFacade.getProjectMirror(); + + final JavaOperationSigMask opMask = new JavaOperationSigMask(); + + // We could parse qnames from string but probably simpler to do that + acu.jjtAccept(new JavaParserVisitorAdapter() { + @Override + public Object visit(ASTMethodDeclaration node, Object data) { + assertTrue(toplevel.hasMatchingSig(node.getQualifiedName(), opMask)); + return data; + } + }, null); + } + + + @Test + public void testFieldsAreThere() { + parseAndVisitForClass(MultifileVisitorTestData.class); + + final ProjectMirror toplevel = MultifileFacade.getProjectMirror(); + + final JavaFieldSigMask fieldSigMask = new JavaFieldSigMask(); + + JavaQualifiedName clazz = JavaQualifiedName.ofClass(MultifileVisitorTestData.class); + + String[] fieldNames = {"x", "y", "z", "t"}; + Visibility[] visibilities = {Visibility.PUBLIC, Visibility.PRIVATE, Visibility.PROTECTED, Visibility.PACKAGE}; + + for (int i = 0; i < fieldNames.length; i++) { + fieldSigMask.restrictVisibilitiesTo(visibilities[i]); + assertTrue(toplevel.hasMatchingSig(clazz, fieldNames[i], fieldSigMask)); + } + } + + + static ASTCompilationUnit parseAndVisitForClass(Class clazz) { + ASTCompilationUnit acu = ParserTstUtil.parseJavaDefaultVersion(clazz); + LanguageVersionHandler handler = ParserTstUtil.getDefaultLanguageVersionHandler(); + handler.getTypeResolutionFacade(JavaMultifileVisitorTest.class.getClassLoader()).start(acu); + handler.getMultifileFacade().start(acu); + return acu; + } +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/PackageStatsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/PackageStatsTest.java similarity index 84% rename from pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/PackageStatsTest.java rename to pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/PackageStatsTest.java index 08ae711e0de..8b17a99d260 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/PackageStatsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/PackageStatsTest.java @@ -2,7 +2,7 @@ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ -package net.sourceforge.pmd.lang.java.metrics; +package net.sourceforge.pmd.lang.java.multifile; import static net.sourceforge.pmd.lang.java.ParserTstUtil.getOrderedNodes; import static org.junit.Assert.assertFalse; @@ -17,13 +17,13 @@ import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration; import net.sourceforge.pmd.lang.java.ast.JavaQualifiedName; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaFieldSigMask; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaFieldSignature; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSigMask; -import net.sourceforge.pmd.lang.java.metrics.signature.JavaOperationSignature; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSignature; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSigMask; +import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature; /** - * Tests functionality of PackageStats, so both its ProjectMemoizer and JavaSignatureMatcher interfaces. + * Tests functionality of PackageStats * * @author Clément Fournier */ @@ -87,5 +87,4 @@ public void testAddField() { } - } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/testdata/MultifileVisitorTestData.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/testdata/MultifileVisitorTestData.java new file mode 100644 index 00000000000..6924ace69e6 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/testdata/MultifileVisitorTestData.java @@ -0,0 +1,75 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.multifile.testdata; + +/** + * Test data for the metrics visitor + * + * @author Clément Fournier + */ +public class MultifileVisitorTestData { + + public String x; + private String y; + protected String z; + String t; + + public MultifileVisitorTestData() { + + } + + private MultifileVisitorTestData(String x) { + + } + + public String getX() { + return x; + } + + public String getY() { + return y; + } + + public void setX(String n) { + x = n; + } + + public void setY(String n) { + y = n; + } + + + public static class NestedClass { + + public NestedClass() { + + } + + public void nestedMethod1() { + + } + } + + public void mymethod1() { + + } + + private void mymethod2() { + + } + + protected static void mystatic1() { + + } + + private static void mystatic2(String k) { + + } + + private static void mystatic2(String k, String l) { + + } + +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/testdata/SignatureCountTestData.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/testdata/SignatureCountTestData.java new file mode 100644 index 00000000000..2d6d1af385b --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/testdata/SignatureCountTestData.java @@ -0,0 +1,140 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.multifile.testdata; + +import org.apache.commons.lang3.StringUtils; + +// Fields: +// 2 private static final +// 3 public +// 1 protected + +// Constructors: +// 3 public + +// Getters/ Setters: +// 4 public +// 4 package + +// Static: +// 2 private +// 2 public + +// Methods: +// 1 public +// 1 private +// 2 protected +// 2 protected final +public abstract class SignatureCountTestData { + + private static final int MAX_X = 0; + private static final int MIN_X = 0; + public int x; + public int y; + public int z; + protected int t; + + + public SignatureCountTestData(int x, int y, int z, int t) { + this.x = x; + this.y = y; + this.z = z; + this.t = t; + } + + + public SignatureCountTestData(int x, int y, int z) {} + + + public SignatureCountTestData(int x, int y) {} + + + public int getX() { + return x; + } + + + void setX(int x) { + this.x = x; + } + + + public int getY() { + return y; + } + + + void setY(int y) { + this.y = y; + } + + + public int getZ() { + return z; + } + + + void setZ(int z) { + this.z = z; + } + + + public int getT() { + return t; + } + + + void setT(int t) { + this.t = t; + } + + + public boolean isNotEmpty(String value) { + return !isEmpty(value); + } + + + private boolean isEmpty(String value) { + return StringUtils.isBlank(value); + } + + + protected boolean isMissing(String value) { + return StringUtils.isEmpty(value); + } + + + protected boolean areSemanticEquals(String a, String b) { + return a.equals(b); + } + + + protected abstract String replaceString(String original, String oldString, String newString); + + + @Deprecated + protected abstract void appendXmlEscaped(StringBuilder buf, String src); + + + public static boolean startsWithAny(String text, String... prefixes) { + return false; + } + + + public static boolean isAnyOf(String text, String... tests) { + return false; + } + + + private static String withoutPrefixes(String text, String... prefixes) { + return text; + } + + + private static void appendXmlEscaped(StringBuilder buf, String src, boolean supportUTF8) { + } + + +} From eed9859053494ee8146905d6a7841afde4941c64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 22 Aug 2017 17:59:48 +0200 Subject: [PATCH 0011/2019] Hide multifile from rules --- .../pmd/lang/java/multifile/ClassMirror.java | 8 +++----- .../pmd/lang/java/multifile/ClassStats.java | 4 ++-- .../pmd/lang/java/multifile/MultifileFacade.java | 10 +++------- .../pmd/lang/java/multifile/MultifileFacadeBacker.java | 2 +- .../lang/java/multifile/MultifileVisitorFacade.java | 2 +- .../pmd/lang/java/multifile/PackageStats.java | 4 ++-- .../pmd/lang/java/multifile/ProjectMirror.java | 2 +- .../pmd/lang/java/multifile/ClassStatsTest.java | 2 +- .../lang/java/multifile/JavaMultifileVisitorTest.java | 9 +++------ 9 files changed, 17 insertions(+), 26 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ClassMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ClassMirror.java index 0211ba37ea8..5ea9a705b90 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ClassMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ClassMirror.java @@ -10,11 +10,9 @@ /** * Represents a class for signature matching. * - * TODO:cf count signatures - * * @author Clément Fournier */ -public interface ClassMirror { +interface ClassMirror { /** * Returns true if the signature of the operation designated by the qualified name is covered by the mask. @@ -24,7 +22,7 @@ public interface ClassMirror { * * @return True if the signature of the operation designated by the qualified name is covered by the mask */ - boolean hasMatchingSig(String opName, JavaOperationSigMask sigMask); + boolean hasMatchingOpSig(String opName, JavaOperationSigMask sigMask); /** @@ -36,7 +34,7 @@ public interface ClassMirror { * * @return True if the signature of the field is covered by the mask */ - boolean hasMatchingSig(String fieldName, JavaFieldSigMask sigMask); + boolean hasMatchingFieldSig(String fieldName, JavaFieldSigMask sigMask); /** diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ClassStats.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ClassStats.java index 525c419905a..9ac6a336892 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ClassStats.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ClassStats.java @@ -95,7 +95,7 @@ void addField(String name, JavaFieldSignature sig) { @Override - public boolean hasMatchingSig(String name, JavaOperationSigMask mask) { + public boolean hasMatchingOpSig(String name, JavaOperationSigMask mask) { // Indexing on signatures optimises this type of request for (JavaOperationSignature sig : operations.keySet()) { if (mask.covers(sig)) { @@ -109,7 +109,7 @@ public boolean hasMatchingSig(String name, JavaOperationSigMask mask) { @Override - public boolean hasMatchingSig(String name, JavaFieldSigMask mask) { + public boolean hasMatchingFieldSig(String name, JavaFieldSigMask mask) { for (JavaFieldSignature sig : fields.keySet()) { if (mask.covers(sig)) { if (fields.get(sig).contains(name)) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileFacade.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileFacade.java index 6d5845535e1..6ab3fdde1c2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileFacade.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileFacade.java @@ -9,7 +9,7 @@ * * @author Clément Fournier */ -public class MultifileFacade { +final class MultifileFacade { private static final MultifileFacadeBacker FACADE = new MultifileFacadeBacker(); @@ -18,6 +18,7 @@ private MultifileFacade() { } + /** Resets the entire data structure. Used for tests. */ static void reset() { FACADE.reset(); @@ -25,15 +26,10 @@ static void reset() { /** - * Gets the ProjectMirror instance representing the currently analysed project. + * Gets the PackageStats instance representing the currently analysed project. * * @return The project mirror */ - public static ProjectMirror getProjectMirror() { - return FACADE.getTopLevelPackageStats(); - } - - static PackageStats getTopLevelPackageStats() { return FACADE.getTopLevelPackageStats(); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileFacadeBacker.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileFacadeBacker.java index c582f2d357b..f5355ff500f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileFacadeBacker.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileFacadeBacker.java @@ -7,7 +7,7 @@ /** * @author Clément Fournier */ -class MultifileFacadeBacker { +final class MultifileFacadeBacker { private final PackageStats topLevelPackageStats = new PackageStats(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileVisitorFacade.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileVisitorFacade.java index 6153848e8de..d90aee34acf 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileVisitorFacade.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/MultifileVisitorFacade.java @@ -10,7 +10,7 @@ /** * @author Clément Fournier */ -public class MultifileVisitorFacade extends JavaParserVisitorAdapter { +public final class MultifileVisitorFacade extends JavaParserVisitorAdapter { public void initializeWith(ASTCompilationUnit rootNode) { PackageStats projectMirror = MultifileFacade.getTopLevelPackageStats(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/PackageStats.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/PackageStats.java index 98db954aad9..1b0289875f2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/PackageStats.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/PackageStats.java @@ -114,7 +114,7 @@ private PackageStats getSubPackage(JavaQualifiedName qname, boolean createIfNotF public boolean hasMatchingSig(JavaQualifiedName qname, JavaOperationSigMask sigMask) { ClassStats clazz = getClassStats(qname, false); - return clazz != null && clazz.hasMatchingSig(qname.getOperation(), sigMask); + return clazz != null && clazz.hasMatchingOpSig(qname.getOperation(), sigMask); } @@ -122,7 +122,7 @@ public boolean hasMatchingSig(JavaQualifiedName qname, JavaOperationSigMask sigM public boolean hasMatchingSig(JavaQualifiedName qname, String fieldName, JavaFieldSigMask sigMask) { ClassStats clazz = getClassStats(qname, false); - return clazz != null && clazz.hasMatchingSig(fieldName, sigMask); + return clazz != null && clazz.hasMatchingFieldSig(fieldName, sigMask); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ProjectMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ProjectMirror.java index b237bee5827..77e945d2593 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ProjectMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/ProjectMirror.java @@ -13,7 +13,7 @@ * * @author Clément Fournier */ -public interface ProjectMirror { +interface ProjectMirror { /** * Returns true if the signature of the operation designated by the qualified name is covered by the mask. diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/ClassStatsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/ClassStatsTest.java index 1b91154fd28..a6c3658c0d7 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/ClassStatsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/ClassStatsTest.java @@ -33,7 +33,7 @@ public void testCountOpSigs() { JavaMultifileVisitorTest.parseAndVisitForClass(SignatureCountTestData.class); - final ProjectMirror toplevel = MultifileFacade.getProjectMirror(); + final ProjectMirror toplevel = MultifileFacade.getTopLevelPackageStats(); final ClassMirror classMirror = toplevel.getClassMirror(JavaQualifiedName.ofClass(SignatureCountTestData.class)); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/JavaMultifileVisitorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/JavaMultifileVisitorTest.java index 9228e816830..c9c6e994416 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/JavaMultifileVisitorTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/JavaMultifileVisitorTest.java @@ -4,7 +4,6 @@ package net.sourceforge.pmd.lang.java.multifile; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -17,10 +16,8 @@ import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter; import net.sourceforge.pmd.lang.java.ast.JavaQualifiedName; -import net.sourceforge.pmd.lang.java.metrics.testdata.MetricsVisitorTestData; import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSigMask; import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSigMask; -import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature.Role; import net.sourceforge.pmd.lang.java.multifile.signature.JavaSignature.Visibility; import net.sourceforge.pmd.lang.java.multifile.testdata.MultifileVisitorTestData; @@ -34,7 +31,7 @@ public class JavaMultifileVisitorTest { @Test public void testPackageStatsNotNull() { - assertNotNull(MultifileFacade.getProjectMirror()); + assertNotNull(MultifileFacade.getTopLevelPackageStats()); } @@ -48,7 +45,7 @@ public void resetMultifile() { public void testOperationsAreThere() { ASTCompilationUnit acu = parseAndVisitForClass(MultifileVisitorTestData.class); - final ProjectMirror toplevel = MultifileFacade.getProjectMirror(); + final ProjectMirror toplevel = MultifileFacade.getTopLevelPackageStats(); final JavaOperationSigMask opMask = new JavaOperationSigMask(); @@ -67,7 +64,7 @@ public Object visit(ASTMethodDeclaration node, Object data) { public void testFieldsAreThere() { parseAndVisitForClass(MultifileVisitorTestData.class); - final ProjectMirror toplevel = MultifileFacade.getProjectMirror(); + final ProjectMirror toplevel = MultifileFacade.getTopLevelPackageStats(); final JavaFieldSigMask fieldSigMask = new JavaFieldSigMask(); From 584041e1e7544f96fba906ebc407ffdf661d3ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 22 Aug 2017 18:23:00 +0200 Subject: [PATCH 0012/2019] Removed the metrics visitor --- .../pmd/lang/apex/ApexHandler.java | 10 -- ...Visitor.java => ApexMultifileVisitor.java} | 11 +- ...e.java => ApexMultifileVisitorFacade.java} | 7 +- ...est.java => ApexMultifileVisitorTest.java} | 5 +- .../apex/metrics/ApexProjectMirrorTest.java | 4 +- .../main/java/net/sourceforge/pmd/Rule.java | 10 +- .../java/net/sourceforge/pmd/RuleSet.java | 15 +- .../net/sourceforge/pmd/RuleSetFactory.java | 4 +- .../java/net/sourceforge/pmd/RuleSets.java | 14 +- .../sourceforge/pmd/SourceCodeProcessor.java | 21 +-- .../sourceforge/pmd/benchmark/Benchmark.java | 15 +- .../lang/AbstractLanguageVersionHandler.java | 5 - .../pmd/lang/LanguageVersionHandler.java | 8 -- .../lang/metrics/BasicProjectMemoizer.java | 21 ++- .../pmd/lang/metrics/ProjectMemoizer.java | 17 --- .../pmd/lang/rule/AbstractDelegateRule.java | 8 +- .../pmd/lang/rule/AbstractRule.java | 130 +----------------- .../pmd/lang/java/AbstractJavaHandler.java | 11 -- .../lang/java/metrics/JavaMetricsVisitor.java | 39 ------ .../metrics/JavaMetricsVisitorFacade.java | 23 ---- .../java/metrics/ProjectMemoizerTest.java | 10 +- .../pmd/testframework/RuleTstTest.java | 2 +- 22 files changed, 70 insertions(+), 320 deletions(-) rename pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/{ApexMetricsVisitor.java => ApexMultifileVisitor.java} (72%) rename pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/{ApexMetricsVisitorFacade.java => ApexMultifileVisitorFacade.java} (63%) rename pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/{ApexMetricsVisitorTest.java => ApexMultifileVisitorTest.java} (90%) delete mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitor.java delete mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitorFacade.java diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexHandler.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexHandler.java index 92dd3d03032..37d3cc0c08e 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexHandler.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexHandler.java @@ -13,7 +13,6 @@ import net.sourceforge.pmd.lang.XPathHandler; import net.sourceforge.pmd.lang.apex.ast.ApexNode; import net.sourceforge.pmd.lang.apex.ast.DumpFacade; -import net.sourceforge.pmd.lang.apex.metrics.ApexMetricsVisitorFacade; import net.sourceforge.pmd.lang.apex.rule.ApexRuleViolationFactory; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.xpath.AbstractASTXPathHandler; @@ -56,13 +55,4 @@ public void start(Node rootNode) { }; } - @Override - public VisitorStarter getMetricsVisitorFacade() { - return new VisitorStarter() { - @Override - public void start(Node rootNode) { - new ApexMetricsVisitorFacade().initializeWith((ApexNode) rootNode); - } - }; - } } diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetricsVisitor.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMultifileVisitor.java similarity index 72% rename from pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetricsVisitor.java rename to pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMultifileVisitor.java index cfa0b8e3058..3c524d23322 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetricsVisitor.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMultifileVisitor.java @@ -11,24 +11,23 @@ import net.sourceforge.pmd.lang.apex.ast.ApexParserVisitorReducedAdapter; /** + * TODO move that out! + * * @author Clément Fournier */ -public class ApexMetricsVisitor extends ApexParserVisitorReducedAdapter { +public class ApexMultifileVisitor extends ApexParserVisitorReducedAdapter { - private final ApexProjectMemoizer memoizer; private final ApexProjectMirror mirror; private final Stack stack = new Stack<>(); - public ApexMetricsVisitor(ApexProjectMemoizer memoizer, ApexProjectMirror mirror) { - this.memoizer = memoizer; + public ApexMultifileVisitor(ApexProjectMirror mirror) { this.mirror = mirror; } @Override public Object visit(ASTUserClassOrInterface node, Object data) { - memoizer.addClassMemoizer(node.getQualifiedName()); stack.push(mirror.getClassStats(node.getQualifiedName(), true)); super.visit(node, data); stack.pop(); @@ -41,8 +40,6 @@ public Object visit(ASTUserClassOrInterface node, Object data) { @Override public Object visit(ASTMethod node, Object data) { - memoizer.addOperationMemoizer(node.getQualifiedName()); - stack.peek().addOperation(node.getQualifiedName().getOperation(), node.getSignature()); return data; } diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetricsVisitorFacade.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMultifileVisitorFacade.java similarity index 63% rename from pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetricsVisitorFacade.java rename to pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMultifileVisitorFacade.java index 78dbcd6870c..6b7802b488c 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetricsVisitorFacade.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMultifileVisitorFacade.java @@ -8,15 +8,14 @@ import net.sourceforge.pmd.lang.apex.ast.ApexParserVisitorAdapter; /** + * TODO: move that out! * @author Clément Fournier */ -public class ApexMetricsVisitorFacade extends ApexParserVisitorAdapter { - +public class ApexMultifileVisitorFacade extends ApexParserVisitorAdapter { public void initializeWith(ApexNode rootNode) { ApexMetricsFacade facade = ApexMetrics.getFacade(); - ApexMetricsVisitor visitor = new ApexMetricsVisitor(facade.getLanguageSpecificProjectMemoizer(), - facade.getProjectMirror()); + ApexMultifileVisitor visitor = new ApexMultifileVisitor(facade.getProjectMirror()); rootNode.jjtAccept(visitor, null); } diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetricsVisitorTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/ApexMultifileVisitorTest.java similarity index 90% rename from pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetricsVisitorTest.java rename to pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/ApexMultifileVisitorTest.java index b16f610ddb8..f0426839b52 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetricsVisitorTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/ApexMultifileVisitorTest.java @@ -27,7 +27,7 @@ /** * @author Clément Fournier */ -public class ApexMetricsVisitorTest extends ApexParserTest { +public class ApexMultifileVisitorTest extends ApexParserTest { @Test public void testProjectMirrorNotNull() { @@ -38,7 +38,7 @@ public void testProjectMirrorNotNull() { @Test public void testOperationsAreThere() throws IOException { ApexNode acu = parseAndVisitForString( - IOUtils.toString(ApexMetricsVisitorTest.class.getResourceAsStream("MetadataDeployController.cls"))); + IOUtils.toString(ApexMultifileVisitorTest.class.getResourceAsStream("MetadataDeployController.cls"))); final ApexSignatureMatcher toplevel = ApexMetrics.getFacade().getProjectMirror(); @@ -63,7 +63,6 @@ static ApexNode parseAndVisitForString(String source) { .getDefaultVersion().getLanguageVersionHandler(); ApexNode acu = ApexParserTestHelpers.parse(source); languageVersionHandler.getSymbolFacade().start(acu); - languageVersionHandler.getMetricsVisitorFacade().start(acu); return acu; } } diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/ApexProjectMirrorTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/ApexProjectMirrorTest.java index 8534858d5db..a8221fb20bc 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/ApexProjectMirrorTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/ApexProjectMirrorTest.java @@ -4,7 +4,7 @@ package net.sourceforge.pmd.lang.apex.metrics; -import static net.sourceforge.pmd.lang.apex.metrics.ApexMetricsVisitorTest.parseAndVisitForString; +import static net.sourceforge.pmd.lang.apex.metrics.ApexMultifileVisitorTest.parseAndVisitForString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; @@ -43,7 +43,7 @@ public class ApexProjectMirrorTest { static { try { acu = parseAndVisitForString( - IOUtils.toString(ApexMetricsVisitorTest.class.getResourceAsStream("MetadataDeployController.cls"))); + IOUtils.toString(ApexMultifileVisitorTest.class.getResourceAsStream("MetadataDeployController.cls"))); } catch (IOException ioe) { // Should definitely not happen } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/Rule.java b/pmd-core/src/main/java/net/sourceforge/pmd/Rule.java index 4a764864fc4..7371895903e 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/Rule.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/Rule.java @@ -283,18 +283,18 @@ public interface Rule extends PropertySource { boolean usesTypeResolution(); /** - * Sets whether this Rule uses Object-Oriented Metrics. + * Sets whether this Rule uses multi-file analysis. */ // FUTURE Use JavaBean conventions for boolean attributes - void setUsesMetrics(); + void setUsesMultifile(); /** - * Gets whether this Rule uses Object-Oriented Metrics. + * Gets whether this Rule uses multi-file analysis. * - * @return true if the Metrics Framework is used. + * @return true if the multi file analysis is used. */ // FUTURE Use JavaBean conventions for boolean attributes - boolean usesMetrics(); + boolean usesMultifile(); /** * Gets whether this Rule uses the RuleChain. diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSet.java b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSet.java index 1fbefe1d9f5..870f9d0bb1c 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSet.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSet.java @@ -604,16 +604,19 @@ public boolean usesTypeResolution(Language language) { return false; } + /** - * Does any Rule for the given Language use the Metrics Framework? + * Does any Rule for the given Language use multi-file analysis? + * + * @param language + * The Language. * - * @param language The Language. - * @return true if a Rule for the Language uses the Metrics - * Framework, false otherwise. + * @return {@code true} if a Rule for the Language uses multi file analysis, + * {@code false} otherwise. */ - public boolean usesMetrics(Language language) { + public boolean usesMultifile(Language language) { for (Rule r : rules) { - if (r.getLanguage().equals(language) && r.usesMetrics()) { + if (r.getLanguage().equals(language) && r.usesMultifile()) { return true; } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetFactory.java b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetFactory.java index 86040feab76..5b98235f90f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetFactory.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetFactory.java @@ -576,8 +576,8 @@ private void parseSingleRuleNode(RuleSetReferenceId ruleSetReferenceId, RuleSetB rule.setUsesTypeResolution(); } - if (hasAttributeSetTrue(ruleElement, "metrics")) { - rule.setUsesMetrics(); + if (hasAttributeSetTrue(ruleElement, "multifile")) { + rule.setUsesMultifile(); } final NodeList nodeList = ruleElement.getChildNodes(); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSets.java b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSets.java index c28f323a6ce..ada471db074 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSets.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSets.java @@ -220,15 +220,17 @@ public boolean usesTypeResolution(Language language) { } /** - * Does any Rule for the given Language use the Metrics Framework? + * Does any Rule for the given Language use multi-file analysis? * - * @param language The Language. - * @return true if a Rule for the Language uses the Metrics - * Framework, false otherwise. + * @param language + * The Language. + * + * @return {@code true} if a Rule for the Language uses multi file analysis, + * {@code false} otherwise. */ - public boolean usesMetrics(Language language) { + public boolean usesMultifile(Language language) { for (RuleSet ruleSet : ruleSets) { - if (ruleSet.usesMetrics(language)) { + if (ruleSet.usesMultifile(language)) { return true; } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/SourceCodeProcessor.java b/pmd-core/src/main/java/net/sourceforge/pmd/SourceCodeProcessor.java index 91ff2769f26..29097f21533 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/SourceCodeProcessor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/SourceCodeProcessor.java @@ -155,24 +155,18 @@ private void usesTypeResolution(LanguageVersion languageVersion, Node rootNode, } } - private void usesMetrics(LanguageVersion languageVersion, Node rootNode, RuleSets ruleSets, - Language language) { - if (ruleSets.usesMetrics(language)) { + private void usesMultifile(Node rootNode, LanguageVersionHandler languageVersionHandler, RuleSets ruleSets, + Language language) { + + if (ruleSets.usesMultifile(language)) { long start = System.nanoTime(); - languageVersion.getLanguageVersionHandler().getMetricsVisitorFacade() - .start(rootNode); + languageVersionHandler.getMultifileFacade().start(rootNode); long end = System.nanoTime(); - Benchmarker.mark(Benchmark.MetricsVisitor, end - start, 0); + Benchmarker.mark(Benchmark.Multifile, end - start, 0); } } - private void multifileAnalysis(Node rootNode, LanguageVersionHandler languageVersionHandler) { - long start = System.nanoTime(); - languageVersionHandler.getMultifileFacade().start(rootNode); - long end = System.nanoTime(); - Benchmarker.mark(Benchmark.Multifile, end - start, 0); - } private void processSource(Reader sourceCode, RuleSets ruleSets, RuleContext ctx) { LanguageVersion languageVersion = ctx.getLanguageVersion(); @@ -184,8 +178,7 @@ private void processSource(Reader sourceCode, RuleSets ruleSets, RuleContext ctx Language language = languageVersion.getLanguage(); usesDFA(languageVersion, rootNode, ruleSets, language); usesTypeResolution(languageVersion, rootNode, ruleSets, language); - multifileAnalysis(rootNode, languageVersionHandler); - usesMetrics(languageVersion, rootNode, ruleSets, language); + usesMultifile(rootNode, languageVersionHandler, ruleSets, language); List acus = Collections.singletonList(rootNode); ruleSets.apply(acus, ctx, language); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmark.java b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmark.java index 8674abd1c18..0d9c7606990 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmark.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmark.java @@ -17,14 +17,13 @@ public enum Benchmark { SymbolTable(5, "Symbol table"), DFA(6, "DFA"), TypeResolution(7, "Type resolution"), - Multifile(8, "Multifile analysis"), - MetricsVisitor(9, "Metrics"), - RuleChainVisit(10, "RuleChain visit"), - Reporting(11, "Reporting"), - RuleTotal(12, "Rule total"), - RuleChainTotal(13, "Rule chain rule total"), - MeasuredTotal(14, "Measured total"), - NonMeasuredTotal(15, "Non-measured total"), + RuleChainVisit(8, "RuleChain visit"), + Multifile(9, "Multifile analysis"), + Reporting(10, "Reporting"), + RuleTotal(11, "Rule total"), + RuleChainTotal(12, "Rule chain rule total"), + MeasuredTotal(13, "Measured total"), + NonMeasuredTotal(14, "Non-measured total"), TotalPMD(16, "Total PMD"); public final int index; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/AbstractLanguageVersionHandler.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/AbstractLanguageVersionHandler.java index 0d78c42dcc6..6acbca3de9a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/AbstractLanguageVersionHandler.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/AbstractLanguageVersionHandler.java @@ -50,11 +50,6 @@ public VisitorStarter getTypeResolutionFacade(ClassLoader classLoader) { return VisitorStarter.DUMMY; } - @Override - public VisitorStarter getMetricsVisitorFacade() { - return VisitorStarter.DUMMY; - } - @Override public VisitorStarter getDumpFacade(final Writer writer, final String prefix, final boolean recurse) { return VisitorStarter.DUMMY; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionHandler.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionHandler.java index 7208da4619f..e2ed8203913 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionHandler.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionHandler.java @@ -78,14 +78,6 @@ public interface LanguageVersionHandler { */ VisitorStarter getTypeResolutionFacade(ClassLoader classLoader); - /** - * Get the Metrics Framework visitor. - * - * @return VisitorStarter - */ - VisitorStarter getMetricsVisitorFacade(); - - /** * Get the DumpFacade. * diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/BasicProjectMemoizer.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/BasicProjectMemoizer.java index b064a60660b..3f67299bf8f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/BasicProjectMemoizer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/BasicProjectMemoizer.java @@ -31,27 +31,22 @@ public void reset() { operations.clear(); } - - @Override - public void addClassMemoizer(QualifiedName qname) { - classes.put(qname, new BasicMetricMemoizer()); - } - - - @Override - public void addOperationMemoizer(QualifiedName qname) { - operations.put(qname, new BasicMetricMemoizer()); - } - - @Override public MetricMemoizer getOperationMemoizer(QualifiedName qname) { + if (!operations.containsKey(qname)) { + operations.put(qname, new BasicMetricMemoizer()); + } + return operations.get(qname); } @Override public MetricMemoizer getClassMemoizer(QualifiedName qname) { + if (!classes.containsKey(qname)) { + classes.put(qname, new BasicMetricMemoizer()); + } + return classes.get(qname); } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/ProjectMemoizer.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/ProjectMemoizer.java index 9807594f14f..f732cdaaf3c 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/ProjectMemoizer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/ProjectMemoizer.java @@ -37,21 +37,4 @@ public interface ProjectMemoizer getClassMemoizer(QualifiedName qname); - - /** - * Adds a memoizer for the class identified by this qualified name. - * - * @param qname The qualified name of the class - */ - void addClassMemoizer(QualifiedName qname); - - - /** - * Adds a memoizer for the operation identified by this qualified name. - * - * @param qname The qualified name of the operations - */ - void addOperationMemoizer(QualifiedName qname); - - } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractDelegateRule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractDelegateRule.java index 97386fdfe81..34727a6ae9d 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractDelegateRule.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractDelegateRule.java @@ -240,13 +240,13 @@ public boolean usesTypeResolution() { } @Override - public void setUsesMetrics() { - rule.setUsesMetrics(); + public void setUsesMultifile() { + rule.setUsesMultifile(); } @Override - public boolean usesMetrics() { - return rule.usesMetrics(); + public boolean usesMultifile() { + return rule.usesMultifile(); } @Override diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java index c7b946c7b56..1670b2eff17 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java @@ -40,7 +40,7 @@ public abstract class AbstractRule extends AbstractPropertySource implements Rul private RulePriority priority = RulePriority.LOW; private boolean usesDFA; private boolean usesTypeResolution; - private boolean usesMetrics; + private boolean usesMultifile; private List ruleChainVisits = new ArrayList<>(); public AbstractRule() { @@ -66,7 +66,7 @@ public void deepCopyValuesTo(AbstractRule otherRule) { otherRule.propertyValuesByDescriptor = copyPropertyValues(); otherRule.usesDFA = usesDFA; otherRule.usesTypeResolution = usesTypeResolution; - otherRule.usesMetrics = usesMetrics; + otherRule.usesMultifile = usesMultifile; otherRule.ruleChainVisits = copyRuleChainVisits(); } @@ -78,17 +78,11 @@ private List copyRuleChainVisits() { return new ArrayList<>(ruleChainVisits); } - /** - * @see Rule#getLanguage() - */ @Override public Language getLanguage() { return language; } - /** - * @see Rule#setLanguage(net.sourceforge.pmd.lang.Language) - */ @Override public void setLanguage(Language language) { if (this.language != null && this instanceof ImmutableLanguage && !this.language.equals(language)) { @@ -98,194 +92,122 @@ public void setLanguage(Language language) { this.language = language; } - /** - * @see Rule#getMinimumLanguageVersion() - */ @Override public LanguageVersion getMinimumLanguageVersion() { return minimumLanguageVersion; } - /** - * @see Rule#setMinimumLanguageVersion(net.sourceforge.pmd.lang.LanguageVersion) - */ @Override public void setMinimumLanguageVersion(LanguageVersion minimumLanguageVersion) { this.minimumLanguageVersion = minimumLanguageVersion; } - /** - * @see Rule#getMaximumLanguageVersion() - */ @Override public LanguageVersion getMaximumLanguageVersion() { return maximumLanguageVersion; } - /** - * @see Rule#setMaximumLanguageVersion(net.sourceforge.pmd.lang.LanguageVersion) - */ @Override public void setMaximumLanguageVersion(LanguageVersion maximumLanguageVersion) { this.maximumLanguageVersion = maximumLanguageVersion; } - /** - * @see Rule#isDeprecated() - */ @Override public boolean isDeprecated() { return deprecated; } - /** - * @see Rule#setDeprecated(boolean) - */ @Override public void setDeprecated(boolean deprecated) { this.deprecated = deprecated; } - /** - * @see Rule#getName() - */ @Override public String getName() { return name; } - /** - * @see Rule#setName(String) - */ @Override public void setName(String name) { this.name = name; } - /** - * @see Rule#getSince() - */ @Override public String getSince() { return since; } - /** - * @see Rule#setSince(String) - */ @Override public void setSince(String since) { this.since = since; } - /** - * @see Rule#getRuleClass() - */ @Override public String getRuleClass() { return ruleClass; } - /** - * @see Rule#setRuleClass(String) - */ @Override public void setRuleClass(String ruleClass) { this.ruleClass = ruleClass; } - /** - * @see Rule#getRuleSetName() - */ @Override public String getRuleSetName() { return ruleSetName; } - /** - * @see Rule#setRuleSetName(String) - */ @Override public void setRuleSetName(String ruleSetName) { this.ruleSetName = ruleSetName; } - /** - * @see Rule#getMessage() - */ @Override public String getMessage() { return message; } - /** - * @see Rule#setMessage(String) - */ @Override public void setMessage(String message) { this.message = message; } - /** - * @see Rule#getDescription() - */ @Override public String getDescription() { return description; } - /** - * @see Rule#setDescription(String) - */ @Override public void setDescription(String description) { this.description = description; } - /** - * @see Rule#getExamples() - */ @Override public List getExamples() { // TODO Needs to be externally immutable return examples; } - /** - * @see Rule#addExample(String) - */ @Override public void addExample(String example) { examples.add(example); } - /** - * @see Rule#getExternalInfoUrl() - */ @Override public String getExternalInfoUrl() { return externalInfoUrl; } - /** - * @see Rule#setExternalInfoUrl(String) - */ @Override public void setExternalInfoUrl(String externalInfoUrl) { this.externalInfoUrl = externalInfoUrl; } - /** - * @see Rule#getPriority() - */ @Override public RulePriority getPriority() { return priority; } - /** - * @see Rule#setPriority(RulePriority) - */ @Override public void setPriority(RulePriority priority) { this.priority = priority; @@ -302,74 +224,46 @@ public ParserOptions getParserOptions() { return new ParserOptions(); } - /** - * @see Rule#setUsesDFA() - */ @Override public void setUsesDFA() { usesDFA = true; } - /** - * @see Rule#usesDFA() - */ @Override public boolean usesDFA() { return usesDFA; } - /** - * @see Rule#setUsesTypeResolution() - */ @Override public void setUsesTypeResolution() { usesTypeResolution = true; } - /** - * @see Rule#usesTypeResolution() - */ @Override public boolean usesTypeResolution() { return usesTypeResolution; } - /** - * @see Rule#setUsesMetrics() - */ @Override - public void setUsesMetrics() { - usesMetrics = true; + public void setUsesMultifile() { + usesMultifile = true; } - /** - * @see Rule#usesMetrics() - */ @Override - public boolean usesMetrics() { - return usesMetrics; + public boolean usesMultifile() { + return usesMultifile; } - - /** - * @see Rule#usesRuleChain() - */ @Override public boolean usesRuleChain() { return !getRuleChainVisits().isEmpty(); } - /** - * @see Rule#getRuleChainVisits() - */ @Override public List getRuleChainVisits() { return ruleChainVisits; } - /** - * @see Rule#addRuleChainVisit(Class) - */ @Override public void addRuleChainVisit(Class nodeClass) { if (!nodeClass.getSimpleName().startsWith("AST")) { @@ -378,9 +272,6 @@ public void addRuleChainVisit(Class nodeClass) { addRuleChainVisit(nodeClass.getSimpleName().substring("AST".length())); } - /** - * @see Rule#addRuleChainVisit(String) - */ @Override public void addRuleChainVisit(String astNodeName) { if (!ruleChainVisits.contains(astNodeName)) { @@ -388,17 +279,11 @@ public void addRuleChainVisit(String astNodeName) { } } - /** - * @see Rule#start(RuleContext) - */ @Override public void start(RuleContext ctx) { // Override as needed } - /** - * @see Rule#end(RuleContext) - */ @Override public void end(RuleContext ctx) { // Override as needed @@ -494,9 +379,6 @@ public boolean equals(Object o) { return equality; } - /** - * @see #equals(Object) - */ @Override public int hashCode() { Object propertyValues = getPropertiesByPropertyDescriptor(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/AbstractJavaHandler.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/AbstractJavaHandler.java index 49913071908..93c14150726 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/AbstractJavaHandler.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/AbstractJavaHandler.java @@ -19,7 +19,6 @@ import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.dfa.DataFlowFacade; import net.sourceforge.pmd.lang.java.dfa.JavaDFAGraphRule; -import net.sourceforge.pmd.lang.java.metrics.JavaMetricsVisitorFacade; import net.sourceforge.pmd.lang.java.multifile.MultifileVisitorFacade; import net.sourceforge.pmd.lang.java.rule.JavaRuleViolationFactory; import net.sourceforge.pmd.lang.java.symboltable.SymbolFacade; @@ -98,16 +97,6 @@ public void start(Node rootNode) { }; } - @Override - public VisitorStarter getMetricsVisitorFacade() { - return new VisitorStarter() { - @Override - public void start(Node rootNode) { - new JavaMetricsVisitorFacade().initializeWith((ASTCompilationUnit) rootNode); - } - }; - } - @Override public VisitorStarter getDumpFacade(final Writer writer, final String prefix, final boolean recurse) { return new VisitorStarter() { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitor.java deleted file mode 100644 index c6b637e87e8..00000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitor.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.metrics; - -import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration; -import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration; -import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorReducedAdapter; - -/** - * Visitor for the metrics framework, that creates the memoizers. - * - * @author Clément Fournier - */ -class JavaMetricsVisitor extends JavaParserVisitorReducedAdapter { - - private final JavaProjectMemoizer memoizer; - - - JavaMetricsVisitor(JavaProjectMemoizer memoizer) { - this.memoizer = memoizer; - } - - - @Override - public Object visit(ASTAnyTypeDeclaration node, Object data) { - memoizer.addClassMemoizer(node.getQualifiedName()); - return super.visit(node, data); - } - - - @Override - public Object visit(ASTMethodOrConstructorDeclaration node, Object data) { - memoizer.addOperationMemoizer(node.getQualifiedName()); - return super.visit(node, data); - } - -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitorFacade.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitorFacade.java deleted file mode 100644 index 4c4f6d4b205..00000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsVisitorFacade.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.metrics; - -import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; -import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter; - -/** - * Wraps the visitor. - * - * @author Clément Fournier - */ -public class JavaMetricsVisitorFacade extends JavaParserVisitorAdapter { - - public void initializeWith(ASTCompilationUnit rootNode) { - JavaMetricsFacade facade = JavaMetrics.getFacade(); - JavaMetricsVisitor visitor = new JavaMetricsVisitor(facade.getLanguageSpecificProjectMemoizer()); - rootNode.jjtAccept(visitor, null); - } - -} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/ProjectMemoizerTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/ProjectMemoizerTest.java index e92b0028d5c..49a0a412673 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/ProjectMemoizerTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/ProjectMemoizerTest.java @@ -38,7 +38,7 @@ public class ProjectMemoizerTest { @Test public void memoizationTest() { - ASTCompilationUnit acu = parseAndVisitForClass(MetricsVisitorTestData.class); + ASTCompilationUnit acu = ParserTstUtil.parseJavaDefaultVersion(MetricsVisitorTestData.class); List expected = visitWith(acu, true); List real = visitWith(acu, false); @@ -50,7 +50,7 @@ public void memoizationTest() { @Test public void forceMemoizationTest() { - ASTCompilationUnit acu = parseAndVisitForClass(MetricsVisitorTestData.class); + ASTCompilationUnit acu = ParserTstUtil.parseJavaDefaultVersion(MetricsVisitorTestData.class); List reference = visitWith(acu, true); List real = visitWith(acu, true); @@ -92,12 +92,6 @@ public Object visit(ASTAnyTypeDeclaration node, Object data) { } - static ASTCompilationUnit parseAndVisitForClass(Class clazz) { - ASTCompilationUnit acu = ParserTstUtil.parseJavaDefaultVersion(clazz); - ParserTstUtil.getDefaultLanguageVersionHandler().getMetricsVisitorFacade().start(acu); - return acu; - } - private class RandomOperationMetric extends AbstractJavaOperationMetric { private Random random = new Random(); diff --git a/pmd-test/src/test/java/net/sourceforge/pmd/testframework/RuleTstTest.java b/pmd-test/src/test/java/net/sourceforge/pmd/testframework/RuleTstTest.java index dd9992ec856..ae83bc9bfaf 100644 --- a/pmd-test/src/test/java/net/sourceforge/pmd/testframework/RuleTstTest.java +++ b/pmd-test/src/test/java/net/sourceforge/pmd/testframework/RuleTstTest.java @@ -39,7 +39,7 @@ public void shouldCallStartAndEnd() { verify(rule, times(5)).getLanguage(); verify(rule).usesDFA(); verify(rule).usesTypeResolution(); - verify(rule).usesMetrics(); + verify(rule).usesMultifile(); verify(rule, times(2)).usesRuleChain(); verify(rule).getMinimumLanguageVersion(); verify(rule).getMaximumLanguageVersion(); From 8b0eaa6c3d8b54f6013e7e3f023fdaa52f8135dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 27 Aug 2017 23:18:22 +0200 Subject: [PATCH 0013/2019] Remove fluent API for sigmasks --- .../multifile/signature/JavaFieldSigMask.java | 68 ++++--------------- .../signature/JavaOperationSigMask.java | 55 +++------------ .../java/multifile/signature/JavaSigMask.java | 20 +----- .../lang/java/multifile/ClassStatsTest.java | 56 ++++++++++++--- 4 files changed, 77 insertions(+), 122 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaFieldSigMask.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaFieldSigMask.java index fa4323fd6bb..74b1bbc062f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaFieldSigMask.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaFieldSigMask.java @@ -4,8 +4,6 @@ package net.sourceforge.pmd.lang.java.multifile.signature; -import net.sourceforge.pmd.lang.java.multifile.signature.JavaSignature.Visibility; - /** * Signature mask for a field. Newly created masks cover any field. * @@ -17,76 +15,40 @@ public final class JavaFieldSigMask extends JavaSigMask { private boolean coverStatic = true; - /** - * Creates a field mask covering any field. - */ public JavaFieldSigMask() { - // everything's initialized - } - - - /** - * Sets the mask to cover final fields. - * - * @return this - */ - public JavaFieldSigMask coverFinal() { - this.coverFinal = true; - return this; + super(); } - /** - * Forbid final fields. - * - * @return this - */ - public JavaFieldSigMask forbidFinal() { - coverFinal = false; - return this; + /** Include final fields?. */ + public void coverFinal(boolean coverFinal) { + this.coverFinal = coverFinal; } - /** - * Sets the mask to cover static fields. - * - * @return this - */ - public JavaFieldSigMask coverStatic() { - this.coverStatic = true; - return this; + public void coverFinal() { + this.coverFinal = true; } - /** - * Forbid abstract operations. - * - * @return this - */ - public JavaFieldSigMask forbidStatic() { - coverStatic = false; - return this; + public void forbidFinal() { + this.coverFinal = false; } - @Override - public JavaFieldSigMask coverAllVisibilities() { - super.coverAllVisibilities(); - return this; + /** Include static fields?. */ + public void coverStatic(boolean coverStatic) { + this.coverStatic = coverStatic; } - @Override - public JavaFieldSigMask restrictVisibilitiesTo(Visibility... visibilities) { - super.restrictVisibilitiesTo(visibilities); - return this; + public void coverStatic() { + this.coverStatic = true; } - @Override - public JavaFieldSigMask forbid(Visibility... visibilities) { - super.forbid(visibilities); - return this; + public void forbidStatic() { + this.coverStatic = false; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaOperationSigMask.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaOperationSigMask.java index 8c19af404bc..ecd9bb79ae7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaOperationSigMask.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/multifile/signature/JavaOperationSigMask.java @@ -9,7 +9,6 @@ import java.util.Set; import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature.Role; -import net.sourceforge.pmd.lang.java.multifile.signature.JavaSignature.Visibility; /** * Signature mask for an operation. Newly created masks cover any operation that is not abstract. @@ -22,20 +21,11 @@ public final class JavaOperationSigMask extends JavaSigMask> implements SigMask private Set visMask = EnumSet.allOf(Visibility.class); - protected JavaSigMask() { - - } - - /** * Sets the mask to cover all visibilities. - * - * @return this */ - public JavaSigMask coverAllVisibilities() { + public void coverAllVisibilities() { visMask.addAll(Arrays.asList(JavaSignature.Visibility.values())); - return this; } @@ -44,13 +36,10 @@ public JavaSigMask coverAllVisibilities() { * Restricts the visibilities covered by the mask to the parameters. * * @param visibilities The visibilities to cover - * - * @return this */ - public JavaSigMask restrictVisibilitiesTo(JavaSignature.Visibility... visibilities) { + public void restrictVisibilitiesTo(JavaSignature.Visibility... visibilities) { visMask.clear(); visMask.addAll(Arrays.asList(visibilities)); - return this; } @@ -58,12 +47,9 @@ public JavaSigMask restrictVisibilitiesTo(JavaSignature.Visibility... visibil * Forbid all mentioned visibilities. * * @param visibilities The visibilities to forbid - * - * @return this */ - public JavaSigMask forbid(JavaSignature.Visibility... visibilities) { + public void forbid(JavaSignature.Visibility... visibilities) { visMask.removeAll(Arrays.asList(visibilities)); - return this; } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/ClassStatsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/ClassStatsTest.java index a6c3658c0d7..9827e9cd04c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/ClassStatsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/multifile/ClassStatsTest.java @@ -37,16 +37,18 @@ public void testCountOpSigs() { final ClassMirror classMirror = toplevel.getClassMirror(JavaQualifiedName.ofClass(SignatureCountTestData.class)); - final JavaOperationSigMask opSigMask = new JavaOperationSigMask().coverAbstract(); + final FluentOperationSigMask opSigMask = new FluentOperationSigMask(); + + opSigMask.mask.coverAbstract(); opSigMask.restrictRolesTo(Role.STATIC); - assertEquals(4, classMirror.countMatchingOpSigs(opSigMask)); + assertEquals(4, classMirror.countMatchingOpSigs(opSigMask.mask)); assertEquals(2, classMirror.countMatchingOpSigs(opSigMask.restrictVisibilitiesTo(Visibility.PRIVATE))); assertEquals(2, classMirror.countMatchingOpSigs(opSigMask.restrictVisibilitiesTo(Visibility.PUBLIC))); opSigMask.restrictRolesTo(Role.METHOD).coverAllVisibilities(); - assertEquals(6, classMirror.countMatchingOpSigs(opSigMask)); + assertEquals(6, classMirror.countMatchingOpSigs(opSigMask.mask)); assertEquals(1, classMirror.countMatchingOpSigs(opSigMask.restrictVisibilitiesTo(Visibility.PUBLIC))); assertEquals(1, classMirror.countMatchingOpSigs(opSigMask.restrictVisibilitiesTo(Visibility.PRIVATE))); assertEquals(4, classMirror.countMatchingOpSigs(opSigMask.restrictVisibilitiesTo(Visibility.PROTECTED))); @@ -54,25 +56,63 @@ public void testCountOpSigs() { opSigMask.restrictRolesTo(Role.GETTER_OR_SETTER).coverAllVisibilities(); - assertEquals(8, classMirror.countMatchingOpSigs(opSigMask)); + assertEquals(8, classMirror.countMatchingOpSigs(opSigMask.mask)); assertEquals(4, classMirror.countMatchingOpSigs(opSigMask.restrictVisibilitiesTo(Visibility.PACKAGE))); assertEquals(4, classMirror.countMatchingOpSigs(opSigMask.restrictVisibilitiesTo(Visibility.PUBLIC))); opSigMask.restrictRolesTo(Role.CONSTRUCTOR).coverAllVisibilities(); - assertEquals(3, classMirror.countMatchingOpSigs(opSigMask)); + assertEquals(3, classMirror.countMatchingOpSigs(opSigMask.mask)); assertEquals(3, classMirror.countMatchingOpSigs(opSigMask.restrictVisibilitiesTo(Visibility.PUBLIC))); - JavaFieldSigMask fieldSigMask = new JavaFieldSigMask(); + FluentFieldSigMask fieldSigMask = new FluentFieldSigMask(); - assertEquals(6, classMirror.countMatchingFieldSigs(fieldSigMask)); + assertEquals(6, classMirror.countMatchingFieldSigs(fieldSigMask.mask)); assertEquals(3, classMirror.countMatchingFieldSigs(fieldSigMask.restrictVisibilitiesTo(Visibility.PUBLIC))); assertEquals(1, classMirror.countMatchingFieldSigs(fieldSigMask.restrictVisibilitiesTo(Visibility.PROTECTED))); assertEquals(2, classMirror.countMatchingFieldSigs(fieldSigMask.restrictVisibilitiesTo(Visibility.PRIVATE))); - assertEquals(0, classMirror.countMatchingFieldSigs(fieldSigMask.restrictVisibilitiesTo(Visibility.PRIVATE).forbidFinal())); + + fieldSigMask.mask.forbidFinal(); + + assertEquals(0, classMirror.countMatchingFieldSigs(fieldSigMask.restrictVisibilitiesTo(Visibility.PRIVATE))); + + + } + + // Containers to clear up tests + private class FluentOperationSigMask { + + JavaOperationSigMask mask = new JavaOperationSigMask(); + + + JavaOperationSigMask forbidAbstract() { + mask.coverAbstract(false); + return mask; + } + + + JavaOperationSigMask restrictVisibilitiesTo(Visibility... visibilities) { + mask.restrictVisibilitiesTo(visibilities); + return mask; + } + + + JavaOperationSigMask restrictRolesTo(Role... roles) { + mask.restrictRolesTo(roles); + return mask; + } + } + + private class FluentFieldSigMask { + + JavaFieldSigMask mask = new JavaFieldSigMask(); + JavaFieldSigMask restrictVisibilitiesTo(Visibility... visibilities) { + mask.restrictVisibilitiesTo(visibilities); + return mask; + } } From dcf5403003ff46e6b2c8059c120d6c86e16238d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 27 Aug 2017 23:29:16 +0200 Subject: [PATCH 0014/2019] Cache signatures in nodes --- .../ast/ASTClassOrInterfaceDeclaration.java | 2 +- .../java/ast/ASTConstructorDeclaration.java | 7 +++++- .../lang/java/ast/ASTFieldDeclaration.java | 8 ++++++- .../lang/java/ast/ASTMethodDeclaration.java | 7 +++++- .../pmd/lang/java/ast/JavaQualifiedName.java | 22 +++---------------- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclaration.java index f6606831595..9e09fe341c3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclaration.java @@ -50,7 +50,7 @@ public void setInterface() { public JavaQualifiedName getQualifiedName() { if (qualifiedName == null) { if (isNested()) { - ASTAnyTypeDeclaration parent = this.getFirstParentOfType(ASTAnyTypeDeclaration.class); + ASTClassOrInterfaceDeclaration parent = this.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class); JavaQualifiedName parentQN = parent.getQualifiedName(); qualifiedName = JavaQualifiedName.ofNestedClass(parentQN, this.getImage()); return qualifiedName; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java index dd598a3668f..42e9ea79d70 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java @@ -11,6 +11,7 @@ public class ASTConstructorDeclaration extends AbstractJavaAccessNode implements private boolean containsComment; private JavaQualifiedName qualifiedName; + private JavaOperationSignature signature; public ASTConstructorDeclaration(int id) { super(id); @@ -54,6 +55,10 @@ public JavaQualifiedName getQualifiedName() { @Override public JavaOperationSignature getSignature() { - return JavaOperationSignature.buildFor(this); + if (signature == null) { + signature = JavaOperationSignature.buildFor(this); + } + + return signature; } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java index 4cc365d1475..f23a3e4e80d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java @@ -10,6 +10,8 @@ public class ASTFieldDeclaration extends AbstractJavaAccessTypeNode implements Dimensionable, SignedNode { + private JavaFieldSignature signature; + public ASTFieldDeclaration(int id) { super(id); @@ -145,6 +147,10 @@ public String getVariableName() { @Override public JavaFieldSignature getSignature() { - return JavaFieldSignature.buildFor(this); + if (signature == null) { + signature = JavaFieldSignature.buildFor(this); + } + + return signature; } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java index 9c9f2309bcf..ae0ad7934b3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java @@ -12,6 +12,7 @@ public class ASTMethodDeclaration extends AbstractJavaAccessNode implements DFAGraphMethod, ASTMethodOrConstructorDeclaration { private JavaQualifiedName qualifiedName; + private JavaOperationSignature signature; public ASTMethodDeclaration(int id) { @@ -127,6 +128,10 @@ public JavaQualifiedName getQualifiedName() { @Override public JavaOperationSignature getSignature() { - return JavaOperationSignature.buildFor(this); + if (signature == null) { + signature = JavaOperationSignature.buildFor(this); + } + + return signature; } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaQualifiedName.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaQualifiedName.java index b105ad6cc82..843fb567e8d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaQualifiedName.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaQualifiedName.java @@ -63,7 +63,7 @@ private JavaQualifiedName() { } - /** Factorises the functionality of ofOperation() */ + /** Factorises the functionality of makeOperationof() */ private static JavaQualifiedName ofOperation(JavaQualifiedName parent, String opName, ASTFormalParameters params) { JavaQualifiedName qname = new JavaQualifiedName(); @@ -115,27 +115,11 @@ private static JavaQualifiedName ofOperation(JavaQualifiedName parent, String op } - /** - * Gets the qualified name of a class. - * - * @param clazz Class object - * - * @return The qualified name of the class, or null if the class is null - */ + // Might be useful with type resolution public static JavaQualifiedName ofClass(Class clazz) { - if (clazz == null) { - return null; - } - - String name = clazz.getName(); - if (name.indexOf('.') < 0) { - name = '.' + name; - } - - return ofString(name); + throw new UnsupportedOperationException(); } - /** * Parses a qualified name given in the format defined for this implementation. The format * is specified by a regex pattern (see {@link JavaQualifiedName#FORMAT}). Examples: From ac7e1e970f7654360f1ba6df5a6f2ecab315eb02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 27 Aug 2017 23:42:13 +0200 Subject: [PATCH 0015/2019] WeakHashMap for project memoizers --- .../pmd/lang/metrics/BasicProjectMemoizer.java | 14 +++++++++----- .../pmd/lang/metrics/ProjectMemoizer.java | 3 +++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/BasicProjectMemoizer.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/BasicProjectMemoizer.java index 3f67299bf8f..d09cbb29dd2 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/BasicProjectMemoizer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/BasicProjectMemoizer.java @@ -4,8 +4,8 @@ package net.sourceforge.pmd.lang.metrics; -import java.util.HashMap; import java.util.Map; +import java.util.WeakHashMap; import net.sourceforge.pmd.lang.ast.QualifiableNode; import net.sourceforge.pmd.lang.ast.QualifiedName; @@ -14,16 +14,19 @@ * Simple implementation of a project memoizer. Memoizers are accessible in constant time, provided the QualifiedName's * hashCode is well distributed. * + *

This implementation takes care of recollecting irrelevant memoizers by storing them in {@link WeakHashMap}. + * * @param Type of type declaration nodes of the language * @param Type of operation declaration nodes of the language * * @author Clément Fournier */ -public abstract class BasicProjectMemoizer implements - ProjectMemoizer { +public abstract class BasicProjectMemoizer + implements ProjectMemoizer { + + private Map> classes = new WeakHashMap<>(); + private Map> operations = new WeakHashMap<>(); - private Map> classes = new HashMap<>(); - private Map> operations = new HashMap<>(); /** Clears all memoizers. Used for tests. */ public void reset() { @@ -31,6 +34,7 @@ public void reset() { operations.clear(); } + @Override public MetricMemoizer getOperationMemoizer(QualifiedName qname) { if (!operations.containsKey(qname)) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/ProjectMemoizer.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/ProjectMemoizer.java index f732cdaaf3c..0d14f380977 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/ProjectMemoizer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/ProjectMemoizer.java @@ -11,6 +11,9 @@ * Object storing the memoizers of the analysed project. This object should ideally be kept separate from the * SignatureMatcher if there is one. A base implementation is available, see {@link BasicProjectMemoizer}. * + *

Memoizers need not be all kept, in fact, only those who refer to operations or classes defined in + * the analysed file are still relevant. + * * @param Type of type declaration nodes of the language * @param Type of operation declaration nodes of the language * From 14d0d14a1858e66b6b25fa416300cb01cdcf4f62 Mon Sep 17 00:00:00 2001 From: oowekyala Date: Sun, 6 Aug 2017 22:19:36 +0200 Subject: [PATCH 0016/2019] Draft w/ mvn system dependency --- pmd-core/pom.xml | 7 + .../pmd/util/fxdesigner/ASTTreeNode.java | 160 ++++++++++++++++++ .../pmd/util/fxdesigner/Designer.java | 36 ++++ .../util/fxdesigner/DesignerController.java | 125 ++++++++++++++ .../pmd/util/fxdesigner/DesignerUtil.java | 45 +++++ .../pmd/util/fxdesigner/designer.fxml | 45 +++++ 6 files changed, 418 insertions(+) create mode 100644 pmd-core/src/main/java/net/sourceforge/pmd/util/fxdesigner/ASTTreeNode.java create mode 100644 pmd-core/src/main/java/net/sourceforge/pmd/util/fxdesigner/Designer.java create mode 100644 pmd-core/src/main/java/net/sourceforge/pmd/util/fxdesigner/DesignerController.java create mode 100644 pmd-core/src/main/java/net/sourceforge/pmd/util/fxdesigner/DesignerUtil.java create mode 100644 pmd-core/src/main/resources/net/sourceforge/pmd/util/fxdesigner/designer.fxml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 9262c561106..b0e9f7de98e 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -140,5 +140,12 @@ system-rules test + + javafx + jfxrt + ${java.version} + system + ${java.home}/lib/ext/jfxrt.jar + diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/fxdesigner/ASTTreeNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/fxdesigner/ASTTreeNode.java new file mode 100644 index 00000000000..94642c519a7 --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/fxdesigner/ASTTreeNode.java @@ -0,0 +1,160 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.util.fxdesigner; + +import java.io.StringWriter; +import java.util.Enumeration; +import java.util.LinkedList; +import java.util.List; +import javax.swing.tree.TreeNode; + +import net.sourceforge.pmd.lang.LanguageVersionHandler; +import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.ast.xpath.Attribute; +import net.sourceforge.pmd.lang.ast.xpath.AttributeAxisIterator; +import net.sourceforge.pmd.lang.symboltable.Scope; +import net.sourceforge.pmd.lang.symboltable.ScopedNode; + +/** + * @author Clément Fournier + */ +class ASTTreeNode implements TreeNode { + + private static DesignerController controller; + + private Node node; + private ASTTreeNode parent; + private ASTTreeNode[] kids; + + + ASTTreeNode(Node theNode) { + node = theNode; + + Node parent = node.jjtGetParent(); + if (parent != null) { + this.parent = new ASTTreeNode(parent); + } + } + + + private ASTTreeNode(ASTTreeNode parent, Node theNode) { + node = theNode; + this.parent = parent; + } + + + @Override + public int getChildCount() { + return node.jjtGetNumChildren(); + } + + + @Override + public boolean getAllowsChildren() { + return false; + } + + + @Override + public boolean isLeaf() { + return node.jjtGetNumChildren() == 0; + } + + + @Override + public TreeNode getParent() { + return parent; + } + + + public Scope getScope() { + if (node instanceof ScopedNode) { + return ((ScopedNode) node).getScope(); + } + return null; + } + + + @Override + public Enumeration children() { + + if (getChildCount() > 0) { + getChildAt(0); // force it to build kids + } + + Enumeration e = new Enumeration() { + int i = 0; + + + @Override + public boolean hasMoreElements() { + return kids != null && i < kids.length; + } + + + @Override + public ASTTreeNode nextElement() { + return kids[i++]; + } + }; + return e; + } + + + @Override + public TreeNode getChildAt(int childIndex) { + + if (kids == null) { + kids = new ASTTreeNode[node.jjtGetNumChildren()]; + for (int i = 0; i < kids.length; i++) { + kids[i] = new ASTTreeNode(this.parent, node.jjtGetChild(i)); + } + } + return kids[childIndex]; + } + + + @Override + public int getIndex(TreeNode node) { + + for (int i = 0; i < kids.length; i++) { + if (kids[i] == node) { + return i; + } + } + return -1; + } + + + public String label() { + LanguageVersionHandler languageVersionHandler = controller.getLanguageVersionHandler(); + StringWriter writer = new StringWriter(); + languageVersionHandler.getDumpFacade(writer, "", false).start(node); + return writer.toString(); + } + + + public String getToolTipText() { + String tooltip = "Line: " + node.getBeginLine() + " Column: " + node.getBeginColumn(); + tooltip += " " + label(); + return tooltip; + } + + + public List getAttributes() { + List result = new LinkedList<>(); + AttributeAxisIterator attributeAxisIterator = new AttributeAxisIterator(node); + while (attributeAxisIterator.hasNext()) { + Attribute attribute = attributeAxisIterator.next(); + result.add(attribute.getName() + "=" + attribute.getStringValue()); + } + return result; + } + + + static void initialize(DesignerController ctrl) { + controller = ctrl; + } +} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/fxdesigner/Designer.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/fxdesigner/Designer.java new file mode 100644 index 00000000000..50eb0e0b3c8 --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/fxdesigner/Designer.java @@ -0,0 +1,36 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.util.fxdesigner; + +import java.io.IOException; + +import net.sourceforge.pmd.PMD; + +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.stage.Stage; + +/** + * @author Clément Fournier + */ +public class Designer extends Application { + + public static void main(String[] args) { + launch(args); + } + + @Override + public void start(Stage stage) throws IOException { + Parent root = FXMLLoader.load(getClass().getResource("designer.fxml")); + + Scene scene = new Scene(root, 900, 600); + + stage.setTitle("PMD Rule Designer (v " + PMD.VERSION + ')'); + stage.setScene(scene); + stage.show(); + } +} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/fxdesigner/DesignerController.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/fxdesigner/DesignerController.java new file mode 100644 index 00000000000..be580e44a61 --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/fxdesigner/DesignerController.java @@ -0,0 +1,125 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.util.fxdesigner; + +import java.io.StringReader; +import java.net.URL; +import java.util.Map; +import java.util.ResourceBundle; + +import net.sourceforge.pmd.lang.LanguageRegistry; +import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.lang.LanguageVersionHandler; +import net.sourceforge.pmd.lang.Parser; +import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.util.designer.Designer; + +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.Menu; +import javafx.scene.control.MenuItem; +import javafx.scene.control.RadioMenuItem; +import javafx.scene.control.ToggleGroup; + +/** + * @author Clément Fournier + */ +class DesignerController implements Initializable { + + @FXML + private Menu languageMenu; + + + private LanguageVersion selectedLanguageVersion; + private Map languageRadioMenuMap; + + + @Override + public void initialize(URL location, ResourceBundle resources) { + ASTTreeNode.initialize(this); + initializeLanguageVersionMenu(); + } + + + private void initializeLanguageVersionMenu() { + LanguageVersion[] supported = DesignerUtil.getSupportedLanguageVersions(); + ObservableList items = languageMenu.getItems(); + assert items.size() == 0; + + System.out.println(supported); + ToggleGroup group = new ToggleGroup(); + + for (LanguageVersion version : supported) { + RadioMenuItem item = new RadioMenuItem(version.getShortName()); + items.add(item); + languageRadioMenuMap.put(version, item); + } + + selectedLanguageVersion = LanguageRegistry.getLanguage("Java").getDefaultVersion(); + languageRadioMenuMap.get(selectedLanguageVersion).setSelected(true); + + languageMenu.show(); + + } + + + private Node getCompilationUnit() { + LanguageVersionHandler languageVersionHandler = getLanguageVersionHandler(); + return getCompilationUnit(languageVersionHandler); + } + + + private Node getCompilationUnit(LanguageVersionHandler languageVersionHandler) { + return null; //getCompilationUnit(languageVersionHandler, codeEditorPane.getText()); + } + + + private LanguageVersion getLanguageVersion() { + return DesignerUtil.getSupportedLanguageVersions()[selectedLanguageVersionIndex()]; + } + + + private void setLanguageVersion(LanguageVersion languageVersion) { + if (languageVersion != null) { + LanguageVersion[] versions = DesignerUtil.getSupportedLanguageVersions(); + for (int i = 0; i < versions.length; i++) { + LanguageVersion version = versions[i]; + if (languageVersion.equals(version)) { + // languageVersionMenuItems[i].setSelected(true); + break; + } + } + } + } + + + private int selectedLanguageVersionIndex() { + /* for (int i = 0; i < languageVersionMenuItems.length; i++) { + if (languageVersionMenuItems[i].isSelected()) { + return i; + } + } + */ + throw new RuntimeException("Initial default language version not specified"); + } + + + LanguageVersionHandler getLanguageVersionHandler() { + LanguageVersion languageVersion = getLanguageVersion(); + return languageVersion.getLanguageVersionHandler(); + } + + + static Node getCompilationUnit(LanguageVersionHandler languageVersionHandler, String code) { + Parser parser = languageVersionHandler.getParser(languageVersionHandler.getDefaultParserOptions()); + Node node = parser.parse(null, new StringReader(code)); + languageVersionHandler.getSymbolFacade().start(node); + languageVersionHandler.getTypeResolutionFacade(Designer.class.getClassLoader()).start(node); + return node; + } + + +} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/fxdesigner/DesignerUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/fxdesigner/DesignerUtil.java new file mode 100644 index 00000000000..3bf3091716e --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/fxdesigner/DesignerUtil.java @@ -0,0 +1,45 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.util.fxdesigner; + +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.pmd.lang.LanguageRegistry; +import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.lang.LanguageVersionHandler; +import net.sourceforge.pmd.lang.Parser; + +/** + * @author Clément Fournier + */ +public class DesignerUtil { + + + private static LanguageVersion[] supportedLanguageVersions; + + + private DesignerUtil() { + + } + + + public static LanguageVersion[] getSupportedLanguageVersions() { + if (supportedLanguageVersions == null) { + List languageVersions = new ArrayList<>(); + for (LanguageVersion languageVersion : LanguageRegistry.findAllVersions()) { + LanguageVersionHandler languageVersionHandler = languageVersion.getLanguageVersionHandler(); + if (languageVersionHandler != null) { + Parser parser = languageVersionHandler.getParser(languageVersionHandler.getDefaultParserOptions()); + if (parser != null && parser.canParse()) { + languageVersions.add(languageVersion); + } + } + } + supportedLanguageVersions = languageVersions.toArray(new LanguageVersion[languageVersions.size()]); + } + return supportedLanguageVersions; + } +} diff --git a/pmd-core/src/main/resources/net/sourceforge/pmd/util/fxdesigner/designer.fxml b/pmd-core/src/main/resources/net/sourceforge/pmd/util/fxdesigner/designer.fxml new file mode 100644 index 00000000000..f48a1961884 --- /dev/null +++ b/pmd-core/src/main/resources/net/sourceforge/pmd/util/fxdesigner/designer.fxml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + +

+ + + + + + + + + + + + + + + + +
+ + + + +