8004979: java.lang.reflect.Modifier.toString should include "default"
authordarcy
Tue, 02 Apr 2013 16:26:54 -0700
changeset 16729 3b26e313ad81
parent 16728 1b7611896b3b
child 16730 5f67810e08fb
8004979: java.lang.reflect.Modifier.toString should include "default" Reviewed-by: mduigou
jdk/src/share/classes/java/lang/reflect/Constructor.java
jdk/src/share/classes/java/lang/reflect/Executable.java
jdk/src/share/classes/java/lang/reflect/Field.java
jdk/src/share/classes/java/lang/reflect/Method.java
jdk/src/share/classes/java/lang/reflect/Modifier.java
jdk/test/java/lang/reflect/Method/GenericStringTest.java
--- a/jdk/src/share/classes/java/lang/reflect/Constructor.java	Tue Apr 02 11:59:34 2013 -0700
+++ b/jdk/src/share/classes/java/lang/reflect/Constructor.java	Tue Apr 02 16:26:54 2013 -0700
@@ -284,9 +284,13 @@
      * modifiers {@code public}, {@code protected} or
      * {@code private}.  Only one of these may appear, or none if the
      * constructor has default (package) access.
+     *
+     * @return a string describing this {@code Constructor}
+     * @jls 8.8.3. Constructor Modifiers
      */
     public String toString() {
         return sharedToString(Modifier.constructorModifiers(),
+                              false,
                               parameterTypes,
                               exceptionTypes);
     }
@@ -328,10 +332,11 @@
      * include type parameters
      *
      * @since 1.5
+     * @jls 8.8.3. Constructor Modifiers
      */
     @Override
     public String toGenericString() {
-        return sharedToGenericString(Modifier.constructorModifiers());
+        return sharedToGenericString(Modifier.constructorModifiers(), false);
     }
 
     @Override
--- a/jdk/src/share/classes/java/lang/reflect/Executable.java	Tue Apr 02 11:59:34 2013 -0700
+++ b/jdk/src/share/classes/java/lang/reflect/Executable.java	Tue Apr 02 16:26:54 2013 -0700
@@ -89,20 +89,31 @@
 
     }
 
