Wed, 13 Feb 2013 17:04:21 +0000
8006345: Report Synthesized Parameters in java.lang.reflect.Parameter API
8006896: ClassReader doesn't see MethodParameters attr for method of anon inner class
8007098: Output Synthesized Parameters to MethodParameters Attributes
Summary: Correctly report synthesized and mandated parameters
Reviewed-by: mcimadamore, jjg
Contributed-by: eric.mccorkle@oracle.com
1.1 --- a/src/share/classes/com/sun/tools/classfile/AccessFlags.java Wed Feb 13 10:33:13 2013 +0100 1.2 +++ b/src/share/classes/com/sun/tools/classfile/AccessFlags.java Wed Feb 13 17:04:21 2013 +0000 1.3 @@ -56,7 +56,7 @@ 1.4 public static final int ACC_SYNTHETIC = 0x1000; // class, inner, field, method 1.5 public static final int ACC_ANNOTATION = 0x2000; // class, inner 1.6 public static final int ACC_ENUM = 0x4000; // class, inner, field 1.7 - public static final int ACC_MODULE = 0x8000; // class, inner, field, method 1.8 + public static final int ACC_MANDATED = 0x8000; // class, inner, field, method 1.9 1.10 public static enum Kind { Class, InnerClass, Field, Method}; 1.11 1.12 @@ -81,12 +81,12 @@ 1.13 } 1.14 1.15 private static final int[] classModifiers = { 1.16 - ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT, ACC_MODULE 1.17 + ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT 1.18 }; 1.19 1.20 private static final int[] classFlags = { 1.21 ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_INTERFACE, ACC_ABSTRACT, 1.22 - ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_MODULE 1.23 + ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM 1.24 }; 1.25 1.26 public Set<String> getClassModifiers() { 1.27 @@ -100,12 +100,12 @@ 1.28 1.29 private static final int[] innerClassModifiers = { 1.30 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, 1.31 - ACC_ABSTRACT, ACC_MODULE 1.32 + ACC_ABSTRACT 1.33 }; 1.34 1.35 private static final int[] innerClassFlags = { 1.36 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SUPER, 1.37 - ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_MODULE 1.38 + ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM 1.39 }; 1.40 1.41 public Set<String> getInnerClassModifiers() { 1.42 @@ -119,12 +119,12 @@ 1.43 1.44 private static final int[] fieldModifiers = { 1.45 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, 1.46 - ACC_VOLATILE, ACC_TRANSIENT, ACC_MODULE 1.47 + ACC_VOLATILE, ACC_TRANSIENT 1.48 }; 1.49 1.50 private static final int[] fieldFlags = { 1.51 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, 1.52 - ACC_VOLATILE, ACC_TRANSIENT, ACC_SYNTHETIC, ACC_ENUM, ACC_MODULE 1.53 + ACC_VOLATILE, ACC_TRANSIENT, ACC_SYNTHETIC, ACC_ENUM 1.54 }; 1.55 1.56 public Set<String> getFieldModifiers() { 1.57 @@ -137,13 +137,13 @@ 1.58 1.59 private static final int[] methodModifiers = { 1.60 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, 1.61 - ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT, ACC_MODULE 1.62 + ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT 1.63 }; 1.64 1.65 private static final int[] methodFlags = { 1.66 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, 1.67 ACC_SYNCHRONIZED, ACC_BRIDGE, ACC_VARARGS, ACC_NATIVE, ACC_ABSTRACT, 1.68 - ACC_STRICT, ACC_SYNTHETIC, ACC_MODULE 1.69 + ACC_STRICT, ACC_SYNTHETIC 1.70 }; 1.71 1.72 public Set<String> getMethodModifiers() { 1.73 @@ -208,8 +208,8 @@ 1.74 return "abstract"; 1.75 case ACC_STRICT: 1.76 return "strictfp"; 1.77 - case ACC_MODULE: 1.78 - return "module"; 1.79 + case ACC_MANDATED: 1.80 + return "mandated"; 1.81 default: 1.82 return null; 1.83 } 1.84 @@ -247,8 +247,8 @@ 1.85 return "ACC_ANNOTATION"; 1.86 case ACC_ENUM: 1.87 return "ACC_ENUM"; 1.88 - case ACC_MODULE: 1.89 - return "ACC_MODULE"; 1.90 + case ACC_MANDATED: 1.91 + return "ACC_MANDATED"; 1.92 default: 1.93 return null; 1.94 }
2.1 --- a/src/share/classes/com/sun/tools/javac/code/Flags.java Wed Feb 13 10:33:13 2013 +0100 2.2 +++ b/src/share/classes/com/sun/tools/javac/code/Flags.java Wed Feb 13 17:04:21 2013 +0000 2.3 @@ -74,6 +74,7 @@ 2.4 if ((mask&DEPRECATED) != 0) flags.add(Flag.DEPRECATED); 2.5 if ((mask&HASINIT) != 0) flags.add(Flag.HASINIT); 2.6 if ((mask&ENUM) != 0) flags.add(Flag.ENUM); 2.7 + if ((mask&MANDATED) != 0) flags.add(Flag.MANDATED); 2.8 if ((mask&IPROXY) != 0) flags.add(Flag.IPROXY); 2.9 if ((mask&NOOUTERTHIS) != 0) flags.add(Flag.NOOUTERTHIS); 2.10 if ((mask&EXISTS) != 0) flags.add(Flag.EXISTS); 2.11 @@ -114,6 +115,9 @@ 2.12 * classfile v49.0. */ 2.13 public static final int ENUM = 1<<14; 2.14 2.15 + /** Added in SE8, represents constructs implicitly declared in source. */ 2.16 + public static final int MANDATED = 1<<15; 2.17 + 2.18 public static final int StandardFlags = 0x0fff; 2.19 public static final int ModifierFlags = StandardFlags & ~INTERFACE; 2.20 2.21 @@ -342,6 +346,7 @@ 2.22 DEPRECATED("deprecated"), 2.23 HASINIT("hasinit"), 2.24 ENUM("enum"), 2.25 + MANDATED("mandated"), 2.26 IPROXY("iproxy"), 2.27 NOOUTERTHIS("noouterthis"), 2.28 EXISTS("exists"),
3.1 --- a/src/share/classes/com/sun/tools/javac/code/Symbol.java Wed Feb 13 10:33:13 2013 +0100 3.2 +++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java Wed Feb 13 17:04:21 2013 +0000 3.3 @@ -217,6 +217,14 @@ 3.4 return (flags() & INTERFACE) != 0; 3.5 } 3.6 3.7 + public boolean isPrivate() { 3.8 + return (flags_field & Flags.AccessFlags) == PRIVATE; 3.9 + } 3.10 + 3.11 + public boolean isEnum() { 3.12 + return (flags() & ENUM) != 0; 3.13 + } 3.14 + 3.15 /** Is this symbol declared (directly or indirectly) local 3.16 * to a method or variable initializer? 3.17 * Also includes fields of inner classes which are in 3.18 @@ -1082,6 +1090,9 @@ 3.19 /** The code of the method. */ 3.20 public Code code = null; 3.21 3.22 + /** The extra (synthetic/mandated) parameters of the method. */ 3.23 + public List<VarSymbol> extraParams = List.nil(); 3.24 + 3.25 /** The parameters of the method. */ 3.26 public List<VarSymbol> params = null; 3.27
4.1 --- a/src/share/classes/com/sun/tools/javac/comp/Lower.java Wed Feb 13 10:33:13 2013 +0100 4.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java Wed Feb 13 17:04:21 2013 +0000 4.3 @@ -1445,22 +1445,49 @@ 4.4 return result; 4.5 } 4.6 4.7 + private VarSymbol makeOuterThisVarSymbol(Symbol owner, long flags) { 4.8 + if (owner.kind == TYP && 4.9 + target.usePrivateSyntheticFields()) 4.10 + flags |= PRIVATE; 4.11 + Type target = types.erasure(owner.enclClass().type.getEnclosingType()); 4.12 + VarSymbol outerThis = 4.13 + new VarSymbol(flags, outerThisName(target, owner), target, owner); 4.14 + outerThisStack = outerThisStack.prepend(outerThis); 4.15 + return outerThis; 4.16 + } 4.17 + 4.18 + private JCVariableDecl makeOuterThisVarDecl(int pos, VarSymbol sym) { 4.19 + JCVariableDecl vd = make.at(pos).VarDef(sym, null); 4.20 + vd.vartype = access(vd.vartype); 4.21 + return vd; 4.22 + } 4.23 + 4.24 + /** Definition for this$n field. 4.25 + * @param pos The source code position of the definition. 4.26 + * @param owner The method in which the definition goes. 4.27 + */ 4.28 + JCVariableDecl outerThisDef(int pos, MethodSymbol owner) { 4.29 + ClassSymbol c = owner.enclClass(); 4.30 + boolean isMandated = 4.31 + // Anonymous constructors 4.32 + (owner.isConstructor() && owner.isAnonymous()) || 4.33 + // Constructors of non-private inner member classes 4.34 + (owner.isConstructor() && c.isInner() && 4.35 + !c.isPrivate() && !c.isStatic()); 4.36 + long flags = 4.37 + FINAL | (isMandated ? MANDATED : SYNTHETIC); 4.38 + VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags); 4.39 + owner.extraParams = owner.extraParams.prepend(outerThis); 4.40 + return makeOuterThisVarDecl(pos, outerThis); 4.41 + } 4.42 + 4.43 /** Definition for this$n field. 4.44 * @param pos The source code position of the definition. 4.45 * @param owner The class in which the definition goes. 4.46 */ 4.47 - JCVariableDecl outerThisDef(int pos, Symbol owner) { 4.48 - long flags = FINAL | SYNTHETIC; 4.49 - if (owner.kind == TYP && 4.50 - target.usePrivateSyntheticFields()) 4.51 - flags |= PRIVATE; 4.52 - Type target = types.erasure(owner.enclClass().type.getEnclosingType()); 4.53 - VarSymbol outerThis = new VarSymbol( 4.54 - flags, outerThisName(target, owner), target, owner); 4.55 - outerThisStack = outerThisStack.prepend(outerThis); 4.56 - JCVariableDecl vd = make.at(pos).VarDef(outerThis, null); 4.57 - vd.vartype = access(vd.vartype); 4.58 - return vd; 4.59 + JCVariableDecl outerThisDef(int pos, ClassSymbol owner) { 4.60 + VarSymbol outerThis = makeOuterThisVarSymbol(owner, FINAL | SYNTHETIC); 4.61 + return makeOuterThisVarDecl(pos, outerThis); 4.62 } 4.63 4.64 /** Return a list of trees that load the free variables in given list, 4.65 @@ -2568,7 +2595,6 @@ 4.66 "enum" + target.syntheticNameChar() + "name"), 4.67 syms.stringType, tree.sym); 4.68 nameParam.mods.flags |= SYNTHETIC; nameParam.sym.flags_field |= SYNTHETIC; 4.69 - 4.70 JCVariableDecl ordParam = make. 4.71 Param(names.fromString(target.syntheticNameChar() + 4.72 "enum" + target.syntheticNameChar() + 4.73 @@ -2579,6 +2605,8 @@ 4.74 tree.params = tree.params.prepend(ordParam).prepend(nameParam); 4.75 4.76 MethodSymbol m = tree.sym; 4.77 + m.extraParams = m.extraParams.prepend(ordParam.sym); 4.78 + m.extraParams = m.extraParams.prepend(nameParam.sym); 4.79 Type olderasure = m.erasure(types); 4.80 m.erasure_field = new MethodType( 4.81 olderasure.getParameterTypes().prepend(syms.intType).prepend(syms.stringType),
5.1 --- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Wed Feb 13 10:33:13 2013 +0100 5.2 +++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Wed Feb 13 17:04:21 2013 +0000 5.3 @@ -465,7 +465,8 @@ 5.4 names.valueOf, 5.5 make.Type(tree.sym.type), 5.6 List.<JCTypeParameter>nil(), 5.7 - List.of(make.VarDef(make.Modifiers(Flags.PARAMETER), 5.8 + List.of(make.VarDef(make.Modifiers(Flags.PARAMETER | 5.9 + Flags.MANDATED), 5.10 names.fromString("name"), 5.11 make.Type(syms.stringType), null)), 5.12 List.<JCExpression>nil(), // thrown
6.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Wed Feb 13 10:33:13 2013 +0100 6.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Wed Feb 13 17:04:21 2013 +0000 6.3 @@ -728,14 +728,24 @@ 6.4 * Write method parameter names attribute. 6.5 */ 6.6 int writeMethodParametersAttr(MethodSymbol m) { 6.7 - if (m.params != null && 0 != m.params.length()) { 6.8 - int attrIndex = writeAttr(names.MethodParameters); 6.9 - databuf.appendByte(m.params.length()); 6.10 + MethodType ty = m.externalType(types).asMethodType(); 6.11 + final int allparams = ty.argtypes.size(); 6.12 + if (m.params != null && allparams != 0) { 6.13 + final int attrIndex = writeAttr(names.MethodParameters); 6.14 + databuf.appendByte(allparams); 6.15 + // Write extra parameters first 6.16 + for (VarSymbol s : m.extraParams) { 6.17 + final int flags = 6.18 + ((int) s.flags() & (FINAL | SYNTHETIC | MANDATED)) | 6.19 + ((int) m.flags() & SYNTHETIC); 6.20 + databuf.appendChar(pool.put(s.name)); 6.21 + databuf.appendInt(flags); 6.22 + } 6.23 + // Now write the real parameters 6.24 for (VarSymbol s : m.params) { 6.25 - // TODO: expand to cover synthesized, once we figure out 6.26 - // how to represent that. 6.27 - final int flags = (int) s.flags() & (FINAL | SYNTHETIC); 6.28 - // output parameter info 6.29 + final int flags = 6.30 + ((int) s.flags() & (FINAL | SYNTHETIC | MANDATED)) | 6.31 + ((int) m.flags() & SYNTHETIC); 6.32 databuf.appendChar(pool.put(s.name)); 6.33 databuf.appendInt(flags); 6.34 }
7.1 --- a/src/share/classes/com/sun/tools/javap/AttributeWriter.java Wed Feb 13 10:33:13 2013 +0100 7.2 +++ b/src/share/classes/com/sun/tools/javap/AttributeWriter.java Wed Feb 13 17:04:21 2013 +0000 7.3 @@ -400,12 +400,14 @@ 7.4 println(header); 7.5 for (MethodParameters_attribute.Entry entry : 7.6 attr.method_parameter_table) { 7.7 + String namestr = 7.8 + entry.name_index != 0 ? 7.9 + constantWriter.stringValue(entry.name_index) : "<no name>"; 7.10 String flagstr = 7.11 - (0 != (entry.flags & ACC_FINAL) ? " final" : "") + 7.12 - (0 != (entry.flags & ACC_SYNTHETIC) ? " synthetic" : ""); 7.13 - println(String.format(format, 7.14 - constantWriter.stringValue(entry.name_index), 7.15 - flagstr)); 7.16 + (0 != (entry.flags & ACC_FINAL) ? "final " : "") + 7.17 + (0 != (entry.flags & ACC_MANDATED) ? "mandated " : "") + 7.18 + (0 != (entry.flags & ACC_SYNTHETIC) ? "synthetic" : ""); 7.19 + println(String.format(format, namestr, flagstr)); 7.20 } 7.21 indent(-1); 7.22 return null;