Skip to content

Commit

Permalink
Support void placeholder expressions in Refaster
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 450510643
  • Loading branch information
java-team-github-bot authored and Error Prone Team committed May 23, 2022
1 parent b822dd4 commit 7cd5def
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 4 deletions.
18 changes: 15 additions & 3 deletions core/src/main/java/com/google/errorprone/refaster/Template.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Type.ForAll;
import com.sun.tools.javac.code.Type.MethodType;
import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.comp.Attr;
import com.sun.tools.javac.comp.AttrContext;
Expand Down Expand Up @@ -139,7 +140,14 @@ protected List<Type> expectedTypes(Inliner inliner) throws CouldNotResolveImport
Ordering.natural()
.immutableSortedCopy(
Iterables.filter(inliner.bindings.keySet(), PlaceholderExpressionKey.class))) {
result.add(key.method.returnType().inline(inliner));
Type type = key.method.returnType().inline(inliner);
// Skip void placeholder expressions, because
// a) if the expected type is void, any actual type is acceptable
// b) these types are used as the argument types in a synthetic MethodType, and method
// argument types cannot be void
if (!type.getTag().equals(TypeTag.VOID)) {
result.add(type);
}
}
return List.from(result);
}
Expand All @@ -149,7 +157,7 @@ protected List<Type> expectedTypes(Inliner inliner) throws CouldNotResolveImport
* bound to the @BeforeTemplate method parameters, concatenated with the types of the expressions
* bound to expression placeholders, sorted by the name of the placeholder method.
*/
protected List<Type> actualTypes(Inliner inliner) {
protected List<Type> actualTypes(Inliner inliner) throws CouldNotResolveImportException {
ArrayList<Type> result = new ArrayList<>();
ImmutableList<String> argNames = expressionArgumentTypes().keySet().asList();
for (int i = 0; i < expressionArgumentTypes().size(); i++) {
Expand Down Expand Up @@ -177,7 +185,11 @@ protected List<Type> actualTypes(Inliner inliner) {
Ordering.natural()
.immutableSortedCopy(
Iterables.filter(inliner.bindings.keySet(), PlaceholderExpressionKey.class))) {
result.add(inliner.getBinding(key).type);
Type keyType = key.method.returnType().inline(inliner);
// See comment in `expectedTypes` for why we skip void placeholder keys.
if (!keyType.getTag().equals(TypeTag.VOID)) {
result.add(inliner.getBinding(key).type);
}
}
return List.from(result);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ public boolean reverify(Unifier unifier) {
@Override
protected Choice<Unifier> defaultAction(Tree node, Unifier unifier) {
// for now we only match JCExpressions
if (placeholder().returnType().equals(UPrimitiveType.VOID) || !(node instanceof JCExpression)) {
if (!(node instanceof JCExpression)) {
return Choice.none();
}
JCExpression expr = (JCExpression) node;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,11 @@ public void expressionPlaceholderAllowsIdentity() throws IOException {
runTest("PlaceholderAllowsIdentityTemplate");
}

@Test
public void voidExpressionPlaceholder() throws IOException {
runTest("VoidExpressionPlaceholderTemplate");
}

@Test
public void blockPlaceholder() throws IOException {
runTest("BlockPlaceholderTemplate");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2022 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.List;

/** Test data for {@code VoidExpressionPlaceholderTemplate}. */
public class VoidExpressionPlaceholderTemplateExample {
public static void foo(String s) {
s.length();
}

public void positiveExample(List<String> list) {
list.stream().forEach(x -> foo(x));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2022 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.List;

/** Test data for {@code VoidExpressionPlaceholderTemplate}. */
public class VoidExpressionPlaceholderTemplateExample {
public static void foo(String s) {
s.length();
}

public void positiveExample(List<String> list) {
list.forEach(x->foo(x));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2022 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 com.google.errorprone.refaster.annotation.Placeholder;
import java.util.Collection;

/** Test case with a void placeholder method that is used as an expression. */
public abstract class VoidExpressionPlaceholderTemplate<T> {
@Placeholder
abstract void consume(T t);

@BeforeTemplate
void before(Collection<T> collection) {
collection.stream().forEach(x -> consume(x));
}

@AfterTemplate
void after(Collection<T> collection) {
collection.forEach(x -> consume(x));
}
}

0 comments on commit 7cd5def

Please sign in to comment.