aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorDinesh Bolkensteyn <dinesh@dinsoft.net>2011-10-25 13:49:12 +0200
committerDinesh Bolkensteyn <dinesh@dinsoft.net>2011-10-25 13:49:49 +0200
commit039f7ae976cc2128e766a94bbdda634e995c66a9 (patch)
treeabf63bc1ff29f24d2eb02578168d5333ed55b270 /plugins
parent176e46458b7700c547520588099ced62347afd5c (diff)
downloadsonarqube-039f7ae976cc2128e766a94bbdda634e995c66a9.tar.gz
sonarqube-039f7ae976cc2128e766a94bbdda634e995c66a9.zip
Moved the place accessors are computed from a bytecode visitor to a property on the bytecode resource AsmMethod
Diffstat (limited to 'plugins')
-rw-r--r--plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/BytecodeScanner.java1
-rw-r--r--plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/asm/AsmMethod.java41
-rw-r--r--plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/visitor/AccessorVisitor.java67
-rw-r--r--plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/visitor/LCOM4Visitor.java6
-rw-r--r--plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmMethodTest.java43
-rw-r--r--plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/visitor/AccessorVisitorTest.java78
6 files changed, 76 insertions, 160 deletions
diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/BytecodeScanner.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/BytecodeScanner.java
index ac2a8c8a75c..b1ca5fdbb1e 100644
--- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/BytecodeScanner.java
+++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/BytecodeScanner.java
@@ -91,7 +91,6 @@ public class BytecodeScanner extends CodeScanner<BytecodeVisitor> {
@Override
public Collection<Class<? extends BytecodeVisitor>> getVisitorClasses() {
List<Class<? extends BytecodeVisitor>> visitorClasses = new ArrayList<Class<? extends BytecodeVisitor>>();
- visitorClasses.add(AccessorVisitor.class);
visitorClasses.add(DITVisitor.class);
visitorClasses.add(RFCVisitor.class);
visitorClasses.add(NOCVisitor.class);
diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/asm/AsmMethod.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/asm/AsmMethod.java
index 5104162d148..e68caf6e8a4 100644
--- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/asm/AsmMethod.java
+++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/asm/AsmMethod.java
@@ -31,6 +31,7 @@ public class AsmMethod extends AsmResource {
private boolean inherited = false;
private boolean empty = false;
private boolean bodyLoaded = true;
+ private boolean accessFieldComputed = false;
private AsmField accessedField = null;
private String signature;
private AsmMethod implementationLinkage = null;
@@ -138,17 +139,45 @@ public class AsmMethod extends AsmResource {
void setEmpty(boolean empty) {
this.empty = empty;
}
-
- public boolean isAccessor() {
- return accessedField != null;
+
+ private void ensureAccessorComputed() {
+ if (accessFieldComputed) return;
+ setAccessedField();
+ accessFieldComputed = true;
+ }
+
+ private void setAccessedField() {
+ if (!isConstructor()) {
+ for (AsmEdge edge: getOutgoingEdges()) {
+ if (isCallToNonStaticInternalField(edge)) {
+ if (accessedField != null && accessedField != edge.getTo()) {
+ accessedField = null;
+ break;
+ }
+ accessedField = (AsmField)edge.getTo();
+ } else if (isCallToNonStaticInternalMethod(edge)) {
+ accessedField = null;
+ break;
+ }
+ }
+ }
+ }
+
+ private boolean isCallToNonStaticInternalField(AsmEdge edge) {
+ return edge.getTargetAsmClass() == (AsmClass)getParent() && edge.getUsage() == SourceCodeEdgeUsage.CALLS_FIELD && !((AsmField)edge.getTo()).isStatic();
+ }
+
+ private boolean isCallToNonStaticInternalMethod(AsmEdge edge) {
+ return edge.getTargetAsmClass() == (AsmClass)getParent() && edge.getUsage() == SourceCodeEdgeUsage.CALLS_METHOD && !((AsmMethod)edge.getTo()).isStatic();
}
public AsmField getAccessedField() {
+ ensureAccessorComputed();
return accessedField;
}
-
- public void setAccessedField(AsmField accessedField) {
- this.accessedField = accessedField;
+
+ public boolean isAccessor() {
+ return getAccessedField() != null;
}
@Override
diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/visitor/AccessorVisitor.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/visitor/AccessorVisitor.java
deleted file mode 100644
index e022590177d..00000000000
--- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/visitor/AccessorVisitor.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2011 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.java.bytecode.visitor;
-
-import org.sonar.java.bytecode.asm.*;
-import org.sonar.squid.api.SourceCodeEdgeUsage;
-
-public class AccessorVisitor extends BytecodeVisitor {
-
- private AsmClass asmClass;
-
- public void visitClass(AsmClass asmClass) {
- this.asmClass = asmClass;
- }
-
- public void visitMethod(AsmMethod asmMethod) {
- if (asmMethod.isConstructor()) return;
-
- AsmField accessedField = getAccessedField(asmMethod);
- asmMethod.setAccessedField(accessedField);
- }
-
- private AsmField getAccessedField(AsmMethod asmMethod) {
- AsmField accessedField = null;
-
- for (AsmEdge edge: asmMethod.getOutgoingEdges()) {
- if (isCallToNonStaticInternalField(edge)) {
- if (accessedField != null && accessedField != edge.getTo()) {
- accessedField = null;
- break;
- }
- accessedField = (AsmField)edge.getTo();
- } else if (isCallToNonStaticInternalMethod(edge)) {
- accessedField = null;
- break;
- }
- }
-
- return accessedField;
- }
-
- private boolean isCallToNonStaticInternalField(AsmEdge edge) {
- return edge.getTargetAsmClass() == asmClass && edge.getUsage() == SourceCodeEdgeUsage.CALLS_FIELD && !((AsmField)edge.getTo()).isStatic();
- }
-
- private boolean isCallToNonStaticInternalMethod(AsmEdge edge) {
- return edge.getTargetAsmClass() == asmClass && edge.getUsage() == SourceCodeEdgeUsage.CALLS_METHOD && !((AsmMethod)edge.getTo()).isStatic();
- }
-
-}
diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/visitor/LCOM4Visitor.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/visitor/LCOM4Visitor.java
index c75c264e8f3..dd124321073 100644
--- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/visitor/LCOM4Visitor.java
+++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/visitor/LCOM4Visitor.java
@@ -48,7 +48,7 @@ public class LCOM4Visitor extends BytecodeVisitor {
unrelatedBlocks = new ArrayList<Set<AsmResource>>();
}
- public void processMethod(AsmMethod asmMethod) {
+ public void visitMethod(AsmMethod asmMethod) {
if (isMethodElligibleForLCOM4Computation(asmMethod)) {
ensureBlockIsCreated(asmMethod);
for (AsmEdge edge : asmMethod.getOutgoingEdges()) {
@@ -82,10 +82,6 @@ public class LCOM4Visitor extends BytecodeVisitor {
}
public void leaveClass(AsmClass asmClass) {
- for (AsmMethod asmMethod: asmClass.getMethods()) {
- processMethod(asmMethod);
- }
-
int lcom4 = unrelatedBlocks.size();
if (lcom4 == 0) {
lcom4 = 1;
diff --git a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmMethodTest.java b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmMethodTest.java
index 127d51b9244..69b37bb94f4 100644
--- a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmMethodTest.java
+++ b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmMethodTest.java
@@ -19,17 +19,26 @@
*/
package org.sonar.java.bytecode.asm;
+import org.junit.BeforeClass;
import org.junit.Test;
+import org.sonar.java.ast.SquidTestUtils;
+import org.sonar.java.bytecode.ClassLoaderBuilder;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
public class AsmMethodTest {
+ private static AsmClass javaBean;
private AsmClass stringClass = new AsmClass("java/lang/String");
private AsmClass numberClass = new AsmClass("java/lang/Number");
+ @BeforeClass
+ public static void init() {
+ AsmClassProvider asmClassProvider = new AsmClassProviderImpl(ClassLoaderBuilder.create(SquidTestUtils.getFile("/bytecode/bin/")));
+ javaBean = asmClassProvider.getClass("properties/JavaBean");
+ }
+
@Test
public void testAsmMethod() {
AsmMethod method = new AsmMethod(new AsmClass("java/lang/String"), "toString()Ljava/lang/String;");
@@ -49,5 +58,33 @@ public class AsmMethodTest {
assertFalse(new AsmMethod(stringClass, "firstMethod()V").hashCode() == new AsmMethod(stringClass, "secondMethod()V").hashCode());
assertFalse(new AsmMethod(stringClass, "firstMethod()V").hashCode() == new AsmMethod(numberClass, "firstMethod()V").hashCode());
}
+
+ @Test
+ public void testIsAccessor() {
+ assertTrue(javaBean.getMethod("getName()Ljava/lang/String;").isAccessor());
+ assertTrue(javaBean.getMethod("setName(Ljava/lang/String;)V").isAccessor());
+ assertTrue(javaBean.getMethod("setFrench(Z)V").isAccessor());
+ assertTrue(javaBean.getMethod("isFrench()Z").isAccessor());
+ assertFalse(javaBean.getMethod("anotherMethod()V").isAccessor());
+ assertTrue(javaBean.getMethod("addFirstName(Ljava/lang/String;)V").isAccessor());
+ assertTrue(javaBean.getMethod("getNameOrDefault()Ljava/lang/String;").isAccessor());
+ assertTrue(javaBean.getMethod("accessorWithABunchOfCalls()V").isAccessor());
+ assertFalse(javaBean.getMethod("iShouldBeAStaticSetter()V").isAccessor());
+ assertTrue(javaBean.getMethod("getFirstName()Ljava/lang/String;").isAccessor());
+ }
+
+ @Test
+ public void testGetAccessedField() {
+ assertThat(javaBean.getMethod("getName()Ljava/lang/String;").getAccessedField().getName(), is("name"));
+ assertThat(javaBean.getMethod("setName(Ljava/lang/String;)V").getAccessedField().getName(), is("name"));
+ assertThat(javaBean.getMethod("setFrench(Z)V").getAccessedField().getName(), is("french"));
+ assertThat(javaBean.getMethod("isFrench()Z").getAccessedField().getName(), is("french"));
+ assertNull(javaBean.getMethod("anotherMethod()V").getAccessedField());
+ assertThat(javaBean.getMethod("addFirstName(Ljava/lang/String;)V").getAccessedField().getName(), is("firstNames"));
+ assertThat(javaBean.getMethod("getNameOrDefault()Ljava/lang/String;").getAccessedField().getName(), is("name"));
+ assertThat(javaBean.getMethod("accessorWithABunchOfCalls()V").getAccessedField().getName(), is("firstNames"));
+ assertNull(javaBean.getMethod("iShouldBeAStaticSetter()V").getAccessedField());
+ assertThat(javaBean.getMethod("getFirstName()Ljava/lang/String;").getAccessedField().getName(), is("FirstName"));
+ }
}
diff --git a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/visitor/AccessorVisitorTest.java b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/visitor/AccessorVisitorTest.java
deleted file mode 100644
index 7a2ded02245..00000000000
--- a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/visitor/AccessorVisitorTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2011 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.java.bytecode.visitor;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.sonar.java.ast.SquidTestUtils;
-import org.sonar.java.bytecode.ClassLoaderBuilder;
-import org.sonar.java.bytecode.asm.AsmClass;
-import org.sonar.java.bytecode.asm.AsmClassProvider;
-import org.sonar.java.bytecode.asm.AsmClassProviderImpl;
-import org.sonar.java.bytecode.asm.AsmMethod;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-public class AccessorVisitorTest {
-
- private static AsmClassProvider asmClassProvider;
- private static AsmClass javaBean;
- private static AccessorVisitor accessorVisitor = new AccessorVisitor();
-
- @BeforeClass
- public static void init() {
- asmClassProvider = new AsmClassProviderImpl(ClassLoaderBuilder.create(SquidTestUtils.getFile("/bytecode/bin/")));
- javaBean = asmClassProvider.getClass("properties/JavaBean");
- accessorVisitor.visitClass(javaBean);
- for (AsmMethod method : javaBean.getMethods()) {
- accessorVisitor.visitMethod(method);
- }
- }
-
- @Test
- public void testIsAccessor() {
- assertTrue(javaBean.getMethod("getName()Ljava/lang/String;").isAccessor());
- assertTrue(javaBean.getMethod("setName(Ljava/lang/String;)V").isAccessor());
- assertTrue(javaBean.getMethod("setFrench(Z)V").isAccessor());
- assertTrue(javaBean.getMethod("isFrench()Z").isAccessor());
- assertFalse(javaBean.getMethod("anotherMethod()V").isAccessor());
- assertTrue(javaBean.getMethod("addFirstName(Ljava/lang/String;)V").isAccessor());
- assertTrue(javaBean.getMethod("getNameOrDefault()Ljava/lang/String;").isAccessor());
- assertTrue(javaBean.getMethod("accessorWithABunchOfCalls()V").isAccessor());
- assertFalse(javaBean.getMethod("iShouldBeAStaticSetter()V").isAccessor());
- assertTrue(javaBean.getMethod("getFirstName()Ljava/lang/String;").isAccessor());
- }
-
- @Test
- public void testAccessedField() {
- assertThat(javaBean.getMethod("getName()Ljava/lang/String;").getAccessedField().getName(), is("name"));
- assertThat(javaBean.getMethod("setName(Ljava/lang/String;)V").getAccessedField().getName(), is("name"));
- assertThat(javaBean.getMethod("setFrench(Z)V").getAccessedField().getName(), is("french"));
- assertThat(javaBean.getMethod("isFrench()Z").getAccessedField().getName(), is("french"));
- assertNull(javaBean.getMethod("anotherMethod()V").getAccessedField());
- assertThat(javaBean.getMethod("addFirstName(Ljava/lang/String;)V").getAccessedField().getName(), is("firstNames"));
- assertThat(javaBean.getMethod("getNameOrDefault()Ljava/lang/String;").getAccessedField().getName(), is("name"));
- assertThat(javaBean.getMethod("accessorWithABunchOfCalls()V").getAccessedField().getName(), is("firstNames"));
- assertNull(javaBean.getMethod("iShouldBeAStaticSetter()V").getAccessedField());
- assertThat(javaBean.getMethod("getFirstName()Ljava/lang/String;").getAccessedField().getName(), is("FirstName"));
- }
-
-}