Skip to content

Commit eb7cbf1

Browse files
committed
// BH 2022.01.17 fixes interface default method referencing own static
fields
1 parent ee5cc0e commit eb7cbf1

File tree

9 files changed

+94
-8
lines changed

9 files changed

+94
-8
lines changed

sources/net.sf.j2s.core/src/net/sf/j2s/core/CorePlugin.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@ public class CorePlugin extends Plugin {
2525
* "net.sf.j2s.core.jar" not "net.sf.j2s.core.3.2.5"
2626
*
2727
*/
28-
public static String VERSION = "3.3.1-v1";
28+
public static String VERSION = "3.3.1-v4";
2929

3030
// if you change the x.x.x number, be sure to also indicate that in
3131
// j2sApplet.js and also (Bob only) update.bat, update-clean.bat
3232

33+
// BH 2022.01.17 -- 3.3.1-v4 fixes default interface methods referencing their own static fields
3334
// BH 2021.01.14 -- 3.3.1-v3 fixes missing finals for nested () -> {...}
3435
// BH 2021.01.03 -- 3.3.1-v2 adds @j2sAsync adds async for function - experimental
3536
// BH 2002.12.31 -- 3.3.1-v1 introduces full primitive 64-bit long support.

sources/net.sf.j2s.core/src/net/sf/j2s/core/Java2ScriptVisitor.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@
135135

136136
// TODO: superclass inheritance for JAXB XmlAccessorType
137137

138+
//BH 2022.01.17 -- 3.3.1-v4 fixes default interface methods referencing their own static fields
138139
//BH 2021.01.14 -- 3.3.1-v3 fixes missing finals for nested () -> {...}
139140
//BH 2021.01.03 -- 3.3.1-v2 adds @j2sAsync adds async for function - experimental
140141
//BH 2020.12.31 -- 3.3.1-v1 64-bit long implemented; adds "@j2sNoLongExact" for classes only, not methods
@@ -698,6 +699,11 @@ int getPrimitiveDefaultType(Code code) {
698699

699700
private String package_currentFinalKey;
700701

702+
/**
703+
* This flag turns off C$ for interfaces, instead pointing to themselves.
704+
*/
705+
private int class_defpt = -1;
706+
701707
private void addApplication() {
702708
if (apps == null)
703709
apps = new ArrayList<String>();
@@ -2647,16 +2653,17 @@ && checkAnnotations(element, CHECK_J2S_IGNORE_AND_ANNOTATIONS)) {
26472653
|| mname.startsWith("is"))
26482654
methods.add(method);
26492655
}
2650-
int defpt = -1;
2656+
class_defpt = -1;
26512657
if (Modifier.isDefault(method.getModifiers())) {
26522658
// log("default method " + method.getKey());
2653-
defpt = buffer.length();
2659+
class_defpt = buffer.length();
26542660
}
26552661
processMethodDeclaration(mnode, method, mnode.parameters(), mnode.getBody(), mnode.isConstructor(),
26562662
abstractMethodList, NOT_LAMBDA);
2657-
if (defpt >= 0) {
2658-
defaults.append(buffer.substring(defpt));
2659-
buffer.setLength(defpt);
2663+
if (class_defpt >= 0) {
2664+
defaults.append(buffer.substring(class_defpt));
2665+
buffer.setLength(class_defpt);
2666+
class_defpt = -1;
26602667
}
26612668
} else if (element instanceof AnnotationTypeMemberDeclaration) {
26622669
processAnnotationTypeMemberDeclaration((AnnotationTypeMemberDeclaration) element);
@@ -2687,7 +2694,7 @@ && checkAnnotations(element, CHECK_J2S_IGNORE_AND_ANNOTATIONS)) {
26872694
// generic
26882695
addSyntheticBridges(binding, abstractMethodList, defaults, true);
26892696
if (defaults.length() > 0) {
2690-
buffer.append("C$.$defaults$ = function(C$){\n").append(defaults).append("};");
2697+
buffer.append("var C$$ = C$;C$.$defaults$ = function(C$){\n").append(defaults).append("};");
26912698
}
26922699
} else {
26932700
addSyntheticBridges(binding, abstractMethodList, buffer, false);
@@ -5699,7 +5706,7 @@ String getFinalJ2SClassNameQualifier(Name methodQualifier, ITypeBinding declarin
56995706
return stripJavaLang(name);
57005707
}
57015708
if (doCache && name.equals(class_fullName)) {
5702-
return "C$"; // anonymous class will be like this
5709+
return (class_defpt < 0 ? "C$" : "C$$"); // anonymous class will be like this
57035710
}
57045711

57055712
// lambda classes will always be defined at this point. No need to cache them
@@ -5903,6 +5910,7 @@ private void addSyntheticBridges(ITypeBinding type, List<IMethodBinding> abstrac
59035910
if (isInterface) {
59045911
buf.append(s);
59055912
} else {
5913+
// see java.text.CollationKey, but $synth$ is never called.
59065914
buf.append("\nC$.$synth$=function(){").append(s).append("}\n");
59075915
}
59085916
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package test;
2+
3+
interface MyInterface extends MyInterface0 {
4+
Integer value = MyInterface2.getValue(0);
5+
Integer value1 = MyInterface2.getValue(1);
6+
7+
default Integer getValue() {
8+
System.out.println("fixed2 " + new MyInterface0() {}.getValue());
9+
return value;
10+
}
11+
12+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package test;
2+
3+
interface MyInterface0 {
4+
Integer value = MyInterface2.getValue(-2);
5+
6+
default Integer getValue() {
7+
return value;
8+
}
9+
10+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package test;
2+
3+
class MyInterface2 {
4+
public static Integer getValue(int v) {
5+
System.out.println("MyInterface2 creating " + v);
6+
return Integer.valueOf(v);
7+
}
8+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package test;
2+
3+
class MyInterfaceImpl implements MyInterface {
4+
5+
static Integer value = MyInterface2.getValue(2);
6+
static Integer value2 = value1;
7+
public Integer getValueImpl() {
8+
return value + MyInterface.value + 100 * value2;
9+
}
10+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package test;
2+
3+
public class Test_Interface4 {
4+
5+
interface MyInterface {
6+
public static final Integer value = Integer.valueOf(1);
7+
8+
public default Integer getValue() {
9+
return MyInterface.value;
10+
}
11+
}
12+
13+
static class MyInterfaceImpl implements MyInterface {
14+
public static final Integer value = Integer.valueOf(2);
15+
public Integer getValueImpl() {
16+
return value + MyInterface.value;
17+
}
18+
}
19+
20+
public static void main(String[] args) {
21+
MyInterfaceImpl impl = new MyInterfaceImpl();
22+
System.out.println(String.valueOf(impl.getValue()));
23+
System.out.println(String.valueOf(impl.getValueImpl()));
24+
}
25+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package test;
2+
3+
class Test_MyInterface extends Test_ {
4+
public static void main(String[] args) {
5+
MyInterfaceImpl impl = new MyInterfaceImpl();
6+
System.out.println(String.valueOf(impl.getValue()));
7+
System.out.println(String.valueOf(impl.getValueImpl()));
8+
System.out.println(String.valueOf(impl.getValue()));
9+
}
10+
}

sources/net.sf.j2s.java.core/srcjs/js/j2sClazz.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
// Google closure compiler cannot handle Clazz.new or Clazz.super
99

10+
// BH 2022.01.17 fixes interface default method referencing own static fields
1011
// BH 2021.12.19 adds Double -0; fixes println(Double)
1112
// BH 2021.12.15 default encoding for String.getBytes() should be utf-8.
1213
// BH 2021.08.16 fix for Interface initializing its subclass with static initialization
@@ -1495,6 +1496,7 @@ var copyStatics = function(clazzFrom, clazzThis, isInterface) {
14951496
}
14961497
}
14971498
if (isInterface) {
1499+
clazzFrom.$static$ && (initStatics(clazzFrom), clazzFrom.$static$());
14981500
clazzThis.$defaults$ && clazzThis.$defaults$(clazzThis);
14991501
for (var o in clazzFrom.prototype) {
15001502
if (clazzThis.prototype[o] == undefined && !excludeSuper(o)) {

0 commit comments

Comments
 (0)