Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/tools/java/MemberDefinition.java
38918 views
1
/*
2
* Copyright (c) 1994, 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.tools.java;
27
28
import sun.tools.tree.Node;
29
import sun.tools.tree.Vset;
30
import sun.tools.tree.Expression;
31
import sun.tools.tree.Statement;
32
import sun.tools.tree.Context;
33
import sun.tools.asm.Assembler;
34
import java.io.PrintStream;
35
import java.util.Vector;
36
import java.util.Map;
37
import java.util.HashMap;
38
39
/**
40
* This class defines a member of a Java class:
41
* a variable, a method, or an inner class.
42
*
43
* WARNING: The contents of this source file are not part of any
44
* supported API. Code that depends on them does so at its own risk:
45
* they are subject to change or removal without notice.
46
*/
47
public
48
class MemberDefinition implements Constants {
49
protected long where;
50
protected int modifiers;
51
protected Type type;
52
protected String documentation;
53
protected IdentifierToken expIds[];
54
protected ClassDeclaration exp[];
55
protected Node value;
56
protected ClassDefinition clazz;
57
protected Identifier name;
58
protected ClassDefinition innerClass;
59
protected MemberDefinition nextMember;
60
protected MemberDefinition nextMatch;
61
protected MemberDefinition accessPeer;
62
protected boolean superAccessMethod;
63
64
/**
65
* Constructor
66
*/
67
public MemberDefinition(long where, ClassDefinition clazz, int modifiers,
68
Type type, Identifier name,
69
IdentifierToken expIds[], Node value) {
70
if (expIds == null) {
71
expIds = new IdentifierToken[0];
72
}
73
this.where = where;
74
this.clazz = clazz;
75
this.modifiers = modifiers;
76
this.type = type;
77
this.name = name;
78
this.expIds = expIds;
79
this.value = value;
80
}
81
82
/**
83
* Constructor for an inner class.
84
* Inner classes are represented as fields right along with
85
* variables and methods for simplicity of data structure,
86
* and to reflect properly the textual declaration order.
87
* <p>
88
* This constructor calls the generic constructor for this
89
* class, extracting all necessary values from the innerClass.
90
*/
91
public MemberDefinition(ClassDefinition innerClass) {
92
this(innerClass.getWhere(),
93
innerClass.getOuterClass(),
94
innerClass.getModifiers(),
95
innerClass.getType(),
96
innerClass.getName().getFlatName().getName(),
97
null, null);
98
this.innerClass = innerClass;
99
}
100
101
/**
102
* A cache of previously created proxy members. Used to ensure
103
* uniqueness of proxy objects. See the makeProxyMember method
104
* defined below.
105
*/
106
static private Map proxyCache;
107
108
/**
109
* Create a member which is externally the same as `field' but
110
* is defined in class `classDef'. This is used by code
111
* in sun.tools.tree.(MethodExpression,FieldExpression) as
112
* part of the fix for bug 4135692.
113
*
114
* Proxy members should not be added, ala addMember(), to classes.
115
* They are merely "stand-ins" to produce modified MethodRef
116
* constant pool entries during code generation.
117
*
118
* We keep a cache of previously created proxy members not to
119
* save time or space, but to ensure uniqueness of the proxy
120
* member for any (field,classDef) pair. If these are not made
121
* unique then we can end up generating duplicate MethodRef
122
* constant pool entries during code generation.
123
*/
124
public static MemberDefinition makeProxyMember(MemberDefinition field,
125
ClassDefinition classDef,
126
Environment env) {
127
128
if (proxyCache == null) {
129
proxyCache = new HashMap();
130
}
131
132
String key = field.toString() + "@" + classDef.toString();
133
// System.out.println("Key is : " + key);
134
MemberDefinition proxy = (MemberDefinition)proxyCache.get(key);
135
136
if (proxy != null)
137
return proxy;
138
139
proxy = new MemberDefinition(field.getWhere(), classDef,
140
field.getModifiers(), field.getType(),
141
field.getName(), field.getExceptionIds(),
142
null);
143
proxy.exp = field.getExceptions(env);
144
proxyCache.put(key, proxy);
145
146
return proxy;
147
}
148
149
/**
150
* Get the position in the input
151
*/
152
public final long getWhere() {
153
return where;
154
}
155
156
/**
157
* Get the class declaration
158
*/
159
public final ClassDeclaration getClassDeclaration() {
160
return clazz.getClassDeclaration();
161
}
162
163
/**
164
* A stub. Subclasses can do more checking.
165
*/
166
public void resolveTypeStructure(Environment env) {
167
}
168
169
/**
170
* Get the class declaration in which the field is actually defined
171
*/
172
public ClassDeclaration getDefiningClassDeclaration() {
173
return getClassDeclaration();
174
}
175
176
/**
177
* Get the class definition
178
*/
179
public final ClassDefinition getClassDefinition() {
180
return clazz;
181
}
182
183
/**
184
* Get the field's top-level enclosing class
185
*/
186
public final ClassDefinition getTopClass() {
187
return clazz.getTopClass();
188
}
189
190
/**
191
* Get the field's modifiers
192
*/
193
public final int getModifiers() {
194
return modifiers;
195
}
196
public final void subModifiers(int mod) {
197
modifiers &= ~mod;
198
}
199
public final void addModifiers(int mod) {
200
modifiers |= mod;
201
}
202
203
/**
204
* Get the field's type
205
*/
206
public final Type getType() {
207
return type;
208
}
209
210
/**
211
* Get the field's name
212
*/
213
public final Identifier getName() {
214
return name;
215
}
216
217
/**
218
* Get arguments (a vector of LocalMember)
219
*/
220
public Vector getArguments() {
221
return isMethod() ? new Vector() : null;
222
}
223
224
/**
225
* Get the exceptions that are thrown by this method.
226
*/
227
public ClassDeclaration[] getExceptions(Environment env) {
228
if (expIds != null && exp == null) {
229
if (expIds.length == 0)
230
exp = new ClassDeclaration[0];
231
else
232
// we should have translated this already!
233
throw new CompilerError("getExceptions "+this);
234
}
235
return exp;
236
}
237
238
public final IdentifierToken[] getExceptionIds() {
239
return expIds;
240
}
241
242
/**
243
* Get an inner class.
244
*/
245
public ClassDefinition getInnerClass() {
246
return innerClass;
247
}
248
249
/**
250
* Is this a synthetic field which holds a copy of,
251
* or reference to, a local variable or enclosing instance?
252
*/
253
public boolean isUplevelValue() {
254
if (!isSynthetic() || !isVariable() || isStatic()) {
255
return false;
256
}
257
String name = this.name.toString();
258
return name.startsWith(prefixVal)
259
|| name.startsWith(prefixLoc)
260
|| name.startsWith(prefixThis);
261
}
262
263
public boolean isAccessMethod() {
264
// This no longer works, because access methods
265
// for constructors do not use the standard naming
266
// scheme.
267
// return isSynthetic() && isMethod()
268
// && name.toString().startsWith(prefixAccess);
269
// Assume that a method is an access method if it has
270
// an access peer. NOTE: An access method will not be
271
// recognized as such until 'setAccessMethodTarget' has
272
// been called on it.
273
return isSynthetic() && isMethod() && (accessPeer != null);
274
}
275
276
/**
277
* Is this a synthetic method which provides access to a
278
* visible private member?
279
*/
280
public MemberDefinition getAccessMethodTarget() {
281
if (isAccessMethod()) {
282
for (MemberDefinition f = accessPeer; f != null; f = f.accessPeer) {
283
// perhaps skip over another access for the same field
284
if (!f.isAccessMethod()) {
285
return f;
286
}
287
}
288
}
289
return null;
290
}
291
292
293
public void setAccessMethodTarget(MemberDefinition target) {
294
if (getAccessMethodTarget() != target) {
295
/*-------------------*
296
if (!isAccessMethod() || accessPeer != null ||
297
target.accessPeer != null) {
298
throw new CompilerError("accessPeer");
299
}
300
*-------------------*/
301
if (accessPeer != null || target.accessPeer != null) {
302
throw new CompilerError("accessPeer");
303
}
304
accessPeer = target;
305
}
306
}
307
308
/**
309
* If this method is a getter for a private field, return the setter.
310
*/
311
public MemberDefinition getAccessUpdateMember() {
312
if (isAccessMethod()) {
313
for (MemberDefinition f = accessPeer; f != null; f = f.accessPeer) {
314
if (f.isAccessMethod()) {
315
return f;
316
}
317
}
318
}
319
return null;
320
}
321
322
public void setAccessUpdateMember(MemberDefinition updater) {
323
if (getAccessUpdateMember() != updater) {
324
if (!isAccessMethod() ||
325
updater.getAccessMethodTarget() != getAccessMethodTarget()) {
326
throw new CompilerError("accessPeer");
327
}
328
updater.accessPeer = accessPeer;
329
accessPeer = updater;
330
}
331
}
332
333
/**
334
* Is this an access method for a field selection or method call
335
* of the form '...super.foo' or '...super.foo()'?
336
*/
337
public final boolean isSuperAccessMethod() {
338
return superAccessMethod;
339
}
340
341
/**
342
* Mark this member as an access method for a field selection
343
* or method call via the 'super' keyword.
344
*/
345
public final void setIsSuperAccessMethod(boolean b) {
346
superAccessMethod = b;
347
}
348
349
/**
350
* Tell if this is a final variable without an initializer.
351
* Such variables are subject to definite single assignment.
352
*/
353
public final boolean isBlankFinal() {
354
return isFinal() && !isSynthetic() && getValue() == null;
355
}
356
357
public boolean isNeverNull() {
358
if (isUplevelValue()) {
359
// loc$x and this$C are never null
360
return !name.toString().startsWith(prefixVal);
361
}
362
return false;
363
}
364
365
/**
366
* Get the field's final value (may return null)
367
*/
368
public Node getValue(Environment env) throws ClassNotFound {
369
return value;
370
}
371
public final Node getValue() {
372
return value;
373
}
374
public final void setValue(Node value) {
375
this.value = value;
376
}
377
public Object getInitialValue() {
378
return null;
379
}
380
381
/**
382
* Get the next field or the next match
383
*/
384
public final MemberDefinition getNextMember() {
385
return nextMember;
386
}
387
public final MemberDefinition getNextMatch() {
388
return nextMatch;
389
}
390
391
/**
392
* Get the field's documentation
393
*/
394
public String getDocumentation() {
395
return documentation;
396
}
397
398
/**
399
* Request a check of the field definition.
400
*/
401
public void check(Environment env) throws ClassNotFound {
402
}
403
404
/**
405
* Really check the field definition.
406
*/
407
public Vset check(Environment env, Context ctx, Vset vset) throws ClassNotFound {
408
return vset;
409
}
410
411
/**
412
* Generate code
413
*/
414
public void code(Environment env, Assembler asm) throws ClassNotFound {
415
throw new CompilerError("code");
416
}
417
public void codeInit(Environment env, Context ctx, Assembler asm) throws ClassNotFound {
418
throw new CompilerError("codeInit");
419
}
420
421
/**
422
* Tells whether to report a deprecation error for this field.
423
*/
424
public boolean reportDeprecated(Environment env) {
425
return (isDeprecated() || clazz.reportDeprecated(env));
426
}
427
428
/**
429
* Check if a field can reach another field (only considers
430
* forward references, not the access modifiers).
431
*/
432
public final boolean canReach(Environment env, MemberDefinition f) {
433
if (f.isLocal() || !f.isVariable() || !(isVariable() || isInitializer()))
434
return true;
435
if ((getClassDeclaration().equals(f.getClassDeclaration())) &&
436
(isStatic() == f.isStatic())) {
437
// They are located in the same class, and are either both
438
// static or both non-static. Check the initialization order.
439
while (((f = f.getNextMember()) != null) && (f != this));
440
return f != null;
441
}
442
return true;
443
}
444
445
//-----------------------------------------------------------------
446
// The code in this section is intended to test certain kinds of
447
// compatibility between methods. There are two kinds of compatibility
448
// that the compiler may need to test. The first is whether one
449
// method can legally override another. The second is whether two
450
// method definitions can legally coexist. We use the word `meet'
451
// to mean the intersection of two legally coexisting methods.
452
// For more information on these kinds of compatibility, see the
453
// comments/code for checkOverride() and checkMeet() below.
454
455
/**
456
* Constants used by getAccessLevel() to represent the access
457
* modifiers as numbers.
458
*/
459
static final int PUBLIC_ACCESS = 1;
460
static final int PROTECTED_ACCESS = 2;
461
static final int PACKAGE_ACCESS = 3;
462
static final int PRIVATE_ACCESS = 4;
463
464
/**
465
* Return the access modifier of this member as a number. The idea
466
* is that this number may be used to check properties like "the
467
* access modifier of x is more restrictive than the access
468
* modifier of y" with a simple inequality test:
469
* "x.getAccessLevel() > y.getAccessLevel.
470
*
471
* This is an internal utility method.
472
*/
473
private int getAccessLevel() {
474
// Could just compute this once instead of recomputing.
475
// Check to see if this is worth it.
476
if (isPublic()) {
477
return PUBLIC_ACCESS;
478
} else if (isProtected()) {
479
return PROTECTED_ACCESS;
480
} else if (isPackagePrivate()) {
481
return PACKAGE_ACCESS;
482
} else if (isPrivate()) {
483
return PRIVATE_ACCESS;
484
} else {
485
throw new CompilerError("getAccessLevel()");
486
}
487
}
488
489
/**
490
* Munge our error message to report whether the override conflict
491
* came from an inherited method or a declared method.
492
*/
493
private void reportError(Environment env, String errorString,
494
ClassDeclaration clazz,
495
MemberDefinition method) {
496
497
if (clazz == null) {
498
// For example:
499
// "Instance method BLAH inherited from CLASSBLAH1 cannot be
500
// overridden by the static method declared in CLASSBLAH2."
501
env.error(getWhere(), errorString,
502
this, getClassDeclaration(),
503
method.getClassDeclaration());
504
} else {
505
// For example:
506
// "In CLASSBLAH1, instance method BLAH inherited from CLASSBLAH2
507
// cannot be overridden by the static method inherited from
508
// CLASSBLAH3."
509
env.error(clazz.getClassDefinition().getWhere(),
510
//"inherit." + errorString,
511
errorString,
512
//clazz,
513
this, getClassDeclaration(),
514
method.getClassDeclaration());
515
}
516
}
517
518
/**
519
* Convenience method to see if two methods return the same type
520
*/
521
public boolean sameReturnType(MemberDefinition method) {
522
// Make sure both are methods.
523
if (!isMethod() || !method.isMethod()) {
524
throw new CompilerError("sameReturnType: not method");
525
}
526
527
Type myReturnType = getType().getReturnType();
528
Type yourReturnType = method.getType().getReturnType();
529
530
return (myReturnType == yourReturnType);
531
}
532
533
/**
534
* Check to see if `this' can override/hide `method'. Caller is
535
* responsible for verifying that `method' has the same signature
536
* as `this'. Caller is also responsible for verifying that
537
* `method' is visible to the class where this override is occurring.
538
* This method is called for the case when class B extends A and both
539
* A and B define some method.
540
* <pre>
541
* A - void foo() throws e1
542
* |
543
* |
544
* B - void foo() throws e2
545
* </pre>
546
*/
547
public boolean checkOverride(Environment env, MemberDefinition method) {
548
return checkOverride(env, method, null);
549
}
550
551
/**
552
* Checks whether `this' can override `method'. It `clazz' is
553
* null, it reports the errors in the class where `this' is
554
* declared. If `clazz' is not null, it reports the error in `clazz'.
555
*/
556
private boolean checkOverride(Environment env,
557
MemberDefinition method,
558
ClassDeclaration clazz) {
559
// This section of code is largely based on section 8.4.6.3
560
// of the JLS.
561
562
boolean success = true;
563
564
// Sanity
565
if (!isMethod()) {
566
throw new CompilerError("checkOverride(), expected method");
567
}
568
569
// Suppress checks for synthetic methods, as the compiler presumably
570
// knows what it is doing, e.g., access methods.
571
if (isSynthetic()) {
572
// Sanity check: We generally do not intend for one synthetic
573
// method to override another, though hiding of static members
574
// is expected. This check may need to be changed if new uses
575
// of synthetic methods are devised.
576
//
577
// Query: this code was copied from elsewhere. What
578
// exactly is the role of the !isStatic() in the test?
579
if (method.isFinal() ||
580
(!method.isConstructor() &&
581
!method.isStatic() && !isStatic())) {
582
////////////////////////////////////////////////////////////
583
// NMG 2003-01-28 removed the following test because it is
584
// invalidated by bridge methods inserted by the "generic"
585
// (1.5) Java compiler. In 1.5, this code is used,
586
// indirectly, by rmic
587
////////////////////////////////////////////////////////////
588
// throw new CompilerError("checkOverride() synthetic");
589
////////////////////////////////////////////////////////////
590
}
591
592
// We trust the compiler. (Ha!) We're done checking.
593
return true;
594
}
595
596
// Our caller should have verified that the method had the
597
// same signature.
598
if (getName() != method.getName() ||
599
!getType().equalArguments(method.getType())) {
600
601
throw new CompilerError("checkOverride(), signature mismatch");
602
}
603
604
// It is forbidden to `override' a static method with an instance
605
// method.
606
if (method.isStatic() && !isStatic()) {
607
reportError(env, "override.static.with.instance", clazz, method);
608
success = false;
609
}
610
611
// It is forbidden to `hide' an instance method with a static
612
// method.
613
if (!method.isStatic() && isStatic()) {
614
reportError(env, "hide.instance.with.static", clazz, method);
615
success = false;
616
}
617
618
// We cannot override a final method.
619
if (method.isFinal()) {
620
reportError(env, "override.final.method", clazz, method);
621
success = false;
622
}
623
624
// Give a warning when we override a deprecated method with
625
// a non-deprecated one.
626
//
627
// We bend over backwards to suppress this warning if
628
// the `method' has not been already compiled or
629
// `this' has been already compiled.
630
if (method.reportDeprecated(env) && !isDeprecated()
631
&& this instanceof sun.tools.javac.SourceMember) {
632
reportError(env, "warn.override.is.deprecated",
633
clazz, method);
634
}
635
636
// Visibility may not be more restrictive
637
if (getAccessLevel() > method.getAccessLevel()) {
638
reportError(env, "override.more.restrictive", clazz, method);
639
success = false;
640
}
641
642
// Return type equality
643
if (!sameReturnType(method)) {
644
////////////////////////////////////////////////////////////
645
// PCJ 2003-07-30 removed the following error because it is
646
// invalidated by the covariant return type feature of the
647
// 1.5 compiler. The resulting check is now much looser
648
// than the actual 1.5 language spec, but that should be OK
649
// because this code is only still used by rmic. See 4892308.
650
////////////////////////////////////////////////////////////
651
// reportError(env, "override.different.return", clazz, method);
652
// success = false;
653
////////////////////////////////////////////////////////////
654
}
655
656
// Exception agreeement
657
if (!exceptionsFit(env, method)) {
658
reportError(env, "override.incompatible.exceptions",
659
clazz, method);
660
success = false;
661
}
662
663
return success;
664
}
665
666
/**
667
* Check to see if two method definitions are compatible, that is
668
* do they have a `meet'. The meet of two methods is essentially
669
* and `intersection' of
670
* two methods. This method is called when some class C inherits
671
* declarations for some method foo from two parents (superclass,
672
* interfaces) but it does not, itself, have a declaration of foo.
673
* Caller is responsible for making sure that both methods are
674
* indeed visible in clazz.
675
* <pre>
676
* A - void foo() throws e1
677
* \
678
* \ B void foo() throws e2
679
* \ /
680
* \ /
681
* C
682
* </pre>
683
*/
684
public boolean checkMeet(Environment env,
685
MemberDefinition method,
686
ClassDeclaration clazz) {
687
// This section of code is largely based on Section 8.4.6
688
// and 9.4.1 of the JLS.
689
690
// Sanity
691
if (!isMethod()) {
692
throw new CompilerError("checkMeet(), expected method");
693
}
694
695
// Check for both non-abstract.
696
if (!isAbstract() && !method.isAbstract()) {
697
throw new CompilerError("checkMeet(), no abstract method");
698
}
699
700
// If either method is non-abstract, then we need to check that
701
// the abstract method can be properly overridden. We call
702
// the checkOverride method to check this and generate any errors.
703
// This test must follow the previous test.
704
else if (!isAbstract()) {
705
return checkOverride(env, method, clazz);
706
} else if (!method.isAbstract()) {
707
return method.checkOverride(env, this, clazz);
708
}
709
710
// Both methods are abstract.
711
712
// Our caller should have verified that the method has the
713
// same signature.
714
if (getName() != method.getName() ||
715
!getType().equalArguments(method.getType())) {
716
717
throw new CompilerError("checkMeet(), signature mismatch");
718
}
719
720
// Check for return type equality
721
if (!sameReturnType(method)) {
722
// More args?
723
env.error(clazz.getClassDefinition().getWhere(),
724
"meet.different.return",
725
this, this.getClassDeclaration(),
726
method.getClassDeclaration());
727
return false;
728
}
729
730
// We don't have to check visibility -- there always
731
// potentially exists a meet. Similarly with exceptions.
732
733
// There does exist a meet.
734
return true;
735
}
736
737
/**
738
* This method is meant to be used to determine if one of two inherited
739
* methods could override the other. Unlike checkOverride(), failure
740
* is not an error. This method is only meant to be called after
741
* checkMeet() has succeeded on the two methods.
742
*
743
* If you call couldOverride() without doing a checkMeet() first, then
744
* you are on your own.
745
*/
746
public boolean couldOverride(Environment env,
747
MemberDefinition method) {
748
749
// Sanity
750
if (!isMethod()) {
751
throw new CompilerError("coulcOverride(), expected method");
752
}
753
754
// couldOverride() is only called with `this' and `method' both
755
// being inherited methods. Neither of them is defined in the
756
// class which we are currently working on. Even though an
757
// abstract method defined *in* a class can override a non-abstract
758
// method defined in a superclass, an abstract method inherited
759
// from an interface *never* can override a non-abstract method.
760
// This comment may sound odd, but that's the way inheritance is.
761
// The following check makes sure we aren't trying to override
762
// an inherited non-abstract definition with an abstract definition
763
// from an interface.
764
if (!method.isAbstract()) {
765
return false;
766
}
767
768
// Visibility should be less restrictive
769
if (getAccessLevel() > method.getAccessLevel()) {
770
return false;
771
}
772
773
// Exceptions
774
if (!exceptionsFit(env, method)) {
775
return false;
776
}
777
778
// Potentially some deprecation warnings could be given here
779
// when we merge two abstract methods, one of which is deprecated.
780
// This is not currently reported.
781
782
return true;
783
}
784
785
/**
786
* Check to see if the exceptions of `this' fit within the
787
* exceptions of `method'.
788
*/
789
private boolean exceptionsFit(Environment env,
790
MemberDefinition method) {
791
ClassDeclaration e1[] = getExceptions(env); // my exceptions
792
ClassDeclaration e2[] = method.getExceptions(env); // parent's
793
794
// This code is taken nearly verbatim from the old implementation
795
// of checkOverride() in SourceClass.
796
outer:
797
for (int i = 0 ; i < e1.length ; i++) {
798
try {
799
ClassDefinition c1 = e1[i].getClassDefinition(env);
800
for (int j = 0 ; j < e2.length ; j++) {
801
if (c1.subClassOf(env, e2[j])) {
802
continue outer;
803
}
804
}
805
if (c1.subClassOf(env,
806
env.getClassDeclaration(idJavaLangError)))
807
continue outer;
808
if (c1.subClassOf(env,
809
env.getClassDeclaration(idJavaLangRuntimeException)))
810
continue outer;
811
812
// the throws was neither something declared by a parent,
813
// nor one of the ignorables.
814
return false;
815
816
} catch (ClassNotFound ee) {
817
// We were unable to find one of the exceptions.
818
env.error(getWhere(), "class.not.found",
819
ee.name, method.getClassDeclaration());
820
}
821
}
822
823
// All of the exceptions `fit'.
824
return true;
825
}
826
827
//-----------------------------------------------------------------
828
829
/**
830
* Checks
831
*/
832
public final boolean isPublic() {
833
return (modifiers & M_PUBLIC) != 0;
834
}
835
public final boolean isPrivate() {
836
return (modifiers & M_PRIVATE) != 0;
837
}
838
public final boolean isProtected() {
839
return (modifiers & M_PROTECTED) != 0;
840
}
841
public final boolean isPackagePrivate() {
842
return (modifiers & (M_PUBLIC | M_PRIVATE | M_PROTECTED)) == 0;
843
}
844
public final boolean isFinal() {
845
return (modifiers & M_FINAL) != 0;
846
}
847
public final boolean isStatic() {
848
return (modifiers & M_STATIC) != 0;
849
}
850
public final boolean isSynchronized() {
851
return (modifiers & M_SYNCHRONIZED) != 0;
852
}
853
public final boolean isAbstract() {
854
return (modifiers & M_ABSTRACT) != 0;
855
}
856
public final boolean isNative() {
857
return (modifiers & M_NATIVE) != 0;
858
}
859
public final boolean isVolatile() {
860
return (modifiers & M_VOLATILE) != 0;
861
}
862
public final boolean isTransient() {
863
return (modifiers & M_TRANSIENT) != 0;
864
}
865
public final boolean isMethod() {
866
return type.isType(TC_METHOD);
867
}
868
public final boolean isVariable() {
869
return !type.isType(TC_METHOD) && innerClass == null;
870
}
871
public final boolean isSynthetic() {
872
return (modifiers & M_SYNTHETIC) != 0;
873
}
874
public final boolean isDeprecated() {
875
return (modifiers & M_DEPRECATED) != 0;
876
}
877
public final boolean isStrict() {
878
return (modifiers & M_STRICTFP) != 0;
879
}
880
public final boolean isInnerClass() {
881
return innerClass != null;
882
}
883
public final boolean isInitializer() {
884
return getName().equals(idClassInit);
885
}
886
public final boolean isConstructor() {
887
return getName().equals(idInit);
888
}
889
public boolean isLocal() {
890
return false;
891
}
892
public boolean isInlineable(Environment env, boolean fromFinal) throws ClassNotFound {
893
return (isStatic() || isPrivate() || isFinal() || isConstructor() || fromFinal) &&
894
!(isSynchronized() || isNative());
895
}
896
897
/**
898
* Check if constant: Will it inline away to a constant?
899
*/
900
public boolean isConstant() {
901
if (isFinal() && isVariable() && value != null) {
902
try {
903
// If an infinite regress requeries this name,
904
// deny that it is a constant.
905
modifiers &= ~M_FINAL;
906
return ((Expression)value).isConstant();
907
} finally {
908
modifiers |= M_FINAL;
909
}
910
}
911
return false;
912
}
913
914
/**
915
* toString
916
*/
917
public String toString() {
918
Identifier name = getClassDefinition().getName();
919
if (isInitializer()) {
920
return isStatic() ? "static {}" : "instance {}";
921
} else if (isConstructor()) {
922
StringBuffer buf = new StringBuffer();
923
buf.append(name);
924
buf.append('(');
925
Type argTypes[] = getType().getArgumentTypes();
926
for (int i = 0 ; i < argTypes.length ; i++) {
927
if (i > 0) {
928
buf.append(',');
929
}
930
buf.append(argTypes[i].toString());
931
}
932
buf.append(')');
933
return buf.toString();
934
} else if (isInnerClass()) {
935
return getInnerClass().toString();
936
}
937
return type.typeString(getName().toString());
938
}
939
940
/**
941
* Print for debugging
942
*/
943
public void print(PrintStream out) {
944
if (isPublic()) {
945
out.print("public ");
946
}
947
if (isPrivate()) {
948
out.print("private ");
949
}
950
if (isProtected()) {
951
out.print("protected ");
952
}
953
if (isFinal()) {
954
out.print("final ");
955
}
956
if (isStatic()) {
957
out.print("static ");
958
}
959
if (isSynchronized()) {
960
out.print("synchronized ");
961
}
962
if (isAbstract()) {
963
out.print("abstract ");
964
}
965
if (isNative()) {
966
out.print("native ");
967
}
968
if (isVolatile()) {
969
out.print("volatile ");
970
}
971
if (isTransient()) {
972
out.print("transient ");
973
}
974
out.println(toString() + ";");
975
}
976
977
public void cleanup(Environment env) {
978
documentation = null;
979
if (isMethod() && value != null) {
980
int cost = 0;
981
if (isPrivate() || isInitializer()) {
982
value = Statement.empty;
983
} else if ((cost =
984
((Statement)value)
985
.costInline(Statement.MAXINLINECOST, null, null))
986
>= Statement.MAXINLINECOST) {
987
// will never be inlined
988
value = Statement.empty;
989
} else {
990
try {
991
if (!isInlineable(null, true)) {
992
value = Statement.empty;
993
}
994
}
995
catch (ClassNotFound ee) { }
996
}
997
if (value != Statement.empty && env.dump()) {
998
env.output("[after cleanup of " + getName() + ", " +
999
cost + " expression cost units remain]");
1000
}
1001
} else if (isVariable()) {
1002
if (isPrivate() || !isFinal() || type.isType(TC_ARRAY)) {
1003
value = null;
1004
}
1005
}
1006
}
1007
}
1008
1009