Implement the strictfp modifier
MOE_MIGRATED_REVID=139271575
diff --git a/java/com/google/turbine/binder/TypeBinder.java b/java/com/google/turbine/binder/TypeBinder.java
index a1feb37..d332a43 100644
--- a/java/com/google/turbine/binder/TypeBinder.java
+++ b/java/com/google/turbine/binder/TypeBinder.java
@@ -129,15 +129,34 @@
return new TypeBinder(env, sym, base).bind();
}
+ private final boolean isStrictFp;
private final Env<ClassSymbol, HeaderBoundClass> env;
private final ClassSymbol owner;
private final SourceHeaderBoundClass base;
- public TypeBinder(
+ private TypeBinder(
Env<ClassSymbol, HeaderBoundClass> env, ClassSymbol owner, SourceHeaderBoundClass base) {
this.env = env;
this.owner = owner;
this.base = base;
+ this.isStrictFp = isStrictFp(env, owner);
+ }
+
+ private boolean isStrictFp(Env<ClassSymbol, HeaderBoundClass> env, ClassSymbol sym) {
+ while (sym != null) {
+ HeaderBoundClass info = env.get(sym);
+ switch (info.kind()) {
+ case ANNOTATION:
+ return false;
+ default:
+ break;
+ }
+ if ((info.access() & TurbineFlag.ACC_STRICT) == TurbineFlag.ACC_STRICT) {
+ return true;
+ }
+ sym = info.owner();
+ }
+ return false;
}
private SourceTypeBoundClass bind() {
@@ -216,7 +235,7 @@
interfaceTypes.build(),
superClassType,
typeParameterTypes,
- base.access(),
+ base.access() & ~TurbineFlag.ACC_STRICT,
ImmutableList.copyOf(methods),
fields,
base.owner(),
@@ -261,6 +280,9 @@
formals = ImmutableList.of();
}
int access = TurbineVisibility.fromAccess(base.access()).flag();
+ if (isStrictFp) {
+ access |= TurbineFlag.ACC_STRICT;
+ }
access |= TurbineFlag.ACC_SYNTH_CTOR;
methods.add(
new MethodInfo(
@@ -277,6 +299,11 @@
}
private void addEnumMethods(List<MethodInfo> methods) {
+ int access = 0;
+ if (isStrictFp) {
+ access |= TurbineFlag.ACC_STRICT;
+ }
+
if (!hasConstructor(methods)) {
methods.add(
new MethodInfo(
@@ -290,7 +317,7 @@
ImmutableList.of(),
true)),
ImmutableList.of(),
- TurbineFlag.ACC_PRIVATE | TurbineFlag.ACC_SYNTH_CTOR,
+ access | TurbineFlag.ACC_PRIVATE | TurbineFlag.ACC_SYNTH_CTOR,
null,
null,
ImmutableList.of(),
@@ -304,7 +331,7 @@
Type.ClassTy.asNonParametricClassTy(owner),
ImmutableList.of(new ParamInfo(Type.ClassTy.STRING, ImmutableList.of(), false)),
ImmutableList.of(),
- TurbineFlag.ACC_PUBLIC | TurbineFlag.ACC_STATIC,
+ access | TurbineFlag.ACC_PUBLIC | TurbineFlag.ACC_STATIC,
null,
null,
ImmutableList.of(),
@@ -317,7 +344,7 @@
new Type.ArrayTy(Type.ClassTy.asNonParametricClassTy(owner), ImmutableList.of()),
ImmutableList.of(),
ImmutableList.of(),
- TurbineFlag.ACC_PUBLIC | TurbineFlag.ACC_STATIC,
+ access | TurbineFlag.ACC_PUBLIC | TurbineFlag.ACC_STATIC,
null,
null,
ImmutableList.of(),
@@ -458,6 +485,10 @@
break;
}
+ if (isStrictFp && (access & TurbineFlag.ACC_ABSTRACT) == 0) {
+ access |= TurbineFlag.ACC_STRICT;
+ }
+
ImmutableList<AnnoInfo> annotations = bindAnnotations(scope, t.annos());
return new MethodInfo(
sym,
diff --git a/javatests/com/google/turbine/lower/LowerIntegrationTest.java b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
index 8d30eca..05db806 100644
--- a/javatests/com/google/turbine/lower/LowerIntegrationTest.java
+++ b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
@@ -270,6 +270,7 @@
"const_boxed.test",
"interface_member_public.test",
"javadoc_deprecated.test",
+ "strictfp.test",
};
List<Object[]> tests =
ImmutableList.copyOf(testCases).stream().map(x -> new Object[] {x}).collect(toList());
diff --git a/javatests/com/google/turbine/lower/testdata/strictfp.test b/javatests/com/google/turbine/lower/testdata/strictfp.test
new file mode 100644
index 0000000..6d50176
--- /dev/null
+++ b/javatests/com/google/turbine/lower/testdata/strictfp.test
@@ -0,0 +1,44 @@
+=== Test.java ===
+strictfp abstract class Test {
+ abstract void a();
+ strictfp void f() {}
+ class Inner {
+ void g() {}
+ }
+ enum E {
+ ;
+ void h() {}
+ }
+ @interface A {
+ int value() default 0;
+ }
+ interface I {
+ default int j() {
+ return 1;
+ }
+ }
+ final double x = 1.0 / 2;
+}
+
+=== I.java ===
+strictfp interface I {
+ void f();
+ abstract void a();
+ abstract class N {
+ void g() {}
+ abstract void a();
+ }
+}
+
+=== E.java ===
+strictfp enum E {
+ I {
+ void a() {}
+ };
+ void f() {}
+ abstract void a();
+ abstract class N {
+ void g() {}
+ abstract void a();
+ }
+}