src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java
changeset 54568 b2ed96c35687
parent 54514 b0651dcc8d98
child 54668 0bda2308eded
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Wed Apr 17 12:41:33 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Wed Apr 17 15:37:20 2019 +0100
@@ -55,6 +55,7 @@
 import com.sun.tools.javac.comp.AttrContext;
 import com.sun.tools.javac.comp.Env;
 import com.sun.tools.javac.jvm.*;
+import com.sun.tools.javac.jvm.PoolConstant;
 import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
 import com.sun.tools.javac.tree.JCTree.Tag;
@@ -91,7 +92,7 @@
  *  This code and its internal interfaces are subject to change or
  *  deletion without notice.</b>
  */
-public abstract class Symbol extends AnnoConstruct implements Element {
+public abstract class Symbol extends AnnoConstruct implements PoolConstant, Element {
 
     /** The kind of this symbol.
      *  @see Kinds
@@ -286,6 +287,11 @@
         this.name = name;
     }
 
+    @Override
+    public int poolTag() {
+        throw new AssertionError("Invalid pool entry");
+    }
+
     /** Clone this symbol with new owner.
      *  Legal only for fields and methods.
      */
@@ -971,6 +977,11 @@
             this.type = new ModuleType(this);
         }
 
+        @Override
+        public int poolTag() {
+            return ClassFile.CONSTANT_Module;
+        }
+
         @Override @DefinedBy(Api.LANGUAGE_MODEL)
         public Name getSimpleName() {
             return Convert.shortName(name);
@@ -1137,6 +1148,11 @@
             return members_field;
         }
 
+        @Override
+        public int poolTag() {
+            return ClassFile.CONSTANT_Package;
+        }
+
         public long flags() {
             complete();
             return flags_field;
@@ -1237,10 +1253,6 @@
          */
         public List<ClassSymbol> trans_local;
 
-        /** the constant pool of the class
-         */
-        public Pool pool;
-
         /** the annotation metadata attached to this class */
         private AnnotationTypeMetadata annotationTypeMetadata;
 
@@ -1251,7 +1263,6 @@
             this.flatname = formFlatName(name, owner);
             this.sourcefile = null;
             this.classfile = null;
-            this.pool = null;
             this.annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType();
         }
 
@@ -1543,6 +1554,11 @@
             super(VAR, flags, name, type, owner);
         }
 
+        @Override
+        public int poolTag() {
+            return ClassFile.CONSTANT_Fieldref;
+        }
+
         /** Clone this symbol with new owner.
          */
         public VarSymbol clone(Symbol newOwner) {
@@ -1551,6 +1567,11 @@
                 public Symbol baseSymbol() {
                     return VarSymbol.this;
                 }
+
+                @Override
+                public Object poolKey(Types types) {
+                    return new Pair<>(newOwner, baseSymbol());
+                }
             };
             v.pos = pos;
             v.adr = adr;
@@ -1711,6 +1732,11 @@
                 public Symbol baseSymbol() {
                     return MethodSymbol.this;
                 }
+
+                @Override
+                public Object poolKey(Types types) {
+                    return new Pair<>(newOwner, baseSymbol());
+                }
             };
             m.code = code;
             return m;
@@ -1740,10 +1766,25 @@
             }
         }
 
+        @Override
+        public int poolTag() {
+            return owner.isInterface() ?
+                    ClassFile.CONSTANT_InterfaceMethodref : ClassFile.CONSTANT_Methodref;
+        }
+
         public boolean isDynamic() {
             return false;
         }
 
+        public boolean isHandle() {
+            return false;
+        }
+
+
+        public MethodHandleSymbol asHandle() {
+            return new MethodHandleSymbol(this);
+        }
+
         /** find a symbol that this (proxy method) symbol implements.
          *  @param    c       The class whose members are searched for
          *                    implementations
@@ -2027,16 +2068,14 @@
 
     /** A class for invokedynamic method calls.
      */
-    public static class DynamicMethodSymbol extends MethodSymbol {
+    public static class DynamicMethodSymbol extends MethodSymbol implements Dynamic {
 
-        public Object[] staticArgs;
-        public Symbol bsm;
-        public int bsmKind;
+        public LoadableConstant[] staticArgs;
+        public MethodHandleSymbol bsm;
 
-        public DynamicMethodSymbol(Name name, Symbol owner, int bsmKind, MethodSymbol bsm, Type type, Object[] staticArgs) {
+        public DynamicMethodSymbol(Name name, Symbol owner, MethodHandleSymbol bsm, Type type, LoadableConstant[] staticArgs) {
             super(0, name, type, owner);
             this.bsm = bsm;
-            this.bsmKind = bsmKind;
             this.staticArgs = staticArgs;
         }
 
@@ -2044,6 +2083,83 @@
         public boolean isDynamic() {
             return true;
         }
+
+        @Override
+        public LoadableConstant[] staticArgs() {
+            return staticArgs;
+        }
+
+        @Override
+        public MethodHandleSymbol bootstrapMethod() {
+            return bsm;
+        }
+
+        @Override
+        public int poolTag() {
+            return ClassFile.CONSTANT_InvokeDynamic;
+        }
+
+        @Override
+        public Type dynamicType() {
+            return type;
+        }
+    }
+
+    /** A class for method handles.
+     */
+    public static class MethodHandleSymbol extends MethodSymbol implements LoadableConstant {
+
+        private Symbol refSym;
+
+        public MethodHandleSymbol(Symbol msym) {
+            super(msym.flags_field, msym.name, msym.type, msym.owner);
+            this.refSym = msym;
+        }
+
+        /**
+         * Returns the kind associated with this method handle.
+         */
+        public int referenceKind() {
+            if (refSym.isConstructor()) {
+                return ClassFile.REF_newInvokeSpecial;
+            } else {
+                if (refSym.isStatic()) {
+                    return ClassFile.REF_invokeStatic;
+                } else if ((refSym.flags() & PRIVATE) != 0) {
+                    return ClassFile.REF_invokeSpecial;
+                } else if (refSym.enclClass().isInterface()) {
+                    return ClassFile.REF_invokeInterface;
+                } else {
+                    return ClassFile.REF_invokeVirtual;
+                }
+            }
+        }
+
+        @Override
+        public int poolTag() {
+            return ClassFile.CONSTANT_MethodHandle;
+        }
+
+        @Override
+        public Object poolKey(Types types) {
+            return new Pair<>(baseSymbol(), referenceKind());
+        }
+
+        @Override
+        public MethodHandleSymbol asHandle() {
+            return this;
+        }
+
+        @Override
+        public Symbol baseSymbol() {
+            return refSym;
+        }
+
+
+        @Override
+        public boolean isHandle() {
+            return true;
+        }
     }
 
     /** A class for predefined operators.