diff options
author | Dinesh Bolkensteyn <dinesh@dinsoft.net> | 2011-10-25 13:49:12 +0200 |
---|---|---|
committer | Dinesh Bolkensteyn <dinesh@dinsoft.net> | 2011-10-25 13:49:49 +0200 |
commit | 039f7ae976cc2128e766a94bbdda634e995c66a9 (patch) | |
tree | abf63bc1ff29f24d2eb02578168d5333ed55b270 /plugins | |
parent | 176e46458b7700c547520588099ced62347afd5c (diff) | |
download | sonarqube-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')
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")); - } - -} |