< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java

Print this page

        

@@ -404,10 +404,11 @@
     }
 
 
     private void writeParamAnnotations(List<VarSymbol> params,
                                        RetentionPolicy retention) {
+        databuf.appendByte(params.length());
         for (VarSymbol s : params) {
             ListBuffer<Attribute.Compound> buf = new ListBuffer<>();
             for (Attribute.Compound a : s.getRawAttributes())
                 if (types.getRetention(a) == retention)
                     buf.append(a);

@@ -425,15 +426,15 @@
     }
 
     /** Write method parameter annotations;
      *  return number of attributes written.
      */
-    int writeParameterAttrs(MethodSymbol m) {
+    int writeParameterAttrs(List<VarSymbol> vars) {
         boolean hasVisible = false;
         boolean hasInvisible = false;
-        if (m.params != null) {
-            for (VarSymbol s : m.params) {
+        if (vars != null) {
+            for (VarSymbol s : vars) {
                 for (Attribute.Compound a : s.getRawAttributes()) {
                     switch (types.getRetention(a)) {
                     case SOURCE: break;
                     case CLASS: hasInvisible = true; break;
                     case RUNTIME: hasVisible = true; break;

@@ -444,17 +445,17 @@
         }
 
         int attrCount = 0;
         if (hasVisible) {
             int attrIndex = writeAttr(names.RuntimeVisibleParameterAnnotations);
-            writeParamAnnotations(m, RetentionPolicy.RUNTIME);
+            writeParamAnnotations(vars, RetentionPolicy.RUNTIME);
             endAttr(attrIndex);
             attrCount++;
         }
         if (hasInvisible) {
             int attrIndex = writeAttr(names.RuntimeInvisibleParameterAnnotations);
-            writeParamAnnotations(m, RetentionPolicy.CLASS);
+            writeParamAnnotations(vars, RetentionPolicy.CLASS);
             endAttr(attrIndex);
             attrCount++;
         }
         return attrCount;
     }

@@ -829,10 +830,29 @@
             databuf.appendChar(flags);
         }
         endAttr(alenIdx);
     }
 
+    int writeRecordAttribute(ClassSymbol csym) {
+        int alenIdx = writeAttr(names.Record);
+        Scope s = csym.members();
+        List<VarSymbol> vars = List.nil();
+        int numParams = 0;
+        for (Symbol sym : s.getSymbols(NON_RECURSIVE)) {
+            if (sym.kind == VAR && sym.isRecord()) {
+                vars = vars.prepend((VarSymbol)sym);
+                numParams++;
+            }
+        }
+        databuf.appendChar(numParams);
+        for (VarSymbol v: vars) {
+            databuf.appendChar(poolWriter.putMember(v.accessors.head.snd));
+        }
+        endAttr(alenIdx);
+        return 1;
+    }
+
     /**
      * Write NestMembers attribute (if needed)
      */
     int writeNestMembersIfNeeded(ClassSymbol csym) {
         ListBuffer<ClassSymbol> nested = new ListBuffer<>();

@@ -879,10 +899,26 @@
                 listNested(s, seen);
             }
         }
     }
 
+    /** Write "PermittedSubtypes" attribute.
+     */
+    int writePermittedSubtypesIfNeeded(ClassSymbol csym) {
+        ClassType ct = (ClassType)csym.type;
+        if (ct.permitted.nonEmpty()) {
+            int alenIdx = writeAttr(names.PermittedSubtypes);
+            databuf.appendChar(ct.permitted.size());
+            for (Type t : ct.permitted) {
+                databuf.appendChar(poolWriter.putClass((ClassSymbol)t.tsym));
+            }
+            endAttr(alenIdx);
+            return 1;
+        }
+        return 0;
+    }
+
     /** Write "bootstrapMethods" attribute.
      */
     void writeBootstrapMethods() {
         int alenIdx = writeAttr(names.BootstrapMethods);
         databuf.appendChar(poolWriter.bootstrapMethods.size());

@@ -958,17 +994,17 @@
             int alenIdx = writeAttr(names.AnnotationDefault);
             m.defaultValue.accept(awriter);
             endAttr(alenIdx);
             acount++;
         }
-        if (options.isSet(PARAMETERS) && target.hasMethodParameters()) {
+        if (target.hasMethodParameters() && (options.isSet(PARAMETERS) || m.isConstructor() && m.isRecord())) {
             if (!m.isLambdaMethod()) // Per JDK-8138729, do not emit parameters table for lambda bodies.
                 acount += writeMethodParametersAttr(m);
         }
         acount += writeMemberAttrs(m);
         if (!m.isLambdaMethod())
-            acount += writeParameterAttrs(m);
+            acount += writeParameterAttrs(m.params);
         endAttrs(acountIdx, acount);
     }
 
     /** Write code attribute of method.
      */

@@ -1489,10 +1525,16 @@
         int flags;
         if (c.owner.kind == MDL) {
             flags = ACC_MODULE;
         } else {
             flags = adjustFlags(c.flags() & ~DEFAULT);
+            if (c.isSealed()) {
+                flags &= ~SEALED;
+                if (((ClassType)c.type).permitted.isEmpty()) {
+                    flags |= FINAL;
+                }
+            }
             if ((flags & PROTECTED) != 0) flags |= PUBLIC;
             flags = flags & ClassFlags & ~STRICTFP;
             if ((flags & INTERFACE) == 0) flags |= ACC_SUPER;
         }
 

@@ -1598,10 +1640,18 @@
                 acount += writeNestMembersIfNeeded(c);
                 acount += writeNestHostIfNeeded(c);
             }
         }
 
+        if (c.isRecord()) {
+            acount += writeRecordAttribute(c);
+        }
+
+        if (target.hasSealedTypes()) {
+            acount += writePermittedSubtypesIfNeeded(c);
+        }
+
         if (!poolWriter.bootstrapMethods.isEmpty()) {
             writeBootstrapMethods();
             acount++;
         }
 

@@ -1635,10 +1685,12 @@
             result |= ACC_BRIDGE;
         if ((flags & VARARGS) != 0)
             result |= ACC_VARARGS;
         if ((flags & DEFAULT) != 0)
             result &= ~ABSTRACT;
+        if ((flags & SEALED) != 0)
+            result |= FINAL;
         return result;
     }
 
     long getLastModified(FileObject filename) {
         long mod = 0;
< prev index next >