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 * ...
698
699 private boolean isPackageInfo(String name, boolean allowUnnamedPackageInfo) {
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 // TODO: Check if type already exists on source or class path?
716 // If so, use warning message key proc.type.already.exists
717 checkName(typename, allowUnnamedPackageInfo);
718 ClassSymbol existing;
719 boolean alreadySeen = aggregateGeneratedSourceNames.contains(Pair.of(mod, typename)) ||
720 aggregateGeneratedClassNames.contains(Pair.of(mod, typename)) ||
721 initialClassNames.contains(typename) ||
722 ((existing = elementUtils.getTypeElement(typename)) != null &&
723 initialInputs.contains(existing.sourcefile));
724 if (alreadySeen) {
725 if (lint)
726 log.warning(Warnings.ProcTypeRecreate(typename));
727 throw new FilerException("Attempt to recreate a file for type " + 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 * ...
699
700 private boolean isPackageInfo(String name, boolean allowUnnamedPackageInfo) {
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 // TODO: Check if type already exists on source or class path?
717 // If so, use warning message key proc.type.already.exists
718 checkName(typename, allowUnnamedPackageInfo);
719
720 boolean alreadySeen = aggregateGeneratedSourceNames.contains(Pair.of(mod, typename)) ||
721 aggregateGeneratedClassNames.contains(Pair.of(mod, typename)) ||
722 initialClassNames.contains(typename) ||
723 containedInInitialInputs(typename);
724 if (alreadySeen) {
725 if (lint)
726 log.warning(Warnings.ProcTypeRecreate(typename));
727 throw new FilerException("Attempt to recreate a file for type " + 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 private boolean containedInInitialInputs(String typename) {
735 // Name could be a type name or the name of a package-info file
736 JavaFileObject sourceFile = null;
737
738 ClassSymbol existingClass = elementUtils.getTypeElement(typename);
739 if (existingClass != null) {
740 sourceFile = existingClass.sourcefile;
741 } else if (typename.endsWith(".package-info")) {
742 String targetName = typename.substring(0, typename.length() - ".package-info".length());
743 PackageSymbol existingPackage =
744 elementUtils.getPackageElement(targetName);
745 // System.err.println("\t\tfound " + existingPackage +
746 // ", sourceFile "+ (existingPackage!= null?existingPackage.sourcefile:null));
747 if (existingPackage != null)
748 sourceFile = existingPackage.sourcefile;
749 }
750 return (sourceFile == null) ? false : initialInputs.contains(sourceFile);
751 }
752
753 /**
754 * Check to see if the file has already been opened; if so, throw
755 * an exception, otherwise add it to the set of files.
756 */
757 private void checkFileReopening(FileObject fileObject, boolean forWriting) throws FilerException {
758 if (isInFileObjectHistory(fileObject, forWriting)) {
759 if (lint)
760 log.warning(Warnings.ProcFileReopening(fileObject.getName()));
761 throw new FilerException("Attempt to reopen a file for path " + fileObject.getName());
762 }
763 if (forWriting)
764 fileObjectHistory.add(fileObject);
765 }
766
767 private boolean isInFileObjectHistory(FileObject fileObject, boolean forWriting) {
768 if (forWriting) {
769 for(FileObject veteran : initialInputs) {
770 try {
|