From b5e410859876860da65705678d0c7de154ec3346 Mon Sep 17 00:00:00 2001
From: rschoene <rene.schoene@tu-dresden.de>
Date: Fri, 3 Jan 2020 14:48:50 +0100
Subject: [PATCH] Added test for inner. Small cleanup in tests.

- anonymous inner classes defined in another source file are not reported yet
---
 .../main/java/org/extendj/ScopeAnalysis.java  |  2 +-
 .../src/test/java/org/extendj/InnerTest.java  | 44 +++++++++++++++++
 scope4j/src/test/resources/inner/ClassA.java  | 47 +++++++++++++++++++
 scope4j/src/test/resources/inner/ClassB.java  | 13 +++++
 scope4j/src/test/resources/simple/ClassA.java |  3 +-
 .../resources/superclassFields/ClassA.java    |  6 +--
 6 files changed, 110 insertions(+), 5 deletions(-)
 create mode 100644 scope4j/src/test/java/org/extendj/InnerTest.java
 create mode 100644 scope4j/src/test/resources/inner/ClassA.java
 create mode 100644 scope4j/src/test/resources/inner/ClassB.java

diff --git a/scope4j/src/main/java/org/extendj/ScopeAnalysis.java b/scope4j/src/main/java/org/extendj/ScopeAnalysis.java
index 4409ba3..c6802fa 100644
--- a/scope4j/src/main/java/org/extendj/ScopeAnalysis.java
+++ b/scope4j/src/main/java/org/extendj/ScopeAnalysis.java
@@ -137,7 +137,7 @@ public class ScopeAnalysis extends Frontend {
   }
 
   private Program readProgram(Collection<String> files) throws IOException {
-
+    System.out.println("Reading " + (files.size() > 10 ? files.size() + " files" : files.toString()));
 
     Program program = new Program();
     program.resetStatistics();
diff --git a/scope4j/src/test/java/org/extendj/InnerTest.java b/scope4j/src/test/java/org/extendj/InnerTest.java
new file mode 100644
index 0000000..c5c1871
--- /dev/null
+++ b/scope4j/src/test/java/org/extendj/InnerTest.java
@@ -0,0 +1,44 @@
+package org.extendj;
+
+import org.extendj.ast.AbstractFinding;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Set;
+
+public class InnerTest extends ScopeAnalysisTest {
+
+  @Test
+  void test() {
+
+    ScopeAnalysis scopeAnalysis = new ScopeAnalysis();
+    Set<AbstractFinding> findings = scopeAnalysis.analyze("src/test/resources/inner", true, true);
+
+    System.out.println(findings);
+
+    // anonymous class
+    assertShadow(findings, "fieldA", 11, 13);
+    assertShadow(findings, "fieldA", 13, 3);
+
+    // local inner class
+    assertShadow(findings, "fieldA", 27, 29);
+    assertShadow(findings, "fieldA", 29, 3);
+    assertShadow(findings, "changingVar", 25, 19);
+
+    // static member class
+    assertShadow(findings, "fieldA", 37, 35);
+    assertShadow(findings, "fieldA", 35, 3);
+
+    // member class
+    assertShadow(findings, "fieldA", 44, 42);
+    assertShadow(findings, "fieldA", 42, 3);
+
+    // anonymous class defined in other class
+    assertShadow(findings, "fieldB", 5, 10);
+    // this finding is currently not found
+//    assertShadow(findings, "fieldB", 10, 4);
+
+    Assertions.assertEquals(10, findings.size());
+  }
+
+}
diff --git a/scope4j/src/test/resources/inner/ClassA.java b/scope4j/src/test/resources/inner/ClassA.java
new file mode 100644
index 0000000..c9dd1fa
--- /dev/null
+++ b/scope4j/src/test/resources/inner/ClassA.java
@@ -0,0 +1,47 @@
+public abstract class ClassA {
+
+  int fieldA;
+  int fieldB;
+
+  abstract void toBeDefined();
+
+  void method1() {
+    ClassA anonymous = new ClassA() {
+      void toBeDefined() {
+        int fieldA = 11;
+      }
+      int fieldA = 1;
+    };
+  }
+
+  void method2() {
+    final int finalVar = 1;
+    int changingVar = 0;
+    changingVar = 1;  // changingVar is not-final and not-effective-final, thus can not be used in InnerA
+    class InnerA extends ClassA {
+      /* This variable shares the name, but actually could never reference the outer scope
+         We include it anyway, because a) it would obscure analysis for this edge-case, and b) warns for potentially
+          unwanted effects (as all shadowing-warnings do) */
+      int changingVar = 4;
+      void toBeDefined() {
+        int fieldA = 21 + changingVar + finalVar;
+      }
+      int fieldA = 2;
+    }
+    ClassA inner = new InnerA();
+  }
+
+  static class StaticMemberClass extends ClassA {
+    int fieldA = 3;
+    void toBeDefined() {
+      int fieldA = 31;
+    }
+  }
+
+  class MemberClass extends ClassA {
+    int fieldA = 4;
+    void toBeDefined() {
+      int fieldA = 41;
+    }
+  }
+}
diff --git a/scope4j/src/test/resources/inner/ClassB.java b/scope4j/src/test/resources/inner/ClassB.java
new file mode 100644
index 0000000..3213a0f
--- /dev/null
+++ b/scope4j/src/test/resources/inner/ClassB.java
@@ -0,0 +1,13 @@
+public class ClassB {
+  void anonymousClassFromOtherSourceFile() {
+    ClassA anonymous = new ClassA() {
+      void toBeDefined() {
+        int fieldB = 11;
+      }
+
+      /* false-negative. there should be two scopes: ClassA and this method of ClassB
+       * But there is only the method, thus, not shadowing of ClassA.fieldB is detected. */
+      int fieldB = 1;
+    }
+  }
+}
diff --git a/scope4j/src/test/resources/simple/ClassA.java b/scope4j/src/test/resources/simple/ClassA.java
index a066a2a..4cd7ec1 100644
--- a/scope4j/src/test/resources/simple/ClassA.java
+++ b/scope4j/src/test/resources/simple/ClassA.java
@@ -37,6 +37,7 @@ public abstract class ClassA {
     ) { /* do stuff */ } catch (java.io.IOException e) {/* do stuff */}
   }
 
-  // this does not appear as a scope (and, more importantly, the parameters are not added anywhere else)
+  // these do not appear as a scope (and, more importantly, the parameters are not added anywhere else)
   public abstract void methodNameB(int parameterForAbstractMethodB);
+  public abstract void methodNameC(int fieldA);
 }
diff --git a/scope4j/src/test/resources/superclassFields/ClassA.java b/scope4j/src/test/resources/superclassFields/ClassA.java
index 675b936..1bd25cd 100644
--- a/scope4j/src/test/resources/superclassFields/ClassA.java
+++ b/scope4j/src/test/resources/superclassFields/ClassA.java
@@ -1,12 +1,12 @@
 public abstract class ClassA {
-​
+
   int fieldA;
   int fieldB;
 
-  void m();
+  abstract void m();
 
   void n() {
     //...
   }
-​
+
 }
-- 
GitLab