diff --git a/core/src/main/java/com/google/errorprone/refaster/UMethodIdent.java b/core/src/main/java/com/google/errorprone/refaster/UMethodIdent.java new file mode 100644 index 00000000000..d9f393059a3 --- /dev/null +++ b/core/src/main/java/com/google/errorprone/refaster/UMethodIdent.java @@ -0,0 +1,62 @@ +/* + * Copyright 2024 The Error Prone Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.errorprone.refaster; + +import static com.google.errorprone.refaster.Unifier.unifications; + +import com.google.auto.value.AutoValue; +import com.google.errorprone.util.ASTHelpers; +import com.sun.source.tree.Tree; +import com.sun.tools.javac.code.Symbol; +import com.sun.tools.javac.code.Symbol.ClassSymbol; +import com.sun.tools.javac.tree.JCTree.JCExpression; + +/** Identifier representing an unqualified instant method. */ +@AutoValue +public abstract class UMethodIdent extends UIdent { + public static UMethodIdent create(UClassIdent classIdent, CharSequence member, UType memberType) { + return new AutoValue_UMethodIdent(classIdent, StringName.of(member), memberType); + } + + public static UMethodIdent create(ClassSymbol classSym, CharSequence member, UType memberType) { + return create(UClassIdent.create(classSym), member, memberType); + } + + abstract UClassIdent classIdent(); + + @Override + public abstract StringName getName(); + + abstract UType memberType(); + + @Override + public JCExpression inline(Inliner inliner) throws CouldNotResolveImportException { + return inliner.maker().Ident(getName().inline(inliner)); + } + + @Override + protected Choice defaultAction(Tree node, Unifier unifier) { + Symbol symbol = ASTHelpers.getSymbol(node); + if (symbol != null) { + return classIdent() + .unify(symbol.getEnclosingElement(), unifier) + .thenChoose(unifications(getName(), symbol.getSimpleName())) + .thenChoose(unifications(memberType(), symbol.asType())); + } + return Choice.none(); + } +} diff --git a/core/src/main/java/com/google/errorprone/refaster/UTemplater.java b/core/src/main/java/com/google/errorprone/refaster/UTemplater.java index c762497387c..b763484ba34 100644 --- a/core/src/main/java/com/google/errorprone/refaster/UTemplater.java +++ b/core/src/main/java/com/google/errorprone/refaster/UTemplater.java @@ -354,6 +354,13 @@ private UStaticIdent staticMember(Symbol symbol) { template(symbol.asType())); } + private UMethodIdent method(Symbol symbol) { + return UMethodIdent.create( + (ClassSymbol) symbol.getEnclosingElement(), + symbol.getSimpleName(), + template(symbol.asType())); + } + private static final UStaticIdent ANY_OF; private static final UStaticIdent IS_INSTANCE; private static final UStaticIdent CLAZZ; @@ -622,6 +629,8 @@ public UExpression visitIdentifier(IdentifierTree tree, Void v) { switch (sym.getKind()) { case TYPE_PARAMETER: return UTypeVarIdent.create(tree.getName()); + case METHOD: + return method(sym); default: return ULocalVarIdent.create(tree.getName()); } diff --git a/core/src/test/java/com/google/errorprone/refaster/TemplateIntegrationTest.java b/core/src/test/java/com/google/errorprone/refaster/TemplateIntegrationTest.java index 0fa97eb22e2..b93b3743235 100644 --- a/core/src/test/java/com/google/errorprone/refaster/TemplateIntegrationTest.java +++ b/core/src/test/java/com/google/errorprone/refaster/TemplateIntegrationTest.java @@ -379,4 +379,9 @@ public void typeArgumentsMethodInvocation() throws IOException { public void memberSelectAndMethodParameterDisambiguation() throws IOException { runTest("MemberSelectAndMethodParameterDisambiguationTemplate"); } + + @Test + public void unqualifiedMethod() throws IOException { + runTest("UnqualifiedMethodTemplate"); + } } diff --git a/core/src/test/java/com/google/errorprone/refaster/testdata/input/UnqualifiedMethodTemplateExample.java b/core/src/test/java/com/google/errorprone/refaster/testdata/input/UnqualifiedMethodTemplateExample.java new file mode 100644 index 00000000000..85415708176 --- /dev/null +++ b/core/src/test/java/com/google/errorprone/refaster/testdata/input/UnqualifiedMethodTemplateExample.java @@ -0,0 +1,22 @@ +/* + * Copyright 2024 The Error Prone Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.errorprone.refaster.testdata; + +/** Test data for {@code UnqualifiedMethodTemplate}. */ +public class UnqualifiedMethodTemplateExample { + public int example() { + return hashCode(); + } +} diff --git a/core/src/test/java/com/google/errorprone/refaster/testdata/output/UnqualifiedMethodTemplateExample.java b/core/src/test/java/com/google/errorprone/refaster/testdata/output/UnqualifiedMethodTemplateExample.java new file mode 100644 index 00000000000..06fb51e7f4a --- /dev/null +++ b/core/src/test/java/com/google/errorprone/refaster/testdata/output/UnqualifiedMethodTemplateExample.java @@ -0,0 +1,24 @@ +/* + * Copyright 2024 The Error Prone Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.errorprone.refaster.testdata; + +import java.util.Objects; + +/** Test data for {@code UnqualifiedMethodTemplate}. */ +public class UnqualifiedMethodTemplateExample { + public int example() { + return Objects.hashCode(this); + } +} diff --git a/core/src/test/java/com/google/errorprone/refaster/testdata/template/UnqualifiedMethodTemplate.java b/core/src/test/java/com/google/errorprone/refaster/testdata/template/UnqualifiedMethodTemplate.java new file mode 100644 index 00000000000..1b637f80c1b --- /dev/null +++ b/core/src/test/java/com/google/errorprone/refaster/testdata/template/UnqualifiedMethodTemplate.java @@ -0,0 +1,33 @@ +/* + * Copyright 2024 The Error Prone Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.errorprone.refaster.testdata.template; + +import com.google.errorprone.refaster.annotation.AfterTemplate; +import com.google.errorprone.refaster.annotation.BeforeTemplate; +import java.util.Objects; + +public class UnqualifiedMethodTemplate { + @BeforeTemplate + public int before() { + return hashCode(); + } + + @AfterTemplate + public int after() { + return Objects.hashCode(this); + } +}