Mergin jlahoda's fix of #8182450: javac aborts when generating ct.sym intermittently - Initialize the module system model even in presence of missing/broken module-infos; BadClassFiles should not immediatelly abort compilation anymore, but should be handled as if the classfile did not exist.
2 * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.
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
26 package com.sun.tools.javac.code;
28 import java.io.IOException;
29 import java.nio.file.Path;
30 import java.util.EnumSet;
31 import java.util.HashMap;
32 import java.util.Iterator;
34 import java.util.NoSuchElementException;
37 import javax.lang.model.SourceVersion;
38 import javax.tools.JavaFileManager;
39 import javax.tools.JavaFileManager.Location;
40 import javax.tools.JavaFileObject;
41 import javax.tools.JavaFileObject.Kind;
42 import javax.tools.StandardJavaFileManager;
43 import javax.tools.StandardLocation;
45 import com.sun.tools.javac.api.ClassNamesForFileOraculum;
46 import com.sun.tools.javac.code.Scope.WriteableScope;
47 import com.sun.tools.javac.code.Symbol.ClassSymbol;
48 import com.sun.tools.javac.code.Symbol.Completer;
49 import com.sun.tools.javac.code.Symbol.CompletionFailure;
50 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
51 import com.sun.tools.javac.code.Symbol.PackageSymbol;
52 import com.sun.tools.javac.code.Symbol.TypeSymbol;
53 import com.sun.tools.javac.comp.Annotate;
54 import com.sun.tools.javac.file.JRTIndex;
55 import com.sun.tools.javac.file.JavacFileManager;
56 import com.sun.tools.javac.jvm.ClassReader;
57 import com.sun.tools.javac.jvm.Profile;
58 import com.sun.tools.javac.main.Option;
59 import com.sun.tools.javac.platform.PlatformDescription;
60 import com.sun.tools.javac.util.*;
62 import static javax.tools.StandardLocation.*;
64 import static com.sun.tools.javac.code.Flags.*;
65 import static com.sun.tools.javac.code.Kinds.Kind.*;
67 import com.sun.tools.javac.util.Dependencies.CompletionCause;
70 * This class provides operations to locate class definitions
71 * from the source and class files on the paths provided to javac.
73 * <p><b>This is NOT part of any supported API.
74 * If you write code that depends on this, you do so at your own risk.
75 * This code and its internal interfaces are subject to change or
76 * deletion without notice.</b>
78 public class ClassFinder {
79 /** The context key for the class finder. */
80 protected static final Context.Key<ClassFinder> classFinderKey = new Context.Key<>();
84 private final Annotate annotate;
86 /** Switch: verbose output.
91 * Switch: cache completion failures unless -XDdev is used
93 private boolean cacheCompletionFailure;
96 * Switch: prefer source files instead of newer when both source
97 * and class are available
99 protected boolean preferSource;
102 * Switch: Search classpath and sourcepath for classes before the
105 protected boolean userPathsFirst;
108 * Switch: should read OTHER classfiles (.sig files) from PLATFORM_CLASS_PATH.
110 private boolean allowSigFiles;
112 /** The log to use for verbose output
116 /** The symbol table. */
119 /** The name table. */
122 /** Force a completion failure on this name
124 final Name completionFailureName;
128 private final JavaFileManager fileManager;
130 /** Dependency tracker
132 private final Dependencies dependencies;
134 /** Factory for diagnostics
136 JCDiagnostic.Factory diagFactory;
138 private final ClassNamesForFileOraculum classNamesOraculum;
140 /** Can be reassigned from outside:
141 * the completer to be used for ".java" files. If this remains unassigned
142 * ".java" files will not be loaded.
144 public Completer sourceCompleter = Completer.NULL_COMPLETER;
146 /** The path name of the class file currently being read.
148 protected JavaFileObject currentClassFile = null;
150 /** The class or method currently being read.
152 protected Symbol currentOwner = null;
155 * The currently selected profile.
157 private final Profile profile;
160 * Use direct access to the JRTIndex to access the temporary
161 * replacement for the info that used to be in ct.sym.
162 * In time, this will go away and be replaced by the module system.
164 private final JRTIndex jrtIndex;
167 * Completer that delegates to the complete-method of this class.
169 private final Completer thisCompleter = this::complete;
171 public Completer getCompleter() {
172 return thisCompleter;
175 /** Get the ClassFinder instance for this invocation. */
176 public static ClassFinder instance(Context context) {
177 ClassFinder instance = context.get(classFinderKey);
178 if (instance == null)
179 instance = new ClassFinder(context);
183 /** Construct a new class finder. */
184 protected ClassFinder(Context context) {
185 context.put(classFinderKey, this);
186 reader = ClassReader.instance(context);
187 names = Names.instance(context);
188 syms = Symtab.instance(context);
189 fileManager = context.get(JavaFileManager.class);
190 dependencies = Dependencies.instance(context);
191 if (fileManager == null)
192 throw new AssertionError("FileManager initialization error");
193 diagFactory = JCDiagnostic.Factory.instance(context);
194 classNamesOraculum = context.get(ClassNamesForFileOraculum.class);
196 log = Log.instance(context);
197 annotate = Annotate.instance(context);
199 Options options = Options.instance(context);
200 verbose = options.isSet(Option.VERBOSE);
201 cacheCompletionFailure = options.isUnset("dev");
202 preferSource = "source".equals(options.get("-Xprefer"));
203 userPathsFirst = options.isSet(Option.XXUSERPATHSFIRST);
204 allowSigFiles = context.get(PlatformDescription.class) != null;
206 completionFailureName =
207 options.isSet("failcomplete")
208 ? names.fromString(options.get("failcomplete"))
211 // Temporary, until more info is available from the module system.
213 JavaFileManager fm = context.get(JavaFileManager.class);
214 if (fm instanceof JavacFileManager) {
215 JavacFileManager jfm = (JavacFileManager) fm;
216 useCtProps = jfm.isDefaultBootClassPath() && jfm.isSymbolFileEnabled();
217 } else if (fm.getClass().getName().equals("com.sun.tools.sjavac.comp.SmartFileManager")) {
218 useCtProps = !options.isSet("ignore.symbol.file");
222 jrtIndex = useCtProps && JRTIndex.isAvailable() ? JRTIndex.getSharedInstance() : null;
224 profile = Profile.instance(context);
228 /************************************************************************
229 * Temporary ct.sym replacement
231 * The following code is a temporary substitute for the ct.sym mechanism
232 * used in JDK 6 thru JDK 8.
233 * This mechanism will eventually be superseded by the Jigsaw module system.
234 ***********************************************************************/
237 * Returns any extra flags for a class symbol.
238 * This information used to be provided using private annotations
239 * in the class file in ct.sym; in time, this information will be
240 * available from the module system.
242 long getSupplementaryFlags(ClassSymbol c) {
243 if (jrtIndex == null || !jrtIndex.isInJRT(c.classfile) || c.name == names.module_info) {
247 if (supplementaryFlags == null) {
248 supplementaryFlags = new HashMap<>();
251 Long flags = supplementaryFlags.get(c.packge());
255 JRTIndex.CtSym ctSym = jrtIndex.getCtSym(c.packge().flatName());
256 Profile minProfile = Profile.DEFAULT;
257 if (ctSym.proprietary)
258 newFlags |= PROPRIETARY;
259 if (ctSym.minProfile != null)
260 minProfile = Profile.lookup(ctSym.minProfile);
261 if (profile != Profile.DEFAULT && minProfile.value > profile.value) {
262 newFlags |= NOT_IN_PROFILE;
264 } catch (IOException ignore) {
266 supplementaryFlags.put(c.packge(), flags = newFlags);
271 private Map<PackageSymbol, Long> supplementaryFlags;
273 public Runnable ap = null;
275 /************************************************************************
277 ***********************************************************************/
279 /** Completion for classes to be loaded. Before a class is loaded
280 * we make sure its enclosing class (if any) is loaded.
282 private void complete(Symbol sym) throws CompletionFailure {
284 if (sym.kind == TYP) {
286 ClassSymbol c = (ClassSymbol) sym;
287 dependencies.push(c, CompletionCause.CLASS_READER);
288 annotate.blockAnnotations();
289 Scope tempScope = c.members_field = new Scope.ErrorScope(c); // make sure it's always defined
290 completeOwners(c.owner);
291 completeEnclosing(c);
292 if (c.members_field == tempScope) { // do not fill in when already completed as a result of completing owners
296 syms.removeClass(c.packge().modle, c.flatname);
300 annotate.unblockAnnotationsNoFlush();
303 } else if (sym.kind == PCK) {
304 PackageSymbol p = (PackageSymbol)sym;
307 } catch (IOException ex) {
308 throw new CompletionFailure(sym, ex.getLocalizedMessage()).initCause(ex);
312 annotate.flush(); // finish attaching annotations
315 final Runnable r = ap;
322 /** complete up through the enclosing package. */
323 private void completeOwners(Symbol o) {
324 if (o.kind != PCK) completeOwners(o.owner);
329 * Tries to complete lexically enclosing classes if c looks like a
330 * nested class. This is similar to completeOwners but handles
331 * the situation when a nested class is accessed directly as it is
332 * possible with the Tree API or javax.lang.model.*.
334 private void completeEnclosing(ClassSymbol c) {
335 if (c.owner.kind == PCK) {
336 Symbol owner = c.owner;
337 for (Name name : Convert.enclosingCandidates(Convert.shortName(c.name))) {
338 Symbol encl = owner.members().findFirst(name);
340 encl = syms.getClass(c.packge().modle, TypeSymbol.formFlatName(name, owner));
347 /** Fill in definition of class `c' from corresponding class or
350 void fillIn(ClassSymbol c) {
351 if (completionFailureName == c.fullname) {
352 throw new CompletionFailure(c, "user-selected completion failure by class name");
355 JavaFileObject classfile = c.classfile;
356 if (classfile != null) {
357 JavaFileObject previousClassFile = currentClassFile;
358 Symbol prevOwner = c.owner;
359 Name prevName = c.fullname;
361 if (reader.filling) {
362 Assert.error("Filling " + classfile.toUri() + " during " + previousClassFile);
364 currentClassFile = classfile;
366 log.printVerbose("loading", currentClassFile.getName());
368 if (classfile.getKind() == JavaFileObject.Kind.CLASS ||
369 classfile.getKind() == JavaFileObject.Kind.OTHER) {
370 reader.readClassFile(c);
371 c.flags_field |= getSupplementaryFlags(c);
373 if (!sourceCompleter.isTerminal()) {
374 if (!classfile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE)) {
375 sourceCompleter.complete(c);
378 throw new IllegalStateException("Source completer required to read "
379 + classfile.toUri());
382 } catch (BadClassFile cf) {
383 //the symbol may be partially initialized, purge it:
385 c.members_field.getSymbols(sym -> sym.kind == TYP).forEach(sym -> {
386 ClassSymbol csym = (ClassSymbol) sym;
387 csym.owner = sym.packge();
388 csym.owner.members().enter(sym);
389 csym.fullname = sym.flatName();
390 csym.name = Convert.shortName(sym.flatName());
393 c.fullname = prevName;
394 c.name = Convert.shortName(prevName);
398 currentClassFile = previousClassFile;
401 throw classFileNotFound(c);
405 private CompletionFailure classFileNotFound(ClassSymbol c) {
407 diagFactory.fragment("class.file.not.found", c.flatname);
408 return newCompletionFailure(c, diag);
410 /** Static factory for CompletionFailure objects.
411 * In practice, only one can be used at a time, so we share one
412 * to reduce the expense of allocating new exception objects.
414 private CompletionFailure newCompletionFailure(TypeSymbol c,
416 if (!cacheCompletionFailure) {
417 // log.warning("proc.messager",
418 // Log.getLocalizedString("class.file.not.found", c.flatname));
419 // c.debug.printStackTrace();
420 return new CompletionFailure(c, diag);
422 CompletionFailure result = cachedCompletionFailure;
428 private final CompletionFailure cachedCompletionFailure =
429 new CompletionFailure(null, (JCDiagnostic) null);
431 cachedCompletionFailure.setStackTrace(new StackTraceElement[0]);
435 /** Load a toplevel class with given fully qualified name
436 * The class is entered into `classes' only if load was successful.
438 public ClassSymbol loadClass(ModuleSymbol msym, Name flatname) throws CompletionFailure {
439 Assert.checkNonNull(msym);
440 Name packageName = Convert.packagePart(flatname);
441 PackageSymbol ps = syms.lookupPackage(msym, packageName);
443 Assert.checkNonNull(ps.modle, () -> "msym=" + msym + "; flatName=" + flatname);
445 boolean absent = syms.getClass(ps.modle, flatname) == null;
446 ClassSymbol c = syms.enterClass(ps.modle, flatname);
448 if (c.members_field == null) {
451 } catch (CompletionFailure ex) {
452 if (absent) syms.removeClass(ps.modle, flatname);
459 /************************************************************************
461 ***********************************************************************/
463 //TODO: for compatibility, remove eventually
464 protected void includeClassFile(PackageSymbol p, JavaFileObject file) {
465 String binaryName = fileManager.inferBinaryName(currentLoc, file);
466 includeClassFile(p, file, binaryName);
469 /** Include class corresponding to given class file in package,
470 * unless (1) we already have one the same kind (.class or .java), or
471 * (2) we have one of the other kind, and the given class file
474 protected void includeClassFile(PackageSymbol p, JavaFileObject file, String binaryName) {
475 if ((p.flags_field & EXISTS) == 0)
476 for (Symbol q = p; q != null && q.kind == PCK; q = q.owner)
477 q.flags_field |= EXISTS;
478 JavaFileObject.Kind kind = file.getKind();
480 if (kind == JavaFileObject.Kind.CLASS || kind == JavaFileObject.Kind.OTHER)
484 int lastDot = binaryName.lastIndexOf(".");
485 Name classname = names.fromString(binaryName.substring(lastDot + 1));
486 boolean isPkgInfo = classname == names.package_info;
487 ClassSymbol c = isPkgInfo
489 : (ClassSymbol) p.members_field.findFirst(classname);
491 c = syms.enterClass(p.modle, classname, p);
492 if (c.classfile == null) // only update the file if's it's newly created
497 if (c.owner == p) // it might be an inner class
498 p.members_field.enter(c);
500 } else if (!preferCurrent && c.classfile != null && (c.flags_field & seen) == 0) {
501 // if c.classfile == null, we are currently compiling this class
502 // and no further action is necessary.
503 // if (c.flags_field & seen) != 0, we have already encountered
504 // a file of the same kind; again no further action is necessary.
505 if ((c.flags_field & (CLASS_SEEN | SOURCE_SEEN)) != 0)
506 c.classfile = preferredFileObject(file, c.classfile);
507 } else if (c.classfile != null && isSigOverClass(c.classfile, file)) {
510 c.flags_field |= seen;
513 private boolean isSigOverClass(final JavaFileObject a, final JavaFileObject b) {
514 String patha = a.getName().toLowerCase();
515 String pathb = b.getName().toLowerCase();
516 return pathb.endsWith(".sig") && patha.endsWith(".class"); //NOI18N
519 /** Implement policy to choose to derive information from a source
520 * file or a class file when both are present. May be overridden
523 protected JavaFileObject preferredFileObject(JavaFileObject a,
526 if (preferSource && !b.getName().toLowerCase().endsWith(".sig"))
527 return (a.getKind() == JavaFileObject.Kind.SOURCE) ? a : b;
529 long adate = a.getLastModified();
530 long bdate = b.getLastModified();
531 // 6449326: policy for bad lastModifiedTime in ClassReader
532 //assert adate >= 0 && bdate >= 0;
533 return (adate > bdate) ? a : b;
538 * specifies types of files to be read when filling in a package symbol
540 // Note: overridden by JavadocClassFinder
541 protected EnumSet<JavaFileObject.Kind> getPackageFileKinds() {
542 return EnumSet.of(JavaFileObject.Kind.CLASS, JavaFileObject.Kind.SOURCE);
546 * this is used to support javadoc
548 protected void extraFileActions(PackageSymbol pack, JavaFileObject fe) {
551 protected Location currentLoc; // FIXME
553 private boolean verbosePath = true;
555 // Set to true when the currently selected file should be kept
556 private boolean preferCurrent;
558 /** Load directory of package into members scope.
560 private void fillIn(PackageSymbol p) throws IOException {
561 if (p.members_field == null)
562 p.members_field = WriteableScope.create(p);
564 ModuleSymbol msym = p.modle;
566 Assert.checkNonNull(msym, p::toString);
570 if (msym == syms.noModule) {
571 preferCurrent = false;
572 if (userPathsFirst) {
573 scanUserPaths(p, true);
574 preferCurrent = true;
578 scanUserPaths(p, true);
580 } else if (msym.classLocation == StandardLocation.CLASS_PATH) {
581 scanUserPaths(p, msym.sourceLocation == StandardLocation.SOURCE_PATH);
583 scanModulePaths(p, msym);
587 // TODO: for now, this is a much simplified form of scanUserPaths
588 // and (deliberately) does not default sourcepath to classpath.
589 // But, we need to think about retaining existing behavior for
590 // -classpath and -sourcepath for single module mode.
591 // One plausible solution is to detect if the module's sourceLocation
592 // is the same as the module's classLocation.
593 private void scanModulePaths(PackageSymbol p, ModuleSymbol msym) throws IOException {
594 Set<JavaFileObject.Kind> kinds = getPackageFileKinds();
596 Set<JavaFileObject.Kind> classKinds = EnumSet.copyOf(kinds);
597 classKinds.remove(JavaFileObject.Kind.SOURCE);
598 boolean wantClassFiles = !classKinds.isEmpty();
600 Set<JavaFileObject.Kind> sourceKinds = EnumSet.copyOf(kinds);
601 sourceKinds.remove(JavaFileObject.Kind.CLASS);
602 boolean wantSourceFiles = !sourceKinds.isEmpty();
604 String packageName = p.fullname.toString();
606 Location classLocn = msym.classLocation;
607 Location sourceLocn = msym.sourceLocation;
608 Location patchLocn = msym.patchLocation;
609 Location patchOutLocn = msym.patchOutputLocation;
611 boolean prevPreferCurrent = preferCurrent;
614 preferCurrent = false;
615 if (wantClassFiles && (patchOutLocn != null)) {
616 fillIn(p, patchOutLocn,
622 if ((wantClassFiles || wantSourceFiles) && (patchLocn != null)) {
623 Set<JavaFileObject.Kind> combined = EnumSet.noneOf(JavaFileObject.Kind.class);
624 combined.addAll(classKinds);
625 combined.addAll(sourceKinds);
632 preferCurrent = true;
633 if (wantClassFiles && (classLocn != null)) {
640 if (wantSourceFiles && (sourceLocn != null)) {
641 fillIn(p, sourceLocn,
648 preferCurrent = prevPreferCurrent;
653 * Scans class path and source path for files in given package.
655 private void scanUserPaths(PackageSymbol p, boolean includeSourcePath) throws IOException {
656 Set<JavaFileObject.Kind> kinds = getPackageFileKinds();
658 Set<JavaFileObject.Kind> classKinds = EnumSet.copyOf(kinds);
659 classKinds.remove(JavaFileObject.Kind.SOURCE);
660 boolean wantClassFiles = !classKinds.isEmpty();
662 Set<JavaFileObject.Kind> sourceKinds = EnumSet.copyOf(kinds);
663 sourceKinds.remove(JavaFileObject.Kind.CLASS);
664 boolean wantSourceFiles = !sourceKinds.isEmpty();
666 boolean haveSourcePath = includeSourcePath && fileManager.hasLocation(SOURCE_PATH);
668 if (verbose && verbosePath) {
669 if (fileManager instanceof StandardJavaFileManager) {
670 StandardJavaFileManager fm = (StandardJavaFileManager)fileManager;
671 if (haveSourcePath && wantSourceFiles) {
672 List<Path> path = List.nil();
673 for (Path sourcePath : fm.getLocationAsPaths(SOURCE_PATH)) {
674 path = path.prepend(sourcePath);
676 log.printVerbose("sourcepath", path.reverse().toString());
677 } else if (wantSourceFiles) {
678 List<Path> path = List.nil();
679 for (Path classPath : fm.getLocationAsPaths(CLASS_PATH)) {
680 path = path.prepend(classPath);
682 log.printVerbose("sourcepath", path.reverse().toString());
684 if (wantClassFiles) {
685 List<Path> path = List.nil();
686 for (Path platformPath : fm.getLocationAsPaths(PLATFORM_CLASS_PATH)) {
687 path = path.prepend(platformPath);
689 for (Path classPath : fm.getLocationAsPaths(CLASS_PATH)) {
690 path = path.prepend(classPath);
692 log.printVerbose("classpath", path.reverse().toString());
697 String packageName = p.fullname.toString();
698 if (wantSourceFiles && !haveSourcePath) {
699 fillIn(p, CLASS_PATH,
706 fillIn(p, CLASS_PATH,
712 fillIn(p, SOURCE_PATH,
721 * Scans platform class path for files in given package.
723 private void scanPlatformPath(PackageSymbol p) throws IOException {
724 fillIn(p, PLATFORM_CLASS_PATH,
725 list(PLATFORM_CLASS_PATH,
727 p.fullname.toString(),
728 allowSigFiles ? EnumSet.of(JavaFileObject.Kind.CLASS,
729 JavaFileObject.Kind.OTHER)
730 : EnumSet.of(JavaFileObject.Kind.CLASS)));
733 @SuppressWarnings("fallthrough")
734 private void fillIn(PackageSymbol p,
736 Iterable<JavaFileObject> files)
738 currentLoc = location;
739 for (JavaFileObject fo : files) {
740 switch (fo.getKind()) {
742 if (!isSigFile(location, fo)) {
743 extraFileActions(p, fo);
746 //intentional fall-through:
749 String[] binaryNames = null;
751 if (classNamesOraculum != null) {
752 binaryNames = classNamesOraculum.divineClassName(fo);
755 if (binaryNames == null) {
756 String binaryName = fileManager.inferBinaryName(currentLoc, fo);
757 if (binaryName != null) {
758 binaryNames = new String[] {binaryName};
761 // TODO pass binaryName to includeClassFile
762 if (binaryNames != null) {
763 for (String binaryName : binaryNames) {
764 String simpleName = binaryName.substring(binaryName.lastIndexOf(".") + 1);
765 if (SourceVersion.isIdentifier(simpleName) ||
766 simpleName.equals("package-info"))
767 includeClassFile(p, fo);
773 extraFileActions(p, fo);
777 if (classNamesOraculum != null && location == SOURCE_PATH) {
778 JavaFileObject[] sources = classNamesOraculum.divineSources(p.fullname.toString());
779 if (sources != null) {
780 for (JavaFileObject fo : sources) {
781 for (String binaryName : classNamesOraculum.divineClassName(fo)) {
782 String simpleName = binaryName.substring(binaryName.lastIndexOf(".") + 1);
783 if (SourceVersion.isIdentifier(simpleName) ||
784 simpleName.equals("package-info")) {
785 includeClassFile(p, fo, binaryName);
793 boolean isSigFile(Location location, JavaFileObject fo) {
794 return location == PLATFORM_CLASS_PATH &&
796 fo.getName().endsWith(".sig");
799 Iterable<JavaFileObject> list(Location location,
802 Set<Kind> kinds) throws IOException {
803 Iterable<JavaFileObject> listed = fileManager.list(location,
805 EnumSet.allOf(Kind.class),
807 return () -> new Iterator<JavaFileObject>() {
808 private final Iterator<JavaFileObject> original = listed.iterator();
809 private JavaFileObject next;
811 public boolean hasNext() {
813 while (original.hasNext()) {
814 JavaFileObject fo = original.next();
816 if (fo.getKind() != Kind.CLASS &&
817 fo.getKind() != Kind.SOURCE &&
818 !isSigFile(currentLoc, fo)) {
819 p.flags_field |= Flags.HAS_RESOURCE;
822 if (kinds.contains(fo.getKind())) {
832 public JavaFileObject next() {
834 throw new NoSuchElementException();
835 JavaFileObject result = next;
844 * Used for bad class definition files, such as bad .class files or
845 * for .java files with unexpected package or class names.
847 public static class BadClassFile extends CompletionFailure {
848 private static final long serialVersionUID = 0;
850 public BadClassFile(TypeSymbol sym, JavaFileObject file, JCDiagnostic diag,
851 JCDiagnostic.Factory diagFactory) {
852 super(sym, createBadClassFileDiagnostic(file, diag, diagFactory));
855 private static JCDiagnostic createBadClassFileDiagnostic(
856 JavaFileObject file, JCDiagnostic diag, JCDiagnostic.Factory diagFactory) {
857 String key = (file.getKind() == JavaFileObject.Kind.SOURCE
858 ? "bad.source.file.header" : "bad.class.file.header");
859 return diagFactory.fragment(key, file, diag);
863 public static class BadEnclosingMethodAttr extends BadClassFile {
864 private static final long serialVersionUID = 0;
866 public BadEnclosingMethodAttr(TypeSymbol sym, JavaFileObject file, JCDiagnostic diag,
867 JCDiagnostic.Factory diagFactory) {
868 super(sym, file, diag, diagFactory);