EMMA Coverage Report (generated Thu Dec 06 15:52:10 GMT 2007)
[all classes][com.sun.tools.javac.processing]

COVERAGE SUMMARY FOR SOURCE FILE [JavacFiler.java]

nameclass, %method, %block, %line, %
JavacFiler.java12%  (1/8)6%   (3/50)10%  (87/854)13%  (23/181)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class JavacFiler$10%   (0/1)0%   (0/1)0%   (0/19)0%   (0/1)
<static initializer> 0%   (0/1)0%   (0/19)0%   (0/1)
     
class JavacFiler$FilerInputFileObject0%   (0/1)0%   (0/4)0%   (0/19)0%   (0/6)
JavacFiler$FilerInputFileObject (JavacFiler, FileObject): void 0%   (0/1)0%   (0/7)0%   (0/3)
delete (): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
openOutputStream (): OutputStream 0%   (0/1)0%   (0/5)0%   (0/1)
openWriter (): Writer 0%   (0/1)0%   (0/5)0%   (0/1)
     
class JavacFiler$FilerInputJavaFileObject0%   (0/1)0%   (0/5)0%   (0/29)0%   (0/8)
JavacFiler$FilerInputJavaFileObject (JavacFiler, JavaFileObject): void 0%   (0/1)0%   (0/11)0%   (0/4)
getAccessLevel (): Modifier 0%   (0/1)0%   (0/4)0%   (0/1)
getKind (): JavaFileObject$Kind 0%   (0/1)0%   (0/4)0%   (0/1)
getNestingKind (): NestingKind 0%   (0/1)0%   (0/4)0%   (0/1)
isNameCompatible (String, JavaFileObject$Kind): boolean 0%   (0/1)0%   (0/6)0%   (0/1)
     
class JavacFiler$FilerOutputFileObject0%   (0/1)0%   (0/7)0%   (0/72)0%   (0/17)
JavacFiler$FilerOutputFileObject (JavacFiler, String, FileObject): void 0%   (0/1)0%   (0/13)0%   (0/5)
delete (): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
getCharContent (boolean): CharSequence 0%   (0/1)0%   (0/5)0%   (0/1)
openInputStream (): InputStream 0%   (0/1)0%   (0/5)0%   (0/1)
openOutputStream (): OutputStream 0%   (0/1)0%   (0/21)0%   (0/4)
openReader (boolean): Reader 0%   (0/1)0%   (0/5)0%   (0/1)
openWriter (): Writer 0%   (0/1)0%   (0/21)0%   (0/4)
     
class JavacFiler$FilerOutputJavaFileObject0%   (0/1)0%   (0/5)0%   (0/30)0%   (0/8)
JavacFiler$FilerOutputJavaFileObject (JavacFiler, String, JavaFileObject): void 0%   (0/1)0%   (0/12)0%   (0/4)
getAccessLevel (): Modifier 0%   (0/1)0%   (0/4)0%   (0/1)
getKind (): JavaFileObject$Kind 0%   (0/1)0%   (0/4)0%   (0/1)
getNestingKind (): NestingKind 0%   (0/1)0%   (0/4)0%   (0/1)
isNameCompatible (String, JavaFileObject$Kind): boolean 0%   (0/1)0%   (0/6)0%   (0/1)
     
class JavacFiler$FilerOutputStream0%   (0/1)0%   (0/2)0%   (0/34)0%   (0/11)
JavacFiler$FilerOutputStream (JavacFiler, String, FileObject): void 0%   (0/1)0%   (0/17)0%   (0/6)
close (): void 0%   (0/1)0%   (0/17)0%   (0/5)
     
class JavacFiler$FilerWriter0%   (0/1)0%   (0/2)0%   (0/34)0%   (0/11)
JavacFiler$FilerWriter (JavacFiler, String, FileObject): void 0%   (0/1)0%   (0/17)0%   (0/6)
close (): void 0%   (0/1)0%   (0/17)0%   (0/5)
     
