--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Mon Jul 28 10:22:10 2008 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Fri Aug 01 15:23:18 2008 -0700
@@ -2110,16 +2110,64 @@
Symbol valuesSym = lookupMethod(tree.pos(), names.values,
tree.type, List.<Type>nil());
- JCTypeCast valuesResult =
- make.TypeCast(valuesSym.type.getReturnType(),
- make.App(make.Select(make.Ident(valuesVar),
- syms.arrayCloneMethod)));
+ List<JCStatement> valuesBody;
+ if (useClone()) {
+ // return (T[]) $VALUES.clone();
+ JCTypeCast valuesResult =
+ make.TypeCast(valuesSym.type.getReturnType(),
+ make.App(make.Select(make.Ident(valuesVar),
+ syms.arrayCloneMethod)));
+ valuesBody = List.<JCStatement>of(make.Return(valuesResult));
+ } else {
+ // template: T[] $result = new T[$values.length];
+ Name resultName = names.fromString(target.syntheticNameChar() + "result");
+ while (tree.sym.members().lookup(resultName).scope != null) // avoid name clash
+ resultName = names.fromString(resultName + "" + target.syntheticNameChar());
+ VarSymbol resultVar = new VarSymbol(FINAL|SYNTHETIC,
+ resultName,
+ arrayType,
+ valuesSym);
+ JCNewArray resultArray = make.NewArray(make.Type(types.erasure(tree.type)),
+ List.of(make.Select(make.Ident(valuesVar), syms.lengthVar)),
+ null);
+ resultArray.type = arrayType;
+ JCVariableDecl decl = make.VarDef(resultVar, resultArray);
+
+ // template: System.arraycopy($VALUES, 0, $result, 0, $VALUES.length);
+ if (systemArraycopyMethod == null) {
+ systemArraycopyMethod =
+ new MethodSymbol(PUBLIC | STATIC,
+ names.fromString("arraycopy"),
+ new MethodType(List.<Type>of(syms.objectType,
+ syms.intType,
+ syms.objectType,
+ syms.intType,
+ syms.intType),
+ syms.voidType,
+ List.<Type>nil(),
+ syms.methodClass),
+ syms.systemType.tsym);
+ }
+ JCStatement copy =
+ make.Exec(make.App(make.Select(make.Ident(syms.systemType.tsym),
+ systemArraycopyMethod),
+ List.of(make.Ident(valuesVar), make.Literal(0),
+ make.Ident(resultVar), make.Literal(0),
+ make.Select(make.Ident(valuesVar), syms.lengthVar))));
+
+ // template: return $result;
+ JCStatement ret = make.Return(make.Ident(resultVar));
+ valuesBody = List.<JCStatement>of(decl, copy, ret);
+ }
+
JCMethodDecl valuesDef =
- make.MethodDef((MethodSymbol)valuesSym,
- make.Block(0, List.<JCStatement>nil()
- .prepend(make.Return(valuesResult))));
+ make.MethodDef((MethodSymbol)valuesSym, make.Block(0, valuesBody));
+
enumDefs.append(valuesDef);
+ if (debugLower)
+ System.err.println(tree.sym + ".valuesDef = " + valuesDef);
+
/** The template for the following code is:
*
* public static E valueOf(String name) {
@@ -2155,6 +2203,17 @@
addEnumCompatibleMembers(tree);
}
}
+ // where
+ private MethodSymbol systemArraycopyMethod;
+ private boolean useClone() {
+ try {
+ Scope.Entry e = syms.objectType.tsym.members().lookup(names.clone);
+ return (e.sym != null);
+ }
+ catch (CompletionFailure e) {
+ return false;
+ }
+ }
/** Translate an enumeration constant and its initializer. */
private void visitEnumConstantDef(JCVariableDecl var, int ordinal) {