test/tools/javac/MethodParameters/ReflectionVisitor.java

Thu, 21 Feb 2013 15:26:46 +0000

author
mcimadamore
date
Thu, 21 Feb 2013 15:26:46 +0000
changeset 1599
9f0ec00514b6
parent 1594
267225edc1fe
child 1791
e9855150c5b0
permissions
-rw-r--r--

8007461: Regression: bad overload resolution when inner class and outer class have method with same name
Summary: Fix regression in varargs method resolution introduced by bad refactoring
Reviewed-by: jjg

     1 /*
     2  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  */
    24 import java.io.*;
    25 import java.util.*;
    26 import java.net.*;
    27 import java.lang.reflect.*;
    29 /**
    30  * Test MethodParameter attributs by reflection API
    31  */
    32 public class ReflectionVisitor extends Tester.Visitor {
    34     public ReflectionVisitor(Tester tester) {
    35         super(tester);
    36     }
    38     public void error(String msg) {
    39         super.error("reflection: " + msg);
    40     }
    42     public void warn(String msg) {
    43         super.warn("reflection: " + msg);
    44     }
    46     boolean isEnum;
    47     boolean isInterface;
    48     boolean isAnon;
    49     boolean isLocal;
    50     boolean isMember;
    51     boolean isStatic;
    52     boolean isPublic;
    53     Class clazz;
    54     StringBuilder sb;
    56     /**
    57      * Read class using {@code ClassFile}, and generate a list of methods
    58      * with parameter names as available in the MethodParameters attribute.
    59      */
    60     void visitClass(final String cl, final File cfile, final StringBuilder sb)
    61         throws Exception {
    63         this.sb = sb;
    64         clazz = Class.forName(cl);
    65         isEnum = clazz.isEnum();
    66         isInterface = clazz.isInterface();
    67         isAnon = clazz.isAnonymousClass();
    68         isLocal = clazz.isLocalClass();
    69         isMember = clazz.isMemberClass();
    70         isStatic = ((clazz.getModifiers() & Modifier.STATIC) != 0);
    71         isPublic = ((clazz.getModifiers() & Modifier.PUBLIC) != 0);
    73         sb.append(isStatic ? "static " : "")
    74             .append(isPublic ? "public " : "")
    75             .append(isEnum ? "enum " : isInterface ? "interface " : "class ")
    76             .append(cl).append(" -- ")
    77             .append(isMember? "member " : "" )
    78             .append(isLocal? "local " : "" )
    79             .append(isAnon ?  "anon" : "")
    80             .append("\n");
    82         for (Constructor c : clazz.getDeclaredConstructors()) {
    83             testConstructor(c);
    84         }
    86         for (Method m :clazz.getDeclaredMethods()) {
    88             testMethod(m);
    89         }
    90     }
    92     void testConstructor(Constructor c) {
    94         String prefix = clazz.getName() + "." + c.getName() + "() - ";
    96         // Parameters must match parameter types
    97         Parameter params[] = c.getParameters();
    98         int paramTypes =  c.getParameterTypes().length;
    99         if (paramTypes != params.length) {
   100             error(prefix + "number of parameter types (" + paramTypes
   101                   + ") != number of parameters (" + params.length + ")");
   102             return;
   103         }
   105         sb.append(clazz.getName()).append(".").append("<init>").append("(");
   106         String sep = "";
   108         // Some paramters are expected
   109         if (params.length < 2 && isEnum) {
   110             error(prefix + "enum constuctor, two arguments expected");
   111         } else if (params.length < 1 && (isAnon || isLocal ||
   112                                          (isMember && !isStatic ))) {
   113             error(prefix + "class constuctor,expected implicit argument");
   114         }
   116         int i = -1;
   117         String param = null;
   118         for (Parameter p : c.getParameters()) {
   119             i++;
   120             String pname = p.getName();
   121             sb.append(sep).append(pname);
   122             if (p.isImplicit()) sb.append("!");
   123             if (p.isSynthetic()) sb.append("!!");
   124             sep = ", ";
   126             // Set expectations
   127             String expect = null;
   128             boolean allowImplicit = false;
   129             boolean allowSynthetic = false;
   130             if (isEnum) {
   131                 if (i == 0) {
   132                     expect = "\\$enum\\$name";
   133                     allowSynthetic = true;
   134                 } else if(i == 1) {
   135                     expect = "\\$enum\\$ordinal";
   136                     allowSynthetic = true;
   137                 }
   138             } else if (i == 0) {
   139                 if (isAnon) {
   140                     allowImplicit = true;
   141                 } else if (isLocal) {
   142                     allowImplicit = true;
   143                     expect = "this\\$[0-n]*";
   144                 } else if ((isMember && !isStatic)) {
   145                     allowImplicit = true;
   146                     if (!isPublic) {
   147                         // some but not all non-public inner classes
   148                         // have synthetic argument. For now we give
   149                         // the test a bit of slack and allow either.
   150                         allowSynthetic = true;
   151                     }
   152                     expect = "this\\$[0-n]*";
   153                 }
   154             } else if (isAnon) {
   155                 // not an implementation gurantee, but okay for now
   156                 expect = "x[0-n]*";
   157             }
   159             // Check expected flags
   160             if (p.isSynthetic() && p.isImplicit()) {
   161                 error(prefix + "param[" + i + "]='" + pname +
   162                       "' both isImplicit() and isSynthetic()");
   163                 break;
   164             }
   165             if (allowImplicit && allowSynthetic &&
   166                 !(p.isSynthetic() || p.isImplicit())) {
   167                 error(prefix + "param[" + i + "]='" + pname +
   168                       "' isImplicit() or isSynthetic() expected");
   169                 break;
   170             }
   172             if (allowImplicit && !allowSynthetic && !p.isImplicit()) {
   173                 error(prefix + "param[" + i + "]='" + pname +
   174                       "' isImplicit() expected");
   175                 break;
   176             }
   177             if (!allowImplicit && allowSynthetic && !p.isSynthetic()) {
   178                 error(prefix + "param[" + i + "]='" + pname +
   179                       "' isSynthetic() expected");
   180                 break;
   181             }
   183             if (!allowImplicit && p.isImplicit()) {
   184                 error(prefix + "param[" + i + "]='" + pname +
   185                       "' isImplicit() unexpected");
   186                 break;
   187             }
   189             if (!allowSynthetic && p.isSynthetic()) {
   190                 error(prefix + "param[" + i + "]='" + pname +
   191                       "' isSynthetic() unexpected");
   192                 break;
   193             }
   195             // Check expected names
   196             if (expect != null) {
   197                 if (pname.matches(expect))  continue;
   198                 error(prefix + "param[" + i + "]='" + pname +
   199                       "' expected '" + expect + "'");
   200                 break;
   201             }
   203             // Test naming convention for explicit parameters.
   204             boolean fidelity = !isAnon;
   205             if (param != null && fidelity) {
   206                 char ch = param.charAt(0);
   207                 expect =  (++ch) + param;
   208             }
   210             if (pname != null && fidelity) {
   211                 param = pname;
   212             }
   214             if (expect != null && !expect.equals(pname)) {
   215                 error(prefix + "param[" + i + "]='" + pname +
   216                       "' expected '" + expect + "'");
   217                 break;
   218             }
   219         }
   220         if  (c.isSynthetic()) {
   221             sb.append(")!!\n");
   222         } else {
   223             sb.append(")\n");
   224         }
   225     }
   227     void testMethod(Method m) {
   229         String prefix = clazz.getName() + "." + m.getName() + "() - ";
   231         // Parameters must match parameter types
   232         int paramTypes =  m.getParameterTypes().length;
   233         int params = m.getParameters().length;
   234         if (paramTypes != params) {
   235             error(prefix + "number of parameter types (" + paramTypes
   236                   + ") != number of parameters (" + params + ")");
   237             return;
   238         }
   240         sb.append(clazz.getName()).append(".").append(m.getName()).append("(");
   241         String sep = "";
   242         String param = null;
   243         int i = -1;
   244         // For methods we expect all parameters to follow
   245         // the test-case design pattern, except synthetic methods.
   246         for (Parameter p : m.getParameters()) {
   247             i++;
   248             if (param == null) {
   249                 param = p.getName();
   250                 sb.append(sep).append(param);
   251             } else  {
   252                 char c = param.charAt(0);
   253                 String expect =  m.isSynthetic() ? ("arg" + i) : ((++c) + param);
   254                 param = p.getName();
   255                 sb.append(sep).append(param);
   256                 if (!expect.equals(param)) {
   257                     error(prefix + "param[" + i + "]='"
   258                           + param + "' expected '" + expect + "'");
   259                     break;
   260                 }
   261             }
   262             sep = ", ";
   263         }
   264         if  (m.isSynthetic()) {
   265             sb.append(")!!\n");
   266         } else {
   267             sb.append(")\n");
   268         }
   269     }
   270 }

mercurial