class JavacFiler100% (1/1)12%  (3/24)14%  (87/617)19%  (23/120)
access$000 (JavacFiler, String, FileObject): void 0%   (0/1)0%   (0/5)0%   (0/1)
checkFileReopening (FileObject, boolean): void 0%   (0/1)0%   (0/53)0%   (0/8)
checkName (String): void 0%   (0/1)0%   (0/5)0%   (0/2)
checkName (String, boolean): void 0%   (0/1)0%   (0/34)0%   (0/5)
checkNameAndExistence (String, boolean): void 0%   (0/1)0%   (0/40)0%   (0/6)
closeFileObject (String, FileObject): void 0%   (0/1)0%   (0/55)0%   (0/13)
createClassFile (CharSequence, Element []): JavaFileObject 0%   (0/1)0%   (0/6)0%   (0/1)
createResource (JavaFileManager$Location, CharSequence, CharSequence, Element... 0%   (0/1)0%   (0/43)0%   (0/9)
createSourceFile (CharSequence, Element []): JavaFileObject 0%   (0/1)0%   (0/6)0%   (0/1)
createSourceOrClassFile (boolean, String): JavaFileObject 0%   (0/1)0%   (0/66)0%   (0/12)
displayState (): void 0%   (0/1)0%   (0/74)0%   (0/8)
getGeneratedClasses (): Map 0%   (0/1)0%   (0/3)0%   (0/1)
getGeneratedSourceFileObjects (): Set 0%   (0/1)0%   (0/3)0%   (0/1)
getGeneratedSourceNames (): Set 0%   (0/1)0%   (0/3)0%   (0/1)
getResource (JavaFileManager$Location, CharSequence, CharSequence): FileObject 0%   (0/1)0%   (0/29)0%   (0/6)
isPackageInfo (String, boolean): boolean 0%   (0/1)0%   (0/39)0%   (0/7)
locationCheck (JavaFileManager$Location): void 0%   (0/1)0%   (0/22)0%   (0/5)
newFiles (): boolean 0%   (0/1)0%   (0/12)0%   (0/1)
newRound (Context, boolean): void 0%   (0/1)0%   (0/13)0%   (0/5)
toString (): String 0%   (0/1)0%   (0/2)0%   (0/1)
warnIfUnclosedFiles (): void 0%   (0/1)0%   (0/17)0%   (0/3)
JavacFiler (Context): void 100% (1/1)100% (62/62)100% (13/13)
clearRoundState (): void 100% (1/1)100% (10/10)100% (4/4)
close (): void 100% (1/1)100% (15/15)100% (6/6)

1/*
2 * Copyright 2005-2006 Sun Microsystems, Inc.  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.  Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25 
26package com.sun.tools.javac.processing;
27 
28import com.sun.tools.javac.util.*;
29import javax.annotation.processing.*;
30import javax.lang.model.SourceVersion;
31import javax.lang.model.element.NestingKind;
32import javax.lang.model.element.Modifier;
33import javax.lang.model.element.Element;
34import java.util.*;
35 
36import java.io.Closeable;
37import java.io.File;
38import java.io.InputStream;
39import java.io.OutputStream;
40import java.io.OutputStreamWriter;
41import java.io.FilterOutputStream;
42import java.io.Reader;
43import java.io.Writer;
44import java.io.FilterWriter;
45import java.io.PrintWriter;
46import java.io.IOException;
47import java.net.URI;
48import javax.tools.FileObject;
49 
50import javax.tools.*;
51import static java.util.Collections.*;
52 
53import javax.tools.JavaFileManager.Location;
54import static javax.tools.StandardLocation.SOURCE_OUTPUT;
55import static javax.tools.StandardLocation.CLASS_OUTPUT;
56 
57/**
58 * The FilerImplementation class must maintain a number of
59 * constraints.  First, multiple attempts to open the same path within
60 * the same invocation of the tool results in an IOException being
61 * thrown.  For example, trying to open the same source file twice:
62 *
63 * <pre>
64 * createSourceFile("foo.Bar")
65 * ...
66 * createSourceFile("foo.Bar")
67 * </pre>
68 *
69 * is disallowed as is opening a text file that happens to have
70 * the same name as a source file:
71 *
72 * <pre>
73 * createSourceFile("foo.Bar")
74 * ...
75 * createTextFile(SOURCE_TREE, "foo", new File("Bar"), null)
76 * </pre>
77 *
78 * <p>Additionally, creating a source file that corresponds to an
79 * already created class file (or vice versa) also results in an
80 * IOException since each type can only be created once.  However, if
81 * the Filer is used to create a text file named *.java that happens
82 * to correspond to an existing class file, a warning is *not*
83 * generated.  Similarly, a warning is not generated for a binary file
84 * named *.class and an existing source file.
85 *
86 * <p>The reason for this difference is that source files and class
87 * files are registered with the tool and can get passed on as
88 * declarations to the next round of processing.  Files that are just
89 * named *.java and *.class are not processed in that manner; although
90 * having extra source files and class files on the source path and
91 * class path can alter the behavior of the tool and any final
92 * compile.
93 *
94 * <p><b>This is NOT part of any API supported by Sun Microsystems.
95 * If you write code that depends on this, you do so at your own risk.
96 * This code and its internal interfaces are subject to change or
97 * deletion without notice.</b>
98 */
99public class JavacFiler implements Filer, Closeable {
100    // TODO: Implement different transaction model for updating the
101    // Filer's record keeping on file close.
102 
103    private static final String ALREADY_OPENED =
104        "Output stream or writer has already been opened.";
105    private static final String NOT_FOR_READING =
106        "FileObject was not opened for reading.";
107    private static final String NOT_FOR_WRITING =
108        "FileObject was not opened for writing.";
109 
110    /**
111     * Wrap a JavaFileObject to manage writing by the Filer.
112     */
113    private class FilerOutputFileObject extends ForwardingFileObject<FileObject> {
114        private boolean opened = false;
115        private String name;
116 
117        FilerOutputFileObject(String name, FileObject fileObject) {
118            super(fileObject);
119            this.name = name;
120        }
121 
122        @Override
123        public synchronized OutputStream openOutputStream() throws IOException {
124            if (opened)
125                throw new IOException(ALREADY_OPENED);
126            opened = true;
127            return new FilerOutputStream(name, fileObject);
128        }
129 
130        @Override
131        public synchronized Writer openWriter() throws IOException {
132            if (opened)
133                throw new IOException(ALREADY_OPENED);
134            opened = true;
135            return new FilerWriter(name, fileObject);
136        }
137 
138        // Three anti-literacy methods
139        @Override
140        public InputStream openInputStream() throws IOException {
141            throw new IllegalStateException(NOT_FOR_READING);
142        }
143 
144        @Override
145        public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
146            throw new IllegalStateException(NOT_FOR_READING);
147        }
148 
149        @Override
150        public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
151            throw new IllegalStateException(NOT_FOR_READING);
152        }
153 
154        @Override
155        public boolean delete() {
156            return false;
157        }
158    }
159 
160    private class FilerOutputJavaFileObject extends FilerOutputFileObject implements JavaFileObject {
161        private final JavaFileObject javaFileObject;
162        FilerOutputJavaFileObject(String name, JavaFileObject javaFileObject) {
163            super(name, javaFileObject);
164            this.javaFileObject = javaFileObject;
165        }
166 
167        public JavaFileObject.Kind getKind() {
168            return javaFileObject.getKind();
169        }
170 
171        public boolean isNameCompatible(String simpleName,
172                                        JavaFileObject.Kind kind) {
173            return javaFileObject.isNameCompatible(simpleName, kind);
174        }
175 
176        public NestingKind getNestingKind() {
177            return javaFileObject.getNestingKind();
178        }
179 
180        public Modifier getAccessLevel() {
181            return javaFileObject.getAccessLevel();
182        }
183    }
184 
185    /**
186     * Wrap a JavaFileObject to manage reading by the Filer.
187     */
188    private class FilerInputFileObject extends ForwardingFileObject<FileObject> {
189        FilerInputFileObject(FileObject fileObject) {
190            super(fileObject);
191        }
192 
193        @Override
194        public OutputStream openOutputStream() throws IOException {
195            throw new IllegalStateException(NOT_FOR_WRITING);
196        }
197 
198        @Override
199        public Writer openWriter() throws IOException {
200            throw new IllegalStateException(NOT_FOR_WRITING);
201        }
202 
203        @Override
204        public boolean delete() {
205            return false;
206        }
207    }
208 
209    private class FilerInputJavaFileObject extends FilerInputFileObject implements JavaFileObject {
210        private final JavaFileObject javaFileObject;
211        FilerInputJavaFileObject(JavaFileObject javaFileObject) {
212            super(javaFileObject);
213            this.javaFileObject = javaFileObject;
214        }
215 
216        public JavaFileObject.Kind getKind() {
217            return javaFileObject.getKind();
218        }
219 
220        public boolean isNameCompatible(String simpleName,
221                                        JavaFileObject.Kind kind) {
222            return javaFileObject.isNameCompatible(simpleName, kind);
223        }
224 
225        public NestingKind getNestingKind() {
226            return javaFileObject.getNestingKind();
227        }
228 
229        public Modifier getAccessLevel() {
230            return javaFileObject.getAccessLevel();
231        }
232    }
233 
234 
235    /**
236     * Wrap a {@code OutputStream} returned from the {@code
237     * JavaFileManager} to properly register source or class files
238     * when they are closed.
239     */
240    private class FilerOutputStream extends FilterOutputStream {
241        String typeName;
242        FileObject fileObject;
243        boolean closed = false;
244 
245        /**
246         * @param typeName name of class or {@code null} if just a
247         * binary file
248         */
249        FilerOutputStream(String typeName, FileObject fileObject) throws IOException {
250            super(fileObject.openOutputStream());
251            this.typeName = typeName;
252            this.fileObject = fileObject;
253        }
254 
255        public synchronized void close() throws IOException {
256            if (!closed) {
257                closed = true;
258                /*
259                 * If an IOException occurs when closing the underlying
260                 * stream, still try to process the file.
261                 */
262 
263                closeFileObject(typeName, fileObject);
264                out.close();
265            }
266        }
267    }
268 
269    /**
270     * Wrap a {@code Writer} returned from the {@code JavaFileManager}
271     * to properly register source or class files when they are
272     * closed.
273     */
274    private class FilerWriter extends FilterWriter {
275        String typeName;
276        FileObject fileObject;
277        boolean closed = false;
278 
279        /**
280         * @param fileObject the fileObject to be written to
281         * @param typeName name of source file or {@code null} if just a
282         * text file
283         */
284        FilerWriter(String typeName, FileObject fileObject) throws IOException {
285            super(fileObject.openWriter());
286            this.typeName = typeName;
287            this.fileObject = fileObject;
288        }
289 
290        public synchronized void close() throws IOException {
291            if (!closed) {
292                closed = true;
293                /*
294                 * If an IOException occurs when closing the underlying
295                 * Writer, still try to process the file.
296                 */
297 
298                closeFileObject(typeName, fileObject);
299                out.close();
300            }
301        }
302    }
303 
304    JavaFileManager fileManager;
305    Log log;
306    Context context;
307    boolean lastRound;
308 
309    private final boolean lint;
310 
311    /**
312     * Logical names of all created files.  This set must be
313     * synchronized.
314     */
315    private final Set<FileObject> fileObjectHistory;
316 
317    /**
318     * Names of types that have had files created but not closed.
319     */
320    private final Set<String> openTypeNames;
321 
322    /**
323     * Names of source files closed in this round.  This set must be
324     * synchronized.  Its iterators should preserve insertion order.
325     */
326    private Set<String> generatedSourceNames;
327 
328    /**
329     * Names and class files of the class files closed in this round.
330     * This set must be synchronized.  Its iterators should preserve
331     * insertion order.
332     */
333    private final Map<String, JavaFileObject> generatedClasses;
334 
335    /**
336     * JavaFileObjects for source files closed in this round.  This
337     * set must be synchronized.  Its iterators should preserve
338     * insertion order.
339     */
340    private Set<JavaFileObject> generatedSourceFileObjects;
341 
342    /**
343     * Names of all created source files.  Its iterators should
344     * preserve insertion order.
345     */
346    private final Set<String> aggregateGeneratedSourceNames;
347 
348    /**
349     * Names of all created class files.  Its iterators should
350     * preserve insertion order.
351     */
352    private final Set<String> aggregateGeneratedClassNames;
353 
354 
355    JavacFiler(Context context) {
356        this.context = context;
357        fileManager = context.get(JavaFileManager.class);
358 
359        log = Log.instance(context);
360 
361        fileObjectHistory = synchronizedSet(new LinkedHashSet<FileObject>());
362        generatedSourceNames = synchronizedSet(new LinkedHashSet<String>());
363        generatedSourceFileObjects = synchronizedSet(new LinkedHashSet<JavaFileObject>());
364 
365        generatedClasses = synchronizedMap(new LinkedHashMap<String, JavaFileObject>());
366 
367        openTypeNames  = synchronizedSet(new LinkedHashSet<String>());
368 
369        aggregateGeneratedSourceNames = new LinkedHashSet<String>();
370        aggregateGeneratedClassNames  = new LinkedHashSet<String>();
371 
372        lint = (Options.instance(context)).lint("processing");
373    }
374 
375    public JavaFileObject createSourceFile(CharSequence name,
376                                           Element... originatingElements) throws IOException {
377        return createSourceOrClassFile(true, name.toString());
378    }
379 
380    public JavaFileObject createClassFile(CharSequence name,
381                                           Element... originatingElements) throws IOException {
382        return createSourceOrClassFile(false, name.toString());
383    }
384 
385    private JavaFileObject createSourceOrClassFile(boolean isSourceFile, String name) throws IOException {
386        checkNameAndExistence(name, isSourceFile);
387        Location loc = (isSourceFile ? SOURCE_OUTPUT : CLASS_OUTPUT);
388        JavaFileObject.Kind kind = (isSourceFile ?
389                                    JavaFileObject.Kind.SOURCE :
390                                    JavaFileObject.Kind.CLASS);
391 
392        JavaFileObject fileObject =
393            fileManager.getJavaFileForOutput(loc, name, kind, null);
394        checkFileReopening(fileObject, true);
395 
396        if (lastRound)
397            log.warning("proc.file.create.last.round", name);
398 
399        if (isSourceFile)
400            aggregateGeneratedSourceNames.add(name);
401        else
402            aggregateGeneratedClassNames.add(name);
403        openTypeNames.add(name);
404 
405        return new FilerOutputJavaFileObject(name, fileObject);
406    }
407 
408    public FileObject createResource(JavaFileManager.Location location,
409                                     CharSequence pkg,
410                                     CharSequence relativeName,
411                                     Element... originatingElements) throws IOException {
412        locationCheck(location);
413 
414        String strPkg = pkg.toString();
415        if (strPkg.length() > 0)
416            checkName(strPkg);
417 
418        FileObject fileObject =
419            fileManager.getFileForOutput(location, strPkg,
420                                         relativeName.toString(), null);
421        checkFileReopening(fileObject, true);
422 
423        if (fileObject instanceof JavaFileObject)
424            return new FilerOutputJavaFileObject(null, (JavaFileObject)fileObject);
425        else
426            return new FilerOutputFileObject(null, fileObject);
427    }
428 
429    private void locationCheck(JavaFileManager.Location location) {
430        if (location instanceof StandardLocation) {
431            StandardLocation stdLoc = (StandardLocation) location;
432            if (!stdLoc.isOutputLocation())
433                throw new IllegalArgumentException("Resource creation not supported in location " +
434                                                   stdLoc);
435        }
436    }
437 
438    public FileObject getResource(JavaFileManager.Location location,
439                                  CharSequence pkg,
440                                  CharSequence relativeName) throws IOException {
441        String strPkg = pkg.toString();
442        if (strPkg.length() > 0)
443            checkName(strPkg);
444 
445        // TODO: Only support reading resources in selected output
446        // locations?  Only allow reading of non-source, non-class
447        // files from the supported input locations?
448        FileObject fileObject = fileManager.getFileForOutput(location,
449                                                             pkg.toString(),
450                                                             relativeName.toString(),
451                                                             null);
452        // If the path was already opened for writing, throw an exception.
453        checkFileReopening(fileObject, false);
454        return new FilerInputFileObject(fileObject);
455    }
456 
457    private void checkName(String name) throws FilerException {
458        checkName(name, false);
459    }
460 
461    private void checkName(String name, boolean allowUnnamedPackageInfo) throws FilerException {
462        if (!SourceVersion.isName(name) && !isPackageInfo(name, allowUnnamedPackageInfo)) {
463            if (lint)
464                log.warning("proc.illegal.file.name", name);
465            throw new FilerException("Illegal name " + name);
466        }
467    }
468 
469    private boolean isPackageInfo(String name, boolean allowUnnamedPackageInfo) {
470        // Is the name of the form "package-info" or
471        // "foo.bar.package-info"?
472        final String PKG_INFO = "package-info";
473        int periodIndex = name.lastIndexOf(".");
474        if (periodIndex == -1) {
475            return allowUnnamedPackageInfo ? name.equals(PKG_INFO) : false;
476        } else {
477            // "foo.bar.package-info." illegal
478            String prefix = name.substring(0, periodIndex);
479            String simple = name.substring(periodIndex+1);
480            return SourceVersion.isName(prefix) && simple.equals(PKG_INFO);
481        }
482    }
483 
484    private void checkNameAndExistence(String typename, boolean allowUnnamedPackageInfo) throws FilerException {
485        // TODO: Check if type already exists on source or class path?
486        // If so, use warning message key proc.type.already.exists
487        checkName(typename, allowUnnamedPackageInfo);
488        if (aggregateGeneratedSourceNames.contains(typename) ||
489            aggregateGeneratedClassNames.contains(typename)) {
490            if (lint)
491                log.warning("proc.type.recreate", typename);
492            throw new FilerException("Attempt to recreate a file for type " + typename);
493        }
494    }
495 
496    /**
497     * Check to see if the file has already been opened; if so, throw
498     * an exception, otherwise add it to the set of files.
499     */
500    private void checkFileReopening(FileObject fileObject, boolean addToHistory) throws FilerException {
501        for(FileObject veteran : fileObjectHistory) {
502            if (fileManager.isSameFile(veteran, fileObject)) {
503                if (lint)
504                    log.warning("proc.file.reopening", fileObject.getName());
505                throw new FilerException("Attempt to reopen a file for path " + fileObject.getName());
506            }
507        }
508        if (addToHistory)
509            fileObjectHistory.add(fileObject);
510    }
511 
512    public boolean newFiles() {
513        return (!generatedSourceNames.isEmpty())
514            || (!generatedClasses.isEmpty());
515    }
516 
517    public Set<String> getGeneratedSourceNames() {
518        return generatedSourceNames;
519    }
520 
521    public Set<JavaFileObject> getGeneratedSourceFileObjects() {
522        return generatedSourceFileObjects;
523    }
524 
525    public Map<String, JavaFileObject> getGeneratedClasses() {
526        return generatedClasses;
527    }
528 
529    public void warnIfUnclosedFiles() {
530        if (!openTypeNames.isEmpty())
531            log.warning("proc.unclosed.type.files", openTypeNames.toString());
532    }
533 
534    /**
535     * Update internal state for a new round.
536     */
537    public void newRound(Context context, boolean lastRound) {
538        this.context = context;
539        this.log = Log.instance(context);
540        this.lastRound = lastRound;
541        clearRoundState();
542    }
543 
544    public void close() {
545        clearRoundState();
546        // Cross-round state
547        fileObjectHistory.clear();
548        openTypeNames.clear();
549        aggregateGeneratedSourceNames.clear();
550        aggregateGeneratedClassNames.clear();
551    }
552 
553    private void clearRoundState() {
554        generatedSourceNames.clear();
555        generatedSourceFileObjects.clear();
556        generatedClasses.clear();
557    }
558 
559    /**
560     * Debugging function to display internal state.
561     */
562    public void displayState() {
563        PrintWriter xout = context.get(Log.outKey);
564        xout.println("File Object History : " +  fileObjectHistory);
565        xout.println("Open Type Names     : " +  openTypeNames);
566        xout.println("Gen. Src Names      : " +  generatedSourceNames);
567        xout.println("Gen. Cls Names      : " +  generatedClasses.keySet());
568        xout.println("Agg. Gen. Src Names : " +  aggregateGeneratedSourceNames);
569        xout.println("Agg. Gen. Cls Names : " +  aggregateGeneratedClassNames);
570    }
571 
572    public String toString() {
573        return "javac Filer";
574    }
575 
576    /**
577     * Upon close, register files opened by create{Source, Class}File
578     * for annotation processing.
579     */
580    private void closeFileObject(String typeName, FileObject fileObject) {
581        /*
582         * If typeName is non-null, the file object was opened as a
583         * source or class file by the user.  If a file was opened as
584         * a resource, typeName will be null and the file is *not*
585         * subject to annotation processing.
586         */
587        if ((typeName != null)) {
588            if (!(fileObject instanceof JavaFileObject))
589                throw new AssertionError("JavaFileOject not found for " + fileObject);
590            JavaFileObject javaFileObject = (JavaFileObject)fileObject;
591            switch(javaFileObject.getKind()) {
592            case SOURCE:
593                generatedSourceNames.add(typeName);
594                generatedSourceFileObjects.add(javaFileObject);
595                openTypeNames.remove(typeName);
596                break;
597 
598            case CLASS:
599                generatedClasses.put(typeName, javaFileObject);
600                openTypeNames.remove(typeName);
601                break;
602 
603            default:
604                break;
605            }
606        }
607    }
608 
609}

[all classes][com.sun.tools.javac.processing]
EMMA 2.0.5312 (C) Vladimir Roubtsov