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

Print this page

        

@@ -724,23 +724,70 @@
         acount += writeJavaAnnotations(sym.getRawAttributes());
         acount += writeTypeAnnotations(sym.getRawTypeAttributes());
         return acount;
     }
 
+    // Decide if the first formal parameter should be mandated.
+    // There are two cases that apply here:
+    //
+    // The first parameter to a non-private member class
+    //
+    // The first parameter of an anonymous constructor
+    boolean firstIsMandated(MethodSymbol m) {
+        ClassSymbol c = m.enclClass();
+
+        return
+            // Anonymous constructors
+            (m.isConstructor() && c.isAnonymous()) ||
+            // Constructors of non-private inner member classes
+            (m.isConstructor() && c.isInner() &&
+             !c.isPrivate() && !c.isStatic());
+    }
+
+    // The "name" parameter of an enum's valueOf is mandated, so we
+    // need to figure out if we're dealing with that function.
+    boolean isEnumValueOf(MethodSymbol m) {
+        return m.enclClass().isEnum() && m.name.contentEquals("valueOf");
+    }
+
     /**
      * Write method parameter names attribute.
      */
     int writeMethodParametersAttr(MethodSymbol m) {
-        if (m.params != null && 0 != m.params.length()) {
-            int attrIndex = writeAttr(names.MethodParameters);
-            databuf.appendByte(m.params.length());
+        MethodType ty = m.externalType(types).asMethodType();
+        final int allparams = ty.argtypes.size();
+        if (m.params != null && allparams != 0) {
+            final int realparams = m.params.length();
+            final int synthparams = allparams - realparams;
+            final int attrIndex = writeAttr(names.MethodParameters);
+            final boolean firstmandated = firstIsMandated(m);
+            final boolean valueof = isEnumValueOf(m);
+            databuf.appendByte(allparams);
+            // Add synthetic/mandatade parameters.  Note: at the
+            // present, these parameters have no easily accessible
+            // list of VarSymbols.  It is probably a good idea to
+            // change MethodSymbol so that one exists, and the proper
+            // flags are set on the symbols when they are created, as
+            // opposed to doing it like this.
+            for (int i = 0; i < synthparams; i++) {
+                databuf.appendChar(0);
+                if(firstmandated && i == 0)
+                    databuf.appendInt(MANDATED);
+                else
+                    databuf.appendInt(SYNTHETIC);
+            }
             for (VarSymbol s : m.params) {
-                // TODO: expand to cover synthesized, once we figure out
-                // how to represent that.
                 final int flags = (int) s.flags() & (FINAL | SYNTHETIC);
+                // TODO: this is done this way to preserve uniformity
+                // in how mandated parameters are detected and set.
+                // If this is changed, then set the MANDATED flag when
+                // this parameter is created.
                 // output parameter info
                 databuf.appendChar(pool.put(s.name));
+                if(valueof && s.name.contentEquals("name"))
+                    databuf.appendInt(MANDATED);
+                else
                 databuf.appendInt(flags);
             }
             endAttr(attrIndex);
             return 1;
         } else