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
--- a/langtools/src/share/classes/com/sun/tools/classfile/AccessFlags.java Wed Feb 13 10:33:13 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/classfile/AccessFlags.java Wed Feb 13 17:04:21 2013 +0000
@@ -56,7 +56,7 @@
public static final int ACC_SYNTHETIC = 0x1000; // class, inner, field, method
public static final int ACC_ANNOTATION = 0x2000; // class, inner
public static final int ACC_ENUM = 0x4000; // class, inner, field
- public static final int ACC_MODULE = 0x8000; // class, inner, field, method
+ public static final int ACC_MANDATED = 0x8000; // class, inner, field, method
public static enum Kind { Class, InnerClass, Field, Method};
@@ -81,12 +81,12 @@
}
private static final int[] classModifiers = {
- ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT, ACC_MODULE
+ ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT
};
private static final int[] classFlags = {
ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_INTERFACE, ACC_ABSTRACT,
- ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_MODULE
+ ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM
};
public Set<String> getClassModifiers() {
@@ -100,12 +100,12 @@
private static final int[] innerClassModifiers = {
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
- ACC_ABSTRACT, ACC_MODULE
+ ACC_ABSTRACT
};
private static final int[] innerClassFlags = {
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SUPER,
- ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_MODULE
+ ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM
};
public Set<String> getInnerClassModifiers() {
@@ -119,12 +119,12 @@
private static final int[] fieldModifiers = {
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
- ACC_VOLATILE, ACC_TRANSIENT, ACC_MODULE
+ ACC_VOLATILE, ACC_TRANSIENT
};
private static final int[] fieldFlags = {
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
- ACC_VOLATILE, ACC_TRANSIENT, ACC_SYNTHETIC, ACC_ENUM, ACC_MODULE
+ ACC_VOLATILE, ACC_TRANSIENT, ACC_SYNTHETIC, ACC_ENUM
};
public Set<String> getFieldModifiers() {
@@ -137,13 +137,13 @@
private static final int[] methodModifiers = {
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
- ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT, ACC_MODULE
+ ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT
};
private static final int[] methodFlags = {
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
ACC_SYNCHRONIZED, ACC_BRIDGE, ACC_VARARGS, ACC_NATIVE, ACC_ABSTRACT,
- ACC_STRICT, ACC_SYNTHETIC, ACC_MODULE
+ ACC_STRICT, ACC_SYNTHETIC
};
public Set<String> getMethodModifiers() {
@@ -208,8 +208,8 @@
return "abstract";
case ACC_STRICT:
return "strictfp";
- case ACC_MODULE:
- return "module";
+ case ACC_MANDATED:
+ return "mandated";
default:
return null;
}
@@ -247,8 +247,8 @@
return "ACC_ANNOTATION";
case ACC_ENUM:
return "ACC_ENUM";
- case ACC_MODULE:
- return "ACC_MODULE";
+ case ACC_MANDATED:
+ return "ACC_MANDATED";
default:
return null;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Wed Feb 13 10:33:13 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Wed Feb 13 17:04:21 2013 +0000
@@ -74,6 +74,7 @@
if ((mask&DEPRECATED) != 0) flags.add(Flag.DEPRECATED);
if ((mask&HASINIT) != 0) flags.add(Flag.HASINIT);
if ((mask&ENUM) != 0) flags.add(Flag.ENUM);
+ if ((mask&MANDATED) != 0) flags.add(Flag.MANDATED);
if ((mask&IPROXY) != 0) flags.add(Flag.IPROXY);
if ((mask&NOOUTERTHIS) != 0) flags.add(Flag.NOOUTERTHIS);
if ((mask&EXISTS) != 0) flags.add(Flag.EXISTS);
@@ -114,6 +115,9 @@
* classfile v49.0. */
public static final int ENUM = 1<<14;
+ /** Added in SE8, represents constructs implicitly declared in source. */
+ public static final int MANDATED = 1<<15;
+
public static final int StandardFlags = 0x0fff;
public static final int ModifierFlags = StandardFlags & ~INTERFACE;
@@ -342,6 +346,7 @@
DEPRECATED("deprecated"),
HASINIT("hasinit"),
ENUM("enum"),
+ MANDATED("mandated"),
IPROXY("iproxy"),
NOOUTERTHIS("noouterthis"),
EXISTS("exists"),
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Wed Feb 13 10:33:13 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Wed Feb 13 17:04:21 2013 +0000
@@ -217,6 +217,14 @@
return (flags() & INTERFACE) != 0;
}
+ public boolean isPrivate() {
+ return (flags_field & Flags.AccessFlags) == PRIVATE;
+ }
+
+ public boolean isEnum() {
+ return (flags() & ENUM) != 0;
+ }
+
/** Is this symbol declared (directly or indirectly) local
* to a method or variable initializer?
* Also includes fields of inner classes which are in
@@ -1082,6 +1090,9 @@
/** The code of the method. */
public Code code = null;
+ /** The extra (synthetic/mandated) parameters of the method. */
+ public List<VarSymbol> extraParams = List.nil();
+
/** The parameters of the method. */
public List<VarSymbol> params = null;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Wed Feb 13 10:33:13 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Wed Feb 13 17:04:21 2013 +0000
@@ -1445,22 +1445,49 @@
return result;
}
+ private VarSymbol makeOuterThisVarSymbol(Symbol owner, long flags) {
+ if (owner.kind == TYP &&
+ target.usePrivateSyntheticFields())
+ flags |= PRIVATE;
+ Type target = types.erasure(owner.enclClass().type.getEnclosingType());
+ VarSymbol outerThis =
+ new VarSymbol(flags, outerThisName(target, owner), target, owner);
+ outerThisStack = outerThisStack.prepend(outerThis);
+ return outerThis;
+ }
+
+ private JCVariableDecl makeOuterThisVarDecl(int pos, VarSymbol sym) {
+ JCVariableDecl vd = make.at(pos).VarDef(sym, null);
+ vd.vartype = access(vd.vartype);
+ return vd;
+ }
+
+ /** Definition for this$n field.
+ * @param pos The source code position of the definition.
+ * @param owner The method in which the definition goes.
+ */
+ JCVariableDecl outerThisDef(int pos, MethodSymbol owner) {
+ ClassSymbol c = owner.enclClass();
+ boolean isMandated =
+ // Anonymous constructors
+ (owner.isConstructor() && owner.isAnonymous()) ||
+ // Constructors of non-private inner member classes
+ (owner.isConstructor() && c.isInner() &&
+ !c.isPrivate() && !c.isStatic());
+ long flags =
+ FINAL | (isMandated ? MANDATED : SYNTHETIC);
+ VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
+ owner.extraParams = owner.extraParams.prepend(outerThis);
+ return makeOuterThisVarDecl(pos, outerThis);
+ }
+
/** Definition for this$n field.
* @param pos The source code position of the definition.
* @param owner The class in which the definition goes.
*/
- JCVariableDecl outerThisDef(int pos, Symbol owner) {
- long flags = FINAL | SYNTHETIC;
- if (owner.kind == TYP &&
- target.usePrivateSyntheticFields())
- flags |= PRIVATE;
- Type target = types.erasure(owner.enclClass().type.getEnclosingType());
- VarSymbol outerThis = new VarSymbol(
- flags, outerThisName(target, owner), target, owner);
- outerThisStack = outerThisStack.prepend(outerThis);
- JCVariableDecl vd = make.at(pos).VarDef(outerThis, null);
- vd.vartype = access(vd.vartype);
- return vd;
+ JCVariableDecl outerThisDef(int pos, ClassSymbol owner) {
+ VarSymbol outerThis = makeOuterThisVarSymbol(owner, FINAL | SYNTHETIC);
+ return makeOuterThisVarDecl(pos, outerThis);
}
/** Return a list of trees that load the free variables in given list,
@@ -2568,7 +2595,6 @@
"enum" + target.syntheticNameChar() + "name"),
syms.stringType, tree.sym);
nameParam.mods.flags |= SYNTHETIC; nameParam.sym.flags_field |= SYNTHETIC;
-
JCVariableDecl ordParam = make.
Param(names.fromString(target.syntheticNameChar() +
"enum" + target.syntheticNameChar() +
@@ -2579,6 +2605,8 @@
tree.params = tree.params.prepend(ordParam).prepend(nameParam);
MethodSymbol m = tree.sym;
+ m.extraParams = m.extraParams.prepend(ordParam.sym);
+ m.extraParams = m.extraParams.prepend(nameParam.sym);
Type olderasure = m.erasure(types);
m.erasure_field = new MethodType(
olderasure.getParameterTypes().prepend(syms.intType).prepend(syms.stringType),
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Wed Feb 13 10:33:13 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Wed Feb 13 17:04:21 2013 +0000
@@ -465,7 +465,8 @@
names.valueOf,
make.Type(tree.sym.type),
List.<JCTypeParameter>nil(),
- List.of(make.VarDef(make.Modifiers(Flags.PARAMETER),
+ List.of(make.VarDef(make.Modifiers(Flags.PARAMETER |
+ Flags.MANDATED),
names.fromString("name"),
make.Type(syms.stringType), null)),
List.<JCExpression>nil(), // thrown
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Wed Feb 13 10:33:13 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Wed Feb 13 17:04:21 2013 +0000
@@ -728,14 +728,24 @@
* 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 attrIndex = writeAttr(names.MethodParameters);
+ databuf.appendByte(allparams);
+ // Write extra parameters first
+ for (VarSymbol s : m.extraParams) {
+ final int flags =
+ ((int) s.flags() & (FINAL | SYNTHETIC | MANDATED)) |
+ ((int) m.flags() & SYNTHETIC);
+ databuf.appendChar(pool.put(s.name));
+ databuf.appendInt(flags);
+ }
+ // Now write the real parameters
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);
- // output parameter info
+ final int flags =
+ ((int) s.flags() & (FINAL | SYNTHETIC | MANDATED)) |
+ ((int) m.flags() & SYNTHETIC);
databuf.appendChar(pool.put(s.name));
databuf.appendInt(flags);
}
--- a/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java Wed Feb 13 10:33:13 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java Wed Feb 13 17:04:21 2013 +0000
@@ -400,12 +400,14 @@
println(header);
for (MethodParameters_attribute.Entry entry :
attr.method_parameter_table) {
+ String namestr =
+ entry.name_index != 0 ?
+ constantWriter.stringValue(entry.name_index) : "<no name>";
String flagstr =
- (0 != (entry.flags & ACC_FINAL) ? " final" : "") +
- (0 != (entry.flags & ACC_SYNTHETIC) ? " synthetic" : "");
- println(String.format(format,
- constantWriter.stringValue(entry.name_index),
- flagstr));
+ (0 != (entry.flags & ACC_FINAL) ? "final " : "") +
+ (0 != (entry.flags & ACC_MANDATED) ? "mandated " : "") +
+ (0 != (entry.flags & ACC_SYNTHETIC) ? "synthetic" : "");
+ println(String.format(format, namestr, flagstr));
}
indent(-1);
return null;