Skip to content

Commit

Permalink
Support pre-JDK-8044853 early-desugaring of JCNewClass
Browse files Browse the repository at this point in the history
`NewClassTree.getEnclosingInstance` doesn't work in JDK 8, because it gets
desugared in an early pass before Error Prone runs. This change adds a
workaround that detects `NewClassTree` by looking at the synthetic parameter
added by the desugaring pass instead of using `getEnclosingInstance`.

Fixes #2099

PiperOrigin-RevId: 351909719
  • Loading branch information
cushon authored and Error Prone Team committed Jan 15, 2021
1 parent 6861403 commit 8ce00a3
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.google.errorprone.bugpatterns;

import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.collect.Iterables.getOnlyElement;

import com.google.errorprone.BugPattern;
Expand All @@ -40,7 +41,9 @@
import com.sun.tools.javac.code.Symbol.TypeSymbol;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import java.util.List;
import java.util.Optional;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -106,16 +109,22 @@ public Description matchMemberReference(MemberReferenceTree tree, VisitorState s
*/
private static Type dropImplicitEnclosingInstanceParameter(
NewClassTree tree, VisitorState state, MethodSymbol anonymousClassConstructor) {
if (tree.getEnclosingExpression() == null) {
return anonymousClassConstructor.asType();
Type type = anonymousClassConstructor.asType();
if (!hasEnclosingExpression(tree)) {
// fast path
return type;
}
com.sun.tools.javac.util.List<Type> origParams =
anonymousClassConstructor.asType().getParameterTypes();
com.sun.tools.javac.util.List<Type> newParams =
com.sun.tools.javac.util.List.from(origParams.subList(1, origParams.size()));
return state
.getTypes()
.createMethodTypeWithParameters(anonymousClassConstructor.asType(), newParams);
com.sun.tools.javac.util.List<Type> params = type.getParameterTypes();
params = firstNonNull(params.tail, com.sun.tools.javac.util.List.nil());
return state.getTypes().createMethodTypeWithParameters(type, params);
}

private static boolean hasEnclosingExpression(NewClassTree tree) {
if (tree.getEnclosingExpression() != null) {
return true;
}
List<? extends ExpressionTree> arguments = tree.getArguments();
return !arguments.isEmpty() && ((JCTree) arguments.get(0)).hasTag(JCTree.Tag.NULLCHK);
}

private static MethodSymbol superclassConstructorSymbol(NewClassTree tree, VisitorState state) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,4 +296,23 @@ public void testAllowAllDefinitionsInFile() {
"}")
.doTest();
}

// https://github.com/google/error-prone/issues/2099
@Test
public void i2099() {
helper
.addSourceLines(
"T.java",
"package t;",
"class T {",
" static class Foo {",
" class Loo {}",
" }",
" public void testFoo(Foo foo) {",
" foo.new Loo() {};",
" }",
"}")
.expectResult(Result.OK)
.doTest();
}
}

0 comments on commit 8ce00a3

Please sign in to comment.