-    void printModifiersIfNonzero(StringBuilder sb, int mask) {
+    void printModifiersIfNonzero(StringBuilder sb, int mask, boolean isDefault) {
         int mod = getModifiers() & mask;
-        if (mod != 0) {
+
+        if (mod != 0 && !isDefault) {
             sb.append(Modifier.toString(mod)).append(' ');
+        } else {
+            int access_mod = mod & Modifier.ACCESS_MODIFIERS;
+            if (access_mod != 0)
+                sb.append(Modifier.toString(access_mod)).append(' ');
+            if (isDefault)
+                sb.append("default ");
+            mod = (mod & ~Modifier.ACCESS_MODIFIERS);
+            if (mod != 0)
+                sb.append(Modifier.toString(mod)).append(' ');
         }
     }
 
     String sharedToString(int modifierMask,
+                          boolean isDefault,
                           Class<?>[] parameterTypes,
                           Class<?>[] exceptionTypes) {
         try {
             StringBuilder sb = new StringBuilder();
 
-            printModifiersIfNonzero(sb, modifierMask);
+            printModifiersIfNonzero(sb, modifierMask, isDefault);
             specificToStringHeader(sb);
 
             sb.append('(');
@@ -124,11 +135,11 @@
      */
     abstract void specificToStringHeader(StringBuilder sb);
 
-    String sharedToGenericString(int modifierMask) {
+    String sharedToGenericString(int modifierMask, boolean isDefault) {
         try {
             StringBuilder sb = new StringBuilder();
 
-            printModifiersIfNonzero(sb, modifierMask);
+            printModifiersIfNonzero(sb, modifierMask, isDefault);
 
             TypeVariable<?>[] typeparms = getTypeParameters();
             if (typeparms.length > 0) {
--- a/jdk/src/share/classes/java/lang/reflect/Field.java	Tue Apr 02 11:59:34 2013 -0700
+++ b/jdk/src/share/classes/java/lang/reflect/Field.java	Tue Apr 02 16:26:54 2013 -0700
@@ -288,6 +288,9 @@
      * {@code protected} or {@code private} first, and then other
      * modifiers in the following order: {@code static}, {@code final},
      * {@code transient}, {@code volatile}.
+     *
+     * @return a string describing this {@code Field}
+     * @jls 8.3.1 Field Modifiers
      */
     public String toString() {
         int mod = getModifiers();
@@ -315,6 +318,7 @@
      * its generic type
      *
      * @since 1.5
+     * @jls 8.3.1 Field Modifiers
      */
     public String toGenericString() {
         int mod = getModifiers();
--- a/jdk/src/share/classes/java/lang/reflect/Method.java	Tue Apr 02 11:59:34 2013 -0700
+++ b/jdk/src/share/classes/java/lang/reflect/Method.java	Tue Apr 02 16:26:54 2013 -0700
@@ -343,10 +343,16 @@
      * {@code public}, {@code protected} or {@code private} first,
      * and then other modifiers in the following order:
      * {@code abstract}, {@code static}, {@code final},
-     * {@code synchronized}, {@code native}, {@code strictfp}.
+     * {@code synchronized}, {@code native}, {@code strictfp},
+     * {@code default}.
+     *
+     * @return a string describing this {@code Method}
+     *
+     * @jls 8.4.3 Method Modifiers
      */
     public String toString() {
         return sharedToString(Modifier.methodModifiers(),
+                              isDefault(),
                               parameterTypes,
                               exceptionTypes);
     }
@@ -389,16 +395,19 @@
      * {@code public}, {@code protected} or {@code private} first,
      * and then other modifiers in the following order:
      * {@code abstract}, {@code static}, {@code final},
-     * {@code synchronized}, {@code native}, {@code strictfp}.
+     * {@code synchronized}, {@code native}, {@code strictfp},
+     * {@code default}.
      *
      * @return a string describing this {@code Method},
      * include type parameters
      *
      * @since 1.5
+     *
+     * @jls 8.4.3 Method Modifiers
      */
     @Override
     public String toGenericString() {
-        return sharedToGenericString(Modifier.methodModifiers());
+        return sharedToGenericString(Modifier.methodModifiers(), isDefault());
     }
 
     @Override
--- a/jdk/src/share/classes/java/lang/reflect/Modifier.java	Tue Apr 02 11:59:34 2013 -0700
+++ b/jdk/src/share/classes/java/lang/reflect/Modifier.java	Tue Apr 02 16:26:54 2013 -0700
@@ -390,6 +390,12 @@
         Modifier.VOLATILE;
 
     /**
+     *
+     */
+    static final int ACCESS_MODIFIERS =
+        Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE;
+
+    /**
      * Return an {@code int} value OR-ing together the source language
      * modifiers that can be applied to a class.
      * @return an {@code int} value OR-ing together the source language
--- a/jdk/test/java/lang/reflect/Method/GenericStringTest.java	Tue Apr 02 11:59:34 2013 -0700
+++ b/jdk/test/java/lang/reflect/Method/GenericStringTest.java	Tue Apr 02 16:26:54 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 5033583 6316717 6470106
+ * @bug 5033583 6316717 6470106 8004979
  * @summary Check toGenericString() and toString() methods
  * @author Joseph D. Darcy
  */
@@ -39,6 +39,7 @@
         classList.add(TestClass1.class);
         classList.add(TestClass2.class);
         classList.add(Roebling.class);
+        classList.add(TestInterface1.class);
 
 
         for(Class<?> clazz: classList)
@@ -129,6 +130,27 @@
     void varArg(Object ... arg) {}
 }
 
+interface TestInterface1 {
+    @ExpectedGenericString(
+   "public default void TestInterface1.foo()")
+    @ExpectedString(
+   "public default void TestInterface1.foo()")
+    public default void foo(){;}
+
+    @ExpectedString(
+   "public default java.lang.Object TestInterface1.bar()")
+    @ExpectedGenericString(
+   "public default <A> A TestInterface1.bar()")
+    default <A> A bar(){return null;}
+
+    @ExpectedString(
+   "public default strictfp double TestInterface1.quux()")
+    @ExpectedGenericString(
+    "public default strictfp double TestInterface1.quux()")
+    strictfp default double quux(){return 1.0;}
+
+}
+
 @Retention(RetentionPolicy.RUNTIME)
 @interface ExpectedGenericString {
     String value();