strarup@1594: /* strarup@1594: * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. strarup@1594: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. strarup@1594: * strarup@1594: * This code is free software; you can redistribute it and/or modify it strarup@1594: * under the terms of the GNU General Public License version 2 only, as strarup@1594: * published by the Free Software Foundation. strarup@1594: * strarup@1594: * This code is distributed in the hope that it will be useful, but WITHOUT strarup@1594: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or strarup@1594: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License strarup@1594: * version 2 for more details (a copy is included in the LICENSE file that strarup@1594: * accompanied this code). strarup@1594: * strarup@1594: * You should have received a copy of the GNU General Public License version strarup@1594: * 2 along with this work; if not, write to the Free Software Foundation, strarup@1594: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. strarup@1594: * strarup@1594: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA strarup@1594: * or visit www.oracle.com if you need additional information or have any strarup@1594: * questions. strarup@1594: */ strarup@1594: strarup@1594: import java.io.*; strarup@1594: import java.util.*; strarup@1594: import java.net.*; strarup@1594: import java.lang.reflect.*; strarup@1594: strarup@1594: /** strarup@1594: * Test MethodParameter attributs by reflection API strarup@1594: */ strarup@1594: public class ReflectionVisitor extends Tester.Visitor { strarup@1594: strarup@1594: public ReflectionVisitor(Tester tester) { strarup@1594: super(tester); strarup@1594: } strarup@1594: strarup@1594: public void error(String msg) { strarup@1594: super.error("reflection: " + msg); strarup@1594: } strarup@1594: strarup@1594: public void warn(String msg) { strarup@1594: super.warn("reflection: " + msg); strarup@1594: } strarup@1594: strarup@1594: boolean isEnum; strarup@1594: boolean isInterface; strarup@1594: boolean isAnon; strarup@1594: boolean isLocal; strarup@1594: boolean isMember; strarup@1594: boolean isStatic; strarup@1594: boolean isPublic; strarup@1594: Class clazz; strarup@1594: StringBuilder sb; strarup@1594: strarup@1594: /** strarup@1594: * Read class using {@code ClassFile}, and generate a list of methods strarup@1594: * with parameter names as available in the MethodParameters attribute. strarup@1594: */ strarup@1594: void visitClass(final String cl, final File cfile, final StringBuilder sb) strarup@1594: throws Exception { strarup@1594: strarup@1594: this.sb = sb; strarup@1594: clazz = Class.forName(cl); strarup@1594: isEnum = clazz.isEnum(); strarup@1594: isInterface = clazz.isInterface(); strarup@1594: isAnon = clazz.isAnonymousClass(); strarup@1594: isLocal = clazz.isLocalClass(); strarup@1594: isMember = clazz.isMemberClass(); strarup@1594: isStatic = ((clazz.getModifiers() & Modifier.STATIC) != 0); strarup@1594: isPublic = ((clazz.getModifiers() & Modifier.PUBLIC) != 0); strarup@1594: strarup@1594: sb.append(isStatic ? "static " : "") strarup@1594: .append(isPublic ? "public " : "") strarup@1594: .append(isEnum ? "enum " : isInterface ? "interface " : "class ") strarup@1594: .append(cl).append(" -- ") strarup@1594: .append(isMember? "member " : "" ) strarup@1594: .append(isLocal? "local " : "" ) strarup@1594: .append(isAnon ? "anon" : "") strarup@1594: .append("\n"); strarup@1594: strarup@1594: for (Constructor c : clazz.getDeclaredConstructors()) { strarup@1594: testConstructor(c); strarup@1594: } strarup@1594: strarup@1594: for (Method m :clazz.getDeclaredMethods()) { strarup@1594: strarup@1594: testMethod(m); strarup@1594: } strarup@1594: } strarup@1594: strarup@1594: void testConstructor(Constructor c) { strarup@1594: strarup@1594: String prefix = clazz.getName() + "." + c.getName() + "() - "; strarup@1594: strarup@1594: // Parameters must match parameter types strarup@1594: Parameter params[] = c.getParameters(); strarup@1594: int paramTypes = c.getParameterTypes().length; strarup@1594: if (paramTypes != params.length) { strarup@1594: error(prefix + "number of parameter types (" + paramTypes strarup@1594: + ") != number of parameters (" + params.length + ")"); strarup@1594: return; strarup@1594: } strarup@1594: strarup@1594: sb.append(clazz.getName()).append(".").append("").append("("); strarup@1594: String sep = ""; strarup@1594: strarup@1594: // Some paramters are expected strarup@1594: if (params.length < 2 && isEnum) { strarup@1594: error(prefix + "enum constuctor, two arguments expected"); strarup@1594: } else if (params.length < 1 && (isAnon || isLocal || strarup@1594: (isMember && !isStatic ))) { strarup@1594: error(prefix + "class constuctor,expected implicit argument"); strarup@1594: } strarup@1594: strarup@1594: int i = -1; strarup@1594: String param = null; strarup@1594: for (Parameter p : c.getParameters()) { strarup@1594: i++; strarup@1594: String pname = p.getName(); strarup@1594: sb.append(sep).append(pname); strarup@1594: if (p.isImplicit()) sb.append("!"); strarup@1594: if (p.isSynthetic()) sb.append("!!"); strarup@1594: sep = ", "; strarup@1594: strarup@1594: // Set expectations strarup@1594: String expect = null; strarup@1594: boolean allowImplicit = false; strarup@1594: boolean allowSynthetic = false; strarup@1594: if (isEnum) { strarup@1594: if (i == 0) { strarup@1594: expect = "\\$enum\\$name"; strarup@1594: allowSynthetic = true; strarup@1594: } else if(i == 1) { strarup@1594: expect = "\\$enum\\$ordinal"; strarup@1594: allowSynthetic = true; strarup@1594: } strarup@1594: } else if (i == 0) { strarup@1594: if (isAnon) { strarup@1594: allowImplicit = true; strarup@1594: } else if (isLocal) { strarup@1594: allowImplicit = true; strarup@1594: expect = "this\\$[0-n]*"; strarup@1594: } else if ((isMember && !isStatic)) { strarup@1594: allowImplicit = true; strarup@1594: if (!isPublic) { strarup@1594: // some but not all non-public inner classes strarup@1594: // have synthetic argument. For now we give strarup@1594: // the test a bit of slack and allow either. strarup@1594: allowSynthetic = true; strarup@1594: } strarup@1594: expect = "this\\$[0-n]*"; strarup@1594: } strarup@1594: } else if (isAnon) { strarup@1594: // not an implementation gurantee, but okay for now strarup@1594: expect = "x[0-n]*"; strarup@1594: } strarup@1594: strarup@1594: // Check expected flags strarup@1594: if (p.isSynthetic() && p.isImplicit()) { strarup@1594: error(prefix + "param[" + i + "]='" + pname + strarup@1594: "' both isImplicit() and isSynthetic()"); strarup@1594: break; strarup@1594: } strarup@1594: if (allowImplicit && allowSynthetic && strarup@1594: !(p.isSynthetic() || p.isImplicit())) { strarup@1594: error(prefix + "param[" + i + "]='" + pname + strarup@1594: "' isImplicit() or isSynthetic() expected"); strarup@1594: break; strarup@1594: } strarup@1594: strarup@1594: if (allowImplicit && !allowSynthetic && !p.isImplicit()) { strarup@1594: error(prefix + "param[" + i + "]='" + pname + strarup@1594: "' isImplicit() expected"); strarup@1594: break; strarup@1594: } strarup@1594: if (!allowImplicit && allowSynthetic && !p.isSynthetic()) { strarup@1594: error(prefix + "param[" + i + "]='" + pname + strarup@1594: "' isSynthetic() expected"); strarup@1594: break; strarup@1594: } strarup@1594: strarup@1594: if (!allowImplicit && p.isImplicit()) { strarup@1594: error(prefix + "param[" + i + "]='" + pname + strarup@1594: "' isImplicit() unexpected"); strarup@1594: break; strarup@1594: } strarup@1594: strarup@1594: if (!allowSynthetic && p.isSynthetic()) { strarup@1594: error(prefix + "param[" + i + "]='" + pname + strarup@1594: "' isSynthetic() unexpected"); strarup@1594: break; strarup@1594: } strarup@1594: strarup@1594: // Check expected names strarup@1594: if (expect != null) { strarup@1594: if (pname.matches(expect)) continue; strarup@1594: error(prefix + "param[" + i + "]='" + pname + strarup@1594: "' expected '" + expect + "'"); strarup@1594: break; strarup@1594: } strarup@1594: strarup@1594: // Test naming convention for explicit parameters. strarup@1594: boolean fidelity = !isAnon; strarup@1594: if (param != null && fidelity) { strarup@1594: char ch = param.charAt(0); strarup@1594: expect = (++ch) + param; strarup@1594: } strarup@1594: strarup@1594: if (pname != null && fidelity) { strarup@1594: param = pname; strarup@1594: } strarup@1594: strarup@1594: if (expect != null && !expect.equals(pname)) { strarup@1594: error(prefix + "param[" + i + "]='" + pname + strarup@1594: "' expected '" + expect + "'"); strarup@1594: break; strarup@1594: } strarup@1594: } strarup@1594: if (c.isSynthetic()) { strarup@1594: sb.append(")!!\n"); strarup@1594: } else { strarup@1594: sb.append(")\n"); strarup@1594: } strarup@1594: } strarup@1594: strarup@1594: void testMethod(Method m) { strarup@1594: strarup@1594: String prefix = clazz.getName() + "." + m.getName() + "() - "; strarup@1594: strarup@1594: // Parameters must match parameter types strarup@1594: int paramTypes = m.getParameterTypes().length; strarup@1594: int params = m.getParameters().length; strarup@1594: if (paramTypes != params) { strarup@1594: error(prefix + "number of parameter types (" + paramTypes strarup@1594: + ") != number of parameters (" + params + ")"); strarup@1594: return; strarup@1594: } strarup@1594: strarup@1594: sb.append(clazz.getName()).append(".").append(m.getName()).append("("); strarup@1594: String sep = ""; strarup@1594: String param = null; strarup@1594: int i = -1; strarup@1594: // For methods we expect all parameters to follow strarup@1594: // the test-case design pattern, except synthetic methods. strarup@1594: for (Parameter p : m.getParameters()) { strarup@1594: i++; strarup@1594: if (param == null) { strarup@1594: param = p.getName(); strarup@1594: sb.append(sep).append(param); strarup@1594: } else { strarup@1594: char c = param.charAt(0); strarup@1594: String expect = m.isSynthetic() ? ("arg" + i) : ((++c) + param); strarup@1594: param = p.getName(); strarup@1594: sb.append(sep).append(param); strarup@1594: if (!expect.equals(param)) { strarup@1594: error(prefix + "param[" + i + "]='" strarup@1594: + param + "' expected '" + expect + "'"); strarup@1594: break; strarup@1594: } strarup@1594: } strarup@1594: sep = ", "; strarup@1594: } strarup@1594: if (m.isSynthetic()) { strarup@1594: sb.append(")!!\n"); strarup@1594: } else { strarup@1594: sb.append(")\n"); strarup@1594: } strarup@1594: } strarup@1594: }