Skip to content

Commit 91baf9b

Browse files
committed
Address review comments
1 parent c9487d2 commit 91baf9b

File tree

1 file changed

+13
-72
lines changed

1 file changed

+13
-72
lines changed

framework/src/main/java/org/checkerframework/framework/ajava/DoubleJavacVisitor.java

Lines changed: 13 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@
1515
import com.sun.source.tree.ModifiersTree;
1616
import com.sun.source.tree.PackageTree;
1717
import com.sun.source.tree.ParameterizedTypeTree;
18-
import com.sun.source.tree.ParenthesizedTree;
1918
import com.sun.source.tree.PrimitiveTypeTree;
2019
import com.sun.source.tree.ReturnTree;
21-
import com.sun.source.tree.StatementTree;
2220
import com.sun.source.tree.ThrowTree;
2321
import com.sun.source.tree.Tree;
2422
import com.sun.source.tree.TryTree;
@@ -27,6 +25,7 @@
2725
import com.sun.source.tree.WildcardTree;
2826
import com.sun.source.util.SimpleTreeVisitor;
2927
import java.util.List;
28+
import org.checkerframework.checker.nullness.qual.Nullable;
3029

3130
/**
3231
* A visitor that visits two javac ASTs simultaneously that almost match.
@@ -46,7 +45,6 @@
4645
* <p>To use this class, extend it, override defaultPairAction, and begin traversal by calling scan
4746
* on the two root trees.
4847
*/
49-
@SuppressWarnings("optional:method.invocation")
5048
public abstract class DoubleJavacVisitor extends SimpleTreeVisitor<Void, Tree> {
5149

5250
/** Create a DoubleJavacVisitor. */
@@ -62,7 +60,7 @@ public DoubleJavacVisitor() {}
6260
* @param tree1 the first tree in the matched pair
6361
* @param tree2 the second tree in the matched pair
6462
*/
65-
public abstract void defaultPairAction(Tree tree1, Tree tree2);
63+
protected abstract void defaultPairAction(Tree tree1, Tree tree2);
6664

6765
/**
6866
* The fallback visitor method used when no specific visitXxx override exists for a tree kind.
@@ -91,16 +89,13 @@ protected Void defaultAction(Tree tree1, Tree tree2) {
9189
* <p>2. Treats exactly one null as an error, because it indicates the trees are no longer
9290
* aligned.
9391
*
94-
* <p>3. Normalizes wrapper nodes (such as parentheses and expression statements) so that
95-
* logically corresponding constructs in the two trees align.
96-
*
97-
* <p>4. Verifies that the normalized trees have the same kind, then dispatches to the appropriate
98-
* visit method via accept.
92+
* <p>3. Verifies that the trees have the same kind, then dispatches to the appropriate visit
93+
* method via accept.
9994
*
10095
* @param tree1 the first tree to scan, or null
10196
* @param tree2 the second tree to scan, or null
10297
*/
103-
public final void scan(Tree tree1, Tree tree2) {
98+
public final void scan(@Nullable Tree tree1, @Nullable Tree tree2) {
10499
if (tree1 == null && tree2 == null) {
105100
return;
106101
}
@@ -112,17 +107,17 @@ public final void scan(Tree tree1, Tree tree2) {
112107
this.getClass().getCanonicalName(), tree1, tree2));
113108
}
114109

115-
Tree t1 = normalize(tree1);
116-
Tree t2 = normalize(tree2);
117-
118-
if (t1.getKind() != t2.getKind()) {
110+
// If we later discover javac introduces wrappers that desynchronize traversal (e.g.
111+
// parentheses),
112+
// we can re-introduce a normalization step here.
113+
if (tree1.getKind() != tree2.getKind()) {
119114
throw new Error(
120115
String.format(
121116
"%s.scan: mismatched kinds: %s vs %s",
122-
this.getClass().getCanonicalName(), t1.getKind(), t2.getKind()));
117+
this.getClass().getCanonicalName(), tree1.getKind(), tree2.getKind()));
123118
}
124119

125-
t1.accept(this, t2);
120+
tree1.accept(this, tree2);
126121
}
127122

128123
/**
@@ -135,7 +130,7 @@ public final void scan(Tree tree1, Tree tree2) {
135130
* @param tree1 the first tree, or null
136131
* @param tree2 the second tree, or null
137132
*/
138-
public final void scanOpt(Tree tree1, Tree tree2) {
133+
public final void scanOpt(@Nullable Tree tree1, @Nullable Tree tree2) {
139134
if (tree1 == null && tree2 == null) {
140135
return;
141136
}
@@ -182,58 +177,6 @@ public final void scanList(List<? extends Tree> list1, List<? extends Tree> list
182177
}
183178
}
184179

185-
/**
186-
* Normalizes a tree by removing wrapper nodes that should not affect structural matching.
187-
*
188-
* <p>javac may introduce wrapper nodes such as parenthesized expressions or expression statements
189-
* depending on context. These wrappers are removed so that corresponding logical constructs in
190-
* the two trees align during traversal.
191-
*
192-
* <p>Normalization is applied repeatedly until the tree stops changing, so nested wrappers are
193-
* fully removed.
194-
*
195-
* @param tree a non-null tree
196-
* @return a normalized tree
197-
*/
198-
protected Tree normalize(Tree tree) {
199-
Tree t = tree;
200-
while (true) {
201-
Tree next = unwrapExpressionStatement(unwrapParentheses(t));
202-
if (next == t) {
203-
return t;
204-
}
205-
t = next;
206-
}
207-
}
208-
209-
/**
210-
* If the given tree is a parenthesized expression, returns the enclosed expression. Otherwise,
211-
* returns the tree unchanged.
212-
*
213-
* @param tree a non-null tree
214-
* @return the unwrapped tree
215-
*/
216-
protected Tree unwrapParentheses(Tree tree) {
217-
if (tree instanceof ParenthesizedTree) {
218-
return ((ParenthesizedTree) tree).getExpression();
219-
}
220-
return tree;
221-
}
222-
223-
/**
224-
* If the given tree is an expression statement, returns the underlying expression. Otherwise,
225-
* returns the tree unchanged.
226-
*
227-
* @param tree a non-null tree
228-
* @return the unwrapped tree
229-
*/
230-
protected Tree unwrapExpressionStatement(Tree tree) {
231-
if (tree instanceof ExpressionStatementTree) {
232-
return ((ExpressionStatementTree) tree).getExpression();
233-
}
234-
return tree;
235-
}
236-
237180
/**
238181
* Visits a compilation unit (top-level file node) and scans its main children.
239182
*
@@ -533,9 +476,7 @@ public Void visitBlock(BlockTree tree1, Tree tree2) {
533476
BlockTree tree2b = (BlockTree) tree2;
534477
defaultPairAction(tree1, tree2b);
535478

536-
List<? extends StatementTree> s1 = tree1.getStatements();
537-
List<? extends StatementTree> s2 = tree2b.getStatements();
538-
scanList(s1, s2);
479+
scanList(tree1.getStatements(), tree2b.getStatements());
539480
return null;
540481
}
541482

0 commit comments

Comments
 (0)