36 import java.io.PrintWriter;
37 import java.io.IOException;
38 import java.util.*;
39
40 import static java.util.Collections.*;
41
42 import javax.annotation.processing.*;
43 import javax.lang.model.SourceVersion;
44 import javax.lang.model.element.NestingKind;
45 import javax.lang.model.element.Modifier;
46 import javax.lang.model.element.Element;
47 import javax.tools.*;
48 import javax.tools.JavaFileManager.Location;
49
50 import static javax.tools.StandardLocation.SOURCE_OUTPUT;
51 import static javax.tools.StandardLocation.CLASS_OUTPUT;
52
53 import com.sun.tools.javac.code.Lint;
54 import com.sun.tools.javac.code.Symbol.ClassSymbol;
55 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
56 import com.sun.tools.javac.code.Symtab;
57 import com.sun.tools.javac.comp.Modules;
58 import com.sun.tools.javac.model.JavacElements;
59 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
60 import com.sun.tools.javac.util.*;
61 import com.sun.tools.javac.util.DefinedBy.Api;
62
63 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
64 import com.sun.tools.javac.code.Symbol.PackageSymbol;
65 import com.sun.tools.javac.main.Option;
66
67 /**
68 * The FilerImplementation class must maintain a number of
69 * constraints. First, multiple attempts to open the same path within
70 * the same invocation of the tool results in an IOException being
71 * thrown. For example, trying to open the same source file twice:
72 *
73 * <pre>
74 * createSourceFile("foo.Bar")
75 * ...
700 // Is the name of the form "package-info" or
701 // "foo.bar.package-info"?
702 final String PKG_INFO = "package-info";
703 int periodIndex = name.lastIndexOf(".");
704 if (periodIndex == -1) {
705 return allowUnnamedPackageInfo ? name.equals(PKG_INFO) : false;
706 } else {
707 // "foo.bar.package-info." illegal
708 String prefix = name.substring(0, periodIndex);
709 String simple = name.substring(periodIndex+1);
710 return SourceVersion.isName(prefix) && simple.equals(PKG_INFO);
711 }
712 }
713
714 private void checkNameAndExistence(ModuleSymbol mod, String typename, boolean allowUnnamedPackageInfo) throws FilerException {
715 checkName(typename, allowUnnamedPackageInfo);
716 ClassSymbol existing = elementUtils.getTypeElement(typename);
717 boolean alreadySeen = aggregateGeneratedSourceNames.contains(Pair.of(mod, typename)) ||
718 aggregateGeneratedClassNames.contains(Pair.of(mod, typename)) ||
719 initialClassNames.contains(typename) ||
720 (existing != null && initialInputs.contains(existing.sourcefile));
721 if (alreadySeen) {
722 if (lint)
723 log.warning(Warnings.ProcTypeRecreate(typename));
724 throw new FilerException("Attempt to recreate a file for type " + typename);
725 }
726 if (lint && existing != null) {
727 log.warning(Warnings.ProcTypeAlreadyExists(typename));
728 }
729 if (!mod.isUnnamed() && !typename.contains(".")) {
730 throw new FilerException("Attempt to create a type in unnamed package of a named module: " + typename);
731 }
732 }
733
734 /**
735 * Check to see if the file has already been opened; if so, throw
736 * an exception, otherwise add it to the set of files.
737 */
738 private void checkFileReopening(FileObject fileObject, boolean forWriting) throws FilerException {
739 if (isInFileObjectHistory(fileObject, forWriting)) {
740 if (lint)
741 log.warning(Warnings.ProcFileReopening(fileObject.getName()));
742 throw new FilerException("Attempt to reopen a file for path " + fileObject.getName());
743 }
744 if (forWriting)
745 fileObjectHistory.add(fileObject);
746 }
747
748 private boolean isInFileObjectHistory(FileObject fileObject, boolean forWriting) {
749 if (forWriting) {
750 for(FileObject veteran : initialInputs) {
751 try {
|
36 import java.io.PrintWriter;
37 import java.io.IOException;
38 import java.util.*;
39
40 import static java.util.Collections.*;
41
42 import javax.annotation.processing.*;
43 import javax.lang.model.SourceVersion;
44 import javax.lang.model.element.NestingKind;
45 import javax.lang.model.element.Modifier;
46 import javax.lang.model.element.Element;
47 import javax.tools.*;
48 import javax.tools.JavaFileManager.Location;
49
50 import static javax.tools.StandardLocation.SOURCE_OUTPUT;
51 import static javax.tools.StandardLocation.CLASS_OUTPUT;
52
53 import com.sun.tools.javac.code.Lint;
54 import com.sun.tools.javac.code.Symbol.ClassSymbol;
55 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
56 import com.sun.tools.javac.code.Symbol.TypeSymbol;
57 import com.sun.tools.javac.code.Symtab;
58 import com.sun.tools.javac.comp.Modules;
59 import com.sun.tools.javac.model.JavacElements;
60 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
61 import com.sun.tools.javac.util.*;
62 import com.sun.tools.javac.util.DefinedBy.Api;
63
64 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
65 import com.sun.tools.javac.code.Symbol.PackageSymbol;
66 import com.sun.tools.javac.main.Option;
67
68 /**
69 * The FilerImplementation class must maintain a number of
70 * constraints. First, multiple attempts to open the same path within
71 * the same invocation of the tool results in an IOException being
72 * thrown. For example, trying to open the same source file twice:
73 *
74 * <pre>
75 * createSourceFile("foo.Bar")
76 * ...
701 // Is the name of the form "package-info" or
702 // "foo.bar.package-info"?
703 final String PKG_INFO = "package-info";
704 int periodIndex = name.lastIndexOf(".");
705 if (periodIndex == -1) {
706 return allowUnnamedPackageInfo ? name.equals(PKG_INFO) : false;
707 } else {
708 // "foo.bar.package-info." illegal
709 String prefix = name.substring(0, periodIndex);
710 String simple = name.substring(periodIndex+1);
711 return SourceVersion.isName(prefix) && simple.equals(PKG_INFO);
712 }
713 }
714
715 private void checkNameAndExistence(ModuleSymbol mod, String typename, boolean allowUnnamedPackageInfo) throws FilerException {
716 checkName(typename, allowUnnamedPackageInfo);
717 ClassSymbol existing = elementUtils.getTypeElement(typename);
718 boolean alreadySeen = aggregateGeneratedSourceNames.contains(Pair.of(mod, typename)) ||
719 aggregateGeneratedClassNames.contains(Pair.of(mod, typename)) ||
720 initialClassNames.contains(typename) ||
721 containedInInitialInputs(typename);
722 if (alreadySeen) {
723 if (lint)
724 log.warning(Warnings.ProcTypeRecreate(typename));
725 throw new FilerException("Attempt to recreate a file for type " + typename);
726 }
727 if (lint && existing != null) {
728 log.warning(Warnings.ProcTypeAlreadyExists(typename));
729 }
730 if (!mod.isUnnamed() && !typename.contains(".")) {
731 throw new FilerException("Attempt to create a type in unnamed package of a named module: " + typename);
732 }
733 }
734
735 private boolean containedInInitialInputs(String typename) {
736 // Name could be a type name or the name of a package-info file
737 JavaFileObject sourceFile = null;
738
739 ClassSymbol existingClass = elementUtils.getTypeElement(typename);
740 if (existingClass != null) {
741 sourceFile = existingClass.sourcefile;
742 } else if (typename.endsWith(".package-info")) {
743 String targetName = typename.substring(0, typename.length() - ".package-info".length());
744 PackageSymbol existingPackage = elementUtils.getPackageElement(targetName);
745 if (existingPackage != null)
746 sourceFile = existingPackage.sourcefile;
747 }
748 return (sourceFile == null) ? false : initialInputs.contains(sourceFile);
749 }
750
751 /**
752 * Check to see if the file has already been opened; if so, throw
753 * an exception, otherwise add it to the set of files.
754 */
755 private void checkFileReopening(FileObject fileObject, boolean forWriting) throws FilerException {
756 if (isInFileObjectHistory(fileObject, forWriting)) {
757 if (lint)
758 log.warning(Warnings.ProcFileReopening(fileObject.getName()));
759 throw new FilerException("Attempt to reopen a file for path " + fileObject.getName());
760 }
761 if (forWriting)
762 fileObjectHistory.add(fileObject);
763 }
764
765 private boolean isInFileObjectHistory(FileObject fileObject, boolean forWriting) {
766 if (forWriting) {
767 for(FileObject veteran : initialInputs) {
768 try {
|