United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 4996963 apt could accept class files and java files on the command line
4996963 : apt could accept class files and java files on the command line

Details
Type:
Enhancement
Submit Date:
2004-02-19
Status:
Resolved
Updated Date:
2012-10-09
Project Name:
JDK
Resolved Date:
2004-09-24
Component:
tools
OS:
generic
Sub-Component:
apt
CPU:
generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
5.0
Fixed Versions:
5.0u1

Related Reports
Backport:
Relates:
Relates:
Relates:
Relates:
Relates:
Relates:
Relates:

Sub Tasks

Description
Like javac, at the moment apt is restricted to being given *.java files on the command line.  However, it may be convenient to process *.class files directly.
 

                                    

Comments
SUGGESTED FIX

src/share/classes/com/sun/tools/apt/main> -r1.16 Main.java                 <

------- Main.java -------
41c41,42
< /** This class provides a commandline interface to the GJC compiler.
---
> /** This class provides a commandline interface to the apt build-time
>  *  tool.
43,46c44,47
<  *  <p><b>This is NOT part of any API suppored by Sun Microsystems.  If
<  *  you write code that depends on this, you do so at your own risk.
<  *  This code and its internal interfaces are subject to change or
<  *  deletion without notice.</b>
---
>  *  <p><b>This is NOT part of any API supported by Sun Microsystems.
>  *  If you write code that depends on this, you do so at your own
>  *  risk.  This code and its internal interfaces are subject to change
>  *  or deletion without notice.</b>
449c450,457
< 
---
> 
>       /*
>        * Option to treat both classes and source files as
>        * declarations that can be given on the command line and
>        * processed as the result of an apt round.
>        */
>       new AptXOption("-XclassesAsDecls", "optXclassesAsDecls"),
> 
530,540c538,553
<           String s;
<           boolean matches(String s) {
<               this.s = s;
<               return s.endsWith(".java");
<           }
<           boolean process(String option) {
<               if (!filenames.contains(s))
<                   filenames.add(s);
<               return false;
<           }
<       },
---
>               String s;
>               boolean matches(String s) {
>                   this.s = s;
>                   return s.endsWith(".java") || 
>                       (options.get("-XclassesAsDecls") != null);
>               }
>               boolean process(String option) {
>                   if (s.endsWith(".java")) {
>                       if (!sourceFileNames.contains(s))
>                           sourceFileNames.add(s);
>                   } else if (options.get("-XclassesAsDecls") != null) {
>                       classFileNames.add(s);
>                   }
>                   return false;
>               }
>           },
561c574
<     /** The list of files to process
---
>     /** The list of source files to process
563c576
<     java.util.List<String> filenames = new java.util.LinkedList<String>();
---
>     java.util.List<String> sourceFileNames = new java.util.LinkedList<String>();
564a578,581
>     /** The list of class files to process
>      */
>     java.util.List<String> classFileNames = new java.util.LinkedList<String>();
> 
643c660,661
<               if (recognizedOptions[j].matches(flag)) break;
---
>               if (recognizedOptions[j].matches(flag))
>                   break;
696c714
<       return filenames;
---
>       return sourceFileNames;
768a787
>       boolean classesAsDecls = options.get("-XclassesAsDecls") != null;
895c914
<               filenames.addAll(genSourceFileNames);
---
>               sourceFileNames.addAll(genSourceFileNames);
905a925
>               classFileNames.addAll(genClassFileNames);
906a927
> 
911c932,934
<                   out.println("filenames: " + filenames);
---
>                   out.println("filenames: " + sourceFileNames);
>                   if (classesAsDecls)
>                       out.println("classnames: " + classFileNames);
920c943,945
<           } while(genSourceFileNames.size() != 0 && bark.nerrors == 0);
---
>           } while(((genSourceFileNames.size() != 0 ) ||
>                    (classesAsDecls && genClassFileNames.size() != 0)) && 
>                   bark.nerrors == 0);
929c954
<        * test would also fail for syntax errors caught be javac.
---
>        * test would also fail for syntax errors caught by javac.
1024,1025c1049,1054
<           
<           List<Symbol.ClassSymbol> cs = comp.compile(List.make(filenames.toArray(new String[0])),
---
>           java.util.List<String> nameList = new java.util.LinkedList<String>();
>           nameList.addAll(sourceFileNames);
>           if (options.get("-XclassesAsDecls") != null) 
>               nameList.addAll(classFileNames);
> 
>           List<Symbol.ClassSymbol> cs = comp.compile(List.make(nameList.toArray(new String[0])),
1074c1103,1104
<           filenames = new java.util.LinkedList<String>();
---
>           sourceFileNames = new java.util.LinkedList<String>();
>           classFileNames  = new java.util.LinkedList<String>();

src/share/classes/com/sun/tools/apt/main>sccs sccsdiff -r1.10 -r1.11 JavaCompiler.java

------- JavaCompiler.java -------
30,38c30,34
< /** This class could be the main entry point for GJC when GJC is used as a
<  *  component in a larger software system. It provides operations to
<  *  construct a new compiler, and to run a new compiler on a set of source
<  *  files.
<  *
<  *  <p><b>This is NOT part of any API suppored by Sun Microsystems.  If
<  *  you write code that depends on this, you do so at your own risk.
<  *  This code and its internal interfaces are subject to change or
<  *  deletion without notice.</b>
---
> /** 
>  *  <p><b>This is NOT part of any API supported by Sun Microsystems.
>  *  If you write code that depends on this, you do so at your own
>  *  risk.  This code and its internal interfaces are subject to change
>  *  or deletion without notice.</b>
159c155
<       reader = ClassReader.instance(context);
---
>       reader = AptClassReader.instance0(context);
198a195
>       classesAsDecls= options.get("-XclassesAsDecls") != null;
259a257,260
>     /** Are class files being treated as declarations
>      */
>     public boolean classesAsDecls;
> 
426a428
> 
431c433,447
<           for (List<String> l = filenames; l.nonEmpty(); l = l.tail)
---
>           for (List<String> l = filenames; l.nonEmpty(); l = l.tail) {
>               if (classesAsDecls) {
>                   if (! l.head.endsWith(".java") ) { // process as class file
>                       ClassSymbol cs = reader.enterClass(names.fromString(l.head));
>                       try {
>                           cs.complete();
>                       } catch(Symbol.CompletionFailure cf) {
>                           bark.error(Position.NOPOS, "CantFindClass", l);
>                           continue;
>                       }
> 
>                       classes.append(cs); // add to list of classes
>                       continue;
>                   }
>               }
432a449
>           }
441c458,460
<               apt.main(roots, origOptions, aptCL,
---
>               apt.main(roots,
>                        classes,
>                        origOptions, aptCL,
568a588,616
> 
>     static class AptClassReader extends com.sun.tools.javac.jvm.ClassReader {
>       public static AptClassReader instance0(Context context) {
>           ClassReader instance = context.get(classReaderKey);
>           if (instance == null) 
>               instance = new AptClassReader(context);
>           return (AptClassReader)instance;
>       }
> 
>       public static void preRegister(final Context context) {
>           context.put(classReaderKey, new Context.Factory<ClassReader>() {
>               public ClassReader make() {
>                   return new AptClassReader(context);
>               }
>           });
>       }
> 
>       private AptClassReader(Context context) {
>           super(context, true);
>       }
> 
>       protected FileEntry preferredFileEntry(FileEntry sourceEntry,
>                                              FileEntry classEntry) {
>           // apt always prefers source over class files so that
>           // annotations with source retention level are maximally
>           // available.
>           return sourceEntry;
>       }
>     }
src/share/classes/com/sun/tools/apt/comp>sccs sccsdiff -r1.16 -r1.17  Apt.java       

------- Apt.java -------
9a10
> import com.sun.tools.javac.code.*;
44,47c45,48
<  *  <p><b>This is NOT part of any API suppored by Sun Microsystems.  If
<  *  you write code that depends on this, you do so at your own risk.
<  *  This code and its internal interfaces are subject to change or
<  *  deletion without notice.</b>
---
>  *  <p><b>This is NOT part of any API supported by Sun Microsystems.
>  *  If you write code that depends on this, you do so at your own
>  *  risk.  This code and its internal interfaces are subject to change
>  *  or deletion without notice.</b>
116c117
<       public AptTreeScanner(){
---
>       public AptTreeScanner() {
120d120
< 
164a165,190
>     Set<String> computeAnnotationSet(Collection<ClassSymbol> classSymbols) {
>       Set<String> annotationSet = new HashSet<String>();
> 
>       for(ClassSymbol classSymbol: classSymbols) {
>           computeAnnotationSet(classSymbol, annotationSet);
>       }
>       return annotationSet;
>     }
> 
>     void computeAnnotationSet(Symbol symbol, Set<String> annotationSet) {
>       if (symbol != null ) {
>           if (symbol.attributes() != null)
>               for(Attribute.Compound compound: symbol.attributes())
>                   annotationSet.add(compound.type.tsym.toString()); // should fullName be used instead of toString?
> 
>           if (symbol instanceof Symbol.MethodSymbol) // add parameter annotations
>               for(Symbol param: ((MethodSymbol) symbol).params())
>                   computeAnnotationSet(param, annotationSet);
> 
>           if (symbol.members() != null) {
>               for(Scope.Entry e: symbol.members().table)
>                   computeAnnotationSet(e.sym, annotationSet);
>           }
>       }
>     }
> 
165a192
>                    ListBuffer<ClassSymbol> classes,
171a199
>       Options options = Options.instance(context);
172a201,210
>       Collection<TypeDeclaration> spectypedecls =     new LinkedHashSet<TypeDeclaration>();
>       Collection<TypeDeclaration> typedecls =         new LinkedHashSet<TypeDeclaration>();
>       Set<String> unmatchedAnnotations =              new LinkedHashSet<String>();
>       Set<AnnotationTypeDeclaration> emptyATDS =      Collections.emptySet();
>       Set<Class<? extends AnnotationProcessorFactory> > currentRoundFactories = 
>           new LinkedHashSet<Class<? extends AnnotationProcessorFactory> >();
>           
>       // Determine what annotations are present on the input source
>       // files, create collections of specified type declarations,
>       // and type declarations.
179,181d216
< 
<       Collection<TypeDeclaration> spectypedecls = new LinkedHashSet<TypeDeclaration>();
< 
187,191c222,226
<       Set<AnnotationTypeDeclaration> emptyATDS = Collections.emptySet();
<       Set<Class<? extends AnnotationProcessorFactory> > currentRoundFactories = 
<           new LinkedHashSet<Class<? extends AnnotationProcessorFactory> >();
<       Collection<TypeDeclaration> typedecls = new LinkedHashSet<TypeDeclaration>();
<       Set<String> unmatchedAnnotations = (new LinkedHashSet<String>());
---
>       for (ClassSymbol cs : ats.declCollection) {
>           TypeDeclaration decl = aptenv.declMaker.getTypeDeclaration(cs);
>           typedecls.add(decl);
>       }
> 
194c229,230
<       for (ClassSymbol cs : ats.declCollection) {
---
>       // Process input class files
>       for(ClassSymbol cs : classes) {
195a232,233
>           // System.out.println("Adding a class to spectypedecls");
>           spectypedecls.add(decl);
196a235
>           computeAnnotationSet(cs, unmatchedAnnotations); 
199,200d237
<       Options options = Options.instance(context);
< 
203c240
<                       (new TreeSet<String>(ats.getAnnotationSet())).toString());
---
>                       (new TreeSet<String>(unmatchedAnnotations)).toString());
218c255
<           if (treeList.size() == 0 )
---
>           if (spectypedecls.size() == 0 )
271c308
<               if (treeList.size() == 0)
---
>               if (spectypedecls.size() == 0)
390c427
<           if (treeList.size() == 0 && 
---
>           if (spectypedecls.size() == 0 && 
src/share/classes/com/sun/tools/apt/comp>sccs sccsdiff -r1.8 -r1.9 PrintAP.java 

------- PrintAP.java -------
321,322c321
<           printFormalTypeParameterSet(e.getFormalTypeParameters());
<           System.out.print(" ");
---
>           printFormalTypeParameterSet(e.getFormalTypeParameters(), true);
326c325
<           printFormalTypeParameterSet(d.getFormalTypeParameters());
---
>           printFormalTypeParameterSet(d.getFormalTypeParameters(), false);
329c328
<       private void printFormalTypeParameterSet(Collection<TypeParameterDeclaration> typeParams) {
---
>       private void printFormalTypeParameterSet(Collection<TypeParameterDeclaration> typeParams, boolean pad) {
340a340,342
>               if (pad)
>                   System.out.print(" ");
> 
src/share/classes/com/sun/tools/apt/mirror/apt>sccs sccsdiff -r1.6 -r1.7 FilerImpl.java

------- FilerImpl.java -------
31a32,65
>     /*
>      * The Filer class must maintain a number of constraints.  First,
>      * multiple attempts to open the same path within the same
>      * invocation of apt results in an IOException being thrown.  For
>      * example, trying to open the same source file twice:
>      *
>      * createSourceFile("foo.Bar")
>      * ...
>      * createSourceFile("foo.Bar")
>      *
>      * is disallowed as is opening a text file that happens to have
>      * the same name as a source file:
>      *
>      * createSourceFile("foo.Bar")
>      * ...
>      * createTextFile(SOURCE_TREE, "foo", new File("Bar"), null)
>      *
>      * Additionally, creating a source file that corresponds to an
>      * already created class file (or vice versa) generates at least a
>      * warning.  This is an error if -XclassesAsDecls is being used
>      * since you can't create the same type twice.  However, if the
>      * Filer is used to create a text file named *.java that happens
>      * to correspond to an existing class file, a warning is *not*
>      * generated.  Similarly, a warning is not generated for a binary
>      * file named *.class and an existing source file.
>      *
>      * The reason for this difference is that source files and class
>      * files are registered with apt and can get passed on as
>      * declarations to the next round of processing.  Files that are
>      * just named *.java and *.class are not processed in that manner;
>      * although having extra source files and class files on the
>      * source path and class path can alter the behavior of the tool
>      * and any final compile.
>      */
32a67,102
>     private enum FileKind { 
>       SOURCE {
>           void register(File file, String name, FilerImpl that) throws IOException {
>               // Check for corresponding class file
>               if (that.filesCreated.contains(new File(that.locations.get(CLASS_TREE),
>                                                       that.nameToPath(name, ".class")))) {
> 
>                   that.bark.warning(Position.NOPOS, "CorrespondingClassFile", name);
>                   if (that.opts.get("-XclassesAsDecls") !
                                     
2004-09-26
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
1.5.0_01
mustang

FIXED IN:
1.5.0_01
mustang

INTEGRATED IN:
1.5.0_01
mustang


                                     
2004-09-26
SUGGESTED FIX

= null)
>                       throw new IOException();
>               }
>               that.sourceFileNames.add(file.getPath());
>           }
>       },
> 
>       CLASS  {
>           void register(File file, String name, FilerImpl that) throws IOException {
>               if (that.filesCreated.contains(new File(that.locations.get(SOURCE_TREE),
>                                                       that.nameToPath(name, ".java")))) {
>                   that.bark.warning(Position.NOPOS, "CorrespondingSourceFile", name);
>                   if (that.opts.get("-XclassesAsDecls") != null)
>                       throw new IOException();
>               }
>               // Track the binary name instead of the filesystem location
>               that.classFileNames.add(name);
>           }
>       },
> 
>       OTHER  {
>           // Nothing special to do
>           void register(File file, String name, FilerImpl that) throws IOException {}
>       };
> 
>       abstract void register(File file, String name, FilerImpl that) throws IOException;
>     }
> 
111a182
>       String pathname = nameToPath(name, ".java");
113,115c184,185
<                            nameToPath(name, ".java"));
<       PrintWriter pw = getPrintWriter(file, encoding);
<       sourceFileNames.add(file.getPath());
---
>                            pathname);
>       PrintWriter pw = getPrintWriter(file, encoding, name, FileKind.SOURCE);
124,125c194,196
<       OutputStream os = getOutputStream(CLASS_TREE, pathname);
<       classFileNames.add(pathname);
---
>       File file = new File(locations.get(CLASS_TREE),
>                            pathname);
>       OutputStream os = getOutputStream(file, name, FileKind.CLASS);
142c213
<       return getPrintWriter(loc, file.getPath(), charsetName);
---
>       return getPrintWriter(loc, file.getPath(), charsetName, null, FileKind.OTHER);
154c225
<       return getOutputStream(loc, file.getPath());
---
>       return getOutputStream(loc, file.getPath(), null, FileKind.OTHER);
179c250
<                                      String encoding) throws IOException {
---
>                                      String encoding, String name, FileKind kind) throws IOException {
181c252
<       return getPrintWriter(file, encoding);
---
>       return getPrintWriter(file, encoding, name, kind);
188,189c259,260
<                                      String encoding) throws IOException {
<       prepareFile(file);
---
>                                      String encoding, String name, FileKind kind) throws IOException {
>       prepareFile(file, name, kind);
203c274
<     private OutputStream getOutputStream(Location loc, String pathname)
---
>     private OutputStream getOutputStream(Location loc, String pathname, String name, FileKind kind)
206c277,281
<       prepareFile(file);
---
>       return getOutputStream(file, name, kind);
>     }
> 
>     private OutputStream getOutputStream(File file, String name, FileKind kind) throws IOException {
>       prepareFile(file, name, kind);
209a285
> 
229c305
<     private void prepareFile(File file) throws IOException {
---
>     private void prepareFile(File file, String name, FileKind kind) throws IOException {
234c310,311
<       if (!filesCreated.add(file)) {
---
> 
>       if (filesCreated.contains(file)) {
237,239d313
<       }
<       if (file.exists()) {
<           file.delete();
241,243c315,324
<           File parent = file.getParentFile();
<           if (parent != null && !parent.exists()) {
<               parent.mkdirs();
---
>           if (file.exists()) {
>               file.delete();
>           } else {
>               File parent = file.getParentFile();
>               if (parent != null && !parent.exists()) {
>                   if(!parent.mkdirs()) {
>                       bark.warning(Position.NOPOS, "BadParentDirectory", file.toString());
>                       throw new IOException();
>                   }
>               }
244a326,328
> 
>           kind.register(file, name, this);
>           filesCreated.add(file);
src/share/classes/com/sun/tools/javac/code>sccs sccsdiff -r1.75 -r1.76 Symbol.java

------- Symbol.java -------
894c894
<                                              name.table.fromString("arg" + i),
---
>                                              name.table.fromString("arg" + i++),
src/share/classes/com/sun/tools/apt/resources>sccs sccsdiff -r1.6 -r1.7 apt.properties

------- apt.properties -------
19a20,25
> apt.msg.bug=> An exception has occurred in apt ({0}). > Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport)  > after checking the Bug Parade for duplicates. > Include your program and the following diagnostic in your report.  Thank you.
> 
55a62,63
> apt.opt.XClassesAsDecls=>     Treat both class and source files as declarations to process
69a78,80
> apt.err.CantFindClass=>     Could not find class file for {0}
> 
104a116,118
> apt.warn.BadParentDirectory=>     Failed to create some parent directory of {0} 
> 
134a149,154
> 
> apt.warn.CorrespondingClassFile=>     A class file corresponding to source file ''{0}'' has already been created.
> 
> apt.warn.CorrespondingSourceFile=>     A source file corresponding to class file ''{0}'' has already been created.

###@###.### 2004-09-16
                                     
2004-09-16
EVALUATION

Probably a useful feature; need to investigate impact on incorporating this into javac infrastructure.

###@###.### 2004-02-18

Requested by JAX* users; should be included in Tiger.

###@###.### 2004-04-25

Evaluating options to provide this functionality post Tiger Beta3.

###@###.### 2004-07-27
                                     
2004-04-25



Hardware and Software, Engineered to Work Together