Skip to content

Commit c897d8f

Browse files
cushonError Prone Team
authored and
Error Prone Team
committed
Open-source more of check_api/src/test/java/com/google/errorprone/util
These tests still don't compile due to a cycle between test_helpers and check_api PiperOrigin-RevId: 686487416
1 parent 4f630fc commit c897d8f

File tree

7 files changed

+4522
-0
lines changed

7 files changed

+4522
-0
lines changed

check_api/pom.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,15 @@
162162
<version>${autoservice.version}</version>
163163
</path>
164164
</annotationProcessorPaths>
165+
<testExcludes>
166+
<!-- TODO(b/172597965): maven sees a cycle here since test_helpers depends on check_api -->
167+
<testExclude>**/ASTHelpersFindSuperMethodsTest.java</testExclude>
168+
<testExclude>**/ASTHelpersTest.java</testExclude>
169+
<testExclude>**/CommentsTest.java</testExclude>
170+
<testExclude>**/FindIdentifiersTest.java</testExclude>
171+
<testExclude>**/MoreAnnotationsTest.java</testExclude>
172+
<testExclude>**/ReachabilityTest.java</testExclude>
173+
</testExcludes>
165174
</configuration>
166175
<executions>
167176
<execution>
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
/*
2+
* Copyright 2017 The Error Prone Authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.errorprone.util;
18+
19+
import static com.google.common.truth.Truth.assertThat;
20+
21+
import com.google.common.collect.HashBasedTable;
22+
import com.google.common.collect.ImmutableList;
23+
import com.google.common.collect.Table;
24+
import com.google.errorprone.VisitorState;
25+
import com.google.errorprone.matchers.CompilerBasedAbstractTest;
26+
import com.google.errorprone.scanner.Scanner;
27+
import com.sun.source.tree.MethodTree;
28+
import com.sun.source.tree.Tree;
29+
import com.sun.tools.javac.code.Symbol.MethodSymbol;
30+
import com.sun.tools.javac.code.Types;
31+
import java.util.Optional;
32+
import org.junit.Before;
33+
import org.junit.Test;
34+
import org.junit.runner.RunWith;
35+
import org.junit.runners.JUnit4;
36+
37+
/**
38+
* Test cases for {@link ASTHelpers#findSuperMethod(MethodSymbol, Types)} and {@link
39+
* ASTHelpers#findSuperMethod(MethodSymbol, Types)}.
40+
*
41+
* @author Łukasz Hanuszczak ([email protected])
42+
*/
43+
@RunWith(JUnit4.class)
44+
public final class ASTHelpersFindSuperMethodsTest extends CompilerBasedAbstractTest {
45+
46+
private FindSuperMethodsTestScanner scanner;
47+
48+
@Before
49+
public void prepareScanClassHierarchy() {
50+
writeFile(
51+
"Foo.java",
52+
"""
53+
abstract class Foo {
54+
public abstract void foo();
55+
}
56+
""");
57+
writeFile(
58+
"Bar.java",
59+
"""
60+
class Bar extends Foo {
61+
@Override
62+
public void foo() {
63+
System.out.println("bar");
64+
}
65+
}
66+
""");
67+
writeFile(
68+
"Baz.java",
69+
"""
70+
class Baz extends Bar {
71+
@Override
72+
public void foo() {
73+
System.out.println("baz");
74+
}
75+
}
76+
""");
77+
writeFile(
78+
"Quux.java",
79+
"""
80+
class Quux extends Baz {
81+
public void foo(String string) {
82+
System.out.println("I am not an override! " + string);
83+
}
84+
85+
public int bar(int x, int y) {
86+
return x * y;
87+
}
88+
}
89+
""");
90+
writeFile(
91+
"Norf.java",
92+
"""
93+
class Norf extends Quux {
94+
@Override
95+
public void foo() {
96+
System.out.println("norf");
97+
}
98+
99+
@Override
100+
public int bar(int x, int y) {
101+
return super.bar(x, y) + 42;
102+
}
103+
}
104+
""");
105+
106+
scanner = new FindSuperMethodsTestScanner();
107+
assertCompiles(scanner);
108+
}
109+
110+
@Test
111+
public void findSuperMethods_findsSingleMethod() {
112+
MethodSymbol barOfNorf = scanner.getMethod("Norf", "bar");
113+
MethodSymbol barOfQuux = scanner.getMethod("Quux", "bar");
114+
assertThat(findSuperMethods(barOfNorf)).containsExactly(barOfQuux);
115+
}
116+
117+
@Test
118+
public void findSuperMethods_findsAllMethodsInTheHierarchy() {
119+
MethodSymbol fooOfNorf = scanner.getMethod("Norf", "foo");
120+
MethodSymbol fooOfBaz = scanner.getMethod("Baz", "foo");
121+
MethodSymbol fooOfBar = scanner.getMethod("Bar", "foo");
122+
MethodSymbol fooOfQuux = scanner.getMethod("Foo", "foo");
123+
assertThat(findSuperMethods(fooOfNorf))
124+
.containsExactly(fooOfBaz, fooOfBar, fooOfQuux)
125+
.inOrder();
126+
}
127+
128+
@Test
129+
public void findSuperMethod_findsNothingForAbstractMethod() {
130+
MethodSymbol fooOfFoo = scanner.getMethod("Foo", "foo");
131+
assertThat(findSuperMethod(fooOfFoo)).isEqualTo(Optional.empty());
132+
}
133+
134+
@Test
135+
public void findSuperMethod_findsNothingForNewNonAbstractMethod() {
136+
MethodSymbol barOfQuux = scanner.getMethod("Quux", "bar");
137+
assertThat(findSuperMethod(barOfQuux)).isEqualTo(Optional.empty());
138+
}
139+
140+
@Test
141+
public void findSuperMethod_findsAbstractSuperMethod() {
142+
MethodSymbol fooOfFoo = scanner.getMethod("Foo", "foo");
143+
MethodSymbol fooOfBar = scanner.getMethod("Bar", "foo");
144+
assertThat(findSuperMethod(fooOfBar)).isEqualTo(Optional.of(fooOfFoo));
145+
}
146+
147+
@Test
148+
public void findSuperMethod_findsNormalSuperMethodForDirectSuperclass() {
149+
MethodSymbol fooOfBar = scanner.getMethod("Bar", "foo");
150+
MethodSymbol fooOfBaz = scanner.getMethod("Baz", "foo");
151+
assertThat(findSuperMethod(fooOfBaz)).isEqualTo(Optional.of(fooOfBar));
152+
153+
MethodSymbol barOfQuux = scanner.getMethod("Quux", "bar");
154+
MethodSymbol barOfNorf = scanner.getMethod("Norf", "bar");
155+
assertThat(findSuperMethod(barOfNorf)).isEqualTo(Optional.of(barOfQuux));
156+
}
157+
158+
@Test
159+
public void findSuperMethod_findsNormalSuperMethodForNonDirectSuperclass() {
160+
MethodSymbol fooOfBaz = scanner.getMethod("Baz", "foo");
161+
MethodSymbol fooOfNorf = scanner.getMethod("Norf", "foo");
162+
assertThat(findSuperMethod(fooOfNorf)).isEqualTo(Optional.of(fooOfBaz));
163+
}
164+
165+
private ImmutableList<MethodSymbol> findSuperMethods(MethodSymbol method) {
166+
return ImmutableList.copyOf(ASTHelpers.findSuperMethods(method, getTypes()));
167+
}
168+
169+
private Optional<MethodSymbol> findSuperMethod(MethodSymbol method) {
170+
return ASTHelpers.findSuperMethod(method, getTypes());
171+
}
172+
173+
private Types getTypes() {
174+
return scanner.getState().getTypes();
175+
}
176+
177+
/**
178+
* A quite hacky class used to assert things in {@link ASTHelpersFindSuperMethodsTest}.
179+
*
180+
* <p>This does two things: it builds a mapping from class names and method names to method
181+
* symbols (for easy assertions) and keeps track of the last visited {@link VisitorState}.
182+
*
183+
* <p>We cannot do assertions in the {@link Scanner#scan(Tree, VisitorState)} like all the other
184+
* test cases do because we need data from all processed classes (and {@link Scanner#scan(Tree,
185+
* VisitorState)} is triggered for every single class). Therefore we need to make all assertions
186+
* in the test method itself but {@link ASTHelpers#findSuperMethods(MethodSymbol, Types)} requires
187+
* a {@link VisitorState} to be used. So we simply remember last state passed to the {@link
188+
* Scanner#scan(Tree, VisitorState)}.
189+
*/
190+
private static class FindSuperMethodsTestScanner extends Scanner {
191+
192+
// A `class name -> method name -> method symbol` structure mapping of given files.
193+
private final Table<String, String, MethodSymbol> methods;
194+
195+
// Last state passed to the `Scanner#scan` method.
196+
private VisitorState state;
197+
198+
public FindSuperMethodsTestScanner() {
199+
this.methods = HashBasedTable.create();
200+
}
201+
202+
public MethodSymbol getMethod(String className, String methodName) {
203+
return methods.get(className, methodName);
204+
}
205+
206+
public VisitorState getState() {
207+
return state;
208+
}
209+
210+
@Override
211+
public Void scan(Tree tree, VisitorState state) {
212+
this.state = state;
213+
return super.scan(tree, state);
214+
}
215+
216+
@Override
217+
public Void visitMethod(MethodTree methodTree, VisitorState state) {
218+
String classContext = ASTHelpers.getSymbol(methodTree).owner.getSimpleName().toString();
219+
String methodContext = methodTree.getName().toString();
220+
221+
MethodSymbol method = ASTHelpers.getSymbol(methodTree);
222+
if (!methods.contains(classContext, methodContext)) {
223+
methods.put(classContext, methodContext, method);
224+
}
225+
226+
return super.visitMethod(methodTree, state);
227+
}
228+
}
229+
}

0 commit comments

Comments
 (0)