Skip to content

Commit

Permalink
Enforce restriction about parameterizing superclasses to non-native J…
Browse files Browse the repository at this point in the history
…sEnum on lambdas.

PiperOrigin-RevId: 223112386
  • Loading branch information
rluble authored and Copybara-Service committed Nov 28, 2018
1 parent fea8c75 commit 91d7736
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
Expand Up @@ -42,6 +42,7 @@
import com.google.j2cl.ast.HasReadableDescription;
import com.google.j2cl.ast.HasSourcePosition;
import com.google.j2cl.ast.InstanceOfExpression;
import com.google.j2cl.ast.IntersectionTypeDescriptor;
import com.google.j2cl.ast.JsEnumInfo;
import com.google.j2cl.ast.JsMemberType;
import com.google.j2cl.ast.JsUtils;
Expand Down Expand Up @@ -449,6 +450,7 @@ private void checkJsEnumUsages(Type type) {
checkJsEnumAssignments(type);
checkJsEnumArrays(type);
checkJsEnumValueFieldAssignment(type);
checkJsEnumLambdas(type);
}

private void checkJsEnumMethodCalls(Type type) {
Expand Down Expand Up @@ -789,6 +791,39 @@ private static boolean hasNonNativeJsEnumArray(TypeDescriptor typeDescriptor) {
return false;
}

private void checkJsEnumLambdas(Type type) {
type.accept(
new AbstractVisitor() {
@Override
public void exitFunctionExpression(FunctionExpression functionExpression) {
for (TypeDescriptor typeDescriptor :
getTypeArgumentDescriptors(functionExpression.getTypeDescriptor())) {
if (AstUtils.isNonNativeJsEnum(typeDescriptor)) {
problems.error(
functionExpression.getSourcePosition(),
"'%s' lambda cannot have non-native JsEnum '%s' as a type argument. "
+ "(b/120087079)",
functionExpression.getTypeDescriptor().getReadableDescription(),
typeDescriptor.getReadableDescription());
}
}
}
});
}

private List<TypeDescriptor> getTypeArgumentDescriptors(TypeDescriptor typeDescriptor) {
if (typeDescriptor instanceof DeclaredTypeDescriptor) {
return ((DeclaredTypeDescriptor) typeDescriptor).getTypeArgumentDescriptors();
}
if (typeDescriptor instanceof IntersectionTypeDescriptor) {
return ((IntersectionTypeDescriptor) typeDescriptor)
.getIntersectionTypeDescriptors().stream()
.flatMap(t -> t.getTypeArgumentDescriptors().stream())
.collect(ImmutableList.toImmutableList());
}
return ImmutableList.of();
}

private boolean checkJsType(Type type) {
TypeDeclaration typeDeclaration = type.getDeclaration();
if (typeDeclaration.isLocal()) {
Expand Down
Expand Up @@ -1625,6 +1625,7 @@ public void testJsEnumFails() {
" A.name();",
" MyJsEnum.values();",
" MyJsEnum.valueOf(null);",
" Consumer<MyJsEnum> consumer = c -> c.ordinal();",
" }",
" int value = 5;",
" int instanceField;",
Expand Down Expand Up @@ -1657,6 +1658,9 @@ public void testJsEnumFails() {
"class AListSubclass<T extends MyJsEnum>",
" extends AList<MyJsEnum> implements List<MyJsEnum> {",
" public MyJsEnum getObject() { return null; }",
"}",
"interface Consumer<T> {",
" void accept(T t);",
"}")
.assertErrorsWithoutSourcePosition(
"Non-custom-valued JsEnum 'MyJsEnum' cannot have constructor 'MyJsEnum()'.",
Expand Down Expand Up @@ -1688,7 +1692,9 @@ public void testJsEnumFails() {
"Method 'MyJsEnum AListSubclass.getObject()' returning JsEnum cannot override method "
+ "'Object List.getObject()'. (b/118301700)",
"Cannot use 'super' in JsOverlay method 'void MyJsEnum.anOverlayMethod()'.",
"Cannot use 'super' in JsEnum method 'void MyJsEnum.aMethod()'.");
"Cannot use 'super' in JsEnum method 'void MyJsEnum.aMethod()'.",
"'Consumer<MyJsEnum>' lambda cannot have non-native JsEnum 'MyJsEnum' as a "
+ "type argument. (b/120087079)");
}

public void testJsEnumSucceeds() {
Expand Down Expand Up @@ -1878,6 +1884,12 @@ public void testNativeJsEnumSucceeds() {
"class AListSubclass<T extends Native>",
" extends AList<Native> implements List<Native> {",
" public Native getObject() { return null; }",
"}",
"interface Consumer<T> {",
" void accept(T t);",
" static void test() {",
" Consumer<Native> consumer = c -> c.toString();",
" }",
"}")
.assertNoWarnings();
}
Expand Down

0 comments on commit 91d7736

Please sign in to comment.