Skip to content

Commit

Permalink
Allow native classes implement native interfaces with overlays.
Browse files Browse the repository at this point in the history
Native classes implementing interfaces with overlays triggerred a compiler
error due to the fact that overlays in native intefaces are "default"
methods and that the strategy of implementing them consists in creating
the corresponding synthetic override in classes that don't explicitly
implement the method.

Bug: #9440
Bug-Link: #9440
Change-Id: I30a100c4d83f13df61fed57a54afb3b25a153250
  • Loading branch information
rluble committed Oct 4, 2016
1 parent 030a9a2 commit 5222a7c
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 5 deletions.
Expand Up @@ -285,7 +285,7 @@ private void checkIllegalOverrides(JMember member) {
}

private void checkJsOverlay(JMember member) {
if (member.getEnclosingType().isJsoType()) {
if (member.getEnclosingType().isJsoType() || member.isSynthetic()) {
return;
}

Expand Down
Expand Up @@ -1613,7 +1613,7 @@ public void testNativeJsTypeInterfaceExtendsNonJsTypeFails() {
"Line 6: Native JsType ''EntryPoint.Buggy'' can only extend native JsType interfaces.");
}

public void testNativeJsTypeInterfaceDefenderMethodsFails() {
public void testNativeJsTypeInterfaceDefaultMethodsFails() {
addSnippetImport("jsinterop.annotations.JsType");
addSnippetImport("jsinterop.annotations.JsOverlay");
addSnippetClassDecl(
Expand All @@ -1626,6 +1626,11 @@ public void testNativeJsTypeInterfaceDefenderMethodsFails() {
"@JsType(isNative=true) public interface Buggy extends Interface {",
" default void someMethod(){}",
" void someOtherMethod();",
"}",
"public static class SomeOtherClass implements Interface {",
"}",
"public static class ClassOverridingOverlayTransitively extends SomeOtherClass {",
" public void someOtherMethod() {}",
"}");

assertBuggyFails(
Expand All @@ -1634,7 +1639,9 @@ public void testNativeJsTypeInterfaceDefenderMethodsFails() {
"Line 12: Native JsType method 'void EntryPoint.Buggy.someMethod()' should be native "
+ "or abstract.",
"Line 13: Method 'void EntryPoint.Buggy.someOtherMethod()' cannot override a JsOverlay"
+ " method 'void EntryPoint.Interface.someOtherMethod()'.");
+ " method 'void EntryPoint.Interface.someOtherMethod()'.",
"Line 18: Method 'void EntryPoint.ClassOverridingOverlayTransitively.someOtherMethod()' "
+ "cannot override a JsOverlay method 'void EntryPoint.Interface.someOtherMethod()'.");
}

public void testJsOptionalSucceeds() throws Exception {
Expand Down Expand Up @@ -2190,13 +2197,28 @@ public void testNonJsTypeExtendingNativeJsTypeWithInstanceMethodSucceeds() throw
" public native void m(Object o);",
" public native void m(Object[] o);",
"}",
"@JsType public static class Buggy extends Super {",
"public static class Buggy extends Super {",
" public void n(Object o) { }",
"}");

assertBuggySucceeds();
}

public void testClassesExtendingNativeJsTypeInterfaceWithOverlaySucceeds() throws Exception {
addSnippetImport("jsinterop.annotations.JsOverlay");
addSnippetImport("jsinterop.annotations.JsType");
addSnippetClassDecl(
"@JsType(isNative=true) interface Super {",
" @JsOverlay default void fun() {}",
"}",
"@JsType(isNative=true) abstract static class Buggy implements Super {",
"}",
"static class JavaSubclass implements Super {",
"}");

assertBuggySucceeds();
}

public void testNonJsTypeExtendingNativeJsTypeWithInstanceMethodOverloadsFails() {
addSnippetImport("jsinterop.annotations.JsType");
addSnippetClassDecl(
Expand Down
Expand Up @@ -26,6 +26,8 @@

import jsinterop.annotations.JsFunction;
import jsinterop.annotations.JsOverlay;
import jsinterop.annotations.JsPackage;
import jsinterop.annotations.JsProperty;
import jsinterop.annotations.JsType;

/**
Expand Down Expand Up @@ -1672,10 +1674,34 @@ public static String m() {
return null;
}
}
// Regression test for bug: #9426.

// Regression test for bug: #9426.
public void testCorrectNaming() {
Function<String> f = ClassWithAVeryLoooooooooooooooooooooooooooooooooooongName::m;
assertNotNull(f);
}

@JsType(isNative = true)
interface InterfaceWithOverlay {

@JsProperty
int getLength();

@JsOverlay
default int len() {
return this.getLength();
}
}

@JsType(isNative = true, name = "Object", namespace = JsPackage.GLOBAL)
static abstract class SubclassImplementingInterfaceWithOverlay implements InterfaceWithOverlay {
}

// Regression test for bug: #9440
public void testInterfaceWithOverlayAndNativeSubclass() {
SubclassImplementingInterfaceWithOverlay object =
(SubclassImplementingInterfaceWithOverlay) (Object) new int[]{1, 2, 3};
assertEquals(3, object.len());
}
}

4 changes: 4 additions & 0 deletions user/test/com/google/gwt/dev/jjs/test/Java8Test.java
Expand Up @@ -308,6 +308,10 @@ public void testCorrectNaming() {
assertFalse(isGwtSourceLevel8());
}

public void testInterfaceWithOverlayAndNativeSubclass() {
assertFalse(isGwtSourceLevel8());
}

private boolean isGwtSourceLevel8() {
return JUnitShell.getCompilerOptions().getSourceLevel().compareTo(SourceLevel.JAVA8) >= 0;
}
Expand Down

0 comments on commit 5222a7c

Please sign in to comment.