Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java
38899 views
1
/*
2
* Copyright (c) 2007, 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 com.sun.tools.javap;
27
28
import java.io.EOFException;
29
import java.io.FileNotFoundException;
30
import java.io.FilterInputStream;
31
import java.io.InputStream;
32
import java.io.IOException;
33
import java.io.OutputStream;
34
import java.io.PrintWriter;
35
import java.io.Reader;
36
import java.io.StringWriter;
37
import java.io.Writer;
38
import java.net.URI;
39
import java.security.DigestInputStream;
40
import java.security.MessageDigest;
41
import java.security.NoSuchAlgorithmException;
42
import java.text.MessageFormat;
43
import java.util.ArrayList;
44
import java.util.Arrays;
45
import java.util.EnumSet;
46
import java.util.HashMap;
47
import java.util.Iterator;
48
import java.util.List;
49
import java.util.Locale;
50
import java.util.Map;
51
import java.util.MissingResourceException;
52
import java.util.ResourceBundle;
53
54
import javax.lang.model.element.Modifier;
55
import javax.lang.model.element.NestingKind;
56
import javax.tools.Diagnostic;
57
import javax.tools.DiagnosticListener;
58
import javax.tools.JavaFileManager;
59
import javax.tools.JavaFileObject;
60
import javax.tools.StandardJavaFileManager;
61
import javax.tools.StandardLocation;
62
63
import com.sun.tools.classfile.*;
64
import java.net.URISyntaxException;
65
import java.net.URL;
66
import java.net.URLConnection;
67
68
/**
69
* "Main" class for javap, normally accessed from the command line
70
* via Main, or from JSR199 via DisassemblerTool.
71
*
72
* <p><b>This is NOT part of any supported API.
73
* If you write code that depends on this, you do so at your own risk.
74
* This code and its internal interfaces are subject to change or
75
* deletion without notice.</b>
76
*/
77
public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
78
public class BadArgs extends Exception {
79
static final long serialVersionUID = 8765093759964640721L;
80
BadArgs(String key, Object... args) {
81
super(JavapTask.this.getMessage(key, args));
82
this.key = key;
83
this.args = args;
84
}
85
86
BadArgs showUsage(boolean b) {
87
showUsage = b;
88
return this;
89
}
90
91
final String key;
92
final Object[] args;
93
boolean showUsage;
94
}
95
96
static abstract class Option {
97
Option(boolean hasArg, String... aliases) {
98
this.hasArg = hasArg;
99
this.aliases = aliases;
100
}
101
102
boolean matches(String opt) {
103
for (String a: aliases) {
104
if (a.equals(opt))
105
return true;
106
}
107
return false;
108
}
109
110
boolean ignoreRest() {
111
return false;
112
}
113
114
abstract void process(JavapTask task, String opt, String arg) throws BadArgs;
115
116
final boolean hasArg;
117
final String[] aliases;
118
}
119
120
static final Option[] recognizedOptions = {
121
122
new Option(false, "-help", "--help", "-?") {
123
void process(JavapTask task, String opt, String arg) {
124
task.options.help = true;
125
}
126
},
127
128
new Option(false, "-version") {
129
void process(JavapTask task, String opt, String arg) {
130
task.options.version = true;
131
}
132
},
133
134
new Option(false, "-fullversion") {
135
void process(JavapTask task, String opt, String arg) {
136
task.options.fullVersion = true;
137
}
138
},
139
140
new Option(false, "-v", "-verbose", "-all") {
141
void process(JavapTask task, String opt, String arg) {
142
task.options.verbose = true;
143
task.options.showDescriptors = true;
144
task.options.showFlags = true;
145
task.options.showAllAttrs = true;
146
}
147
},
148
149
new Option(false, "-l") {
150
void process(JavapTask task, String opt, String arg) {
151
task.options.showLineAndLocalVariableTables = true;
152
}
153
},
154
155
new Option(false, "-public") {
156
void process(JavapTask task, String opt, String arg) {
157
task.options.accessOptions.add(opt);
158
task.options.showAccess = AccessFlags.ACC_PUBLIC;
159
}
160
},
161
162
new Option(false, "-protected") {
163
void process(JavapTask task, String opt, String arg) {
164
task.options.accessOptions.add(opt);
165
task.options.showAccess = AccessFlags.ACC_PROTECTED;
166
}
167
},
168
169
new Option(false, "-package") {
170
void process(JavapTask task, String opt, String arg) {
171
task.options.accessOptions.add(opt);
172
task.options.showAccess = 0;
173
}
174
},
175
176
new Option(false, "-p", "-private") {
177
void process(JavapTask task, String opt, String arg) {
178
if (!task.options.accessOptions.contains("-p") &&
179
!task.options.accessOptions.contains("-private")) {
180
task.options.accessOptions.add(opt);
181
}
182
task.options.showAccess = AccessFlags.ACC_PRIVATE;
183
}
184
},
185
186
new Option(false, "-c") {
187
void process(JavapTask task, String opt, String arg) {
188
task.options.showDisassembled = true;
189
}
190
},
191
192
new Option(false, "-s") {
193
void process(JavapTask task, String opt, String arg) {
194
task.options.showDescriptors = true;
195
}
196
},
197
198
new Option(false, "-sysinfo") {
199
void process(JavapTask task, String opt, String arg) {
200
task.options.sysInfo = true;
201
}
202
},
203
204
new Option(false, "-XDdetails") {
205
void process(JavapTask task, String opt, String arg) {
206
task.options.details = EnumSet.allOf(InstructionDetailWriter.Kind.class);
207
}
208
209
},
210
211
new Option(false, "-XDdetails:") {
212
@Override
213
boolean matches(String opt) {
214
int sep = opt.indexOf(":");
215
return sep != -1 && super.matches(opt.substring(0, sep + 1));
216
}
217
218
void process(JavapTask task, String opt, String arg) throws BadArgs {
219
int sep = opt.indexOf(":");
220
for (String v: opt.substring(sep + 1).split("[,: ]+")) {
221
if (!handleArg(task, v))
222
throw task.new BadArgs("err.invalid.arg.for.option", v);
223
}
224
}
225
226
boolean handleArg(JavapTask task, String arg) {
227
if (arg.length() == 0)
228
return true;
229
230
if (arg.equals("all")) {
231
task.options.details = EnumSet.allOf(InstructionDetailWriter.Kind.class);
232
return true;
233
}
234
235
boolean on = true;
236
if (arg.startsWith("-")) {
237
on = false;
238
arg = arg.substring(1);
239
}
240
241
for (InstructionDetailWriter.Kind k: InstructionDetailWriter.Kind.values()) {
242
if (arg.equalsIgnoreCase(k.option)) {
243
if (on)
244
task.options.details.add(k);
245
else
246
task.options.details.remove(k);
247
return true;
248
}
249
}
250
return false;
251
}
252
},
253
254
new Option(false, "-constants") {
255
void process(JavapTask task, String opt, String arg) {
256
task.options.showConstants = true;
257
}
258
},
259
260
new Option(false, "-XDinner") {
261
void process(JavapTask task, String opt, String arg) {
262
task.options.showInnerClasses = true;
263
}
264
},
265
266
new Option(false, "-XDindent:") {
267
@Override
268
boolean matches(String opt) {
269
int sep = opt.indexOf(":");
270
return sep != -1 && super.matches(opt.substring(0, sep + 1));
271
}
272
273
void process(JavapTask task, String opt, String arg) throws BadArgs {
274
int sep = opt.indexOf(":");
275
try {
276
int i = Integer.valueOf(opt.substring(sep + 1));
277
if (i > 0) // silently ignore invalid values
278
task.options.indentWidth = i;
279
} catch (NumberFormatException e) {
280
}
281
}
282
},
283
284
new Option(false, "-XDtab:") {
285
@Override
286
boolean matches(String opt) {
287
int sep = opt.indexOf(":");
288
return sep != -1 && super.matches(opt.substring(0, sep + 1));
289
}
290
291
void process(JavapTask task, String opt, String arg) throws BadArgs {
292
int sep = opt.indexOf(":");
293
try {
294
int i = Integer.valueOf(opt.substring(sep + 1));
295
if (i > 0) // silently ignore invalid values
296
task.options.tabColumn = i;
297
} catch (NumberFormatException e) {
298
}
299
}
300
}
301
302
};
303
304
public JavapTask() {
305
context = new Context();
306
context.put(Messages.class, this);
307
options = Options.instance(context);
308
attributeFactory = new Attribute.Factory();
309
}
310
311
public JavapTask(Writer out,
312
JavaFileManager fileManager,
313
DiagnosticListener<? super JavaFileObject> diagnosticListener) {
314
this();
315
this.log = getPrintWriterForWriter(out);
316
this.fileManager = fileManager;
317
this.diagnosticListener = diagnosticListener;
318
}
319
320
public JavapTask(Writer out,
321
JavaFileManager fileManager,
322
DiagnosticListener<? super JavaFileObject> diagnosticListener,
323
Iterable<String> options,
324
Iterable<String> classes) {
325
this(out, fileManager, diagnosticListener);
326
327
this.classes = new ArrayList<String>();
328
for (String classname: classes) {
329
classname.getClass(); // null-check
330
this.classes.add(classname);
331
}
332
333
try {
334
if (options != null)
335
handleOptions(options, false);
336
} catch (BadArgs e) {
337
throw new IllegalArgumentException(e.getMessage());
338
}
339
}
340
341
public void setLocale(Locale locale) {
342
if (locale == null)
343
locale = Locale.getDefault();
344
task_locale = locale;
345
}
346
347
public void setLog(Writer log) {
348
this.log = getPrintWriterForWriter(log);
349
}
350
351
public void setLog(OutputStream s) {
352
setLog(getPrintWriterForStream(s));
353
}
354
355
private static PrintWriter getPrintWriterForStream(OutputStream s) {
356
return new PrintWriter(s == null ? System.err : s, true);
357
}
358
359
private static PrintWriter getPrintWriterForWriter(Writer w) {
360
if (w == null)
361
return getPrintWriterForStream(null);
362
else if (w instanceof PrintWriter)
363
return (PrintWriter) w;
364
else
365
return new PrintWriter(w, true);
366
}
367
368
public void setDiagnosticListener(DiagnosticListener<? super JavaFileObject> dl) {
369
diagnosticListener = dl;
370
}
371
372
public void setDiagnosticListener(OutputStream s) {
373
setDiagnosticListener(getDiagnosticListenerForStream(s));
374
}
375
376
private DiagnosticListener<JavaFileObject> getDiagnosticListenerForStream(OutputStream s) {
377
return getDiagnosticListenerForWriter(getPrintWriterForStream(s));
378
}
379
380
private DiagnosticListener<JavaFileObject> getDiagnosticListenerForWriter(Writer w) {
381
final PrintWriter pw = getPrintWriterForWriter(w);
382
return new DiagnosticListener<JavaFileObject> () {
383
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
384
switch (diagnostic.getKind()) {
385
case ERROR:
386
pw.print(getMessage("err.prefix"));
387
break;
388
case WARNING:
389
pw.print(getMessage("warn.prefix"));
390
break;
391
case NOTE:
392
pw.print(getMessage("note.prefix"));
393
break;
394
}
395
pw.print(" ");
396
pw.println(diagnostic.getMessage(null));
397
}
398
};
399
}
400
401
/** Result codes.
402
*/
403
static final int
404
EXIT_OK = 0, // Compilation completed with no errors.
405
EXIT_ERROR = 1, // Completed but reported errors.
406
EXIT_CMDERR = 2, // Bad command-line arguments
407
EXIT_SYSERR = 3, // System error or resource exhaustion.
408
EXIT_ABNORMAL = 4; // Compiler terminated abnormally
409
410
int run(String[] args) {
411
try {
412
handleOptions(args);
413
414
// the following gives consistent behavior with javac
415
if (classes == null || classes.size() == 0) {
416
if (options.help || options.version || options.fullVersion)
417
return EXIT_OK;
418
else
419
return EXIT_CMDERR;
420
}
421
422
try {
423
return run();
424
} finally {
425
if (defaultFileManager != null) {
426
try {
427
defaultFileManager.close();
428
defaultFileManager = null;
429
} catch (IOException e) {
430
throw new InternalError(e);
431
}
432
}
433
}
434
} catch (BadArgs e) {
435
reportError(e.key, e.args);
436
if (e.showUsage) {
437
printLines(getMessage("main.usage.summary", progname));
438
}
439
return EXIT_CMDERR;
440
} catch (InternalError e) {
441
Object[] e_args;
442
if (e.getCause() == null)
443
e_args = e.args;
444
else {
445
e_args = new Object[e.args.length + 1];
446
e_args[0] = e.getCause();
447
System.arraycopy(e.args, 0, e_args, 1, e.args.length);
448
}
449
reportError("err.internal.error", e_args);
450
return EXIT_ABNORMAL;
451
} finally {
452
log.flush();
453
}
454
}
455
456
public void handleOptions(String[] args) throws BadArgs {
457
handleOptions(Arrays.asList(args), true);
458
}
459
460
private void handleOptions(Iterable<String> args, boolean allowClasses) throws BadArgs {
461
if (log == null) {
462
log = getPrintWriterForStream(System.out);
463
if (diagnosticListener == null)
464
diagnosticListener = getDiagnosticListenerForStream(System.err);
465
} else {
466
if (diagnosticListener == null)
467
diagnosticListener = getDiagnosticListenerForWriter(log);
468
}
469
470
471
if (fileManager == null)
472
fileManager = getDefaultFileManager(diagnosticListener, log);
473
474
Iterator<String> iter = args.iterator();
475
boolean noArgs = !iter.hasNext();
476
477
while (iter.hasNext()) {
478
String arg = iter.next();
479
if (arg.startsWith("-"))
480
handleOption(arg, iter);
481
else if (allowClasses) {
482
if (classes == null)
483
classes = new ArrayList<String>();
484
classes.add(arg);
485
while (iter.hasNext())
486
classes.add(iter.next());
487
} else
488
throw new BadArgs("err.unknown.option", arg).showUsage(true);
489
}
490
491
if (options.accessOptions.size() > 1) {
492
StringBuilder sb = new StringBuilder();
493
for (String opt: options.accessOptions) {
494
if (sb.length() > 0)
495
sb.append(" ");
496
sb.append(opt);
497
}
498
throw new BadArgs("err.incompatible.options", sb);
499
}
500
501
if ((classes == null || classes.size() == 0) &&
502
!(noArgs || options.help || options.version || options.fullVersion)) {
503
throw new BadArgs("err.no.classes.specified");
504
}
505
506
if (noArgs || options.help)
507
showHelp();
508
509
if (options.version || options.fullVersion)
510
showVersion(options.fullVersion);
511
}
512
513
private void handleOption(String name, Iterator<String> rest) throws BadArgs {
514
for (Option o: recognizedOptions) {
515
if (o.matches(name)) {
516
if (o.hasArg) {
517
if (rest.hasNext())
518
o.process(this, name, rest.next());
519
else
520
throw new BadArgs("err.missing.arg", name).showUsage(true);
521
} else
522
o.process(this, name, null);
523
524
if (o.ignoreRest()) {
525
while (rest.hasNext())
526
rest.next();
527
}
528
return;
529
}
530
}
531
532
try {
533
if (fileManager.handleOption(name, rest))
534
return;
535
} catch (IllegalArgumentException e) {
536
throw new BadArgs("err.invalid.use.of.option", name).showUsage(true);
537
}
538
539
throw new BadArgs("err.unknown.option", name).showUsage(true);
540
}
541
542
public Boolean call() {
543
return run() == 0;
544
}
545
546
public int run() {
547
if (classes == null || classes.isEmpty()) {
548
return EXIT_ERROR;
549
}
550
551
context.put(PrintWriter.class, log);
552
ClassWriter classWriter = ClassWriter.instance(context);
553
SourceWriter sourceWriter = SourceWriter.instance(context);
554
sourceWriter.setFileManager(fileManager);
555
556
int result = EXIT_OK;
557
558
for (String className: classes) {
559
try {
560
result = writeClass(classWriter, className);
561
} catch (ConstantPoolException e) {
562
reportError("err.bad.constant.pool", className, e.getLocalizedMessage());
563
result = EXIT_ERROR;
564
} catch (EOFException e) {
565
reportError("err.end.of.file", className);
566
result = EXIT_ERROR;
567
} catch (FileNotFoundException e) {
568
reportError("err.file.not.found", e.getLocalizedMessage());
569
result = EXIT_ERROR;
570
} catch (IOException e) {
571
//e.printStackTrace();
572
Object msg = e.getLocalizedMessage();
573
if (msg == null) {
574
msg = e;
575
}
576
reportError("err.ioerror", className, msg);
577
result = EXIT_ERROR;
578
} catch (Throwable t) {
579
StringWriter sw = new StringWriter();
580
PrintWriter pw = new PrintWriter(sw);
581
t.printStackTrace(pw);
582
pw.close();
583
reportError("err.crash", t.toString(), sw.toString());
584
result = EXIT_ABNORMAL;
585
}
586
}
587
588
return result;
589
}
590
591
protected int writeClass(ClassWriter classWriter, String className)
592
throws IOException, ConstantPoolException {
593
JavaFileObject fo = open(className);
594
if (fo == null) {
595
reportError("err.class.not.found", className);
596
return EXIT_ERROR;
597
}
598
599
ClassFileInfo cfInfo = read(fo);
600
if (!className.endsWith(".class")) {
601
String cfName = cfInfo.cf.getName();
602
if (!cfName.replaceAll("[/$]", ".").equals(className.replaceAll("[/$]", "."))) {
603
reportWarning("warn.unexpected.class", className, cfName.replace('/', '.'));
604
}
605
}
606
write(cfInfo);
607
608
if (options.showInnerClasses) {
609
ClassFile cf = cfInfo.cf;
610
Attribute a = cf.getAttribute(Attribute.InnerClasses);
611
if (a instanceof InnerClasses_attribute) {
612
InnerClasses_attribute inners = (InnerClasses_attribute) a;
613
try {
614
int result = EXIT_OK;
615
for (int i = 0; i < inners.classes.length; i++) {
616
int outerIndex = inners.classes[i].outer_class_info_index;
617
ConstantPool.CONSTANT_Class_info outerClassInfo = cf.constant_pool.getClassInfo(outerIndex);
618
String outerClassName = outerClassInfo.getName();
619
if (outerClassName.equals(cf.getName())) {
620
int innerIndex = inners.classes[i].inner_class_info_index;
621
ConstantPool.CONSTANT_Class_info innerClassInfo = cf.constant_pool.getClassInfo(innerIndex);
622
String innerClassName = innerClassInfo.getName();
623
classWriter.println("// inner class " + innerClassName.replaceAll("[/$]", "."));
624
classWriter.println();
625
result = writeClass(classWriter, innerClassName);
626
if (result != EXIT_OK) return result;
627
}
628
}
629
return result;
630
} catch (ConstantPoolException e) {
631
reportError("err.bad.innerclasses.attribute", className);
632
return EXIT_ERROR;
633
}
634
} else if (a != null) {
635
reportError("err.bad.innerclasses.attribute", className);
636
return EXIT_ERROR;
637
}
638
}
639
640
return EXIT_OK;
641
}
642
643
protected JavaFileObject open(String className) throws IOException {
644
// for compatibility, first see if it is a class name
645
JavaFileObject fo = getClassFileObject(className);
646
if (fo != null)
647
return fo;
648
649
// see if it is an inner class, by replacing dots to $, starting from the right
650
String cn = className;
651
int lastDot;
652
while ((lastDot = cn.lastIndexOf(".")) != -1) {
653
cn = cn.substring(0, lastDot) + "$" + cn.substring(lastDot + 1);
654
fo = getClassFileObject(cn);
655
if (fo != null)
656
return fo;
657
}
658
659
if (!className.endsWith(".class"))
660
return null;
661
662
if (fileManager instanceof StandardJavaFileManager) {
663
StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager;
664
fo = sfm.getJavaFileObjects(className).iterator().next();
665
if (fo != null && fo.getLastModified() != 0) {
666
return fo;
667
}
668
}
669
670
// see if it is a URL, and if so, wrap it in just enough of a JavaFileObject
671
// to suit javap's needs
672
if (className.matches("^[A-Za-z]+:.*")) {
673
try {
674
final URI uri = new URI(className);
675
final URL url = uri.toURL();
676
final URLConnection conn = url.openConnection();
677
return new JavaFileObject() {
678
public Kind getKind() {
679
return JavaFileObject.Kind.CLASS;
680
}
681
682
public boolean isNameCompatible(String simpleName, Kind kind) {
683
throw new UnsupportedOperationException();
684
}
685
686
public NestingKind getNestingKind() {
687
throw new UnsupportedOperationException();
688
}
689
690
public Modifier getAccessLevel() {
691
throw new UnsupportedOperationException();
692
}
693
694
public URI toUri() {
695
return uri;
696
}
697
698
public String getName() {
699
return url.toString();
700
}
701
702
public InputStream openInputStream() throws IOException {
703
return conn.getInputStream();
704
}
705
706
public OutputStream openOutputStream() throws IOException {
707
throw new UnsupportedOperationException();
708
}
709
710
public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
711
throw new UnsupportedOperationException();
712
}
713
714
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
715
throw new UnsupportedOperationException();
716
}
717
718
public Writer openWriter() throws IOException {
719
throw new UnsupportedOperationException();
720
}
721
722
public long getLastModified() {
723
return conn.getLastModified();
724
}
725
726
public boolean delete() {
727
throw new UnsupportedOperationException();
728
}
729
730
};
731
} catch (URISyntaxException ignore) {
732
} catch (IOException ignore) {
733
}
734
}
735
736
return null;
737
}
738
739
public static class ClassFileInfo {
740
ClassFileInfo(JavaFileObject fo, ClassFile cf, byte[] digest, int size) {
741
this.fo = fo;
742
this.cf = cf;
743
this.digest = digest;
744
this.size = size;
745
}
746
public final JavaFileObject fo;
747
public final ClassFile cf;
748
public final byte[] digest;
749
public final int size;
750
}
751
752
public ClassFileInfo read(JavaFileObject fo) throws IOException, ConstantPoolException {
753
InputStream in = fo.openInputStream();
754
try {
755
SizeInputStream sizeIn = null;
756
MessageDigest md = null;
757
if (options.sysInfo || options.verbose) {
758
try {
759
md = MessageDigest.getInstance("MD5");
760
} catch (NoSuchAlgorithmException ignore) {
761
}
762
in = new DigestInputStream(in, md);
763
in = sizeIn = new SizeInputStream(in);
764
}
765
766
ClassFile cf = ClassFile.read(in, attributeFactory);
767
byte[] digest = (md == null) ? null : md.digest();
768
int size = (sizeIn == null) ? -1 : sizeIn.size();
769
return new ClassFileInfo(fo, cf, digest, size);
770
} finally {
771
in.close();
772
}
773
}
774
775
public void write(ClassFileInfo info) {
776
ClassWriter classWriter = ClassWriter.instance(context);
777
if (options.sysInfo || options.verbose) {
778
classWriter.setFile(info.fo.toUri());
779
classWriter.setLastModified(info.fo.getLastModified());
780
classWriter.setDigest("MD5", info.digest);
781
classWriter.setFileSize(info.size);
782
}
783
784
classWriter.write(info.cf);
785
}
786
787
protected void setClassFile(ClassFile classFile) {
788
ClassWriter classWriter = ClassWriter.instance(context);
789
classWriter.setClassFile(classFile);
790
}
791
792
protected void setMethod(Method enclosingMethod) {
793
ClassWriter classWriter = ClassWriter.instance(context);
794
classWriter.setMethod(enclosingMethod);
795
}
796
797
protected void write(Attribute value) {
798
AttributeWriter attrWriter = AttributeWriter.instance(context);
799
ClassWriter classWriter = ClassWriter.instance(context);
800
ClassFile cf = classWriter.getClassFile();
801
attrWriter.write(cf, value, cf.constant_pool);
802
}
803
804
protected void write(Attributes attrs) {
805
AttributeWriter attrWriter = AttributeWriter.instance(context);
806
ClassWriter classWriter = ClassWriter.instance(context);
807
ClassFile cf = classWriter.getClassFile();
808
attrWriter.write(cf, attrs, cf.constant_pool);
809
}
810
811
protected void write(ConstantPool constant_pool) {
812
ConstantWriter constantWriter = ConstantWriter.instance(context);
813
constantWriter.writeConstantPool(constant_pool);
814
}
815
816
protected void write(ConstantPool constant_pool, int value) {
817
ConstantWriter constantWriter = ConstantWriter.instance(context);
818
constantWriter.write(value);
819
}
820
821
protected void write(ConstantPool.CPInfo value) {
822
ConstantWriter constantWriter = ConstantWriter.instance(context);
823
constantWriter.println(value);
824
}
825
826
protected void write(Field value) {
827
ClassWriter classWriter = ClassWriter.instance(context);
828
classWriter.writeField(value);
829
}
830
831
protected void write(Method value) {
832
ClassWriter classWriter = ClassWriter.instance(context);
833
classWriter.writeMethod(value);
834
}
835
836
private JavaFileManager getDefaultFileManager(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) {
837
if (defaultFileManager == null)
838
defaultFileManager = JavapFileManager.create(dl, log);
839
return defaultFileManager;
840
}
841
842
private JavaFileObject getClassFileObject(String className) throws IOException {
843
JavaFileObject fo;
844
fo = fileManager.getJavaFileForInput(StandardLocation.PLATFORM_CLASS_PATH, className, JavaFileObject.Kind.CLASS);
845
if (fo == null)
846
fo = fileManager.getJavaFileForInput(StandardLocation.CLASS_PATH, className, JavaFileObject.Kind.CLASS);
847
return fo;
848
}
849
850
private void showHelp() {
851
printLines(getMessage("main.usage", progname));
852
for (Option o: recognizedOptions) {
853
String name = o.aliases[0].substring(1); // there must always be at least one name
854
if (name.startsWith("X") || name.equals("fullversion") || name.equals("h") || name.equals("verify"))
855
continue;
856
printLines(getMessage("main.opt." + name));
857
}
858
String[] fmOptions = { "-classpath", "-cp", "-bootclasspath" };
859
for (String o: fmOptions) {
860
if (fileManager.isSupportedOption(o) == -1)
861
continue;
862
String name = o.substring(1);
863
printLines(getMessage("main.opt." + name));
864
}
865
866
}
867
868
private void showVersion(boolean full) {
869
printLines(version(full ? "full" : "release"));
870
}
871
872
private void printLines(String msg) {
873
log.println(msg.replace("\n", nl));
874
}
875
876
private static final String nl = System.getProperty("line.separator");
877
878
private static final String versionRBName = "com.sun.tools.javap.resources.version";
879
private static ResourceBundle versionRB;
880
881
private String version(String key) {
882
// key=version: mm.nn.oo[-milestone]
883
// key=full: mm.mm.oo[-milestone]-build
884
if (versionRB == null) {
885
try {
886
versionRB = ResourceBundle.getBundle(versionRBName);
887
} catch (MissingResourceException e) {
888
return getMessage("version.resource.missing", System.getProperty("java.version"));
889
}
890
}
891
try {
892
return versionRB.getString(key);
893
}
894
catch (MissingResourceException e) {
895
return getMessage("version.unknown", System.getProperty("java.version"));
896
}
897
}
898
899
private void reportError(String key, Object... args) {
900
diagnosticListener.report(createDiagnostic(Diagnostic.Kind.ERROR, key, args));
901
}
902
903
private void reportNote(String key, Object... args) {
904
diagnosticListener.report(createDiagnostic(Diagnostic.Kind.NOTE, key, args));
905
}
906
907
private void reportWarning(String key, Object... args) {
908
diagnosticListener.report(createDiagnostic(Diagnostic.Kind.WARNING, key, args));
909
}
910
911
private Diagnostic<JavaFileObject> createDiagnostic(
912
final Diagnostic.Kind kind, final String key, final Object... args) {
913
return new Diagnostic<JavaFileObject>() {
914
public Kind getKind() {
915
return kind;
916
}
917
918
public JavaFileObject getSource() {
919
return null;
920
}
921
922
public long getPosition() {
923
return Diagnostic.NOPOS;
924
}
925
926
public long getStartPosition() {
927
return Diagnostic.NOPOS;
928
}
929
930
public long getEndPosition() {
931
return Diagnostic.NOPOS;
932
}
933
934
public long getLineNumber() {
935
return Diagnostic.NOPOS;
936
}
937
938
public long getColumnNumber() {
939
return Diagnostic.NOPOS;
940
}
941
942
public String getCode() {
943
return key;
944
}
945
946
public String getMessage(Locale locale) {
947
return JavapTask.this.getMessage(locale, key, args);
948
}
949
950
@Override
951
public String toString() {
952
return getClass().getName() + "[key=" + key + ",args=" + Arrays.asList(args) + "]";
953
}
954
955
};
956
957
}
958
959
public String getMessage(String key, Object... args) {
960
return getMessage(task_locale, key, args);
961
}
962
963
public String getMessage(Locale locale, String key, Object... args) {
964
if (bundles == null) {
965
// could make this a HashMap<Locale,SoftReference<ResourceBundle>>
966
// and for efficiency, keep a hard reference to the bundle for the task
967
// locale
968
bundles = new HashMap<Locale, ResourceBundle>();
969
}
970
971
if (locale == null)
972
locale = Locale.getDefault();
973
974
ResourceBundle b = bundles.get(locale);
975
if (b == null) {
976
try {
977
b = ResourceBundle.getBundle("com.sun.tools.javap.resources.javap", locale);
978
bundles.put(locale, b);
979
} catch (MissingResourceException e) {
980
throw new InternalError("Cannot find javap resource bundle for locale " + locale);
981
}
982
}
983
984
try {
985
return MessageFormat.format(b.getString(key), args);
986
} catch (MissingResourceException e) {
987
throw new InternalError(e, key);
988
}
989
}
990
991
protected Context context;
992
JavaFileManager fileManager;
993
JavaFileManager defaultFileManager;
994
PrintWriter log;
995
DiagnosticListener<? super JavaFileObject> diagnosticListener;
996
List<String> classes;
997
Options options;
998
//ResourceBundle bundle;
999
Locale task_locale;
1000
Map<Locale, ResourceBundle> bundles;
1001
protected Attribute.Factory attributeFactory;
1002
1003
private static final String progname = "javap";
1004
1005
private static class SizeInputStream extends FilterInputStream {
1006
SizeInputStream(InputStream in) {
1007
super(in);
1008
}
1009
1010
int size() {
1011
return size;
1012
}
1013
1014
@Override
1015
public int read(byte[] buf, int offset, int length) throws IOException {
1016
int n = super.read(buf, offset, length);
1017
if (n > 0)
1018
size += n;
1019
return n;
1020
}
1021
1022
@Override
1023
public int read() throws IOException {
1024
int b = super.read();
1025
size += 1;
1026
return b;
1027
}
1028
1029
private int size;
1030
}
1031
}
1032
1033