author | sogoel |
Thu, 05 Jun 2014 10:57:10 -0700 | |
changeset 24797 | 850ebd4d80a7 |
parent 21044 | ffba9cdeff1a |
child 28452 | 6afa05455443 |
permissions | -rw-r--r-- |
16307 | 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 |
*/ |
|
23 |
||
18000
5d29ce00a7a2
6695379: Copy method annotations and parameter annotations to synthetic bridge methods
vromero
parents:
17999
diff
changeset
|
24 |
import java.io.*; |
16307 | 25 |
import com.sun.tools.classfile.*; |
26 |
||
27 |
/** |
|
28 |
* The {@code ClassFileVisitor} reads a class file using the |
|
29 |
* {@code com.sun.tools.classfile} library. It iterates over the methods |
|
30 |
* in a class, and checks MethodParameters attributes against JLS |
|
31 |
* requirements, as well as assumptions about the javac implementations. |
|
32 |
* <p> |
|
33 |
* It enforces the following rules: |
|
34 |
* <ul> |
|
35 |
* <li>All non-synthetic methods with arguments must have the |
|
36 |
* MethodParameters attribute. </li> |
|
37 |
* <li>At most one MethodParameters attribute per method.</li> |
|
38 |
* <li>An empty MethodParameters attribute is not allowed (i.e. no |
|
39 |
* attribute for methods taking no parameters).</li> |
|
40 |
* <li>The number of recorded parameter names much equal the number |
|
41 |
* of parameters, including any implicit or synthetic parameters generated |
|
42 |
* by the compiler.</li> |
|
43 |
* <li>Although the spec allow recording parameters with no name, the javac |
|
44 |
* implementation is assumed to record a name for all parameters. That is, |
|
45 |
* the Methodparameters attribute must record a non-zero, valid constant |
|
46 |
* pool index for each parameter.</li> |
|
47 |
* <li>Check presence, expected names (e.g. this$N, $enum$name, ...) and flags |
|
48 |
* (e.g. ACC_SYNTHETIC, ACC_MANDATED) for compiler generated parameters.</li> |
|
49 |
* <li>Names of explicit parameters must reflect the names in the Java source. |
|
50 |
* This is checked by assuming a design pattern where any name is permitted |
|
51 |
* for the first explicit parameter. For subsequent parameters the following |
|
52 |
* rule is checked: <i>param[n] == ++param[n-1].charAt(0) + param[n-1]</i> |
|
53 |
* </ul> |
|
54 |
*/ |
|
55 |
class ClassFileVisitor extends Tester.Visitor { |
|
56 |
||
57 |
Tester tester; |
|
58 |
||
59 |
public String cname; |
|
60 |
public boolean isEnum; |
|
61 |
public boolean isInterface; |
|
62 |
public boolean isInner; |
|
63 |
public boolean isPublic; |
|
64 |
public boolean isStatic; |
|
65 |
public boolean isAnon; |
|
66 |
public ClassFile classFile; |
|
67 |
||
68 |
||
69 |
public ClassFileVisitor(Tester tester) { |
|
70 |
super(tester); |
|
71 |
} |
|
72 |
||
73 |
public void error(String msg) { |
|
74 |
super.error("classfile: " + msg); |
|
75 |
} |
|
76 |
||
77 |
public void warn(String msg) { |
|
78 |
super.warn("classfile: " + msg); |
|
79 |
} |
|
80 |
||
81 |
/** |
|
82 |
* Read the class and determine some key characteristics, like if it's |
|
83 |
* an enum, or inner class, etc. |
|
84 |
*/ |
|
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
85 |
void visitClass(final String cname, final File cfile, final StringBuilder sb) throws Exception { |
16307 | 86 |
this.cname = cname; |
87 |
classFile = ClassFile.read(cfile); |
|
88 |
isEnum = classFile.access_flags.is(AccessFlags.ACC_ENUM); |
|
89 |
isInterface = classFile.access_flags.is(AccessFlags.ACC_INTERFACE); |
|
90 |
isPublic = classFile.access_flags.is(AccessFlags.ACC_PUBLIC); |
|
91 |
isInner = false; |
|
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
92 |
isStatic = false; |
16307 | 93 |
isAnon = false; |
94 |
||
95 |
Attribute attr = classFile.getAttribute("InnerClasses"); |
|
96 |
if (attr != null) attr.accept(new InnerClassVisitor(), null); |
|
97 |
isAnon = isInner & isAnon; |
|
98 |
||
99 |
sb.append(isStatic ? "static " : "") |
|
100 |
.append(isPublic ? "public " : "") |
|
101 |
.append(isEnum ? "enum " : isInterface ? "interface " : "class ") |
|
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
102 |
.append(cname).append(" -- "); |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
103 |
if (isInner) { |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
104 |
sb.append(isAnon ? "anon" : "inner"); |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
105 |
} |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
106 |
sb.append("\n"); |
16307 | 107 |
|
108 |
for (Method method : classFile.methods) { |
|
109 |
new MethodVisitor().visitMethod(method, sb); |
|
110 |
} |
|
111 |
} |
|
112 |
||
113 |
/** |
|
114 |
* Used to visit InnerClasses_attribute of a class, |
|
115 |
* to determne if this class is an local class, and anonymous |
|
116 |
* inner class or a none-static member class. These types of |
|
117 |
* classes all have an containing class instances field that |
|
118 |
* requires an implicit or synthetic constructor argument. |
|
119 |
*/ |
|
120 |
class InnerClassVisitor extends AttributeVisitor<Void, Void> { |
|
121 |
public Void visitInnerClasses(InnerClasses_attribute iattr, Void v) { |
|
122 |
try{ |
|
123 |
for (InnerClasses_attribute.Info info : iattr.classes) { |
|
124 |
if (info.getInnerClassInfo(classFile.constant_pool) == null) continue; |
|
125 |
String in = info.getInnerClassInfo(classFile.constant_pool).getName(); |
|
126 |
if (in == null || !cname.equals(in)) continue; |
|
127 |
isInner = true; |
|
128 |
isAnon = null == info.getInnerName(classFile.constant_pool); |
|
129 |
isStatic = info.inner_class_access_flags.is(AccessFlags.ACC_STATIC); |
|
130 |
break; |
|
131 |
} |
|
132 |
} catch(Exception e) { |
|
133 |
throw new IllegalStateException(e); |
|
134 |
} |
|
135 |
return null; |
|
136 |
} |
|
137 |
} |
|
138 |
||
139 |
/** |
|
140 |
* Check the MethodParameters attribute of a method. |
|
141 |
*/ |
|
142 |
class MethodVisitor extends AttributeVisitor<Void, StringBuilder> { |
|
143 |
||
144 |
public String mName; |
|
145 |
public Descriptor mDesc; |
|
146 |
public int mParams; |
|
147 |
public int mAttrs; |
|
148 |
public int mNumParams; |
|
149 |
public boolean mSynthetic; |
|
150 |
public boolean mIsConstructor; |
|
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
151 |
public boolean mIsClinit; |
18000
5d29ce00a7a2
6695379: Copy method annotations and parameter annotations to synthetic bridge methods
vromero
parents:
17999
diff
changeset
|
152 |
public boolean mIsBridge; |
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
153 |
public boolean isFinal; |
16307 | 154 |
public String prefix; |
155 |
||
156 |
void visitMethod(Method method, StringBuilder sb) throws Exception { |
|
157 |
||
158 |
mName = method.getName(classFile.constant_pool); |
|
159 |
mDesc = method.descriptor; |
|
160 |
mParams = mDesc.getParameterCount(classFile.constant_pool); |
|
161 |
mAttrs = method.attributes.attrs.length; |
|
162 |
mNumParams = -1; // no MethodParameters attribute found |
|
163 |
mSynthetic = method.access_flags.is(AccessFlags.ACC_SYNTHETIC); |
|
164 |
mIsConstructor = mName.equals("<init>"); |
|
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
165 |
mIsClinit = mName.equals("<clinit>"); |
16307 | 166 |
prefix = cname + "." + mName + "() - "; |
18000
5d29ce00a7a2
6695379: Copy method annotations and parameter annotations to synthetic bridge methods
vromero
parents:
17999
diff
changeset
|
167 |
mIsBridge = method.access_flags.is(AccessFlags.ACC_BRIDGE); |
16307 | 168 |
|
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
169 |
if (mIsClinit) { |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
170 |
sb = new StringBuilder(); // Discard output |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
171 |
} |
16307 | 172 |
sb.append(cname).append(".").append(mName).append("("); |
173 |
||
174 |
for (Attribute a : method.attributes) { |
|
175 |
a.accept(this, sb); |
|
176 |
} |
|
177 |
if (mNumParams == -1) { |
|
178 |
if (mSynthetic) { |
|
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
179 |
// We don't generate MethodParameters attribute for synthetic |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
180 |
// methods, so we are creating a parameter pattern to match |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
181 |
// ReflectionVisitor API output. |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
182 |
for (int i = 0; i < mParams; i++) { |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
183 |
if (i == 0) |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
184 |
sb.append("arg").append(i); |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
185 |
else |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
186 |
sb.append(", arg").append(i); |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
187 |
} |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
188 |
sb.append(")/*synthetic*/"); |
16307 | 189 |
} else { |
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
190 |
sb.append(")"); |
16307 | 191 |
} |
192 |
} |
|
193 |
sb.append("\n"); |
|
194 |
||
195 |
// IMPL: methods with arguments must have a MethodParameters |
|
196 |
// attribute, except possibly some synthetic methods. |
|
197 |
if (mNumParams == -1 && mParams > 0 && ! mSynthetic) { |
|
198 |
error(prefix + "missing MethodParameters attribute"); |
|
199 |
} |
|
200 |
} |
|
201 |
||
202 |
public Void visitMethodParameters(MethodParameters_attribute mp, |
|
203 |
StringBuilder sb) { |
|
204 |
||
205 |
// SPEC: At most one MethodParameters attribute allowed |
|
206 |
if (mNumParams != -1) { |
|
207 |
error(prefix + "Multiple MethodParameters attributes"); |
|
208 |
return null; |
|
209 |
} |
|
210 |
||
211 |
mNumParams = mp.method_parameter_table_length; |
|
212 |
||
213 |
// SPEC: An empty attribute is not allowed! |
|
214 |
if (mNumParams == 0) { |
|
215 |
error(prefix + "0 length MethodParameters attribute"); |
|
216 |
return null; |
|
217 |
} |
|
218 |
||
219 |
// SPEC: one name per parameter. |
|
220 |
if (mNumParams != mParams) { |
|
221 |
error(prefix + "found " + mNumParams + |
|
222 |
" parameters, expected " + mParams); |
|
223 |
return null; |
|
224 |
} |
|
225 |
||
226 |
// IMPL: Whether MethodParameters attributes will be generated |
|
227 |
// for some synthetics is unresolved. For now, assume no. |
|
228 |
if (mSynthetic) { |
|
229 |
warn(prefix + "synthetic has MethodParameter attribute"); |
|
230 |
} |
|
231 |
||
232 |
String sep = ""; |
|
233 |
String userParam = null; |
|
234 |
for (int x = 0; x < mNumParams; x++) { |
|
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
235 |
isFinal = (mp.method_parameter_table[x].flags & AccessFlags.ACC_FINAL) != 0; |
16307 | 236 |
// IMPL: Assume all parameters are named, something. |
237 |
int cpi = mp.method_parameter_table[x].name_index; |
|
238 |
if (cpi == 0) { |
|
239 |
error(prefix + "name expected, param[" + x + "]"); |
|
240 |
return null; |
|
241 |
} |
|
242 |
||
243 |
// SPEC: a non 0 index, must be valid! |
|
244 |
String param = null; |
|
245 |
try { |
|
246 |
param = classFile.constant_pool.getUTF8Value(cpi); |
|
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
247 |
if (isFinal) |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
248 |
param = "final " + param; |
16307 | 249 |
sb.append(sep).append(param); |
250 |
sep = ", "; |
|
251 |
} catch(ConstantPoolException e) { |
|
252 |
error(prefix + "invalid index " + cpi + " for param[" |
|
253 |
+ x + "]"); |
|
254 |
return null; |
|
255 |
} |
|
256 |
||
257 |
||
258 |
// Check availability, flags and special names |
|
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
259 |
int check = checkParam(mp, param, x, sb, isFinal); |
16307 | 260 |
if (check < 0) { |
261 |
return null; |
|
262 |
} |
|
263 |
||
264 |
// TEST: check test assumptions about parameter name. |
|
265 |
// Expected names are calculated starting with the |
|
266 |
// 2nd explicit (user given) parameter. |
|
267 |
// param[n] == ++param[n-1].charAt(0) + param[n-1] |
|
268 |
String expect = null; |
|
269 |
if (userParam != null) { |
|
270 |
char c = userParam.charAt(0); |
|
271 |
expect = (++c) + userParam; |
|
272 |
} |
|
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
273 |
if(isFinal && expect != null) |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
274 |
expect = "final " + expect; |
16307 | 275 |
if (check > 0) { |
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
276 |
if(isFinal) { |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
277 |
userParam = param.substring(6); |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
278 |
} else { |
16307 | 279 |
userParam = param; |
280 |
} |
|
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
281 |
} |
16307 | 282 |
if (expect != null && !param.equals(expect)) { |
283 |
error(prefix + "param[" + x + "]='" |
|
284 |
+ param + "' expected '" + expect + "'"); |
|
285 |
return null; |
|
286 |
} |
|
287 |
} |
|
288 |
if (mSynthetic) { |
|
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
289 |
sb.append(")/*synthetic*/"); |
16307 | 290 |
} else { |
291 |
sb.append(")"); |
|
292 |
} |
|
293 |
return null; |
|
294 |
} |
|
295 |
||
296 |
/* |
|
297 |
* Check a parameter for conformity to JLS and javac specific |
|
298 |
* assumptions. |
|
299 |
* Return -1, if an error is detected. Otherwise, return 0, if |
|
300 |
* the parameter is compiler generated, or 1 for an (presumably) |
|
301 |
* explicitly declared parameter. |
|
302 |
*/ |
|
303 |
int checkParam(MethodParameters_attribute mp, String param, int index, |
|
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
304 |
StringBuilder sb, boolean isFinal) { |
16307 | 305 |
|
306 |
boolean synthetic = (mp.method_parameter_table[index].flags |
|
307 |
& AccessFlags.ACC_SYNTHETIC) != 0; |
|
308 |
boolean mandated = (mp.method_parameter_table[index].flags |
|
309 |
& AccessFlags.ACC_MANDATED) != 0; |
|
310 |
||
311 |
// Setup expectations for flags and special names |
|
312 |
String expect = null; |
|
313 |
boolean allowMandated = false; |
|
314 |
boolean allowSynthetic = false; |
|
315 |
if (mSynthetic || synthetic) { |
|
316 |
// not an implementation gurantee, but okay for now |
|
317 |
expect = "arg" + index; // default |
|
318 |
} |
|
319 |
if (mIsConstructor) { |
|
320 |
if (isEnum) { |
|
321 |
if (index == 0) { |
|
322 |
expect = "\\$enum\\$name"; |
|
323 |
allowSynthetic = true; |
|
324 |
} else if(index == 1) { |
|
325 |
expect = "\\$enum\\$ordinal"; |
|
326 |
allowSynthetic = true; |
|
327 |
} |
|
328 |
} else if (index == 0) { |
|
329 |
if (isAnon) { |
|
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
330 |
expect = "this\\$[0-9]+"; |
16307 | 331 |
allowMandated = true; |
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
332 |
if (isFinal) { |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
333 |
expect = "final this\\$[0-9]+"; |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
334 |
} |
16307 | 335 |
} else if (isInner && !isStatic) { |
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
336 |
expect = "this\\$[0-9]+"; |
16307 | 337 |
allowMandated = true; |
338 |
if (!isPublic) { |
|
339 |
// some but not all non-public inner classes |
|
340 |
// have synthetic argument. For now we give |
|
341 |
// the test a bit of slack and allow either. |
|
342 |
allowSynthetic = true; |
|
343 |
} |
|
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
344 |
if (isFinal) { |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
345 |
expect = "final this\\$[0-9]+"; |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
346 |
} |
16307 | 347 |
} |
348 |
} |
|
349 |
} else if (isEnum && mNumParams == 1 && index == 0 && mName.equals("valueOf")) { |
|
350 |
expect = "name"; |
|
351 |
allowMandated = true; |
|
18000
5d29ce00a7a2
6695379: Copy method annotations and parameter annotations to synthetic bridge methods
vromero
parents:
17999
diff
changeset
|
352 |
} else if (mIsBridge) { |
5d29ce00a7a2
6695379: Copy method annotations and parameter annotations to synthetic bridge methods
vromero
parents:
17999
diff
changeset
|
353 |
allowSynthetic = true; |
5d29ce00a7a2
6695379: Copy method annotations and parameter annotations to synthetic bridge methods
vromero
parents:
17999
diff
changeset
|
354 |
/* you can't expect an special name for bridges' parameters. |
5d29ce00a7a2
6695379: Copy method annotations and parameter annotations to synthetic bridge methods
vromero
parents:
17999
diff
changeset
|
355 |
* The name of the original parameters are now copied. |
5d29ce00a7a2
6695379: Copy method annotations and parameter annotations to synthetic bridge methods
vromero
parents:
17999
diff
changeset
|
356 |
*/ |
5d29ce00a7a2
6695379: Copy method annotations and parameter annotations to synthetic bridge methods
vromero
parents:
17999
diff
changeset
|
357 |
expect = null; |
16307 | 358 |
} |
21044
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
359 |
if (mandated) sb.append("/*implicit*/"); |
ffba9cdeff1a
8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final
mnunez
parents:
18000
diff
changeset
|
360 |
if (synthetic) sb.append("/*synthetic*/"); |
16307 | 361 |
|
362 |
// IMPL: our rules a somewhat fuzzy, sometimes allowing both mandated |
|
363 |
// and synthetic. However, a parameters cannot be both. |
|
364 |
if (mandated && synthetic) { |
|
365 |
error(prefix + "param[" + index + "] == \"" + param |
|
366 |
+ "\" ACC_SYNTHETIC and ACC_MANDATED"); |
|
367 |
return -1; |
|
368 |
} |
|
369 |
// ... but must be either, if both "allowed". |
|
370 |
if (!(mandated || synthetic) && allowMandated && allowSynthetic) { |
|
371 |
error(prefix + "param[" + index + "] == \"" + param |
|
372 |
+ "\" expected ACC_MANDATED or ACC_SYNTHETIC"); |
|
373 |
return -1; |
|
374 |
} |
|
375 |
||
376 |
// ... if only one is "allowed", we meant "required". |
|
377 |
if (!mandated && allowMandated && !allowSynthetic) { |
|
378 |
error(prefix + "param[" + index + "] == \"" + param |
|
379 |
+ "\" expected ACC_MANDATED"); |
|
380 |
return -1; |
|
381 |
} |
|
382 |
if (!synthetic && !allowMandated && allowSynthetic) { |
|
383 |
error(prefix + "param[" + index + "] == \"" + param |
|
384 |
+ "\" expected ACC_SYNTHETIC"); |
|
385 |
return -1; |
|
386 |
} |
|
387 |
||
388 |
// ... and not "allowed", means prohibited. |
|
389 |
if (mandated && !allowMandated) { |
|
390 |
error(prefix + "param[" + index + "] == \"" + param |
|
391 |
+ "\" unexpected, is ACC_MANDATED"); |
|
392 |
return -1; |
|
393 |
} |
|
394 |
if (synthetic && !allowSynthetic) { |
|
395 |
error(prefix + "param[" + index + "] == \"" + param |
|
396 |
+ "\" unexpected, is ACC_SYNTHETIC"); |
|
397 |
return -1; |
|
398 |
} |
|
399 |
||
400 |
// Test special name expectations |
|
401 |
if (expect != null) { |
|
402 |
if (param.matches(expect)) { |
|
403 |
return 0; |
|
404 |
} |
|
405 |
error(prefix + "param[" + index + "]='" + param + |
|
406 |
"' expected '" + expect + "'"); |
|
407 |
return -1; |
|
408 |
} |
|
409 |
||
410 |
// No further checking for synthetic methods. |
|
411 |
if (mSynthetic) { |
|
412 |
return 0; |
|
413 |
} |
|
414 |
||
415 |
// Otherwise, do check test parameter naming convention. |
|
416 |
return 1; |
|
417 |
} |
|
418 |
} |
|
419 |
} |