changeset 48739:2070de830fbd condy-folding

trust the user intention even if it contradits the facts at compile time
author vromero
date Fri, 12 Jan 2018 18:54:56 -0500
parents 8d1c08b46091
children d1b9262fab0e
files src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfClassOrMemberNotFound3.java test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfClassOrMemberNotFound3.out test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfMemberIncorrect.out
diffstat 4 files changed, 85 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java	Fri Jan 12 16:45:26 2018 -0500
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java	Fri Jan 12 18:54:56 2018 -0500
@@ -417,26 +417,68 @@
             case ClassFile.REF_invokeSpecial:
             case ClassFile.REF_invokeInterface:
                 if (refKind == ClassFile.REF_invokeInterface && (owner.flags_field & INTERFACE) == 0) {
-                    // we need a new owner for the symbol
-                    ClassSymbol newOwner = new ClassSymbol(owner.flags_field | Flags.INTERFACE, owner.name, syms.noSymbol);
-                    Symbol newMS = new MethodSymbol(flags, symbolName, methodType, newOwner);
-                    newOwner.members_field = WriteableScope.create(newOwner);
-                    newOwner.members_field.enter(newMS);
-                    return newMS;
+                    return generateMethodSymbolHelper(owner, symbolName, methodType, flags, true);
+                }
+                if (refKind != ClassFile.REF_invokeInterface && (owner.flags_field & INTERFACE) != 0) {
+                    return generateMethodSymbolHelper(owner, symbolName, methodType, flags, false);
+                }
+                if (refKind == ClassFile.REF_newInvokeSpecial && (owner.flags_field & INTERFACE) != 0) {
+                    return generateMethodSymbolHelper(owner, symbolName, methodType, flags, false);
                 }
                 return new MethodSymbol(flags, symbolName, methodType, owner);
             case ClassFile.REF_putField:
+                if ((owner.flags_field & INTERFACE) != 0) {
+                    return generateVarSymbolHelper(owner, symbolName, methodType, flags, false);
+                }
                 return new VarSymbol(flags, symbolName, methodType.argtypes.tail.head, owner);
             case ClassFile.REF_putStatic:
                 return new VarSymbol(flags, symbolName, methodType.argtypes.head, owner);
             case ClassFile.REF_getField:
             case ClassFile.REF_getStatic:
+                if (refKind == ClassFile.REF_getField && (owner.flags_field & INTERFACE) != 0) {
+                    return generateVarSymbolHelper(owner, symbolName, methodType, flags, false);
+                }
                 return new VarSymbol(flags, symbolName, methodType.restype, owner);
             default:
                 throw new AssertionError("invalid refKind value " + refKind);
         }
     }
 
+    private Symbol generateMethodSymbolHelper(
+            Symbol currentOwner,
+            Name symbolName,
+            MethodType methodType,
+            long flags,
+            boolean shouldBeInterface) {
+        ClassSymbol newOwner = createNewOwner(currentOwner, shouldBeInterface);
+        Symbol newMS = new MethodSymbol(flags, symbolName, methodType, newOwner);
+        newOwner.members_field.enter(newMS);
+        return newMS;
+    }
+
+    private ClassSymbol createNewOwner(Symbol currentOwner,
+            boolean shouldBeInterface) {
+        long newFlags = shouldBeInterface ?
+                currentOwner.flags_field | Flags.INTERFACE :
+                currentOwner.flags_field & ~Flags.INTERFACE;
+        ClassSymbol newOwner = new ClassSymbol(newFlags,
+                currentOwner.name, syms.noSymbol);
+        newOwner.members_field = WriteableScope.create(newOwner);
+        return newOwner;
+    }
+
+    private Symbol generateVarSymbolHelper(
+            Symbol currentOwner,
+            Name symbolName,
+            MethodType methodType,
+            long flags,
+            boolean shouldBeInterface) {
+        ClassSymbol newOwner = createNewOwner(currentOwner, shouldBeInterface);
+        Symbol newVS = new VarSymbol(flags, symbolName, methodType.restype, newOwner);
+        newOwner.members_field.enter(newVS);
+        return newVS;
+    }
+
     public Object invokeMethodReflectively(
             Class<?> hostClass,
             Object instance,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfClassOrMemberNotFound3.java	Fri Jan 12 18:54:56 2018 -0500
@@ -0,0 +1,30 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary warn if a class or member is not found at compile time
+ * @compile/fail/ref=WarningIfClassOrMemberNotFound3.out -XDdoConstantFold -Werror -XDrawDiagnostics WarningIfClassOrMemberNotFound3.java
+ */
+
+import java.lang.invoke.*;
+import java.lang.sym.*;
+import static java.lang.invoke.Intrinsics.*;
+
+public class WarningIfClassOrMemberNotFound3 {
+    interface I {}
+
+    private static final ClassRef THE_INTERFACE = ClassRef.of("WarningIfClassOrMemberNotFound3$I");
+
+    public void test1() {
+        MethodHandleRef negIMethodRef = MethodHandleRef.of(MethodHandleRef.Kind.CONSTRUCTOR, THE_INTERFACE, "", MethodTypeRef.ofDescriptor("()V"));
+        Intrinsics.ldc(negIMethodRef);
+    }
+
+    public void test2() {
+        MethodHandleRef negIMethodRef = MethodHandleRef.ofField(MethodHandleRef.Kind.GETTER, THE_INTERFACE, "strField", SymbolicRefs.CR_String);
+        Intrinsics.ldc(negIMethodRef);
+    }
+
+    public void test3() {
+        MethodHandleRef negIMethodRef = MethodHandleRef.ofField(MethodHandleRef.Kind.SETTER, THE_INTERFACE, "strField", SymbolicRefs.CR_String);
+        Intrinsics.ldc(negIMethodRef);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfClassOrMemberNotFound3.out	Fri Jan 12 18:54:56 2018 -0500
@@ -0,0 +1,6 @@
+WarningIfClassOrMemberNotFound3.java:18:23: compiler.warn.member.not.found.at.class: <init>, class, I
+WarningIfClassOrMemberNotFound3.java:23:23: compiler.warn.member.not.found.at.class: strField, class, I
+WarningIfClassOrMemberNotFound3.java:28:23: compiler.warn.member.not.found.at.class: strField, class, I
+- compiler.err.warnings.and.werror
+1 error
+3 warnings
--- a/test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfMemberIncorrect.out	Fri Jan 12 16:45:26 2018 -0500
+++ b/test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfMemberIncorrect.out	Fri Jan 12 18:54:56 2018 -0500
@@ -2,7 +2,7 @@
 WarningIfMemberIncorrect.java:22:31: compiler.warn.incorrect.staticness.for.symbol: bar
 WarningIfMemberIncorrect.java:22:31: compiler.warn.unexpected.kind.for.symbol: bar, MTH, VAR
 WarningIfMemberIncorrect.java:25:41: compiler.warn.incorrect.name.for.method: WarningIfMemberIncorrect(), 5
-WarningIfMemberIncorrect.java:28:31: compiler.warn.non.interface.owner.expected.for.symbol: foo()
+WarningIfMemberIncorrect.java:28:31: compiler.warn.member.not.found.at.class: foo, class, I
 - compiler.err.warnings.and.werror
 1 error
 5 warnings