# HG changeset patch # User lana # Date 1449768265 28800 # Node ID 8b372e28f10639bf23119703ce7b615766c2d596 # Parent 9229cc3b38028905766456bc23e01b39b66c6956# Parent afc0330fa0d485bcae2e039f1adebfcac9690167 Merge diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java Thu Dec 10 09:24:25 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -110,6 +110,12 @@ IDENTIFIER, /** + * Used for instances of {@index term optional-descr} + * representing a search term. + */ + INDEX("index"), + + /** * Used for instances of {@link InheritDocTree} * representing an @inheritDoc tag. */ diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTreeVisitor.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTreeVisitor.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTreeVisitor.java Thu Dec 10 09:24:25 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -138,6 +138,14 @@ R visitIdentifier(IdentifierTree node, P p); /** + * Visits an IndexTree node. + * @param node the node being visited + * @param p a parameter value + * @return a result value + */ + R visitIndex(IndexTree node, P p); + + /** * Visits an InheritDocTree node. * @param node the node being visited * @param p a parameter value diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/source/doctree/IndexTree.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/doctree/IndexTree.java Thu Dec 10 09:24:25 2015 -0800 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.source.doctree; + +import java.util.List; + +/** + * A tree node for an @index or @index inline tag. + * + *

+ * {@index keyword optional description}
+ * + * @since 1.9 + */ +@jdk.Exported +public interface IndexTree extends InlineTagTree { + /** + * Returns the specified search term. + * @return the search term + */ + DocTree getSearchTerm(); + + /** + * Returns the description, if any. + * @return the description + */ + List getDescription(); +} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeScanner.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeScanner.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeScanner.java Thu Dec 10 09:24:25 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package com.sun.source.util; import com.sun.source.doctree.*; +import com.sun.tools.javac.tree.DCTree.DCIndex; /** @@ -255,6 +256,20 @@ * @return the result of scanning */ @Override + public R visitIndex(IndexTree node, P p) { + R r = scan(node.getSearchTerm(), p); + r = scanAndReduce(node.getDescription(), p, r); + return r; + } + + /** + * {@inheritDoc} This implementation returns {@code null}. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of scanning + */ + @Override public R visitInheritDoc(InheritDocTree node, P p) { return null; } diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/source/util/SimpleDocTreeVisitor.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/source/util/SimpleDocTreeVisitor.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/util/SimpleDocTreeVisitor.java Thu Dec 10 09:24:25 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -224,6 +224,18 @@ * @return the result of {@code defaultAction} */ @Override + public R visitIndex(IndexTree node, P p) { + return defaultAction(node, p); + } + + /** + * {@inheritDoc} This implementation calls {@code defaultAction}. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of {@code defaultAction} + */ + @Override public R visitInheritDoc(InheritDocTree node, P p) { return defaultAction(node, p); } diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java Thu Dec 10 09:24:25 2015 -0800 @@ -343,7 +343,7 @@ } currentClassFile = classfile; if (verbose) { - log.printVerbose("loading", currentClassFile.toString()); + log.printVerbose("loading", currentClassFile.getName()); } if (classfile.getKind() == JavaFileObject.Kind.CLASS || classfile.getKind() == JavaFileObject.Kind.OTHER) { diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Thu Dec 10 09:24:25 2015 -0800 @@ -424,6 +424,9 @@ } /** The closest enclosing class of this symbol's declaration. + * Warning: this (misnamed) method returns the receiver itself + * when the receiver is a class (as opposed to its enclosing + * class as one may be misled to believe.) */ public ClassSymbol enclClass() { Symbol c = this; diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Thu Dec 10 09:24:25 2015 -0800 @@ -1056,7 +1056,7 @@ } /** - * A polymorphic signature method (JLS SE 7, 8.4.1) is a method that + * A polymorphic signature method (JLS 15.12.3) is a method that * (i) is declared in the java.lang.invoke.MethodHandle class, (ii) takes * a single variable arity parameter (iii) whose declared type is Object[], * (iv) has a return type of Object and (v) is native. diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Dec 10 09:24:25 2015 -0800 @@ -2037,7 +2037,7 @@ }; break; case CAPTURED_OUTER_THIS: - Name name = names.fromString(new String(sym.flatName().toString() + names.dollarThis)); + Name name = names.fromString(new String(sym.flatName().toString().replace('.', '$') + names.dollarThis)); ret = new VarSymbol(SYNTHETIC | FINAL | PARAMETER, name, types.erasure(sym.type), translatedSym) { @Override public Symbol baseSymbol() { diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Dec 10 09:24:25 2015 -0800 @@ -2784,8 +2784,6 @@ .map(c -> StaticKind.from(c.sym)) .reduce(StaticKind::reduce) .orElse(StaticKind.UNDEFINED); - case HIDDEN: - return StaticKind.from(((AccessError)sym).sym); default: return StaticKind.UNDEFINED; } @@ -3365,7 +3363,7 @@ if (env1 != null) { while (env1 != null && env1.outer != null) { if (isStatic(env1)) staticOnly = true; - if (env1.enclClass.sym.isSubClass(member.owner, types)) { + if (env1.enclClass.sym.isSubClass(member.owner.enclClass(), types)) { Symbol sym = env1.info.scope.findFirst(name); if (sym != null) { if (staticOnly) sym = new StaticError(sym); diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileObject.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileObject.java Thu Dec 10 08:17:12 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tools.javac.file; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.charset.CharsetDecoder; -import java.nio.file.Path; - -import javax.lang.model.element.Modifier; -import javax.lang.model.element.NestingKind; -import javax.tools.FileObject; -import javax.tools.JavaFileObject; - -import com.sun.tools.javac.util.DefinedBy; -import com.sun.tools.javac.util.DefinedBy.Api; - -/** - *

This is NOT part of any supported API. - * 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. -*/ -public abstract class BaseFileObject implements JavaFileObject { - protected BaseFileObject(JavacFileManager fileManager) { - this.fileManager = fileManager; - } - - /** Return a short name for the object, such as for use in raw diagnostics - */ - public abstract String getShortName(); - - @Override - public String toString() { - return getClass().getSimpleName() + "[" + getName() + "]"; - } - - @DefinedBy(Api.COMPILER) - public NestingKind getNestingKind() { return null; } - - @DefinedBy(Api.COMPILER) - public Modifier getAccessLevel() { return null; } - - @DefinedBy(Api.COMPILER) - public Reader openReader(boolean ignoreEncodingErrors) throws IOException { - return new InputStreamReader(openInputStream(), getDecoder(ignoreEncodingErrors)); - } - - protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { - throw new UnsupportedOperationException(); - } - - protected abstract String inferBinaryName(Iterable path); - - protected static JavaFileObject.Kind getKind(String filename) { - return BaseFileManager.getKind(filename); - } - - protected static String removeExtension(String fileName) { - int lastDot = fileName.lastIndexOf("."); - return (lastDot == -1 ? fileName : fileName.substring(0, lastDot)); - } - - protected static URI createJarUri(Path jarFile, String entryName) { - URI jarURI = jarFile.toUri().normalize(); - String separator = entryName.startsWith("/") ? "!" : "!/"; - try { - // The jar URI convention appears to be not to re-encode the jarURI - return new URI("jar:" + jarURI + separator + entryName); - } catch (URISyntaxException e) { - throw new CannotCreateUriError(jarURI + separator + entryName, e); - } - } - - /** Used when URLSyntaxException is thrown unexpectedly during - * implementations of (Base)FileObject.toURI(). */ - protected static class CannotCreateUriError extends Error { - private static final long serialVersionUID = 9101708840997613546L; - public CannotCreateUriError(String value, Throwable cause) { - super(value, cause); - } - } - - /** Return the last component of a presumed hierarchical URI. - * From the scheme specific part of the URI, it returns the substring - * after the last "/" if any, or everything if no "/" is found. - */ - public static String getSimpleName(FileObject fo) { - URI uri = fo.toUri(); - String s = uri.getSchemeSpecificPart(); - return s.substring(s.lastIndexOf("/") + 1); // safe when / not found - - } - - // force subtypes to define equals - @Override - public abstract boolean equals(Object other); - - // force subtypes to define hashCode - @Override - public abstract int hashCode(); - - /** The file manager that created this JavaFileObject. */ - protected final JavacFileManager fileManager; -} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java Thu Dec 10 09:24:25 2015 -0800 @@ -48,7 +48,7 @@ try { return file.toRealPath(); } catch (IOException e) { - return file.toAbsolutePath(); + return file.toAbsolutePath().normalize(); } } diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JRTIndex.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JRTIndex.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JRTIndex.java Thu Dec 10 09:24:25 2015 -0800 @@ -200,7 +200,7 @@ if (Files.exists(dir)) { try (DirectoryStream modules = Files.newDirectoryStream(dir)) { for (Path module: modules) { - Path p = rd.getFile(module); + Path p = rd.resolveAgainst(module); if (!Files.exists(p)) continue; try (DirectoryStream stream = Files.newDirectoryStream(p)) { diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Thu Dec 10 09:24:25 2015 -0800 @@ -26,7 +26,6 @@ package com.sun.tools.javac.file; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.net.MalformedURLException; import java.net.URI; @@ -34,16 +33,20 @@ import java.net.URL; import java.nio.CharBuffer; import java.nio.charset.Charset; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitOption; +import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.LinkOption; -import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.Comparator; import java.util.EnumSet; import java.util.HashMap; @@ -53,7 +56,6 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; -import java.util.zip.ZipFile; import javax.lang.model.SourceVersion; import javax.tools.FileObject; @@ -69,6 +71,8 @@ import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; +import static java.nio.file.FileVisitOption.FOLLOW_LINKS; + import static javax.tools.StandardLocation.*; /** @@ -92,9 +96,6 @@ private FSInfo fsInfo; - private boolean contextUseOptimizedZip; - private ZipFileIndexCache zipFileIndexCache; - private final Set sourceOrClass = EnumSet.of(JavaFileObject.Kind.SOURCE, JavaFileObject.Kind.CLASS); @@ -149,10 +150,6 @@ fsInfo = FSInfo.instance(context); - contextUseOptimizedZip = options.getBoolean("useOptimizedZip", true); - if (contextUseOptimizedZip) - zipFileIndexCache = ZipFileIndexCache.getSharedInstance(); - symbolFileEnabled = !options.isSet("ignore.symbol.file"); String sf = options.get("sortFiles"); @@ -173,13 +170,13 @@ } // used by tests - public JavaFileObject getFileForInput(String name) { - return getRegularFile(Paths.get(name)); + public JavaFileObject getJavaFileObject(String name) { + return getJavaFileObjects(name).iterator().next(); } // used by tests - public JavaFileObject getRegularFile(Path file) { - return new RegularFileObject(this, file); + public JavaFileObject getJavaFileObject(Path file) { + return getJavaFileObjects(file).iterator().next(); } public JavaFileObject getFileForOutput(String classname, @@ -277,7 +274,7 @@ for (Path file: e.files.values()) { if (fileKinds.contains(getKind(file))) { JavaFileObject fe - = PathFileObject.createJRTPathFileObject(JavacFileManager.this, file); + = PathFileObject.forJRTPath(JavacFileManager.this, file); resultList.append(fe); } } @@ -302,14 +299,14 @@ * Insert all files in subdirectory subdirectory of directory directory * which match fileKinds into resultList */ - private void listDirectory(Path directory, + private void listDirectory(Path directory, Path realDirectory, RelativeDirectory subdirectory, Set fileKinds, boolean recurse, ListBuffer resultList) { Path d; try { - d = subdirectory.getFile(directory); + d = subdirectory.resolveAgainst(directory); } catch (InvalidPathException ignore) { return; } @@ -329,13 +326,16 @@ return; } + if (realDirectory == null) + realDirectory = fsInfo.getCanonicalFile(directory); + for (Path f: files) { String fname = f.getFileName().toString(); if (fname.endsWith("/")) fname = fname.substring(0, fname.length() - 1); if (Files.isDirectory(f)) { if (recurse && SourceVersion.isIdentifier(fname)) { - listDirectory(directory, + listDirectory(directory, realDirectory, new RelativeDirectory(subdirectory, fname), fileKinds, recurse, @@ -343,8 +343,9 @@ } } else { if (isValidFile(fname, fileKinds)) { - JavaFileObject fe = - new RegularFileObject(this, fname, d.resolve(fname)); + RelativeFile file = new RelativeFile(subdirectory, fname); + JavaFileObject fe = PathFileObject.forDirectoryPath(this, + file.resolveAgainst(realDirectory), directory, file); resultList.append(fe); } } @@ -352,34 +353,61 @@ } /** - * Insert all files in subdirectory subdirectory of archive archive + * Insert all files in subdirectory subdirectory of archive archivePath * which match fileKinds into resultList */ - private void listArchive(Archive archive, - RelativeDirectory subdirectory, - Set fileKinds, - boolean recurse, - ListBuffer resultList) { - // Get the files directly in the subdir - List files = archive.getFiles(subdirectory); - if (files != null) { - for (; !files.isEmpty(); files = files.tail) { - String file = files.head; - if (isValidFile(file, fileKinds)) { - resultList.append(archive.getFileObject(subdirectory, file)); - } - } + private void listArchive(Path archivePath, + RelativeDirectory subdirectory, + Set fileKinds, + boolean recurse, + ListBuffer resultList) + throws IOException { + FileSystem fs = getFileSystem(archivePath); + if (fs == null) { + return; + } + + Path containerSubdir = subdirectory.resolveAgainst(fs); + if (!Files.exists(containerSubdir)) { + return; } - if (recurse) { - for (RelativeDirectory s: archive.getSubdirectories()) { - if (subdirectory.contains(s)) { - // Because the archive map is a flat list of directories, - // the enclosing loop will pick up all child subdirectories. - // Therefore, there is no need to recurse deeper. - listArchive(archive, s, fileKinds, false, resultList); - } - } - } + + int maxDepth = (recurse ? Integer.MAX_VALUE : 1); + Set opts = EnumSet.of(FOLLOW_LINKS); + Files.walkFileTree(containerSubdir, opts, maxDepth, + new SimpleFileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { + if (isValid(dir.getFileName())) { + return FileVisitResult.CONTINUE; + } else { + return FileVisitResult.SKIP_SUBTREE; + } + } + + boolean isValid(Path fileName) { + if (fileName == null) { + return true; + } else { + String name = fileName.toString(); + if (name.endsWith("/")) { + name = name.substring(0, name.length() - 1); + } + return SourceVersion.isIdentifier(name); + } + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { + if (attrs.isRegularFile() && fileKinds.contains(getKind(file.getFileName().toString()))) { + JavaFileObject fe = PathFileObject.forJarPath( + JavacFileManager.this, file, archivePath); + resultList.append(fe); + } + return FileVisitResult.CONTINUE; + } + }); + } /** @@ -391,54 +419,46 @@ RelativeDirectory subdirectory, Set fileKinds, boolean recurse, - ListBuffer resultList) { - Archive archive = archives.get(container); - if (archive == null) { - // Very temporary and obnoxious interim hack - if (container.endsWith("bootmodules.jimage")) { - System.err.println("Warning: reference to bootmodules.jimage replaced by jrt:"); - container = Locations.JRT_MARKER_FILE; - } else if (container.getFileName().toString().endsWith(".jimage")) { - System.err.println("Warning: reference to " + container + " ignored"); - return; - } + ListBuffer resultList) + throws IOException { + // Very temporary and obnoxious interim hack + if (container.endsWith("bootmodules.jimage")) { + System.err.println("Warning: reference to bootmodules.jimage replaced by jrt:"); + container = Locations.JRT_MARKER_FILE; + } else if (container.getFileName().toString().endsWith(".jimage")) { + System.err.println("Warning: reference to " + container + " ignored"); + return; + } - // archives are not created for directories or jrt: images - if (container == Locations.JRT_MARKER_FILE) { - try { - listJRTImage(subdirectory, - fileKinds, - recurse, - resultList); - } catch (IOException ex) { - ex.printStackTrace(System.err); - log.error("error.reading.file", container, getMessage(ex)); - } - return; + if (container == Locations.JRT_MARKER_FILE) { + try { + listJRTImage(subdirectory, + fileKinds, + recurse, + resultList); + } catch (IOException ex) { + ex.printStackTrace(System.err); + log.error("error.reading.file", container, getMessage(ex)); } + return; + } - if (fsInfo.isDirectory(container)) { - listDirectory(container, - subdirectory, - fileKinds, - recurse, - resultList); - return; - } + if (fsInfo.isDirectory(container)) { + listDirectory(container, null, + subdirectory, + fileKinds, + recurse, + resultList); + return; + } - // Not a directory; either a file or non-existant, create the archive - try { - archive = openArchive(container); - } catch (IOException ex) { - log.error("error.reading.file", container, getMessage(ex)); - return; - } - } - listArchive(archive, + if (Files.exists(container)) { + listArchive(container, subdirectory, fileKinds, recurse, resultList); + } } private boolean isValidFile(String s, Set fileKinds) { @@ -481,141 +501,17 @@ return j < 0; } - /** - * An archive provides a flat directory structure of a ZipFile by - * mapping directory names to lists of files (basenames). - */ - public interface Archive { - void close() throws IOException; - - boolean contains(RelativePath name); - - JavaFileObject getFileObject(RelativeDirectory subdirectory, String file); - - List getFiles(RelativeDirectory subdirectory); - - Set getSubdirectories(); - } - - public class MissingArchive implements Archive { - final Path zipFileName; - public MissingArchive(Path name) { - zipFileName = name; - } - @Override - public boolean contains(RelativePath name) { - return false; + private FileSystem getFileSystem(Path path) throws IOException { + Path realPath = fsInfo.getCanonicalFile(path); + FileSystem fs = fileSystems.get(realPath); + if (fs == null) { + fileSystems.put(realPath, fs = FileSystems.newFileSystem(realPath, null)); } - - @Override - public void close() { - } - - @Override - public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) { - return null; - } - - @Override - public List getFiles(RelativeDirectory subdirectory) { - return List.nil(); - } - - @Override - public Set getSubdirectories() { - return Collections.emptySet(); - } - - @Override - public String toString() { - return "MissingArchive[" + zipFileName + "]"; - } + return fs; } - /** A directory of zip files already opened. - */ - Map archives = new HashMap<>(); - - /* - * This method looks for a ZipFormatException and takes appropriate - * evasive action. If there is a failure in the fast mode then we - * fail over to the platform zip, and allow it to deal with a potentially - * non compliant zip file. - */ - protected Archive openArchive(Path zipFilename) throws IOException { - try { - return openArchive(zipFilename, contextUseOptimizedZip); - } catch (IOException ioe) { - if (ioe instanceof ZipFileIndex.ZipFormatException) { - return openArchive(zipFilename, false); - } else { - throw ioe; - } - } - } - - /** Open a new zip file directory, and cache it. - */ - private Archive openArchive(Path zipFileName, boolean useOptimizedZip) throws IOException { - Archive archive; - try { - - ZipFile zdir = null; - - boolean usePreindexedCache = false; - String preindexCacheLocation = null; - - if (!useOptimizedZip) { - zdir = new ZipFile(zipFileName.toFile()); - } else { - usePreindexedCache = options.isSet("usezipindex"); - preindexCacheLocation = options.get("java.io.tmpdir"); - String optCacheLoc = options.get("cachezipindexdir"); + private final Map fileSystems = new HashMap<>(); - if (optCacheLoc != null && optCacheLoc.length() != 0) { - if (optCacheLoc.startsWith("\"")) { - if (optCacheLoc.endsWith("\"")) { - optCacheLoc = optCacheLoc.substring(1, optCacheLoc.length() - 1); - } - else { - optCacheLoc = optCacheLoc.substring(1); - } - } - - File cacheDir = new File(optCacheLoc); - if (cacheDir.exists() && cacheDir.canWrite()) { - preindexCacheLocation = optCacheLoc; - if (!preindexCacheLocation.endsWith("/") && - !preindexCacheLocation.endsWith(File.separator)) { - preindexCacheLocation += File.separator; - } - } - } - } - - if (!useOptimizedZip) { - archive = new ZipArchive(this, zdir); - } else { - archive = new ZipFileIndexArchive(this, - zipFileIndexCache.getZipFileIndex(zipFileName, - null, - usePreindexedCache, - preindexCacheLocation, - options.isSet("writezipindexfiles"))); - } - } catch (FileNotFoundException | NoSuchFileException ex) { - archive = new MissingArchive(zipFileName); - } catch (ZipFileIndex.ZipFormatException zfe) { - throw zfe; - } catch (IOException ex) { - if (Files.exists(zipFileName)) - log.error("error.reading.file", zipFileName, getMessage(ex)); - archive = new MissingArchive(zipFileName); - } - - archives.put(zipFileName, archive); - return archive; - } /** Flush any output resources. */ @@ -628,15 +524,9 @@ * Close the JavaFileManager, releasing resources. */ @Override @DefinedBy(Api.COMPILER) - public void close() { - for (Iterator i = archives.values().iterator(); i.hasNext(); ) { - Archive a = i.next(); - i.remove(); - try { - a.close(); - } catch (IOException ignore) { - } - } + public void close() throws IOException { + for (FileSystem fs: fileSystems.values()) + fs.close(); } @Override @DefinedBy(Api.COMPILER) @@ -689,10 +579,8 @@ return null; } - if (file instanceof BaseFileObject) { - return ((BaseFileObject) file).inferBinaryName(path); - } else if (file instanceof PathFileObject) { - return ((PathFileObject) file).inferBinaryName(null); + if (file instanceof PathFileObject) { + return ((PathFileObject) file).inferBinaryName(path); } else throw new IllegalArgumentException(file.getClass().getName()); } @@ -703,11 +591,6 @@ nullCheck(b); if (a instanceof PathFileObject && b instanceof PathFileObject) return ((PathFileObject) a).isSameFile((PathFileObject) b); - // In time, we should phase out BaseFileObject in favor of PathFileObject - if (!(a instanceof BaseFileObject || a instanceof PathFileObject)) - throw new IllegalArgumentException("Not supported: " + a); - if (!(b instanceof BaseFileObject || b instanceof PathFileObject)) - throw new IllegalArgumentException("Not supported: " + b); return a.equals(b); } @@ -754,32 +637,29 @@ return null; for (Path file: path) { - Archive a = archives.get(file); - if (a == null) { - // archives are not created for directories or jrt: images - if (file == Locations.JRT_MARKER_FILE) { - JRTIndex.Entry e = getJRTIndex().getEntry(name.dirname()); - if (symbolFileEnabled && e.ctSym.hidden) - continue; - Path p = e.files.get(name.basename()); - if (p != null) - return PathFileObject.createJRTPathFileObject(this, p); + if (file == Locations.JRT_MARKER_FILE) { + JRTIndex.Entry e = getJRTIndex().getEntry(name.dirname()); + if (symbolFileEnabled && e.ctSym.hidden) continue; - } else if (fsInfo.isDirectory(file)) { - try { - Path f = name.getFile(file); - if (Files.exists(f)) - return new RegularFileObject(this, f); - } catch (InvalidPathException ignore) { - } - continue; + Path p = e.files.get(name.basename()); + if (p != null) + return PathFileObject.forJRTPath(this, p); + } else if (fsInfo.isDirectory(file)) { + try { + Path f = name.resolveAgainst(file); + if (Files.exists(f)) + return PathFileObject.forSimplePath(this, + fsInfo.getCanonicalFile(f), f); + } catch (InvalidPathException ignore) { } - // Not a directory, create the archive - a = openArchive(file); - } - // Process the archive - if (a.contains(name)) { - return a.getFileObject(name.dirname(), name.basename()); + } else if (Files.exists(file)) { + FileSystem fs = getFileSystem(file); + if (fs != null) { + Path fsRoot = fs.getRootDirectories().iterator().next(); + Path f = name.resolveAgainst(fsRoot); + if (Files.exists(f)) + return PathFileObject.forJarPath(this, f, file); + } } } return null; @@ -829,14 +709,14 @@ if (getClassOutDir() != null) { dir = getClassOutDir(); } else { - Path siblingDir = null; - if (sibling != null && sibling instanceof RegularFileObject) { - siblingDir = ((RegularFileObject)sibling).file.getParent(); + String baseName = fileName.basename(); + if (sibling != null && sibling instanceof PathFileObject) { + return ((PathFileObject) sibling).getSibling(baseName); + } else { + Path p = Paths.get(baseName); + Path real = fsInfo.getCanonicalFile(p); + return PathFileObject.forSimplePath(this, real, p); } - if (siblingDir == null) - return new RegularFileObject(this, Paths.get(fileName.basename())); - else - return new RegularFileObject(this, siblingDir.resolve(fileName.basename())); } } else if (location == SOURCE_OUTPUT) { dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir()); @@ -850,8 +730,11 @@ } try { - Path file = fileName.getFile(dir); // null-safe - return new RegularFileObject(this, file); + if (dir == null) { + dir = Paths.get(System.getProperty("user.dir")); + } + Path path = fileName.resolveAgainst(fsInfo.getCanonicalFile(dir)); + return PathFileObject.forDirectoryPath(this, path, dir, fileName); } catch (InvalidPathException e) { throw new IOException("bad filename " + fileName, e); } @@ -861,13 +744,17 @@ public Iterable getJavaFileObjectsFromFiles( Iterable files) { - ArrayList result; + ArrayList result; if (files instanceof Collection) result = new ArrayList<>(((Collection)files).size()); else result = new ArrayList<>(); - for (File f: files) - result.add(new RegularFileObject(this, nullCheck(f).toPath())); + for (File f: files) { + Objects.requireNonNull(f); + Path p = f.toPath(); + result.add(PathFileObject.forSimplePath(this, + fsInfo.getCanonicalFile(p), p)); + } return result; } @@ -875,13 +762,14 @@ public Iterable getJavaFileObjectsFromPaths( Iterable paths) { - ArrayList result; + ArrayList result; if (paths instanceof Collection) result = new ArrayList<>(((Collection)paths).size()); else result = new ArrayList<>(); for (Path p: paths) - result.add(new RegularFileObject(this, nullCheck(p))); + result.add(PathFileObject.forSimplePath(this, + fsInfo.getCanonicalFile(p), p)); return result; } @@ -935,8 +823,8 @@ @Override @DefinedBy(Api.COMPILER) public Path asPath(FileObject file) { - if (file instanceof RegularFileObject) { - return ((RegularFileObject) file).file; + if (file instanceof PathFileObject) { + return ((PathFileObject) file).path; } else throw new IllegalArgumentException(file.getName()); } diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java Thu Dec 10 09:24:25 2015 -0800 @@ -33,18 +33,24 @@ import java.io.Reader; import java.io.Writer; import java.net.URI; +import java.net.URISyntaxException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharsetDecoder; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.LinkOption; import java.nio.file.Path; +import java.text.Normalizer; import java.util.Objects; import javax.lang.model.element.Modifier; import javax.lang.model.element.NestingKind; +import javax.tools.FileObject; import javax.tools.JavaFileObject; +import com.sun.tools.javac.file.RelativePath.RelativeFile; import com.sun.tools.javac.util.DefinedBy; import com.sun.tools.javac.util.DefinedBy.Api; @@ -53,10 +59,16 @@ * Implementation of JavaFileObject using java.nio.file API. * *

PathFileObjects are, for the most part, straightforward wrappers around - * Path objects. The primary complexity is the support for "inferBinaryName". - * This is left as an abstract method, implemented by each of a number of - * different factory methods, which compute the binary name based on - * information available at the time the file object is created. + * immutable absolute Path objects. Different subtypes are used to provide + * specialized implementations of "inferBinaryName" and "getName" that capture + * additional information available at the time the object is created. + * + *

In general, {@link JavaFileManager#isSameFile} should be used to + * determine whether two file objects refer to the same file on disk. + * PathFileObject also supports the standard {@code equals} and {@code hashCode} + * methods, primarily for convenience when working with collections. + * All of these operations delegate to the equivalent operations on the + * underlying Path object. * *

This is NOT part of any supported API. * If you write code that depends on this, you do so at your own risk. @@ -64,108 +76,297 @@ * deletion without notice. */ public abstract class PathFileObject implements JavaFileObject { - private final BaseFileManager fileManager; - private final Path path; + private static final FileSystem defaultFileSystem = FileSystems.getDefault(); + private static final boolean isMacOS = System.getProperty("os.name", "").contains("OS X"); + + protected final BaseFileManager fileManager; + protected final Path path; + private boolean hasParents; /** - * Create a PathFileObject within a directory, such that the binary name - * can be inferred from the relationship to the parent directory. + * Create a PathFileObject for a file within a directory, such that the + * binary name can be inferred from the relationship to an enclosing directory. + * + * The binary name is derived from {@code relativePath}. + * The name is derived from the composition of {@code userPackageRootDir} + * and {@code relativePath}. + * + * @param fileManager the file manager creating this file object + * @param path the absolute path referred to by this file object + * @param userPackageRootDir the path of the directory containing the + * root of the package hierarchy + * @param relativePath the path of this file relative to {@code userPackageRootDir} */ - static PathFileObject createDirectoryPathFileObject(BaseFileManager fileManager, - final Path path, final Path dir) { - return new PathFileObject(fileManager, path) { - @Override - public String inferBinaryName(Iterable paths) { - return toBinaryName(dir.relativize(path)); - } - }; + static PathFileObject forDirectoryPath(BaseFileManager fileManager, Path path, + Path userPackageRootDir, RelativePath relativePath) { + return new DirectoryFileObject(fileManager, path, userPackageRootDir, relativePath); + } + + private static class DirectoryFileObject extends PathFileObject { + private final Path userPackageRootDir; + private final RelativePath relativePath; + + private DirectoryFileObject(BaseFileManager fileManager, Path path, + Path userPackageRootDir, RelativePath relativePath) { + super(fileManager, path); + this.userPackageRootDir = userPackageRootDir; + this.relativePath = relativePath; + } + + @Override @DefinedBy(Api.COMPILER) + public String getName() { + return relativePath.resolveAgainst(userPackageRootDir).toString(); + } + + @Override + public String inferBinaryName(Iterable paths) { + return toBinaryName(relativePath); + } + + @Override + public String toString() { + return "DirectoryFileObject[" + userPackageRootDir + ":" + relativePath.path + "]"; + } + + @Override + PathFileObject getSibling(String baseName) { + return new DirectoryFileObject(fileManager, + path.resolveSibling(baseName), + userPackageRootDir, + new RelativeFile(relativePath.dirname(), baseName) + ); + } } /** - * Create a PathFileObject in a file system such as a jar file, such that - * the binary name can be inferred from its position within the filesystem. + * Create a PathFileObject for a file in a file system such as a jar file, + * such that the binary name can be inferred from its position within the + * file system. + * + * The binary name is derived from {@code path}. + * The name is derived from the composition of {@code userJarPath} + * and {@code path}. + * + * @param fileManager the file manager creating this file object + * @param path the path referred to by this file object + * @param userJarPath the path of the jar file containing the file system. */ - public static PathFileObject createJarPathFileObject(BaseFileManager fileManager, - final Path path) { - return new PathFileObject(fileManager, path) { - @Override - public String inferBinaryName(Iterable paths) { - return toBinaryName(path); - } - }; + public static PathFileObject forJarPath(BaseFileManager fileManager, + Path path, Path userJarPath) { + return new JarFileObject(fileManager, path, userJarPath); } - /** - * Create a PathFileObject in a modular file system, such as jrt:, such that - * the binary name can be inferred from its position within the filesystem. - */ - public static PathFileObject createJRTPathFileObject(BaseFileManager fileManager, - final Path path) { - return new PathFileObject(fileManager, path) { - @Override - public String inferBinaryName(Iterable paths) { - // use subpath to ignore the leading /modules/MODULE-NAME - return toBinaryName(path.subpath(2, path.getNameCount())); + private static class JarFileObject extends PathFileObject { + private final Path userJarPath; + + private JarFileObject(BaseFileManager fileManager, Path path, Path userJarPath) { + super(fileManager, path); + this.userJarPath = userJarPath; + } + + @Override @DefinedBy(Api.COMPILER) + public String getName() { + // The use of ( ) to delimit the entry name is not ideal + // but it does match earlier behavior + return userJarPath + "(" + path + ")"; + } + + @Override + public String inferBinaryName(Iterable paths) { + Path root = path.getFileSystem().getRootDirectories().iterator().next(); + return toBinaryName(root.relativize(path)); + } + + @Override @DefinedBy(Api.COMPILER) + public URI toUri() { + // Work around bug JDK-8134451: + // path.toUri() returns double-encoded URIs, that cannot be opened by URLConnection + return createJarUri(userJarPath, path.toString()); + } + + @Override + public String toString() { + return "JarFileObject[" + userJarPath + ":" + path + "]"; + } + + @Override + PathFileObject getSibling(String baseName) { + return new JarFileObject(fileManager, + path.resolveSibling(baseName), + userJarPath + ); + } + + private static URI createJarUri(Path jarFile, String entryName) { + URI jarURI = jarFile.toUri().normalize(); + String separator = entryName.startsWith("/") ? "!" : "!/"; + try { + // The jar URI convention appears to be not to re-encode the jarURI + return new URI("jar:" + jarURI + separator + entryName); + } catch (URISyntaxException e) { + throw new CannotCreateUriError(jarURI + separator + entryName, e); } - }; + } } /** - * Create a PathFileObject whose binary name can be inferred from the - * relative path to a sibling. + * Create a PathFileObject for a file in a modular file system, such as jrt:, + * such that the binary name can be inferred from its position within the + * filesystem. + * + * The binary name is derived from {@code path}, ignoring the first two + * elements of the name (which are "modules" and a module name). + * The name is derived from {@code path}. + * + * @param fileManager the file manager creating this file object + * @param path the path referred to by this file object */ - static PathFileObject createSiblingPathFileObject(BaseFileManager fileManager, - final Path path, final String relativePath) { - return new PathFileObject(fileManager, path) { - @Override - public String inferBinaryName(Iterable paths) { - return toBinaryName(relativePath, "/"); - } - }; + public static PathFileObject forJRTPath(BaseFileManager fileManager, + final Path path) { + return new JRTFileObject(fileManager, path); + } + + private static class JRTFileObject extends PathFileObject { + // private final Path javaHome; + private JRTFileObject(BaseFileManager fileManager, Path path) { + super(fileManager, path); + } + + @Override @DefinedBy(Api.COMPILER) + public String getName() { + return path.toString(); + } + + @Override + public String inferBinaryName(Iterable paths) { + // use subpath to ignore the leading /modules/MODULE-NAME + return toBinaryName(path.subpath(2, path.getNameCount())); + } + + @Override + public String toString() { + return "JRTFileObject[" + path + "]"; + } + + @Override + PathFileObject getSibling(String baseName) { + return new JRTFileObject(fileManager, + path.resolveSibling(baseName) + ); + } } /** - * Create a PathFileObject whose binary name might be inferred from its - * position on a search path. + * Create a PathFileObject for a file whose binary name must be inferred + * from its position on a search path. + * + * The binary name is inferred by finding an enclosing directory in + * the sequence of paths associated with the location given to + * {@link JavaFileManager#inferBinaryName). + * The name is derived from {@code userPath}. + * + * @param fileManager the file manager creating this file object + * @param path the path referred to by this file object + * @param userPath the "user-friendly" name for this path. */ - static PathFileObject createSimplePathFileObject(BaseFileManager fileManager, - final Path path) { - return new PathFileObject(fileManager, path) { - @Override - public String inferBinaryName(Iterable paths) { - Path absPath = path.toAbsolutePath(); - for (Path p: paths) { - Path ap = p.toAbsolutePath(); - if (absPath.startsWith(ap)) { - try { - Path rp = ap.relativize(absPath); - if (rp != null) // maybe null if absPath same as ap - return toBinaryName(rp); - } catch (IllegalArgumentException e) { - // ignore this p if cannot relativize path to p - } + static PathFileObject forSimplePath(BaseFileManager fileManager, + Path path, Path userPath) { + return new SimpleFileObject(fileManager, path, userPath); + } + + private static class SimpleFileObject extends PathFileObject { + private final Path userPath; + private SimpleFileObject(BaseFileManager fileManager, Path path, Path userPath) { + super(fileManager, path); + this.userPath = userPath; + } + + @Override @DefinedBy(Api.COMPILER) + public String getName() { + return userPath.toString(); + } + + @Override + public String inferBinaryName(Iterable paths) { + Path absPath = path.toAbsolutePath(); + for (Path p: paths) { + Path ap = p.toAbsolutePath(); + if (absPath.startsWith(ap)) { + try { + Path rp = ap.relativize(absPath); + if (rp != null) // maybe null if absPath same as ap + return toBinaryName(rp); + } catch (IllegalArgumentException e) { + // ignore this p if cannot relativize path to p } } - return null; } - }; + return null; + } + + @Override + PathFileObject getSibling(String baseName) { + return new SimpleFileObject(fileManager, + path.resolveSibling(baseName), + userPath.resolveSibling(baseName) + ); + } } + /** + * Create a PathFileObject, for a specified path, in the context of + * a given file manager. + * + * In general, this path should be an + * {@link Path#toAbsolutePath absolute path}, if not a + * {@link Path#toRealPath} real path. + * It will be used as the basis of {@code equals}, {@code hashCode} + * and {@code isSameFile} methods on this file object. + * + * A PathFileObject should also have a "friendly name" per the + * specification for {@link FileObject#getName}. The friendly name + * is provided by the various subtypes of {@code PathFileObject}. + * + * @param fileManager the file manager creating this file object + * @param path the path contained in this file object. + */ protected PathFileObject(BaseFileManager fileManager, Path path) { this.fileManager = Objects.requireNonNull(fileManager); - this.path = Objects.requireNonNull(path); + if (Files.isDirectory(path)) { + throw new IllegalArgumentException("directories not supported"); + } + this.path = path; } - public abstract String inferBinaryName(Iterable paths); + /** + * See {@link JavacFileManager#inferBinaryName}. + */ + abstract String inferBinaryName(Iterable paths); + + /** + * Return the file object for a sibling file with a given file name. + * See {@link JavacFileManager#getFileForOutput} and + * {@link JavacFileManager#getJavaFileForOutput}. + */ + abstract PathFileObject getSibling(String basename); /** * Return the Path for this object. * @return the Path for this object. + * @see StandardJavaFileManager#asPath */ public Path getPath() { return path; } + /** + * The short name is used when generating raw diagnostics. + * @return the last component of the path + */ + public String getShortName() { + return path.getFileName().toString(); + } + @Override @DefinedBy(Api.COMPILER) public Kind getKind() { return BaseFileManager.getKind(path.getFileName().toString()); @@ -174,22 +375,43 @@ @Override @DefinedBy(Api.COMPILER) public boolean isNameCompatible(String simpleName, Kind kind) { Objects.requireNonNull(simpleName); - // null check + Objects.requireNonNull(kind); + if (kind == Kind.OTHER && getKind() != kind) { return false; } + String sn = simpleName + kind.extension; String pn = path.getFileName().toString(); if (pn.equals(sn)) { return true; } - if (pn.equalsIgnoreCase(sn)) { - try { - // allow for Windows - return path.toRealPath(LinkOption.NOFOLLOW_LINKS).getFileName().toString().equals(sn); - } catch (IOException e) { + + if (path.getFileSystem() == defaultFileSystem) { + if (isMacOS) { + String name = path.getFileName().toString(); + if (Normalizer.isNormalized(name, Normalizer.Form.NFD) + && Normalizer.isNormalized(sn, Normalizer.Form.NFC)) { + // On Mac OS X it is quite possible to have the file name and the + // given simple name normalized in different ways. + // In that case we have to normalize file name to the + // Normal Form Composed (NFC). + String normName = Normalizer.normalize(name, Normalizer.Form.NFC); + if (normName.equals(sn)) { + return true; + } + } + } + + if (pn.equalsIgnoreCase(sn)) { + try { + // allow for Windows + return path.toRealPath(LinkOption.NOFOLLOW_LINKS).getFileName().toString().equals(sn); + } catch (IOException e) { + } } } + return false; } @@ -209,11 +431,6 @@ } @Override @DefinedBy(Api.COMPILER) - public String getName() { - return path.toString(); - } - - @Override @DefinedBy(Api.COMPILER) public InputStream openInputStream() throws IOException { return Files.newInputStream(path); } @@ -264,7 +481,7 @@ try { return Files.getLastModifiedTime(path).toMillis(); } catch (IOException e) { - return -1; + return 0; } } @@ -278,7 +495,7 @@ } } - public boolean isSameFile(PathFileObject other) { + boolean isSameFile(PathFileObject other) { try { return Files.isSameFile(path, other.path); } catch (IOException e) { @@ -302,17 +519,21 @@ } private void ensureParentDirectoriesExist() throws IOException { - Path parent = path.getParent(); - if (parent != null) - Files.createDirectories(parent); + if (!hasParents) { + Path parent = path.getParent(); + if (parent != null && !Files.isDirectory(parent)) { + try { + Files.createDirectories(parent); + } catch (IOException e) { + throw new IOException("could not create parent directories", e); + } + } + hasParents = true; + } } - private long size() { - try { - return Files.size(path); - } catch (IOException e) { - return -1; - } + protected static String toBinaryName(RelativePath relativePath) { + return toBinaryName(relativePath.path, "/"); } protected static String toBinaryName(Path relativePath) { @@ -320,12 +541,32 @@ relativePath.getFileSystem().getSeparator()); } - protected static String toBinaryName(String relativePath, String sep) { + private static String toBinaryName(String relativePath, String sep) { return removeExtension(relativePath).replace(sep, "."); } - protected static String removeExtension(String fileName) { + private static String removeExtension(String fileName) { int lastDot = fileName.lastIndexOf("."); return (lastDot == -1 ? fileName : fileName.substring(0, lastDot)); } + + /** Return the last component of a presumed hierarchical URI. + * From the scheme specific part of the URI, it returns the substring + * after the last "/" if any, or everything if no "/" is found. + */ + public static String getSimpleName(FileObject fo) { + URI uri = fo.toUri(); + String s = uri.getSchemeSpecificPart(); + return s.substring(s.lastIndexOf("/") + 1); // safe when / not found + + } + + /** Used when URLSyntaxException is thrown unexpectedly during + * implementations of FileObject.toURI(). */ + public static class CannotCreateUriError extends Error { + private static final long serialVersionUID = 9101708840997613546L; + public CannotCreateUriError(String value, Throwable cause) { + super(value, cause); + } + } } diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RegularFileObject.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RegularFileObject.java Thu Dec 10 08:17:12 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,265 +0,0 @@ -/* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tools.javac.file; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.lang.ref.Reference; -import java.lang.ref.SoftReference; -import java.net.URI; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.CharsetDecoder; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.text.Normalizer; -import java.util.Objects; - -import javax.tools.JavaFileObject; - -import com.sun.tools.javac.util.DefinedBy; -import com.sun.tools.javac.util.DefinedBy.Api; - -/** - * A subclass of JavaFileObject representing regular files. - * - *

This is NOT part of any supported API. - * 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. - */ -class RegularFileObject extends BaseFileObject { - - /** Have the parent directories been created? - */ - private boolean hasParents = false; - private String name; - final Path file; - private Reference absFileRef; - final static boolean isMacOS = System.getProperty("os.name", "").contains("OS X"); - - public RegularFileObject(JavacFileManager fileManager, Path f) { - this(fileManager, f.getFileName().toString(), f); - } - - public RegularFileObject(JavacFileManager fileManager, String name, Path f) { - super(fileManager); - if (Files.isDirectory(f)) { - throw new IllegalArgumentException("directories not supported"); - } - this.name = name; - this.file = f; - if (getLastModified() > System.currentTimeMillis()) - fileManager.log.warning("file.from.future", f); - } - - @Override @DefinedBy(Api.COMPILER) - public URI toUri() { - return file.toUri().normalize(); - } - - @Override @DefinedBy(Api.COMPILER) - public String getName() { - return file.toString(); - } - - @Override - public String getShortName() { - return name; - } - - @Override @DefinedBy(Api.COMPILER) - public JavaFileObject.Kind getKind() { - return getKind(name); - } - - @Override @DefinedBy(Api.COMPILER) - public InputStream openInputStream() throws IOException { - return Files.newInputStream(file); - } - - @Override @DefinedBy(Api.COMPILER) - public OutputStream openOutputStream() throws IOException { - fileManager.flushCache(this); - ensureParentDirectoriesExist(); - return Files.newOutputStream(file); - } - - @Override @DefinedBy(Api.COMPILER) - public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { - CharBuffer cb = fileManager.getCachedContent(this); - if (cb == null) { - try (InputStream in = Files.newInputStream(file)) { - ByteBuffer bb = fileManager.makeByteBuffer(in); - JavaFileObject prev = fileManager.log.useSource(this); - try { - cb = fileManager.decode(bb, ignoreEncodingErrors); - } finally { - fileManager.log.useSource(prev); - } - fileManager.recycleByteBuffer(bb); - if (!ignoreEncodingErrors) { - fileManager.cache(this, cb); - } - } - } - return cb; - } - - @Override @DefinedBy(Api.COMPILER) - public Writer openWriter() throws IOException { - fileManager.flushCache(this); - ensureParentDirectoriesExist(); - return new OutputStreamWriter(Files.newOutputStream(file), fileManager.getEncodingName()); - } - - @Override @DefinedBy(Api.COMPILER) - public long getLastModified() { - try { - return Files.getLastModifiedTime(file).toMillis(); - } catch (IOException e) { - return 0; - } - } - - @Override @DefinedBy(Api.COMPILER) - public boolean delete() { - try { - Files.delete(file); - return true; - } catch (IOException e) { - return false; - } - } - - @Override - protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { - return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors); - } - - @Override - protected String inferBinaryName(Iterable path) { - String fPath = file.toString(); - //System.err.println("RegularFileObject " + file + " " +r.getPath()); - for (Path dir: path) { - //System.err.println("dir: " + dir); - String sep = dir.getFileSystem().getSeparator(); - String dPath = dir.toString(); - if (dPath.length() == 0) - dPath = System.getProperty("user.dir"); - if (!dPath.endsWith(sep)) - dPath += sep; - if (fPath.regionMatches(true, 0, dPath, 0, dPath.length()) - && Paths.get(fPath.substring(0, dPath.length())).equals(Paths.get(dPath))) { - String relativeName = fPath.substring(dPath.length()); - return removeExtension(relativeName).replace(sep, "."); - } - } - return null; - } - - @Override @DefinedBy(Api.COMPILER) - public boolean isNameCompatible(String cn, JavaFileObject.Kind kind) { - Objects.requireNonNull(cn); - // null check - if (kind == Kind.OTHER && getKind() != kind) { - return false; - } - String n = cn + kind.extension; - if (name.equals(n)) { - return true; - } - if (isMacOS && Normalizer.isNormalized(name, Normalizer.Form.NFD) - && Normalizer.isNormalized(n, Normalizer.Form.NFC)) { - // On Mac OS X it is quite possible to file name and class - // name normalized in a different way - in that case we have to normalize file name - // to the Normal Form Compised (NFC) - String normName = Normalizer.normalize(name, Normalizer.Form.NFC); - if (normName.equals(n)) { - this.name = normName; - return true; - } - } - - if (name.equalsIgnoreCase(n)) { - try { - // allow for Windows - return file.toRealPath().getFileName().toString().equals(n); - } catch (IOException e) { - } - } - return false; - } - - private void ensureParentDirectoriesExist() throws IOException { - if (!hasParents) { - Path parent = file.getParent(); - if (parent != null && !Files.isDirectory(parent)) { - try { - Files.createDirectories(parent); - } catch (IOException e) { - throw new IOException("could not create parent directories", e); - } - } - hasParents = true; - } - } - - /** - * Check if two file objects are equal. - * Two RegularFileObjects are equal if the absolute paths of the underlying - * files are equal. - */ - @Override - public boolean equals(Object other) { - if (this == other) - return true; - - if (!(other instanceof RegularFileObject)) - return false; - - RegularFileObject o = (RegularFileObject) other; - return getAbsoluteFile().equals(o.getAbsoluteFile()); - } - - @Override - public int hashCode() { - return getAbsoluteFile().hashCode(); - } - - private Path getAbsoluteFile() { - Path absFile = (absFileRef == null ? null : absFileRef.get()); - if (absFile == null) { - absFile = file.toAbsolutePath(); - absFileRef = new SoftReference<>(absFile); - } - return absFile; - } -} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RelativePath.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RelativePath.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RelativePath.java Thu Dec 10 09:24:25 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package com.sun.tools.javac.file; import java.io.File; +import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.InvalidPathException; import java.nio.file.Path; @@ -57,7 +58,7 @@ public abstract String basename(); - public Path getFile(Path directory) throws /*unchecked*/ InvalidPathException { + public Path resolveAgainst(Path directory) throws /*unchecked*/ InvalidPathException { if (directory == null) { String sep = FileSystems.getDefault().getSeparator(); return Paths.get(path.replace("/", sep)); @@ -67,6 +68,12 @@ } } + public Path resolveAgainst(FileSystem fs) throws /*unchecked*/ InvalidPathException { + String sep = fs.getSeparator(); + Path root = fs.getRootDirectories().iterator().next(); + return root.resolve(path.replace("/", sep)); + } + @Override public int compareTo(RelativePath other) { return path.compareTo(other.path); diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipArchive.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipArchive.java Thu Dec 10 08:17:12 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,290 +0,0 @@ -/* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tools.javac.file; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Writer; -import java.lang.ref.Reference; -import java.lang.ref.SoftReference; -import java.net.URI; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.CharsetDecoder; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -import javax.tools.JavaFileObject; - -import com.sun.tools.javac.file.JavacFileManager.Archive; -import com.sun.tools.javac.file.RelativePath.RelativeDirectory; -import com.sun.tools.javac.file.RelativePath.RelativeFile; -import com.sun.tools.javac.util.DefinedBy; -import com.sun.tools.javac.util.DefinedBy.Api; -import com.sun.tools.javac.util.List; - -/** - *

This is NOT part of any supported API. - * 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. - */ -public class ZipArchive implements Archive { - - public ZipArchive(JavacFileManager fm, ZipFile zfile) throws IOException { - this(fm, zfile, true); - } - - protected ZipArchive(JavacFileManager fm, ZipFile zfile, boolean initMap) throws IOException { - this.fileManager = fm; - this.zfile = zfile; - this.map = new HashMap<>(); - if (initMap) - initMap(); - } - - protected void initMap() throws IOException { - for (Enumeration e = zfile.entries(); e.hasMoreElements(); ) { - ZipEntry entry; - try { - entry = e.nextElement(); - } catch (InternalError ex) { - IOException io = new IOException(); - io.initCause(ex); // convenience constructors added in Mustang :-( - throw io; - } - addZipEntry(entry); - } - } - - void addZipEntry(ZipEntry entry) { - String name = entry.getName(); - int i = name.lastIndexOf('/'); - RelativeDirectory dirname = new RelativeDirectory(name.substring(0, i+1)); - String basename = name.substring(i+1); - if (basename.length() == 0) - return; - List list = map.get(dirname); - if (list == null) - list = List.nil(); - list = list.prepend(basename); - map.put(dirname, list); - } - - public boolean contains(RelativePath name) { - RelativeDirectory dirname = name.dirname(); - String basename = name.basename(); - if (basename.length() == 0) - return false; - List list = map.get(dirname); - return (list != null && list.contains(basename)); - } - - public List getFiles(RelativeDirectory subdirectory) { - return map.get(subdirectory); - } - - public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) { - ZipEntry ze = new RelativeFile(subdirectory, file).getZipEntry(zfile); - return new ZipFileObject(this, file, ze); - } - - public Set getSubdirectories() { - return map.keySet(); - } - - public void close() throws IOException { - zfile.close(); - } - - @Override - public String toString() { - return "ZipArchive[" + zfile.getName() + "]"; - } - - private Path getAbsoluteFile() { - Path absFile = (absFileRef == null ? null : absFileRef.get()); - if (absFile == null) { - absFile = Paths.get(zfile.getName()).toAbsolutePath(); - absFileRef = new SoftReference<>(absFile); - } - return absFile; - } - - /** - * The file manager that created this archive. - */ - protected JavacFileManager fileManager; - /** - * The index for the contents of this archive. - */ - protected final Map> map; - /** - * The zip file for the archive. - */ - protected final ZipFile zfile; - /** - * A reference to the absolute filename for the zip file for the archive. - */ - protected Reference absFileRef; - - /** - * A subclass of JavaFileObject representing zip entries. - */ - public static class ZipFileObject extends BaseFileObject { - - private String name; - ZipArchive zarch; - ZipEntry entry; - - protected ZipFileObject(ZipArchive zarch, String name, ZipEntry entry) { - super(zarch.fileManager); - this.zarch = zarch; - this.name = name; - this.entry = entry; - } - - @DefinedBy(Api.COMPILER) - public URI toUri() { - Path zipFile = Paths.get(zarch.zfile.getName()); - return createJarUri(zipFile, entry.getName()); - } - - @Override @DefinedBy(Api.COMPILER) - public String getName() { - return zarch.zfile.getName() + "(" + entry.getName() + ")"; - } - - @Override - public String getShortName() { - return Paths.get(zarch.zfile.getName()).getFileName() + "(" + entry + ")"; - } - - @Override @DefinedBy(Api.COMPILER) - public JavaFileObject.Kind getKind() { - return getKind(entry.getName()); - } - - @Override @DefinedBy(Api.COMPILER) - public InputStream openInputStream() throws IOException { - return zarch.zfile.getInputStream(entry); - } - - @Override @DefinedBy(Api.COMPILER) - public OutputStream openOutputStream() throws IOException { - throw new UnsupportedOperationException(); - } - - @Override @DefinedBy(Api.COMPILER) - public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { - CharBuffer cb = fileManager.getCachedContent(this); - if (cb == null) { - try (InputStream in = zarch.zfile.getInputStream(entry)) { - ByteBuffer bb = fileManager.makeByteBuffer(in); - JavaFileObject prev = fileManager.log.useSource(this); - try { - cb = fileManager.decode(bb, ignoreEncodingErrors); - } finally { - fileManager.log.useSource(prev); - } - fileManager.recycleByteBuffer(bb); - if (!ignoreEncodingErrors) { - fileManager.cache(this, cb); - } - } - } - return cb; - } - - @Override @DefinedBy(Api.COMPILER) - public Writer openWriter() throws IOException { - throw new UnsupportedOperationException(); - } - - @Override @DefinedBy(Api.COMPILER) - public long getLastModified() { - return entry.getTime(); - } - - @Override @DefinedBy(Api.COMPILER) - public boolean delete() { - throw new UnsupportedOperationException(); - } - - @Override - protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { - return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors); - } - - @Override - protected String inferBinaryName(Iterable path) { - String entryName = entry.getName(); - return removeExtension(entryName).replace('/', '.'); - } - - @Override @DefinedBy(Api.COMPILER) - public boolean isNameCompatible(String cn, JavaFileObject.Kind k) { - Objects.requireNonNull(cn); - // null check - if (k == Kind.OTHER && getKind() != k) { - return false; - } - return name.equals(cn + k.extension); - } - - /** - * Check if two file objects are equal. - * Two ZipFileObjects are equal if the absolute paths of the underlying - * zip files are equal and if the paths within those zip files are equal. - */ - @Override - public boolean equals(Object other) { - if (this == other) - return true; - - if (!(other instanceof ZipFileObject)) - return false; - - ZipFileObject o = (ZipFileObject) other; - return zarch.getAbsoluteFile().equals(o.zarch.getAbsoluteFile()) - && entry.getName().equals(o.entry.getName()); - } - - @Override - public int hashCode() { - return zarch.getAbsoluteFile().hashCode() + entry.getName().hashCode(); - } - } - -} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipFileIndex.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipFileIndex.java Thu Dec 10 08:17:12 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1171 +0,0 @@ -/* - * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tools.javac.file; - - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.lang.ref.Reference; -import java.lang.ref.SoftReference; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.zip.DataFormatException; -import java.util.zip.Inflater; -import java.util.zip.ZipException; - -import com.sun.tools.javac.file.RelativePath.RelativeDirectory; -import com.sun.tools.javac.file.RelativePath.RelativeFile; - -/** - * This class implements the building of index of a zip archive and access to - * its context. It also uses a prebuilt index if available. - * It supports invocations where it will serialize an optimized zip index file - * to disk. - * - * In order to use a secondary index file, set "usezipindex" in the Options - * object when JavacFileManager is invoked. (You can pass "-XDusezipindex" on - * the command line.) - * - * Location where to look for/generate optimized zip index files can be - * provided using "{@code -XDcachezipindexdir=}". If this flag is not - * provided, the default location is the value of the "java.io.tmpdir" system - * property. - * - * If "-XDwritezipindexfiles" is specified, there will be new optimized index - * file created for each archive, used by the compiler for compilation, at the - * location specified by the "cachezipindexdir" option. - * - * If system property nonBatchMode option is specified the compiler will use - * timestamp checking to reindex the zip files if it is needed. In batch mode - * the timestamps are not checked and the compiler uses the cached indexes. - * - *

This is NOT part of any supported API. - * 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. - */ -public class ZipFileIndex { - private static final String MIN_CHAR = String.valueOf(Character.MIN_VALUE); - private static final String MAX_CHAR = String.valueOf(Character.MAX_VALUE); - - public final static long NOT_MODIFIED = Long.MIN_VALUE; - - - private static final boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this. - - private Map directories = - Collections.emptyMap(); - private Set allDirs = - Collections.emptySet(); - - // ZipFileIndex data entries - final Path zipFile; - private Reference absFileRef; - long zipFileLastModified = NOT_MODIFIED; - private RandomAccessFile zipRandomFile; - private Entry[] entries; - - private boolean readFromIndex = false; - private Path zipIndexFile = null; - private boolean triedToReadIndex = false; - final RelativeDirectory symbolFilePrefix; - private final int symbolFilePrefixLength; - private boolean hasPopulatedData = false; - long lastReferenceTimeStamp = NOT_MODIFIED; - - private final boolean usePreindexedCache; - private final String preindexedCacheLocation; - - private boolean writeIndex = false; - - private Map> relativeDirectoryCache = new HashMap<>(); - - - public synchronized boolean isOpen() { - return (zipRandomFile != null); - } - - ZipFileIndex(Path zipFile, RelativeDirectory symbolFilePrefix, boolean writeIndex, - boolean useCache, String cacheLocation) throws IOException { - this.zipFile = zipFile; - this.symbolFilePrefix = symbolFilePrefix; - this.symbolFilePrefixLength = (symbolFilePrefix == null ? 0 : - symbolFilePrefix.getPath().getBytes("UTF-8").length); - this.writeIndex = writeIndex; - this.usePreindexedCache = useCache; - this.preindexedCacheLocation = cacheLocation; - - if (zipFile != null) { - this.zipFileLastModified = Files.getLastModifiedTime(zipFile).toMillis(); - } - - // Validate integrity of the zip file - checkIndex(); - } - - @Override - public String toString() { - return "ZipFileIndex[" + zipFile + "]"; - } - - // Just in case... - @Override - protected void finalize() throws Throwable { - closeFile(); - super.finalize(); - } - - private boolean isUpToDate() { - try { - return (zipFile != null - && ((!NON_BATCH_MODE) || zipFileLastModified == Files.getLastModifiedTime(zipFile).toMillis()) - && hasPopulatedData); - } catch (IOException ignore) { - } - - return false; - } - - /** - * Here we need to make sure that the ZipFileIndex is valid. Check the timestamp of the file and - * if its the same as the one at the time the index was build we don't need to reopen anything. - */ - private void checkIndex() throws IOException { - boolean isUpToDate = true; - if (!isUpToDate()) { - closeFile(); - isUpToDate = false; - } - - if (zipRandomFile != null || isUpToDate) { - lastReferenceTimeStamp = System.currentTimeMillis(); - return; - } - - hasPopulatedData = true; - - if (readIndex()) { - lastReferenceTimeStamp = System.currentTimeMillis(); - return; - } - - directories = Collections.emptyMap(); - allDirs = Collections.emptySet(); - - try { - openFile(); - long totalLength = zipRandomFile.length(); - ZipDirectory directory = new ZipDirectory(zipRandomFile, 0L, totalLength, this); - directory.buildIndex(); - } finally { - if (zipRandomFile != null) { - closeFile(); - } - } - - lastReferenceTimeStamp = System.currentTimeMillis(); - } - - private void openFile() throws FileNotFoundException { - if (zipRandomFile == null && zipFile != null) { - zipRandomFile = new RandomAccessFile(zipFile.toFile(), "r"); - } - } - - private void cleanupState() { - // Make sure there is a valid but empty index if the file doesn't exist - entries = Entry.EMPTY_ARRAY; - directories = Collections.emptyMap(); - zipFileLastModified = NOT_MODIFIED; - allDirs = Collections.emptySet(); - } - - public synchronized void close() { - writeIndex(); - closeFile(); - } - - private void closeFile() { - if (zipRandomFile != null) { - try { - zipRandomFile.close(); - } catch (IOException ex) { - } - zipRandomFile = null; - } - } - - /** - * Returns the ZipFileIndexEntry for a path, if there is one. - */ - synchronized Entry getZipIndexEntry(RelativePath path) { - try { - checkIndex(); - DirectoryEntry de = directories.get(path.dirname()); - String lookFor = path.basename(); - return (de == null) ? null : de.getEntry(lookFor); - } - catch (IOException e) { - return null; - } - } - - /** - * Returns a javac List of filenames within a directory in the ZipFileIndex. - */ - public synchronized com.sun.tools.javac.util.List getFiles(RelativeDirectory path) { - try { - checkIndex(); - - DirectoryEntry de = directories.get(path); - com.sun.tools.javac.util.List ret = de == null ? null : de.getFiles(); - - if (ret == null) { - return com.sun.tools.javac.util.List.nil(); - } - return ret; - } - catch (IOException e) { - return com.sun.tools.javac.util.List.nil(); - } - } - - public synchronized List getDirectories(RelativeDirectory path) { - try { - checkIndex(); - - DirectoryEntry de = directories.get(path); - com.sun.tools.javac.util.List ret = de == null ? null : de.getDirectories(); - - if (ret == null) { - return com.sun.tools.javac.util.List.nil(); - } - - return ret; - } - catch (IOException e) { - return com.sun.tools.javac.util.List.nil(); - } - } - - public synchronized Set getAllDirectories() { - try { - checkIndex(); - if (allDirs == Collections.EMPTY_SET) { - allDirs = new java.util.LinkedHashSet<>(directories.keySet()); - } - - return allDirs; - } - catch (IOException e) { - return Collections.emptySet(); - } - } - - /** - * Tests if a specific path exists in the zip. This method will return true - * for file entries and directories. - * - * @param path A path within the zip. - * @return True if the path is a file or dir, false otherwise. - */ - public synchronized boolean contains(RelativePath path) { - try { - checkIndex(); - return getZipIndexEntry(path) != null; - } - catch (IOException e) { - return false; - } - } - - public synchronized boolean isDirectory(RelativePath path) throws IOException { - // The top level in a zip file is always a directory. - if (path.getPath().length() == 0) { - lastReferenceTimeStamp = System.currentTimeMillis(); - return true; - } - - checkIndex(); - return directories.get(path) != null; - } - - public synchronized long getLastModified(RelativeFile path) throws IOException { - Entry entry = getZipIndexEntry(path); - if (entry == null) - throw new FileNotFoundException(); - return entry.getLastModified(); - } - - public synchronized int length(RelativeFile path) throws IOException { - Entry entry = getZipIndexEntry(path); - if (entry == null) - throw new FileNotFoundException(); - - if (entry.isDir) { - return 0; - } - - byte[] header = getHeader(entry); - // entry is not compressed? - if (get2ByteLittleEndian(header, 8) == 0) { - return entry.compressedSize; - } else { - return entry.size; - } - } - - public synchronized byte[] read(RelativeFile path) throws IOException { - Entry entry = getZipIndexEntry(path); - if (entry == null) - throw new FileNotFoundException("Path not found in ZIP: " + path.path); - return read(entry); - } - - synchronized byte[] read(Entry entry) throws IOException { - openFile(); - byte[] result = readBytes(entry); - closeFile(); - return result; - } - - public synchronized int read(RelativeFile path, byte[] buffer) throws IOException { - Entry entry = getZipIndexEntry(path); - if (entry == null) - throw new FileNotFoundException(); - return read(entry, buffer); - } - - synchronized int read(Entry entry, byte[] buffer) - throws IOException { - int result = readBytes(entry, buffer); - return result; - } - - private byte[] readBytes(Entry entry) throws IOException { - byte[] header = getHeader(entry); - int csize = entry.compressedSize; - byte[] cbuf = new byte[csize]; - zipRandomFile.skipBytes(get2ByteLittleEndian(header, 26) + get2ByteLittleEndian(header, 28)); - zipRandomFile.readFully(cbuf, 0, csize); - - // is this compressed - offset 8 in the ZipEntry header - if (get2ByteLittleEndian(header, 8) == 0) - return cbuf; - - int size = entry.size; - byte[] buf = new byte[size]; - if (inflate(cbuf, buf) != size) - throw new ZipException("corrupted zip file"); - - return buf; - } - - /** - * - */ - private int readBytes(Entry entry, byte[] buffer) throws IOException { - byte[] header = getHeader(entry); - - // entry is not compressed? - if (get2ByteLittleEndian(header, 8) == 0) { - zipRandomFile.skipBytes(get2ByteLittleEndian(header, 26) + get2ByteLittleEndian(header, 28)); - int offset = 0; - int size = buffer.length; - while (offset < size) { - int count = zipRandomFile.read(buffer, offset, size - offset); - if (count == -1) - break; - offset += count; - } - return entry.size; - } - - int csize = entry.compressedSize; - byte[] cbuf = new byte[csize]; - zipRandomFile.skipBytes(get2ByteLittleEndian(header, 26) + get2ByteLittleEndian(header, 28)); - zipRandomFile.readFully(cbuf, 0, csize); - - int count = inflate(cbuf, buffer); - if (count == -1) - throw new ZipException("corrupted zip file"); - - return entry.size; - } - - //---------------------------------------------------------------------------- - // Zip utilities - //---------------------------------------------------------------------------- - - private byte[] getHeader(Entry entry) throws IOException { - zipRandomFile.seek(entry.offset); - byte[] header = new byte[30]; - zipRandomFile.readFully(header); - if (get4ByteLittleEndian(header, 0) != 0x04034b50) - throw new ZipException("corrupted zip file"); - if ((get2ByteLittleEndian(header, 6) & 1) != 0) - throw new ZipException("encrypted zip file"); // offset 6 in the header of the ZipFileEntry - return header; - } - - /* - * Inflate using the java.util.zip.Inflater class - */ - private SoftReference inflaterRef; - private int inflate(byte[] src, byte[] dest) { - Inflater inflater = (inflaterRef == null ? null : inflaterRef.get()); - - // construct the inflater object or reuse an existing one - if (inflater == null) - inflaterRef = new SoftReference<>(inflater = new Inflater(true)); - - inflater.reset(); - inflater.setInput(src); - try { - return inflater.inflate(dest); - } catch (DataFormatException ex) { - return -1; - } - } - - /** - * return the two bytes buf[pos], buf[pos+1] as an unsigned integer in little - * endian format. - */ - private static int get2ByteLittleEndian(byte[] buf, int pos) { - return (buf[pos] & 0xFF) + ((buf[pos+1] & 0xFF) << 8); - } - - /** - * return the 4 bytes buf[i..i+3] as an integer in little endian format. - */ - private static int get4ByteLittleEndian(byte[] buf, int pos) { - return (buf[pos] & 0xFF) + ((buf[pos + 1] & 0xFF) << 8) + - ((buf[pos + 2] & 0xFF) << 16) + ((buf[pos + 3] & 0xFF) << 24); - } - - /* ---------------------------------------------------------------------------- - * ZipDirectory - * ----------------------------------------------------------------------------*/ - - private class ZipDirectory { - private RelativeDirectory lastDir; - private int lastStart; - private int lastLen; - - byte[] zipDir; - RandomAccessFile zipRandomFile = null; - ZipFileIndex zipFileIndex = null; - - public ZipDirectory(RandomAccessFile zipRandomFile, long start, long end, ZipFileIndex index) throws IOException { - this.zipRandomFile = zipRandomFile; - this.zipFileIndex = index; - hasValidHeader(); - findCENRecord(start, end); - } - - /* - * the zip entry signature should be at offset 0, otherwise allow the - * calling logic to take evasive action by throwing ZipFormatException. - */ - private boolean hasValidHeader() throws IOException { - final long pos = zipRandomFile.getFilePointer(); - try { - if (zipRandomFile.read() == 'P') { - if (zipRandomFile.read() == 'K') { - if (zipRandomFile.read() == 0x03) { - if (zipRandomFile.read() == 0x04) { - return true; - } - } - } - } - } finally { - zipRandomFile.seek(pos); - } - throw new ZipFormatException("invalid zip magic"); - } - - /* - * Reads zip file central directory. - * For more details see readCEN in zip_util.c from the JDK sources. - * This is a Java port of that function. - */ - private void findCENRecord(long start, long end) throws IOException { - long totalLength = end - start; - int endbuflen = 1024; - byte[] endbuf = new byte[endbuflen]; - long endbufend = end - start; - - // There is a variable-length field after the dir offset record. We need to do consequential search. - while (endbufend >= 22) { - if (endbufend < endbuflen) - endbuflen = (int)endbufend; - long endbufpos = endbufend - endbuflen; - zipRandomFile.seek(start + endbufpos); - zipRandomFile.readFully(endbuf, 0, endbuflen); - int i = endbuflen - 22; - while (i >= 0 && - !(endbuf[i] == 0x50 && - endbuf[i + 1] == 0x4b && - endbuf[i + 2] == 0x05 && - endbuf[i + 3] == 0x06 && - endbufpos + i + 22 + - get2ByteLittleEndian(endbuf, i + 20) == totalLength)) { - i--; - } - - if (i >= 0) { - zipDir = new byte[get4ByteLittleEndian(endbuf, i + 12)]; - int sz = get4ByteLittleEndian(endbuf, i + 16); - // a negative offset or the entries field indicates a - // potential zip64 archive - if (sz < 0 || get2ByteLittleEndian(endbuf, i + 10) == 0xffff) { - throw new ZipFormatException("detected a zip64 archive"); - } - zipRandomFile.seek(start + sz); - zipRandomFile.readFully(zipDir, 0, zipDir.length); - return; - } else { - endbufend = endbufpos + 21; - } - } - throw new ZipException("cannot read zip file"); - } - - private void buildIndex() throws IOException { - int len = zipDir.length; - - // Add each of the files - if (len > 0) { - directories = new LinkedHashMap<>(); - ArrayList entryList = new ArrayList<>(); - for (int pos = 0; pos < len; ) { - pos = readEntry(pos, entryList, directories); - } - - // Add the accumulated dirs into the same list - for (RelativeDirectory d: directories.keySet()) { - // use shared RelativeDirectory objects for parent dirs - RelativeDirectory parent = getRelativeDirectory(d.dirname().getPath()); - String file = d.basename(); - Entry zipFileIndexEntry = new Entry(parent, file); - zipFileIndexEntry.isDir = true; - entryList.add(zipFileIndexEntry); - } - - entries = entryList.toArray(new Entry[entryList.size()]); - Arrays.sort(entries); - } else { - cleanupState(); - } - } - - private int readEntry(int pos, List entryList, - Map directories) throws IOException { - if (get4ByteLittleEndian(zipDir, pos) != 0x02014b50) { - throw new ZipException("cannot read zip file entry"); - } - - int dirStart = pos + 46; - int fileStart = dirStart; - int fileEnd = fileStart + get2ByteLittleEndian(zipDir, pos + 28); - - if (zipFileIndex.symbolFilePrefixLength != 0 && - ((fileEnd - fileStart) >= symbolFilePrefixLength)) { - dirStart += zipFileIndex.symbolFilePrefixLength; - fileStart += zipFileIndex.symbolFilePrefixLength; - } - // Force any '\' to '/'. Keep the position of the last separator. - for (int index = fileStart; index < fileEnd; index++) { - byte nextByte = zipDir[index]; - if (nextByte == (byte)'\\') { - zipDir[index] = (byte)'/'; - fileStart = index + 1; - } else if (nextByte == (byte)'/') { - fileStart = index + 1; - } - } - - RelativeDirectory directory = null; - if (fileStart == dirStart) - directory = getRelativeDirectory(""); - else if (lastDir != null && lastLen == fileStart - dirStart - 1) { - int index = lastLen - 1; - while (zipDir[lastStart + index] == zipDir[dirStart + index]) { - if (index == 0) { - directory = lastDir; - break; - } - index--; - } - } - - // Sub directories - if (directory == null) { - lastStart = dirStart; - lastLen = fileStart - dirStart - 1; - - directory = getRelativeDirectory(new String(zipDir, dirStart, lastLen, "UTF-8")); - lastDir = directory; - - // Enter also all the parent directories - RelativeDirectory tempDirectory = directory; - - while (directories.get(tempDirectory) == null) { - directories.put(tempDirectory, new DirectoryEntry(tempDirectory, zipFileIndex)); - if (tempDirectory.path.indexOf("/") == tempDirectory.path.length() - 1) - break; - else { - // use shared RelativeDirectory objects for parent dirs - tempDirectory = getRelativeDirectory(tempDirectory.dirname().getPath()); - } - } - } - else { - if (directories.get(directory) == null) { - directories.put(directory, new DirectoryEntry(directory, zipFileIndex)); - } - } - - // For each dir create also a file - if (fileStart != fileEnd) { - Entry entry = new Entry(directory, - new String(zipDir, fileStart, fileEnd - fileStart, "UTF-8")); - - entry.setNativeTime(get4ByteLittleEndian(zipDir, pos + 12)); - entry.compressedSize = get4ByteLittleEndian(zipDir, pos + 20); - entry.size = get4ByteLittleEndian(zipDir, pos + 24); - entry.offset = get4ByteLittleEndian(zipDir, pos + 42); - entryList.add(entry); - } - - return pos + 46 + - get2ByteLittleEndian(zipDir, pos + 28) + - get2ByteLittleEndian(zipDir, pos + 30) + - get2ByteLittleEndian(zipDir, pos + 32); - } - } - - /** - * Returns the last modified timestamp of a zip file. - * @return long - */ - public long getZipFileLastModified() throws IOException { - synchronized (this) { - checkIndex(); - return zipFileLastModified; - } - } - - /** ------------------------------------------------------------------------ - * DirectoryEntry class - * -------------------------------------------------------------------------*/ - - static class DirectoryEntry { - private boolean filesInited; - private boolean directoriesInited; - private boolean zipFileEntriesInited; - private boolean entriesInited; - - private long writtenOffsetOffset = 0; - - private RelativeDirectory dirName; - - private com.sun.tools.javac.util.List zipFileEntriesFiles = com.sun.tools.javac.util.List.nil(); - private com.sun.tools.javac.util.List zipFileEntriesDirectories = com.sun.tools.javac.util.List.nil(); - private com.sun.tools.javac.util.List zipFileEntries = com.sun.tools.javac.util.List.nil(); - - private List entries = new ArrayList<>(); - - private ZipFileIndex zipFileIndex; - - private int numEntries; - - DirectoryEntry(RelativeDirectory dirName, ZipFileIndex index) { - filesInited = false; - directoriesInited = false; - entriesInited = false; - - this.dirName = dirName; - this.zipFileIndex = index; - } - - private com.sun.tools.javac.util.List getFiles() { - if (!filesInited) { - initEntries(); - for (Entry e : entries) { - if (!e.isDir) { - zipFileEntriesFiles = zipFileEntriesFiles.append(e.name); - } - } - filesInited = true; - } - return zipFileEntriesFiles; - } - - private com.sun.tools.javac.util.List getDirectories() { - if (!directoriesInited) { - initEntries(); - for (Entry e : entries) { - if (e.isDir) { - zipFileEntriesDirectories = zipFileEntriesDirectories.append(e.name); - } - } - directoriesInited = true; - } - return zipFileEntriesDirectories; - } - - private com.sun.tools.javac.util.List getEntries() { - if (!zipFileEntriesInited) { - initEntries(); - zipFileEntries = com.sun.tools.javac.util.List.nil(); - for (Entry zfie : entries) { - zipFileEntries = zipFileEntries.append(zfie); - } - zipFileEntriesInited = true; - } - return zipFileEntries; - } - - private Entry getEntry(String rootName) { - initEntries(); - int index = Collections.binarySearch(entries, new Entry(dirName, rootName)); - if (index < 0) { - return null; - } - - return entries.get(index); - } - - private void initEntries() { - if (entriesInited) { - return; - } - - if (!zipFileIndex.readFromIndex) { - int from = -Arrays.binarySearch(zipFileIndex.entries, - new Entry(dirName, ZipFileIndex.MIN_CHAR)) - 1; - int to = -Arrays.binarySearch(zipFileIndex.entries, - new Entry(dirName, MAX_CHAR)) - 1; - - for (int i = from; i < to; i++) { - entries.add(zipFileIndex.entries[i]); - } - } else { - Path indexFile = zipFileIndex.getIndexFile(); - if (indexFile != null) { - RandomAccessFile raf = null; - try { - raf = new RandomAccessFile(indexFile.toFile(), "r"); - raf.seek(writtenOffsetOffset); - - for (int nFiles = 0; nFiles < numEntries; nFiles++) { - // Read the name bytes - int zfieNameBytesLen = raf.readInt(); - byte [] zfieNameBytes = new byte[zfieNameBytesLen]; - raf.read(zfieNameBytes); - String eName = new String(zfieNameBytes, "UTF-8"); - - // Read isDir - boolean eIsDir = raf.readByte() == (byte)0 ? false : true; - - // Read offset of bytes in the real Jar/Zip file - int eOffset = raf.readInt(); - - // Read size of the file in the real Jar/Zip file - int eSize = raf.readInt(); - - // Read compressed size of the file in the real Jar/Zip file - int eCsize = raf.readInt(); - - // Read java time stamp of the file in the real Jar/Zip file - long eJavaTimestamp = raf.readLong(); - - Entry rfie = new Entry(dirName, eName); - rfie.isDir = eIsDir; - rfie.offset = eOffset; - rfie.size = eSize; - rfie.compressedSize = eCsize; - rfie.javatime = eJavaTimestamp; - entries.add(rfie); - } - } catch (Throwable t) { - // Do nothing - } finally { - try { - if (raf != null) { - raf.close(); - } - } catch (Throwable t) { - // Do nothing - } - } - } - } - - entriesInited = true; - } - - List getEntriesAsCollection() { - initEntries(); - - return entries; - } - } - - private boolean readIndex() { - if (triedToReadIndex || !usePreindexedCache) { - return false; - } - - boolean ret = false; - synchronized (this) { - triedToReadIndex = true; - RandomAccessFile raf = null; - try { - Path indexFileName = getIndexFile(); - raf = new RandomAccessFile(indexFileName.toFile(), "r"); - - long fileStamp = raf.readLong(); - if (Files.getLastModifiedTime(zipFile).toMillis() != fileStamp) { - ret = false; - } else { - directories = new LinkedHashMap<>(); - int numDirs = raf.readInt(); - for (int nDirs = 0; nDirs < numDirs; nDirs++) { - int dirNameBytesLen = raf.readInt(); - byte [] dirNameBytes = new byte[dirNameBytesLen]; - raf.read(dirNameBytes); - - RelativeDirectory dirNameStr = getRelativeDirectory(new String(dirNameBytes, "UTF-8")); - DirectoryEntry de = new DirectoryEntry(dirNameStr, this); - de.numEntries = raf.readInt(); - de.writtenOffsetOffset = raf.readLong(); - directories.put(dirNameStr, de); - } - ret = true; - zipFileLastModified = fileStamp; - } - } catch (Throwable t) { - // Do nothing - } finally { - if (raf != null) { - try { - raf.close(); - } catch (Throwable tt) { - // Do nothing - } - } - } - if (ret == true) { - readFromIndex = true; - } - } - - return ret; - } - - private boolean writeIndex() { - boolean ret = false; - if (readFromIndex || !usePreindexedCache) { - return true; - } - - if (!writeIndex) { - return true; - } - - Path indexFile = getIndexFile(); - if (indexFile == null) { - return false; - } - - RandomAccessFile raf = null; - long writtenSoFar = 0; - try { - raf = new RandomAccessFile(indexFile.toFile(), "rw"); - - raf.writeLong(zipFileLastModified); - writtenSoFar += 8; - - List directoriesToWrite = new ArrayList<>(); - Map offsets = new HashMap<>(); - raf.writeInt(directories.keySet().size()); - writtenSoFar += 4; - - for (RelativeDirectory dirName: directories.keySet()) { - DirectoryEntry dirEntry = directories.get(dirName); - - directoriesToWrite.add(dirEntry); - - // Write the dir name bytes - byte [] dirNameBytes = dirName.getPath().getBytes("UTF-8"); - int dirNameBytesLen = dirNameBytes.length; - raf.writeInt(dirNameBytesLen); - writtenSoFar += 4; - - raf.write(dirNameBytes); - writtenSoFar += dirNameBytesLen; - - // Write the number of files in the dir - List dirEntries = dirEntry.getEntriesAsCollection(); - raf.writeInt(dirEntries.size()); - writtenSoFar += 4; - - offsets.put(dirName, new Long(writtenSoFar)); - - // Write the offset of the file's data in the dir - dirEntry.writtenOffsetOffset = 0L; - raf.writeLong(0L); - writtenSoFar += 8; - } - - for (DirectoryEntry de : directoriesToWrite) { - // Fix up the offset in the directory table - long currFP = raf.getFilePointer(); - - long offsetOffset = offsets.get(de.dirName).longValue(); - raf.seek(offsetOffset); - raf.writeLong(writtenSoFar); - - raf.seek(currFP); - - // Now write each of the files in the DirectoryEntry - List list = de.getEntriesAsCollection(); - for (Entry zfie : list) { - // Write the name bytes - byte [] zfieNameBytes = zfie.name.getBytes("UTF-8"); - int zfieNameBytesLen = zfieNameBytes.length; - raf.writeInt(zfieNameBytesLen); - writtenSoFar += 4; - raf.write(zfieNameBytes); - writtenSoFar += zfieNameBytesLen; - - // Write isDir - raf.writeByte(zfie.isDir ? (byte)1 : (byte)0); - writtenSoFar += 1; - - // Write offset of bytes in the real Jar/Zip file - raf.writeInt(zfie.offset); - writtenSoFar += 4; - - // Write size of the file in the real Jar/Zip file - raf.writeInt(zfie.size); - writtenSoFar += 4; - - // Write compressed size of the file in the real Jar/Zip file - raf.writeInt(zfie.compressedSize); - writtenSoFar += 4; - - // Write java time stamp of the file in the real Jar/Zip file - raf.writeLong(zfie.getLastModified()); - writtenSoFar += 8; - } - } - } catch (Throwable t) { - // Do nothing - } finally { - try { - if (raf != null) { - raf.close(); - } - } catch(IOException ioe) { - // Do nothing - } - } - - return ret; - } - - public boolean writeZipIndex() { - synchronized (this) { - return writeIndex(); - } - } - - private Path getIndexFile() { - if (zipIndexFile == null) { - if (zipFile == null) { - return null; - } - - zipIndexFile = Paths.get((preindexedCacheLocation == null ? "" : preindexedCacheLocation) + - zipFile.getFileName() + ".index"); - } - - return zipIndexFile; - } - - public Path getZipFile() { - return zipFile; - } - - Path getAbsoluteFile() { - Path absFile = (absFileRef == null ? null : absFileRef.get()); - if (absFile == null) { - absFile = zipFile.toAbsolutePath(); - absFileRef = new SoftReference<>(absFile); - } - return absFile; - } - - private RelativeDirectory getRelativeDirectory(String path) { - RelativeDirectory rd; - SoftReference ref = relativeDirectoryCache.get(path); - if (ref != null) { - rd = ref.get(); - if (rd != null) - return rd; - } - rd = new RelativeDirectory(path); - relativeDirectoryCache.put(path, new SoftReference<>(rd)); - return rd; - } - - static class Entry implements Comparable { - public static final Entry[] EMPTY_ARRAY = {}; - - // Directory related - RelativeDirectory dir; - boolean isDir; - - // File related - String name; - - int offset; - int size; - int compressedSize; - long javatime; - - private int nativetime; - - public Entry(RelativePath path) { - this(path.dirname(), path.basename()); - } - - public Entry(RelativeDirectory directory, String name) { - this.dir = directory; - this.name = name; - } - - public String getName() { - return new RelativeFile(dir, name).getPath(); - } - - public String getFileName() { - return name; - } - - public long getLastModified() { - if (javatime == 0) { - javatime = dosToJavaTime(nativetime); - } - return javatime; - } - - // based on dosToJavaTime in java.util.Zip, but avoiding the - // use of deprecated Date constructor - private static long dosToJavaTime(int dtime) { - Calendar c = Calendar.getInstance(); - c.set(Calendar.YEAR, ((dtime >> 25) & 0x7f) + 1980); - c.set(Calendar.MONTH, ((dtime >> 21) & 0x0f) - 1); - c.set(Calendar.DATE, ((dtime >> 16) & 0x1f)); - c.set(Calendar.HOUR_OF_DAY, ((dtime >> 11) & 0x1f)); - c.set(Calendar.MINUTE, ((dtime >> 5) & 0x3f)); - c.set(Calendar.SECOND, ((dtime << 1) & 0x3e)); - c.set(Calendar.MILLISECOND, 0); - return c.getTimeInMillis(); - } - - void setNativeTime(int natTime) { - nativetime = natTime; - } - - public boolean isDirectory() { - return isDir; - } - - public int compareTo(Entry other) { - RelativeDirectory otherD = other.dir; - if (dir != otherD) { - int c = dir.compareTo(otherD); - if (c != 0) - return c; - } - return name.compareTo(other.name); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof Entry)) - return false; - Entry other = (Entry) o; - return dir.equals(other.dir) && name.equals(other.name); - } - - @Override - public int hashCode() { - int hash = 7; - hash = 97 * hash + (this.dir != null ? this.dir.hashCode() : 0); - hash = 97 * hash + (this.name != null ? this.name.hashCode() : 0); - return hash; - } - - @Override - public String toString() { - return isDir ? ("Dir:" + dir + " : " + name) : - (dir + ":" + name); - } - } - - /* - * Exception primarily used to implement a failover, used exclusively here. - */ - - static final class ZipFormatException extends IOException { - private static final long serialVersionUID = 8000196834066748623L; - protected ZipFormatException(String message) { - super(message); - } - - protected ZipFormatException(String message, Throwable cause) { - super(message, cause); - } - } -} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java Thu Dec 10 08:17:12 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tools.javac.file; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Writer; -import java.net.URI; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.CharsetDecoder; -import java.nio.file.Path; -import java.util.Objects; -import java.util.Set; - -import javax.tools.JavaFileObject; - -import com.sun.tools.javac.file.JavacFileManager.Archive; -import com.sun.tools.javac.file.RelativePath.RelativeDirectory; -import com.sun.tools.javac.file.RelativePath.RelativeFile; -import com.sun.tools.javac.util.Assert; -import com.sun.tools.javac.util.DefinedBy; -import com.sun.tools.javac.util.DefinedBy.Api; -import com.sun.tools.javac.util.List; - -/** - *

This is NOT part of any supported API. - * 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. - */ -public class ZipFileIndexArchive implements Archive { - - private final ZipFileIndex zfIndex; - private final JavacFileManager fileManager; - - public ZipFileIndexArchive(JavacFileManager fileManager, ZipFileIndex zdir) throws IOException { - super(); - this.fileManager = fileManager; - this.zfIndex = zdir; - } - - public boolean contains(RelativePath name) { - return zfIndex.contains(name); - } - - public List getFiles(RelativeDirectory subdirectory) { - return zfIndex.getFiles(subdirectory); - } - - public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) { - RelativeFile fullZipFileName = new RelativeFile(subdirectory, file); - ZipFileIndex.Entry entry = zfIndex.getZipIndexEntry(fullZipFileName); - JavaFileObject ret = new ZipFileIndexFileObject(fileManager, zfIndex, entry, zfIndex.getZipFile()); - return ret; - } - - public Set getSubdirectories() { - return zfIndex.getAllDirectories(); - } - - public void close() throws IOException { - zfIndex.close(); - } - - @Override - public String toString() { - return "ZipFileIndexArchive[" + zfIndex + "]"; - } - - /** - * A subclass of JavaFileObject representing zip entries using the com.sun.tools.javac.file.ZipFileIndex implementation. - */ - public static class ZipFileIndexFileObject extends BaseFileObject { - - /** The entry's name. - */ - private String name; - - /** The zipfile containing the entry. - */ - ZipFileIndex zfIndex; - - /** The underlying zip entry object. - */ - ZipFileIndex.Entry entry; - - /** The name of the zip file where this entry resides. - */ - Path zipName; - - - ZipFileIndexFileObject(JavacFileManager fileManager, ZipFileIndex zfIndex, ZipFileIndex.Entry entry, Path zipFileName) { - super(fileManager); - this.name = entry.getFileName(); - this.zfIndex = zfIndex; - this.entry = entry; - this.zipName = zipFileName; - } - - @Override @DefinedBy(Api.COMPILER) - public URI toUri() { - return createJarUri(zipName, getPrefixedEntryName()); - } - - @Override @DefinedBy(Api.COMPILER) - public String getName() { - return zipName + "(" + getPrefixedEntryName() + ")"; - } - - @Override - public String getShortName() { - return zipName.getFileName() + "(" + entry.getName() + ")"; - } - - @Override @DefinedBy(Api.COMPILER) - public JavaFileObject.Kind getKind() { - return getKind(entry.getName()); - } - - @Override @DefinedBy(Api.COMPILER) - public InputStream openInputStream() throws IOException { - Assert.checkNonNull(entry); // see constructor - return new ByteArrayInputStream(zfIndex.read(entry)); - } - - @Override @DefinedBy(Api.COMPILER) - public OutputStream openOutputStream() throws IOException { - throw new UnsupportedOperationException(); - } - - @Override @DefinedBy(Api.COMPILER) - public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { - CharBuffer cb = fileManager.getCachedContent(this); - if (cb == null) { - try (InputStream in = new ByteArrayInputStream(zfIndex.read(entry))) { - ByteBuffer bb = fileManager.makeByteBuffer(in); - JavaFileObject prev = fileManager.log.useSource(this); - try { - cb = fileManager.decode(bb, ignoreEncodingErrors); - } finally { - fileManager.log.useSource(prev); - } - fileManager.recycleByteBuffer(bb); // save for next time - if (!ignoreEncodingErrors) - fileManager.cache(this, cb); - } - } - return cb; - } - - @Override @DefinedBy(Api.COMPILER) - public Writer openWriter() throws IOException { - throw new UnsupportedOperationException(); - } - - @Override @DefinedBy(Api.COMPILER) - public long getLastModified() { - return entry.getLastModified(); - } - - @Override @DefinedBy(Api.COMPILER) - public boolean delete() { - throw new UnsupportedOperationException(); - } - - @Override - protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { - return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors); - } - - @Override - protected String inferBinaryName(Iterable path) { - String entryName = entry.getName(); - if (zfIndex.symbolFilePrefix != null) { - String prefix = zfIndex.symbolFilePrefix.path; - if (entryName.startsWith(prefix)) - entryName = entryName.substring(prefix.length()); - } - return removeExtension(entryName).replace('/', '.'); - } - - @Override @DefinedBy(Api.COMPILER) - public boolean isNameCompatible(String cn, JavaFileObject.Kind k) { - Objects.requireNonNull(cn); - if (k == Kind.OTHER && getKind() != k) - return false; - return name.equals(cn + k.extension); - } - - /** - * Check if two file objects are equal. - * Two ZipFileIndexFileObjects are equal if the absolute paths of the underlying - * zip files are equal and if the paths within those zip files are equal. - */ - @Override - public boolean equals(Object other) { - if (this == other) - return true; - - if (!(other instanceof ZipFileIndexFileObject)) - return false; - - ZipFileIndexFileObject o = (ZipFileIndexFileObject) other; - return zfIndex.getAbsoluteFile().equals(o.zfIndex.getAbsoluteFile()) - && entry.equals(o.entry); - } - - @Override - public int hashCode() { - return zfIndex.getAbsoluteFile().hashCode() + entry.hashCode(); - } - - private String getPrefixedEntryName() { - if (zfIndex.symbolFilePrefix != null) - return zfIndex.symbolFilePrefix.path + entry.getName(); - else - return entry.getName(); - } - } - -} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipFileIndexCache.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipFileIndexCache.java Thu Dec 10 08:17:12 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tools.javac.file; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.sun.tools.javac.file.RelativePath.RelativeDirectory; -import com.sun.tools.javac.util.Context; - - -/** A cache for ZipFileIndex objects. */ -public class ZipFileIndexCache { - - private final Map map = new HashMap<>(); - - /** Get a shared instance of the cache. */ - private static ZipFileIndexCache sharedInstance; - public synchronized static ZipFileIndexCache getSharedInstance() { - if (sharedInstance == null) - sharedInstance = new ZipFileIndexCache(); - return sharedInstance; - } - - /** Get a context-specific instance of a cache. */ - public static ZipFileIndexCache instance(Context context) { - ZipFileIndexCache instance = context.get(ZipFileIndexCache.class); - if (instance == null) - context.put(ZipFileIndexCache.class, instance = new ZipFileIndexCache()); - return instance; - } - - /** - * Returns a list of all ZipFileIndex entries - * - * @return A list of ZipFileIndex entries, or an empty list - */ - public List getZipFileIndexes() { - return getZipFileIndexes(false); - } - - /** - * Returns a list of all ZipFileIndex entries - * - * @param openedOnly If true it returns a list of only opened ZipFileIndex entries, otherwise - * all ZipFileEntry(s) are included into the list. - * @return A list of ZipFileIndex entries, or an empty list - */ - public synchronized List getZipFileIndexes(boolean openedOnly) { - List zipFileIndexes = new ArrayList<>(); - - zipFileIndexes.addAll(map.values()); - - if (openedOnly) { - for(ZipFileIndex elem : zipFileIndexes) { - if (!elem.isOpen()) { - zipFileIndexes.remove(elem); - } - } - } - - return zipFileIndexes; - } - - public synchronized ZipFileIndex getZipFileIndex(Path zipFile, - RelativeDirectory symbolFilePrefix, - boolean useCache, String cacheLocation, - boolean writeIndex) throws IOException { - ZipFileIndex zi = getExistingZipIndex(zipFile); - - if (zi == null || (zi != null && Files.getLastModifiedTime(zipFile).toMillis() != zi.zipFileLastModified)) { - zi = new ZipFileIndex(zipFile, symbolFilePrefix, writeIndex, - useCache, cacheLocation); - map.put(zipFile, zi); - } - return zi; - } - - public synchronized ZipFileIndex getExistingZipIndex(Path zipFile) { - return map.get(zipFile); - } - - public synchronized void clearCache() { - map.clear(); - } - - public synchronized void clearCache(long timeNotUsed) { - for (Path cachedFile : map.keySet()) { - ZipFileIndex cachedZipIndex = map.get(cachedFile); - if (cachedZipIndex != null) { - long timeToTest = cachedZipIndex.lastReferenceTimeStamp + timeNotUsed; - if (timeToTest < cachedZipIndex.lastReferenceTimeStamp || // Overflow... - System.currentTimeMillis() > timeToTest) { - map.remove(cachedFile); - } - } - } - } - - public synchronized void removeFromCache(Path file) { - map.remove(file); - } - - /** Sets already opened list of ZipFileIndexes from an outside client - * of the compiler. This functionality should be used in a non-batch clients of the compiler. - */ - public synchronized void setOpenedIndexes(Listindexes) throws IllegalStateException { - if (map.isEmpty()) { - String msg = - "Setting opened indexes should be called only when the ZipFileCache is empty. " - + "Call JavacFileManager.flush() before calling this method."; - throw new IllegalStateException(msg); - } - - for (ZipFileIndex zfi : indexes) { - map.put(zfi.zipFile, zfi); - } - } -} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Dec 10 09:24:25 2015 -0800 @@ -29,15 +29,18 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.CharBuffer; -import java.nio.file.Path; import java.util.Arrays; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; + +import javax.lang.model.element.Modifier; +import javax.lang.model.element.NestingKind; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; + import com.sun.tools.javac.comp.Annotate; import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter; import com.sun.tools.javac.code.*; @@ -47,7 +50,8 @@ import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata; -import com.sun.tools.javac.file.BaseFileObject; +import com.sun.tools.javac.file.BaseFileManager; +import com.sun.tools.javac.file.PathFileObject; import com.sun.tools.javac.jvm.ClassFile.NameAndType; import com.sun.tools.javac.jvm.ClassFile.Version; import com.sun.tools.javac.util.*; @@ -2465,15 +2469,14 @@ * to be valid as is, so operations other than those to access the name throw * UnsupportedOperationException */ - private static class SourceFileObject extends BaseFileObject { + private static class SourceFileObject implements JavaFileObject { /** The file's name. */ - private Name name; - private Name flatname; + private final Name name; + private final Name flatname; public SourceFileObject(Name name, Name flatname) { - super(null); // no file manager; never referenced for this file object this.name = name; this.flatname = flatname; } @@ -2483,7 +2486,7 @@ try { return new URI(null, name.toString(), null); } catch (URISyntaxException e) { - throw new CannotCreateUriError(name.toString(), e); + throw new PathFileObject.CannotCreateUriError(name.toString(), e); } } @@ -2492,14 +2495,9 @@ return name.toString(); } - @Override - public String getShortName() { - return getName(); - } - @Override @DefinedBy(Api.COMPILER) public JavaFileObject.Kind getKind() { - return getKind(getName()); + return BaseFileManager.getKind(getName()); } @Override @DefinedBy(Api.COMPILER) @@ -2537,14 +2535,19 @@ throw new UnsupportedOperationException(); } - @Override - protected String inferBinaryName(Iterable path) { - return flatname.toString(); + @Override @DefinedBy(Api.COMPILER) + public boolean isNameCompatible(String simpleName, JavaFileObject.Kind kind) { + return true; // fail-safe mode } @Override @DefinedBy(Api.COMPILER) - public boolean isNameCompatible(String simpleName, JavaFileObject.Kind kind) { - return true; // fail-safe mode + public NestingKind getNestingKind() { + return null; + } + + @Override @DefinedBy(Api.COMPILER) + public Modifier getAccessLevel() { + return null; } /** diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Thu Dec 10 09:24:25 2015 -0800 @@ -40,7 +40,7 @@ import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Types.UniqueType; -import com.sun.tools.javac.file.BaseFileObject; +import com.sun.tools.javac.file.PathFileObject; import com.sun.tools.javac.jvm.Pool.DynamicMethod; import com.sun.tools.javac.jvm.Pool.Method; import com.sun.tools.javac.jvm.Pool.MethodHandle; @@ -52,6 +52,7 @@ import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE; import static com.sun.tools.javac.code.TypeTag.*; import static com.sun.tools.javac.main.Option.*; + import static javax.tools.StandardLocation.CLASS_OUTPUT; /** This class provides operations to map an internal symbol table graph @@ -1699,7 +1700,7 @@ // the last possible moment because the sourcefile may be used // elsewhere in error diagnostics. Fixes 4241573. //databuf.appendChar(c.pool.put(c.sourcefile)); - String simpleName = BaseFileObject.getSimpleName(c.sourcefile); + String simpleName = PathFileObject.getSimpleName(c.sourcefile); databuf.appendChar(c.pool.put(names.fromString(simpleName))); endAttr(alenIdx); acount++; diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Thu Dec 10 09:24:25 2015 -0800 @@ -141,8 +141,11 @@ JavacFileManager.preRegister(context); // can't create it until Log has been set up Result result = compile(args, context); if (fileManager instanceof JavacFileManager) { - // A fresh context was created above, so jfm must be a JavacFileManager - ((JavacFileManager)fileManager).close(); + try { + // A fresh context was created above, so jfm must be a JavacFileManager + ((JavacFileManager)fileManager).close(); + } catch (IOException ignore) { + } } return result; } diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java Thu Dec 10 09:24:25 2015 -0800 @@ -578,12 +578,49 @@ } /** + * Read a term ie. one word. + * It is an error if the beginning of the next tag is detected. + */ + @SuppressWarnings("fallthrough") + protected DCText inlineWord() { + int pos = bp; + int depth = 0; + loop: + while (bp < buflen) { + switch (ch) { + case '\n': + newline = true; + // fallthrough + + case '\r': case '\f': case ' ': case '\t': + return m.at(pos).Text(newString(pos, bp)); + + case '@': + if (newline) + break loop; + + case '{': + depth++; + break; + + case '}': + if (depth == 0 || --depth == 0) + return m.at(pos).Text(newString(pos, bp)); + break; + } + newline = false; + nextChar(); + } + return null; + } + + /** * Read general text content of an inline tag, including HTML entities and elements. * Matching pairs of { } are skipped; the text is terminated by the first * unmatched }. It is an error if the beginning of the next tag is detected. */ @SuppressWarnings("fallthrough") - protected List inlineContent() { + private List inlineContent() { ListBuffer trees = new ListBuffer<>(); skipWhitespace(); @@ -614,6 +651,8 @@ break; case '{': + if (textStart == -1) + textStart = bp; newline = false; depth++; nextChar(); @@ -1022,6 +1061,28 @@ } }, + // @index search-term options-description + new TagParser(Kind.INLINE, DCTree.Kind.INDEX) { + public DCTree parse(int pos) throws ParseException { + skipWhitespace(); + if (ch == '}') { + throw new ParseException("dc.no.content"); + } + DCTree term = ch == '"' ? quotedString() : inlineWord(); + if (term == null) { + throw new ParseException("dc.no.content"); + } + skipWhitespace(); + List description = List.nil(); + if (ch != '}') { + description = inlineContent(); + } else { + nextChar(); + } + return m.at(pos).Index(term, description); + } + }, + // {@inheritDoc} new TagParser(Kind.INLINE, DCTree.Kind.INHERIT_DOC) { public DCTree parse(int pos) throws ParseException { diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/ct.properties --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/ct.properties Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/ct.properties Thu Dec 10 09:24:25 2015 -0800 @@ -1,4 +1,3 @@ -apple.applescript.*: hidden apple.laf.*: hidden apple.security.*: hidden com.apple.concurrent.*: hidden diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java Thu Dec 10 09:24:25 2015 -0800 @@ -408,6 +408,36 @@ } } + public static class DCIndex extends DCInlineTag implements IndexTree { + public final DCTree term; + public final List description; + + DCIndex(DCTree term, List description) { + this.term = term; + this.description = description; + } + + @Override @DefinedBy(Api.COMPILER_TREE) + public Kind getKind() { + return Kind.INDEX; + } + + @Override @DefinedBy(Api.COMPILER_TREE) + public R accept(DocTreeVisitor v, D d) { + return v.visitIndex(this, d); + } + + @Override @DefinedBy(Api.COMPILER_TREE) + public DocTree getSearchTerm() { + return term; + } + + @Override @DefinedBy(Api.COMPILER_TREE) + public java.util.List getDescription() { + return description; + } + } + public static class DCInheritDoc extends DCInlineTag implements InheritDocTree { @Override @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java Thu Dec 10 09:24:25 2015 -0800 @@ -270,6 +270,24 @@ } @DefinedBy(Api.COMPILER_TREE) + public Void visitIndex(IndexTree node, Void p) { + try { + print("{"); + printTagName(node); + print(" "); + print(node.getSearchTerm()); + if (!node.getDescription().isEmpty()) { + print(" "); + print(node.getDescription()); + } + print("}"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return null; + } + + @DefinedBy(Api.COMPILER_TREE) public Void visitInheritDoc(InheritDocTree node, Void p) { try { print("{"); diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java Thu Dec 10 09:24:25 2015 -0800 @@ -50,6 +50,7 @@ import com.sun.tools.javac.tree.DCTree.DCEntity; import com.sun.tools.javac.tree.DCTree.DCErroneous; import com.sun.tools.javac.tree.DCTree.DCIdentifier; +import com.sun.tools.javac.tree.DCTree.DCIndex; import com.sun.tools.javac.tree.DCTree.DCInheritDoc; import com.sun.tools.javac.tree.DCTree.DCLink; import com.sun.tools.javac.tree.DCTree.DCLiteral; @@ -224,6 +225,12 @@ return tree; } + public DCIndex Index(DCTree term, List description) { + DCIndex tree = new DCIndex(term, description); + tree.pos = pos; + return tree; + } + public DCInheritDoc InheritDoc() { DCInheritDoc tree = new DCInheritDoc(); tree.pos = pos; diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java Thu Dec 10 09:24:25 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Type.CapturedType; -import com.sun.tools.javac.file.BaseFileObject; +import com.sun.tools.javac.file.PathFileObject; import com.sun.tools.javac.jvm.Profile; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.Pretty; @@ -144,10 +144,10 @@ throw new IllegalArgumentException(); // d should have source set if (fullname) return fo.getName(); - else if (fo instanceof BaseFileObject) - return ((BaseFileObject) fo).getShortName(); + else if (fo instanceof PathFileObject) + return ((PathFileObject) fo).getShortName(); else - return BaseFileObject.getSimpleName(fo); + return PathFileObject.getSimpleName(fo); } /** diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java Thu Dec 10 09:24:25 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.*; import com.sun.tools.javac.api.Formattable; -import com.sun.tools.javac.file.BaseFileObject; +import com.sun.tools.javac.file.PathFileObject; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.util.AbstractDiagnosticFormatter.SimpleConfiguration; @@ -123,8 +123,8 @@ } else if (arg instanceof JCExpression) { JCExpression tree = (JCExpression)arg; s = "@" + tree.getStartPosition(); - } else if (arg instanceof BaseFileObject) { - s = ((BaseFileObject) arg).getShortName(); + } else if (arg instanceof PathFileObject) { + s = ((PathFileObject) arg).getShortName(); } else { s = super.formatArgument(diag, arg, null); } diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java Thu Dec 10 09:24:25 2015 -0800 @@ -115,7 +115,11 @@ // Clean up JavaFileManager fileManager = context.get(JavaFileManager.class); if (fileManager instanceof JavacFileManager) { - ((JavacFileManager) fileManager).close(); + try { + ((JavacFileManager) fileManager).close(); + } catch (IOException e) { + return RC_FATAL; + } } return result.exitCode; diff -r 9229cc3b3802 -r 8b372e28f106 langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/SourcePositionImpl.java --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/SourcePositionImpl.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/SourcePositionImpl.java Thu Dec 10 09:24:25 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -103,10 +103,14 @@ String fn = filename.getName(); if (fn.endsWith(")")) { int paren = fn.lastIndexOf("("); - if (paren != -1) + if (paren != -1) { + int i = paren+1; + if (fn.charAt(i) == '/') + i++; fn = fn.substring(0, paren) + File.separatorChar - + fn.substring(paren + 1, fn.length() - 1); + + fn.substring(i, fn.length() - 1); + } } if (position == Position.NOPOS) diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/com/sun/javadoc/testSearch/TestSearch.java --- a/langtools/test/com/sun/javadoc/testSearch/TestSearch.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/com/sun/javadoc/testSearch/TestSearch.java Thu Dec 10 09:24:25 2015 -0800 @@ -71,7 +71,8 @@ @Test void test3() { - javadoc("-d", "out-3", "-noindex", "-sourcepath", testSrc, + javadoc("-d", "out-3", "-noindex", "-Xdoclint:none", + "-sourcepath", testSrc, "-use", "pkg", "pkg1", "pkg2", "pkg3"); checkExit(Exit.OK); checkSearchOutput(false); @@ -86,7 +87,8 @@ @Test void test4() { - javadoc("-d", "out-4", "-html5", "-sourcepath", testSrc, + javadoc("-d", "out-4", "-html5", "-Xdoclint:none", + "-sourcepath", testSrc, "-use", "pkg", "pkg1", "pkg2", "pkg3"); checkExit(Exit.OK); checkSearchOutput(true); @@ -101,7 +103,8 @@ @Test void test5() { - javadoc("-d", "out-5", "-noindex", "-html5", "-sourcepath", testSrc, + javadoc("-d", "out-5", "-noindex", "-html5", "-Xdoclint:none", + "-sourcepath", testSrc, "-use", "pkg", "pkg1", "pkg2", "pkg3"); checkExit(Exit.OK); checkSearchOutput(false); @@ -116,7 +119,8 @@ @Test void test6() { - javadoc("-d", "out-6", "-nocomment", "-sourcepath", testSrc, + javadoc("-d", "out-6", "-nocomment", "-Xdoclint:none", + "-sourcepath", testSrc, "-use", "pkg", "pkg1", "pkg2", "pkg3"); checkExit(Exit.OK); checkSearchOutput(true); @@ -131,7 +135,8 @@ @Test void test7() { - javadoc("-d", "out-7", "-nodeprecated", "-sourcepath", testSrc, + javadoc("-d", "out-7", "-nodeprecated", "-Xdoclint:none", + "-sourcepath", testSrc, "-use", "pkg", "pkg1", "pkg2", "pkg3"); checkExit(Exit.OK); checkSearchOutput(true); diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/6508981/TestInferBinaryName.java --- a/langtools/test/tools/javac/6508981/TestInferBinaryName.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/6508981/TestInferBinaryName.java Thu Dec 10 09:24:25 2015 -0800 @@ -53,9 +53,6 @@ * the impl of inferBinaryName for that file object. */ public class TestInferBinaryName { - static final boolean DONT_USE_ZIP_FILE_INDEX = false; - static final boolean USE_ZIP_FILE_INDEX = true; - public static void main(String... args) throws Exception { new TestInferBinaryName().run(); } @@ -64,10 +61,7 @@ testDirectory(); File testJar = createJar(); - testZipArchive(testJar); - testZipFileIndexArchive(testJar); - testZipFileIndexArchive2(testJar); if (errors > 0) throw new Exception(errors + " error found"); @@ -87,40 +81,18 @@ void testDirectory() throws IOException { String testClassName = "p.A"; List testClasses = Arrays.asList(new File(System.getProperty("test.classes"))); - try (JavaFileManager fm = - getFileManager(testClasses, USE_ZIP_FILE_INDEX)) { + try (JavaFileManager fm = getFileManager(testClasses)) { test("testDirectory", - fm, testClassName, "com.sun.tools.javac.file.RegularFileObject"); + fm, testClassName, "SimpleFileObject"); } } void testZipArchive(File testJar) throws IOException { String testClassName = "java.lang.String"; List path = Arrays.asList(testJar); - try (JavaFileManager fm = - getFileManager(path, DONT_USE_ZIP_FILE_INDEX)) { + try (JavaFileManager fm = getFileManager(path)) { test("testZipArchive", - fm, testClassName, "com.sun.tools.javac.file.ZipArchive$ZipFileObject"); - } - } - - void testZipFileIndexArchive(File testJar) throws IOException { - String testClassName = "java.lang.String"; - List path = Arrays.asList(testJar); - try (JavaFileManager fm = - getFileManager(path, USE_ZIP_FILE_INDEX)) { - test("testZipFileIndexArchive", - fm, testClassName, "com.sun.tools.javac.file.ZipFileIndexArchive$ZipFileIndexFileObject"); - } - } - - void testZipFileIndexArchive2(File testJar) throws IOException { - String testClassName = "java.lang.String"; - List path = Arrays.asList(testJar); - try (JavaFileManager fm = - getFileManager(path, USE_ZIP_FILE_INDEX)) { - test("testZipFileIndexArchive2", - fm, testClassName, "com.sun.tools.javac.file.ZipFileIndexArchive$ZipFileIndexFileObject"); + fm, testClassName, "JarFileObject"); } } @@ -141,21 +113,17 @@ return; } - String cn = fo.getClass().getName(); + String cn = fo.getClass().getSimpleName(); String bn = fm.inferBinaryName(CLASS_PATH, fo); System.err.println(testName + " " + cn + " " + bn); - check(cn, implClassName); - check(bn, testClassName); + checkEqual(cn, implClassName); + checkEqual(bn, testClassName); System.err.println("OK"); } - JavaFileManager getFileManager(List path, - boolean zipFileIndexKind) + JavaFileManager getFileManager(List path) throws IOException { Context ctx = new Context(); - Options options = Options.instance(ctx); - options.put("useOptimizedZip", - Boolean.toString(zipFileIndexKind == USE_ZIP_FILE_INDEX)); JavacFileManager fm = new JavacFileManager(ctx, false, null); fm.setLocation(CLASS_PATH, path); @@ -163,7 +131,7 @@ } List getPath(String s) { - List path = new ArrayList(); + List path = new ArrayList<>(); for (String f: s.split(File.pathSeparator)) { if (f.length() > 0) path.add(new File(f)); @@ -172,7 +140,7 @@ return path; } - void check(String found, String expect) { + void checkEqual(String found, String expect) { if (!found.equals(expect)) { System.err.println("Expected: " + expect); System.err.println(" Found: " + found); diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/T6358024.java --- a/langtools/test/tools/javac/T6358024.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/T6358024.java Thu Dec 10 09:24:25 2015 -0800 @@ -53,7 +53,7 @@ String testSrc = System.getProperty("test.src"); fm = new JavacFileManager(new Context(), false, null); - JavaFileObject f = fm.getFileForInput(testSrc + File.separatorChar + self + ".java"); + JavaFileObject f = fm.getJavaFileObject(testSrc + File.separatorChar + self + ".java"); test(fm, f, new Option[] { new Option("-d", ".")}, diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/T6358166.java --- a/langtools/test/tools/javac/T6358166.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/T6358166.java Thu Dec 10 09:24:25 2015 -0800 @@ -54,7 +54,7 @@ String testSrc = System.getProperty("test.src"); JavacFileManager fm = new JavacFileManager(new Context(), false, null); - JavaFileObject f = fm.getFileForInput(testSrc + File.separatorChar + self + ".java"); + JavaFileObject f = fm.getJavaFileObject(testSrc + File.separatorChar + self + ".java"); test(fm, f, "-verbose", "-d", "."); diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/T6705935.java --- a/langtools/test/tools/javac/T6705935.java Thu Dec 10 08:17:12 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 6705935 - * @summary javac reports path name of entry in ZipFileIndex incorectly - * @modules jdk.compiler/com.sun.tools.javac.file - */ - -import java.io.*; -import java.util.*; -import javax.tools.*; -import com.sun.tools.javac.file.*; -import com.sun.tools.javac.file.ZipArchive.ZipFileObject; -import com.sun.tools.javac.file.ZipFileIndexArchive.ZipFileIndexFileObject; - -public class T6705935 { - public static void main(String... args) throws Exception { - new T6705935().run(); - } - - public void run() throws Exception { - File java_home = new File(System.getProperty("java.home")); - - JavaCompiler c = ToolProvider.getSystemJavaCompiler(); - try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { - //System.err.println("platform class path: " + asList(fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH))); - - for (JavaFileObject fo: fm.list(StandardLocation.PLATFORM_CLASS_PATH, - "java.lang", - Collections.singleton(JavaFileObject.Kind.CLASS), - false)) { - test++; - - if (!(fo instanceof ZipFileObject || fo instanceof ZipFileIndexFileObject)) { - System.out.println("Skip " + fo.getClass().getSimpleName() + " " + fo.getName()); - skip++; - continue; - } - - //System.err.println(fo.getName()); - String p = fo.getName(); - int bra = p.indexOf("("); - int ket = p.indexOf(")"); - //System.err.println(bra + "," + ket + "," + p.length()); - if (bra == -1 || ket != p.length() -1) - throw new Exception("unexpected path: " + p + "[" + bra + "," + ket + "," + p.length()); - String part1 = p.substring(0, bra); - String part2 = p.substring(bra + 1, ket); - //System.err.println("[" + part1 + "|" + part2 + "]" + " " + java_home); - if (part1.equals(part2) || !part1.startsWith(java_home.getPath())) - throw new Exception("bad path: " + p); - - } - - if (test == 0) - throw new Exception("no files found"); - - if (skip == 0) - System.out.println(test + " files found"); - else - System.out.println(test + " files found, " + skip + " files skipped"); - - if (test == skip) - System.out.println("Warning: all files skipped; no platform classes found in zip files."); - } - } - - private List asList(Iterable items) { - List list = new ArrayList(); - for (T item: items) - list.add(item); - return list; - } - - private int skip; - private int test; -} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/T6725036.java --- a/langtools/test/tools/javac/T6725036.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/T6725036.java Thu Dec 10 09:24:25 2015 -0800 @@ -37,16 +37,15 @@ import java.io.File; import java.io.IOException; +import java.util.Collections; import java.util.Date; import java.util.jar.JarEntry; import java.util.jar.JarFile; + import javax.tools.*; import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.file.RelativePath.RelativeFile; -import com.sun.tools.javac.file.ZipFileIndex; -import com.sun.tools.javac.file.ZipFileIndexArchive; -import com.sun.tools.javac.file.ZipFileIndexCache; import com.sun.tools.javac.util.Context; public class T6725036 { @@ -63,21 +62,14 @@ JarEntry je = j.getJarEntry(TEST_ENTRY_NAME.getPath()); long jarEntryTime = je.getTime(); - ZipFileIndexCache zfic = ZipFileIndexCache.getSharedInstance(); - ZipFileIndex zfi = zfic.getZipFileIndex(testJar.toPath(), null, false, null, false); - long zfiTime = zfi.getLastModified(TEST_ENTRY_NAME); - - check(je, jarEntryTime, zfi + ":" + TEST_ENTRY_NAME.getPath(), zfiTime); - Context context = new Context(); JavacFileManager fm = new JavacFileManager(context, false, null); - ZipFileIndexArchive zfia = new ZipFileIndexArchive(fm, zfi); - JavaFileObject jfo = - zfia.getFileObject(TEST_ENTRY_NAME.dirname(), - TEST_ENTRY_NAME.basename()); - long jfoTime = jfo.getLastModified(); + fm.setLocation(StandardLocation.CLASS_PATH, Collections.singletonList(testJar)); + FileObject fo = + fm.getFileForInput(StandardLocation.CLASS_PATH, "", TEST_ENTRY_NAME.getPath()); + long jfoTime = fo.getLastModified(); - check(je, jarEntryTime, jfo, jfoTime); + check(je, jarEntryTime, fo, jfoTime); if (errors > 0) throw new Exception(errors + " occurred"); diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/TryWithResources/T7022711.java --- a/langtools/test/tools/javac/TryWithResources/T7022711.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/TryWithResources/T7022711.java Thu Dec 10 09:24:25 2015 -0800 @@ -9,12 +9,22 @@ class T7022711 { public static void main (String args[]) throws Exception { + // declared resource try (DataInputStream is = new DataInputStream(new FileInputStream("x"))) { while (true) { is.getChar(); // method not found } } catch (EOFException e) { } + + // resource as variable + DataInputStream is = new DataInputStream(new FileInputStream("x")); + try (is) { + while (true) { + is.getChar(); // method not found + } + } catch (EOFException e) { + } } } diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/TryWithResources/T7022711.out --- a/langtools/test/tools/javac/TryWithResources/T7022711.out Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/TryWithResources/T7022711.out Thu Dec 10 09:24:25 2015 -0800 @@ -1,2 +1,3 @@ -T7022711.java:14:19: compiler.err.cant.resolve.location.args: kindname.method, getChar, , , (compiler.misc.location.1: kindname.variable, is, java.io.DataInputStream) -1 error +T7022711.java:15:19: compiler.err.cant.resolve.location.args: kindname.method, getChar, , , (compiler.misc.location.1: kindname.variable, is, java.io.DataInputStream) +T7022711.java:24:19: compiler.err.cant.resolve.location.args: kindname.method, getChar, , , (compiler.misc.location.1: kindname.variable, is, java.io.DataInputStream) +2 errors diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/TryWithResources/T7032633.java --- a/langtools/test/tools/javac/TryWithResources/T7032633.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/TryWithResources/T7032633.java Thu Dec 10 09:24:25 2015 -0800 @@ -33,8 +33,15 @@ public class T7032633 { void test() throws IOException { + // declared resource try (OutputStream out = System.out) { out.flush(); } + + // resource as variable + OutputStream out = System.out; + try (out) { + out.flush(); + } } } diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/TryWithResources/TwrAndLambda.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/TryWithResources/TwrAndLambda.java Thu Dec 10 09:24:25 2015 -0800 @@ -0,0 +1,55 @@ +/* + * @test /nodynamiccopyright/ + * @bug 7196163 + * @summary Twr with resource variables as lambda expressions and method references + * @compile/fail/ref=TwrAndLambda.out -XDrawDiagnostics TwrAndLambda.java + */ + +public class TwrAndLambda { + + public static void main(String... args) { + + // Lambda expression + AutoCloseable v1 = () -> {}; + // Static method reference + AutoCloseable v2 = TwrAndLambda::close1; + // Instance method reference + AutoCloseable v3 = new TwrAndLambda()::close2; + // Lambda expression which is not AutoCloseable + Runnable r1 = () -> {}; + // Static method reference which is not AutoCloseable + Runnable r2 = TwrAndLambda::close1; + // Instance method reference which is not AutoCloseable + Runnable r3 = new TwrAndLambda()::close2; + + try (v1) { + } catch(Exception e) {} + try (v2) { + } catch(Exception e) {} + try (v3) { + } catch(Exception e) {} + try (r1) { + } catch(Exception e) {} + try (r2) { + } catch(Exception e) {} + try (r3) { + } catch(Exception e) {} + + // lambda invocation + I i = (x) -> { try(x) { } catch (Exception e) { } }; + i.m(v1); + i.m(v2); + i.m(v3); + i.m(r1); + i.m(r2); + i.m(r3); + } + + static interface I { + public void m(AutoCloseable r); + } + + public static void close1() { } + + public void close2() { } +} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/TryWithResources/TwrAndLambda.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/TryWithResources/TwrAndLambda.out Thu Dec 10 09:24:25 2015 -0800 @@ -0,0 +1,7 @@ +TwrAndLambda.java:31:14: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type: (compiler.misc.inconvertible.types: java.lang.Runnable, java.lang.AutoCloseable)) +TwrAndLambda.java:33:14: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type: (compiler.misc.inconvertible.types: java.lang.Runnable, java.lang.AutoCloseable)) +TwrAndLambda.java:35:14: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type: (compiler.misc.inconvertible.types: java.lang.Runnable, java.lang.AutoCloseable)) +TwrAndLambda.java:43:10: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.AutoCloseable, java.lang.Runnable, kindname.interface, TwrAndLambda.I, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Runnable, java.lang.AutoCloseable)) +TwrAndLambda.java:44:10: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.AutoCloseable, java.lang.Runnable, kindname.interface, TwrAndLambda.I, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Runnable, java.lang.AutoCloseable)) +TwrAndLambda.java:45:10: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.AutoCloseable, java.lang.Runnable, kindname.interface, TwrAndLambda.I, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Runnable, java.lang.AutoCloseable)) +6 errors diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/TryWithResources/TwrAndTypeVariables.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/TryWithResources/TwrAndTypeVariables.java Thu Dec 10 09:24:25 2015 -0800 @@ -0,0 +1,23 @@ +/* + * @test /nodynamiccopyright/ + * @bug 7196163 + * @summary Twr with resource variables of parametrized types + * @compile/fail/ref=TwrAndTypeVariables.out -XDrawDiagnostics TwrAndTypeVariables.java + */ + +public class TwrAndTypeVariables { + + // positive + public static + void copy(S s, T t) throws Exception { + try (s; t;) { + } + } + + // negative + public static void copy(S s) throws Exception { + try (s) { + } + } +} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/TryWithResources/TwrAndTypeVariables.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/TryWithResources/TwrAndTypeVariables.out Thu Dec 10 09:24:25 2015 -0800 @@ -0,0 +1,2 @@ +TwrAndTypeVariables.java:20:14: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type: (compiler.misc.inconvertible.types: S, java.lang.AutoCloseable)) +1 error diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/TryWithResources/TwrForVariable1.java --- a/langtools/test/tools/javac/TryWithResources/TwrForVariable1.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable1.java Thu Dec 10 09:24:25 2015 -0800 @@ -37,6 +37,49 @@ } assertCloseCount(6); + + // null test cases + TwrForVariable1 n = null; + + try (n) { + } + try (n) { + throw new Exception(); + } catch (Exception e) { + } + + assertCloseCount(6); + + // initialization exception + TwrForVariable1 i1 = new TwrForVariable1(); + try (i1; TwrForVariable1 i2 = new TwrForVariable1(true)) { + } catch (Exception e) { + } + + assertCloseCount(7); + + // multiple closures + TwrForVariable1 m1 = new TwrForVariable1(); + try (m1; TwrForVariable1 m2 = m1; TwrForVariable1 m3 = m2;) { + } + + assertCloseCount(10); + + // aliasing of variables keeps equality (bugs 6911256 6964740) + TwrForVariable1 a1 = new TwrForVariable1(); + try (a1; TwrForVariable1 a2 = a1;) { + if (a2 != a2) + throw new RuntimeException("Unexpected inequality."); + } + + assertCloseCount(12); + + // anonymous class implementing AutoCloseable as variable in twr + AutoCloseable a = new AutoCloseable() { + public void close() { }; + }; + try (a) { + } catch (Exception e) {} } static void assertCloseCount(int expectedCloseCount) { @@ -66,4 +109,13 @@ closeCount++; } } + + public TwrForVariable1(boolean throwException) { + if (throwException) + throw new RuntimeException("Initialization exception"); + } + + public TwrForVariable1() { + this(false); + } } diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/TryWithResources/TwrForVariable2.java --- a/langtools/test/tools/javac/TryWithResources/TwrForVariable2.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable2.java Thu Dec 10 09:24:25 2015 -0800 @@ -8,6 +8,7 @@ public static void main(String... args) { TwrForVariable2 v = new TwrForVariable2(); TwrForVariable3[] v2 = new TwrForVariable3[1]; + TwrForVariable3[][] v3 = new TwrForVariable3[1][1]; try (final v) { fail("no modifiers before variables"); @@ -24,9 +25,15 @@ try (v2[0]) { fail("array access not allowed"); } + try (v3[0][0]) { + fail("array access not allowed"); + } try (args.length == 0 ? v : v) { fail("general expressions not allowed"); } + try ((TwrForVariable2)null) { + fail("null as variable is not allowed"); + } } static void fail(String reason) { diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/TryWithResources/TwrForVariable2.out --- a/langtools/test/tools/javac/TryWithResources/TwrForVariable2.out Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable2.out Thu Dec 10 09:24:25 2015 -0800 @@ -1,7 +1,9 @@ -TwrForVariable2.java:12:21: compiler.err.expected: token.identifier -TwrForVariable2.java:15:27: compiler.err.expected: token.identifier -TwrForVariable2.java:18:16: compiler.err.illegal.start.of.expr -TwrForVariable2.java:21:14: compiler.err.try.with.resources.expr.needs.var -TwrForVariable2.java:24:16: compiler.err.try.with.resources.expr.needs.var -TwrForVariable2.java:27:31: compiler.err.try.with.resources.expr.needs.var -6 errors +TwrForVariable2.java:13:21: compiler.err.expected: token.identifier +TwrForVariable2.java:16:27: compiler.err.expected: token.identifier +TwrForVariable2.java:19:16: compiler.err.illegal.start.of.expr +TwrForVariable2.java:22:14: compiler.err.try.with.resources.expr.needs.var +TwrForVariable2.java:25:16: compiler.err.try.with.resources.expr.needs.var +TwrForVariable2.java:28:19: compiler.err.try.with.resources.expr.needs.var +TwrForVariable2.java:31:31: compiler.err.try.with.resources.expr.needs.var +TwrForVariable2.java:34:14: compiler.err.try.with.resources.expr.needs.var +8 errors diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/TryWithResources/TwrForVariable3.java --- a/langtools/test/tools/javac/TryWithResources/TwrForVariable3.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable3.java Thu Dec 10 09:24:25 2015 -0800 @@ -7,9 +7,16 @@ public static void main(String... args) { TwrForVariable3 v1 = new TwrForVariable3(); Object v2 = new Object(); + Object v3 = new Object() { + public void close() { + } + }; try (v2) { - fail("no an AutoCloseable"); + fail("not an AutoCloseable"); + } + try (v3) { + fail("not an AutoCloseable although has close() method"); } try (java.lang.Object) { fail("not a variable access"); diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/TryWithResources/TwrForVariable3.out --- a/langtools/test/tools/javac/TryWithResources/TwrForVariable3.out Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable3.out Thu Dec 10 09:24:25 2015 -0800 @@ -1,4 +1,5 @@ -TwrForVariable3.java:11:14: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.AutoCloseable)) -TwrForVariable3.java:14:18: compiler.err.cant.resolve.location: kindname.class, lang, , , (compiler.misc.location: kindname.package, java, null) -TwrForVariable3.java:17:14: compiler.err.cant.resolve.location: kindname.variable, java, , , (compiler.misc.location: kindname.class, TwrForVariable3, null) -3 errors +TwrForVariable3.java:15:14: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.AutoCloseable)) +TwrForVariable3.java:18:14: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.AutoCloseable)) +TwrForVariable3.java:21:18: compiler.err.cant.resolve.location: kindname.class, lang, , , (compiler.misc.location: kindname.package, java, null) +TwrForVariable3.java:24:14: compiler.err.cant.resolve.location: kindname.variable, java, , , (compiler.misc.location: kindname.class, TwrForVariable3, null) +4 errors diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/TryWithResources/TwrVarKinds.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/TryWithResources/TwrVarKinds.java Thu Dec 10 09:24:25 2015 -0800 @@ -0,0 +1,81 @@ +/* + * @test /nodynamiccopyright/ + * @bug 7196163 + * @summary Twr with different kinds of variables: local, instance, class, array component, parameter + * @compile/fail/ref=TwrVarKinds.out -XDrawDiagnostics TwrVarKinds.java + */ + +public class TwrVarKinds implements AutoCloseable { + + final static TwrVarKinds r1 = new TwrVarKinds(); + final TwrVarKinds r2 = new TwrVarKinds(); + static TwrVarKinds r3 = new TwrVarKinds(); + TwrVarKinds r4 = new TwrVarKinds(); + + public static void main(String... args) { + + TwrVarKinds r5 = new TwrVarKinds(); + + /* static final field - ok */ + try (r1) { + } + + /* non-static final field - ok */ + try (r1.r2) { + } + + /* static non-final field - wrong */ + try (r3) { + fail("Static non-final field is not allowed"); + } + + /* non-static non-final field - wrong */ + try (r1.r4) { + fail("Non-static non-final field is not allowed"); + } + + /* local variable - covered by TwrForVariable1 test */ + + /* array components - covered by TwrForVariable2 test */ + + /* method parameter - ok */ + method(r5); + + /* constructor parameter - ok */ + TwrVarKinds r6 = new TwrVarKinds(r5); + + /* lambda parameter - covered by TwrAndLambda */ + + /* exception parameter - ok */ + try { + throw new ResourceException(); + } catch (ResourceException e) { + try (e) { + } + } + } + + public TwrVarKinds() { + } + + public TwrVarKinds(TwrVarKinds r) { + try (r) { + } + } + + static void method(TwrVarKinds r) { + /* parameter */ + try (r) { + } + } + + static void fail(String reason) { + throw new RuntimeException(reason); + } + + public void close() {} + + static class ResourceException extends Exception implements AutoCloseable { + public void close() {} + } +} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/TryWithResources/TwrVarKinds.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/TryWithResources/TwrVarKinds.out Thu Dec 10 09:24:25 2015 -0800 @@ -0,0 +1,3 @@ +TwrVarKinds.java:28:14: compiler.err.try.with.resources.expr.effectively.final.var: r3 +TwrVarKinds.java:33:16: compiler.err.try.with.resources.expr.effectively.final.var: r4 +2 errors diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/TryWithResources/TwrVarRedeclaration.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/TryWithResources/TwrVarRedeclaration.java Thu Dec 10 09:24:25 2015 -0800 @@ -0,0 +1,28 @@ +/* + * @test /nodynamiccopyright/ + * @bug 7196163 + * @summary Variable redeclaration inside twr block + * @compile/fail/ref=TwrVarRedeclaration.out -XDrawDiagnostics TwrVarRedeclaration.java + */ + +public class TwrVarRedeclaration implements AutoCloseable { + + public static void main(String... args) { + TwrVarRedeclaration r = new TwrVarRedeclaration(); + + try (r) { + TwrVarRedeclaration r = new TwrVarRedeclaration(); + } + + try (r) { + Object r = new Object(); + } + + try (r) { + } catch (Exception e) { + Exception r = new Exception(); + } + } + + public void close() {} +} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/TryWithResources/TwrVarRedeclaration.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/TryWithResources/TwrVarRedeclaration.out Thu Dec 10 09:24:25 2015 -0800 @@ -0,0 +1,4 @@ +TwrVarRedeclaration.java:14:33: compiler.err.already.defined: kindname.variable, r, kindname.method, main(java.lang.String...) +TwrVarRedeclaration.java:18:20: compiler.err.already.defined: kindname.variable, r, kindname.method, main(java.lang.String...) +TwrVarRedeclaration.java:23:23: compiler.err.already.defined: kindname.variable, r, kindname.method, main(java.lang.String...) +3 errors diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/api/6440528/T6440528.java --- a/langtools/test/tools/javac/api/6440528/T6440528.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/api/6440528/T6440528.java Thu Dec 10 09:24:25 2015 -0800 @@ -55,19 +55,13 @@ "package-info.class", src); File expect = new File(test_src, "package-info.class"); - File got = getUnderlyingFile(cls); + File got = fm.asPath(cls).toFile(); if (!got.equals(expect)) throw new AssertionError(String.format("Expected: %s; got: %s", expect, got)); System.err.println("Expected: " + expect); System.err.println("Got: " + got); } - private File getUnderlyingFile(FileObject o) throws Exception { - Field file = o.getClass().getDeclaredField("file"); // assumes RegularFileObject - file.setAccessible(true); - return ((Path)file.get(o)).toFile(); - } - public static void main(String... args) throws Exception { try (T6440528 t = new T6440528()) { t.test(args); diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/api/T6358955.java --- a/langtools/test/tools/javac/api/T6358955.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/api/T6358955.java Thu Dec 10 09:24:25 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 6358955 - * @summary JavacFileManager.getFileForInput(dir) shuld throw IAE + * @summary JavacFileManager.getFileForInput(dir) should throw IAE * @modules java.compiler * jdk.compiler */ diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/api/T6838467.java --- a/langtools/test/tools/javac/api/T6838467.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/api/T6838467.java Thu Dec 10 09:24:25 2015 -0800 @@ -32,18 +32,18 @@ import java.io.*; import java.util.*; import java.util.zip.*; + import javax.tools.*; +import javax.tools.JavaFileManager.Location; + import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.Options; public class T6838467 { - boolean fileSystemIsCaseSignificant = !new File("a").equals(new File("A")); enum FileKind { DIR("dir"), - ZIP("zip"), - ZIPFILEINDEX("zip"); + ZIP("zip"); FileKind(String path) { file = new File(path); } @@ -52,15 +52,19 @@ enum CompareKind { SAME { + @Override File other(File f) { return f; } }, ABSOLUTE { + @Override File other(File f) { return f.getAbsoluteFile(); } }, DIFFERENT { + @Override File other(File f) { return new File("not_" + f.getPath()); } }, CASEEQUIV { + @Override File other(File f) { return new File(f.getPath().toUpperCase()); } }; abstract File other(File f); @@ -73,10 +77,17 @@ } void run() throws Exception { + boolean fileNameIsCaseSignificant = isFileNameCaseSignificant(); + boolean fileLookupIsCaseSignificant = isFileLookupCaseSignificant(); + + String osName = System.getProperty("os.name"); + System.err.println("OS: " + osName); + System.err.println("fileNameIsCaseSignificant:" + fileNameIsCaseSignificant); + System.err.println("fileLookupIsCaseSignificant:" + fileLookupIsCaseSignificant); + // on Windows, verify file system is not case significant - if (System.getProperty("os.name").toLowerCase().startsWith("windows") - && fileSystemIsCaseSignificant) { - error("fileSystemIsCaseSignificant is set on Windows."); + if ((osName.startsWith("windows")) && fileNameIsCaseSignificant) { + error("fileNameIsCaseSignificant is set on " + osName + "."); } // create a set of directories and zip files to compare @@ -84,7 +95,7 @@ createTestDir(new File("not_dir"), paths); createTestZip(new File("zip"), paths); createTestZip(new File("not_zip"), paths); - if (fileSystemIsCaseSignificant) { + if (fileNameIsCaseSignificant || fileLookupIsCaseSignificant) { createTestDir(new File("DIR"), paths); createTestZip(new File("ZIP"), paths); } @@ -99,8 +110,9 @@ // verify that the various different types of file object were all // tested - Set expectClasses = new HashSet(Arrays.asList( - "RegularFileObject", "ZipFileObject", "ZipFileIndexFileObject" )); + Set expectClasses = new HashSet<>(Arrays.asList( + "DirectoryFileObject", + "JarFileObject" )); if (!foundClasses.equals(expectClasses)) { error("expected fileobject classes not found\n" + "expected: " + expectClasses + "\n" @@ -112,26 +124,22 @@ } void test(FileKind fk, CompareKind ck) throws IOException { - File f1 = fk.file; - JavaFileManager fm1 = createFileManager(fk, f1); + try (StandardJavaFileManager fm = createFileManager()) { + File f1 = fk.file; + Location l1 = createLocation(fm, "l1", f1); - File f2 = ck.other(fk.file); - JavaFileManager fm2 = createFileManager(fk, f2); + File f2 = ck.other(fk.file); + Location l2 = createLocation(fm, "l2", f2); - try { // If the directories or zip files match, we expect "n" matches in // the "n-squared" comparisons to come, where "n" is the number of // entries in the the directories or zip files. // If the directories or zip files don't themselves match, // we obviously don't expect any of their contents to match either. - int expect = (f1.getAbsoluteFile().equals(f2.getAbsoluteFile()) ? paths.length : 0); + int expectEqualCount = (f1.getCanonicalFile().equals(f2.getCanonicalFile()) ? paths.length : 0); System.err.println("test " + (++count) + " " + fk + " " + ck + " " + f1 + " " + f2); - test(fm1, fm2, expect); - - } finally { - fm1.close(); - fm2.close(); + test(fm, l1, l2, expectEqualCount); } } @@ -140,17 +148,17 @@ // returned from the other. For each pair of files, verify that if they // are equal, the hashcode is equal as well, and finally verify that the // expected number of matches was found. - void test(JavaFileManager fm1, JavaFileManager fm2, int expectEqualCount) throws IOException { + void test(JavaFileManager fm, Location l1, Location l2, int expectEqualCount) throws IOException { boolean foundFiles1 = false; boolean foundFiles2 = false; int foundEqualCount = 0; Set kinds = EnumSet.allOf(JavaFileObject.Kind.class); - for (FileObject fo1: fm1.list(StandardLocation.CLASS_PATH, "p", kinds, false)) { + for (FileObject fo1: fm.list(l1, "p", kinds, false)) { foundFiles1 = true; foundClasses.add(fo1.getClass().getSimpleName()); - for (FileObject fo2: fm2.list(StandardLocation.CLASS_PATH, "p", kinds, false)) { + for (FileObject fo2: fm.list(l2, "p", kinds, false)) { foundFiles2 = true; - foundClasses.add(fo1.getClass().getSimpleName()); + foundClasses.add(fo2.getClass().getSimpleName()); System.err.println("compare " + fo1 + " " + fo2); if (fo1.equals(fo2)) { foundEqualCount++; @@ -163,26 +171,35 @@ } } if (!foundFiles1) - error("no files found for file manager 1"); + error("no files found for location " + l1); if (!foundFiles2) - error("no files found for file manager 2"); + error("no files found for location " + l2); // verify the expected number of matches were found if (foundEqualCount != expectEqualCount) error("expected matches not found: expected " + expectEqualCount + ", found " + foundEqualCount); } - // create a file manager to test a FileKind, with a given directory - // or zip file placed on the classpath - JavaFileManager createFileManager(FileKind fk, File classpath) throws IOException { - StandardJavaFileManager fm = createFileManager(fk == FileKind.ZIP); - fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(classpath)); - return fm; + // create and initialize a location to test a FileKind, with a given directory + // or zip file placed on the path + Location createLocation(StandardJavaFileManager fm, String name, File classpath) throws IOException { + Location l = new Location() { + @Override + public String getName() { + return name; + } + + @Override + public boolean isOutputLocation() { + return false; + } + + }; + fm.setLocation(l, Arrays.asList(classpath)); + return l; } - JavacFileManager createFileManager(boolean useOptimizedZip) { + JavacFileManager createFileManager() { Context ctx = new Context(); - Options options = Options.instance(ctx); - options.put("useOptimizedZip", Boolean.toString(useOptimizedZip)); return new JavacFileManager(ctx, false, null); } @@ -191,21 +208,17 @@ for (String p: paths) { File file = new File(dir, p); file.getParentFile().mkdirs(); - FileWriter out = new FileWriter(file); - try { + try (FileWriter out = new FileWriter(file)) { out.write(p); - } finally { - out.close(); } } } - // create a sip file containing a given set of entries + // create a zip file containing a given set of entries void createTestZip(File zip, String[] paths) throws IOException { if (zip.getParentFile() != null) zip.getParentFile().mkdirs(); - ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip)); - try { + try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip))) { for (String p: paths) { ZipEntry ze = new ZipEntry(p); zos.putNextEntry(ze); @@ -213,8 +226,6 @@ zos.write(bytes, 0, bytes.length); zos.closeEntry(); } - } finally { - zos.close(); } } @@ -223,8 +234,24 @@ errors++; } + boolean isFileNameCaseSignificant() { + File lower = new File("test.txt"); + File upper = new File(lower.getPath().toUpperCase()); + return !lower.equals(upper); + } + + boolean isFileLookupCaseSignificant() throws IOException { + File lower = new File("test.txt"); + File upper = new File(lower.getPath().toUpperCase()); + if (upper.exists()) { + upper.delete(); + } + try (FileWriter out = new FileWriter(lower)) { } + return !upper.exists(); + } + int count; int errors; - Set foundClasses = new HashSet(); + Set foundClasses = new HashSet<>(); } diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/api/T6877206.java --- a/langtools/test/tools/javac/api/T6877206.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/api/T6877206.java Thu Dec 10 09:24:25 2015 -0800 @@ -62,15 +62,12 @@ test(createFileManager(), createDir("dir", entries), "p", entries.length); test(createFileManager(), createDir("a b/dir", entries), "p", entries.length); - - for (boolean useOptimizedZip: new boolean[] { false, true }) { - test(createFileManager(useOptimizedZip), createJar("jar", entries), "p", entries.length); - test(createFileManager(useOptimizedZip), createJar("jar jar", entries), "p", entries.length); - } + test(createFileManager(), createJar("jar", entries), "p", entries.length); + test(createFileManager(), createJar("jar jar", entries), "p", entries.length); // Verify that we hit the files we intended checkCoverage("classes", foundClasses, - "RegularFileObject", "ZipFileIndexFileObject", "ZipFileObject"); + "DirectoryFileObject", "JarFileObject"); // Verify that we hit the jar files we intended checkCoverage("jar files", foundJars, "jar", "jar jar"); @@ -153,17 +150,12 @@ } JavacFileManager createFileManager() { - return createFileManager(false, false); + return createFileManager(false); } - JavacFileManager createFileManager(boolean useOptimizedZip) { - return createFileManager(useOptimizedZip, false); - } - - JavacFileManager createFileManager(boolean useOptimizedZip, boolean useSymbolFile) { + JavacFileManager createFileManager(boolean useSymbolFile) { Context ctx = new Context(); Options options = Options.instance(ctx); - options.put("useOptimizedZip", Boolean.toString(useOptimizedZip)); if (!useSymbolFile) { options.put("ignore.symbol.file", "true"); } diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/defaultMethods/private/PrivateGenerics.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/private/PrivateGenerics.java Thu Dec 10 09:24:25 2015 -0800 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8071453 + * @summary Verify that generics work with private method in interface + */ + +public class PrivateGenerics { + + interface I { + private T foo() { return null; }; + default void m(T t) { + T t1 = t; + T t2 = foo(); + } + } + + interface J { + private M foo() { return null; } + default void m(N n) { + N n1 = n; + N n2 = foo(); + } + } + + public static void main(String[] args) { + I i = new I<>() {}; + i.m("string"); + String s = i.foo(); + + J j = new J() {}; + j.m("string"); + s = j.foo(); + } +} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/doctree/DocCommentTester.java --- a/langtools/test/tools/javac/doctree/DocCommentTester.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/doctree/DocCommentTester.java Thu Dec 10 09:24:25 2015 -0800 @@ -444,6 +444,18 @@ return null; } + @Override + public Void visitIndex(IndexTree node, Void p) { + header(node); + indent(+1); + print("term", node.getSearchTerm()); + print("description", node.getDescription()); + indent(-1); + indent(); + out.println("]"); + return null; + } + public Void visitInheritDoc(InheritDocTree node, Void p) { header(node, ""); return null; @@ -619,11 +631,19 @@ throw new UnsupportedOperationException("Not supported yet."); } + /* + * Use this method to start printing a multi-line representation of a + * DocTree node. The representation should be termintated by calling + * out.println("]"). + */ void header(DocTree node) { indent(); out.println(simpleClassName(node) + "[" + node.getKind() + ", pos:" + ((DCTree) node).pos); } + /* + * Use this method to print a single-line representation of a DocTree node. + */ void header(DocTree node, String rest) { indent(); out.println(simpleClassName(node) + "[" + node.getKind() + ", pos:" + ((DCTree) node).pos diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/doctree/IndexTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/doctree/IndexTest.java Thu Dec 10 09:24:25 2015 -0800 @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8144287 + * @summary extend com.sun.source API to support parsing javadoc comments + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.file + * jdk.compiler/com.sun.tools.javac.tree + * jdk.compiler/com.sun.tools.javac.util + * @build DocCommentTester + * @run main DocCommentTester IndexTest.java + */ + +class IndexTest { + /** + * abc {@index xyz} def + */ + void simple_term() {} +/* +DocComment[DOC_COMMENT, pos:1 + firstSentence: 3 + Text[TEXT, pos:1, abc_] + Index[INDEX, pos:5 + term: + Text[TEXT, pos:13, xyz] + description: empty + ] + Text[TEXT, pos:17, _def] + body: empty + block tags: empty +] +*/ + + /** + * abc {@index lmn pqr stu} def + */ + void simple_term_with_description() { } +/* +DocComment[DOC_COMMENT, pos:1 + firstSentence: 3 + Text[TEXT, pos:1, abc_] + Index[INDEX, pos:5 + term: + Text[TEXT, pos:13, lmn] + description: 1 + Text[TEXT, pos:17, pqr_stu] + ] + Text[TEXT, pos:25, _def] + body: empty + block tags: empty +] +*/ + + /** + * abc {@index ijk {lmn opq} } def + */ + void phrase_with_curly_description() { } +/* +DocComment[DOC_COMMENT, pos:1 + firstSentence: 3 + Text[TEXT, pos:1, abc_] + Index[INDEX, pos:5 + term: + Text[TEXT, pos:13, ijk] + description: 1 + Text[TEXT, pos:17, {lmn_opq}_] + ] + Text[TEXT, pos:28, _def] + body: empty + block tags: empty +] +*/ + /** + * abc {@index ijk lmn + * opq + * rst + * } def + */ + void phrase_with_nl_description() { } +/* +DocComment[DOC_COMMENT, pos:1 + firstSentence: 3 + Text[TEXT, pos:1, abc_] + Index[INDEX, pos:5 + term: + Text[TEXT, pos:13, ijk] + description: 1 + Text[TEXT, pos:17, lmn|_opq|_rst|_] + ] + Text[TEXT, pos:33, _def] + body: empty + block tags: empty +] +*/ + + /** + * abc {@index "lmn pqr"} def + */ + void phrase_no_description() { } +/* +DocComment[DOC_COMMENT, pos:1 + firstSentence: 3 + Text[TEXT, pos:1, abc_] + Index[INDEX, pos:5 + term: + Text[TEXT, pos:13, "lmn_pqr"] + description: empty + ] + Text[TEXT, pos:23, _def] + body: empty + block tags: empty +] +*/ + + /** + * abc {@index "ijk lmn" pqr xyz} def + */ + void phrase_with_description() { } +/* +DocComment[DOC_COMMENT, pos:1 + firstSentence: 3 + Text[TEXT, pos:1, abc_] + Index[INDEX, pos:5 + term: + Text[TEXT, pos:13, "ijk_lmn"] + description: 1 + Text[TEXT, pos:23, pqr_xyz] + ] + Text[TEXT, pos:31, _def] + body: empty + block tags: empty +] +*/ + + /** + * abc {@index {@xyz} "{@see xyz}" def} + */ + void term_and_description_with_nested_tag() {} +/* +DocComment[DOC_COMMENT, pos:1 + firstSentence: 2 + Text[TEXT, pos:1, abc_] + Index[INDEX, pos:5 + term: + Text[TEXT, pos:13, {@xyz}] + description: 1 + Text[TEXT, pos:20, "{@see_xyz}"_def] + ] + body: empty + block tags: empty +] +*/ + /** + * abc {@index @def lmn } xyz + */ + void term_with_at() { } +/* +DocComment[DOC_COMMENT, pos:1 + firstSentence: 3 + Text[TEXT, pos:1, abc_] + Index[INDEX, pos:5 + term: + Text[TEXT, pos:13, @def] + description: 1 + Text[TEXT, pos:18, lmn_] + ] + Text[TEXT, pos:23, _xyz] + body: empty + block tags: empty +] +*/ + + /** + * abc {@index ijk@lmn pqr } xyz + */ + void term_with_text_at() { } +/* +DocComment[DOC_COMMENT, pos:1 + firstSentence: 3 + Text[TEXT, pos:1, abc_] + Index[INDEX, pos:5 + term: + Text[TEXT, pos:13, ijk@lmn] + description: 1 + Text[TEXT, pos:21, pqr_] + ] + Text[TEXT, pos:26, _xyz] + body: empty + block tags: empty +] +*/ + + /** + * abc {@index ""} def + */ + void empty_index_in_quotes() {} +/* +DocComment[DOC_COMMENT, pos:1 + firstSentence: 3 + Text[TEXT, pos:1, abc_] + Index[INDEX, pos:5 + term: + Text[TEXT, pos:13, ""] + description: empty + ] + Text[TEXT, pos:16, _def] + body: empty + block tags: empty +] +*/ + + /** + * abc {@index + * @return def} xyz + */ + void bad_nl_at_in_term() {} +/* +DocComment[DOC_COMMENT, pos:1 + firstSentence: 2 + Text[TEXT, pos:1, abc_] + Erroneous[ERRONEOUS, pos:5 + code: compiler.err.dc.no.content + body: {@index + ] + body: empty + block tags: 1 + Return[RETURN, pos:14 + description: 1 + Text[TEXT, pos:22, def}_xyz] + ] +] +*/ + /** + * abc {@index "xyz } def + */ + void bad_unbalanced_quote() {} +/* +DocComment[DOC_COMMENT, pos:1 + firstSentence: 2 + Text[TEXT, pos:1, abc_] + Erroneous[ERRONEOUS, pos:5 + code: compiler.err.dc.no.content + body: {@index_"xyz_}_def + ] + body: empty + block tags: empty +] +*/ + /** + * abc {@index} def + */ + void bad_no_index() {} +/* +DocComment[DOC_COMMENT, pos:1 + firstSentence: 3 + Text[TEXT, pos:1, abc_] + Erroneous[ERRONEOUS, pos:5 + code: compiler.err.dc.no.content + body: {@index + ] + Text[TEXT, pos:12, }_def] + body: empty + block tags: empty +] +*/ + +} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/file/zip/T8076104.java --- a/langtools/test/tools/javac/file/zip/T8076104.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/file/zip/T8076104.java Thu Dec 10 09:24:25 2015 -0800 @@ -60,7 +60,6 @@ void run() throws Exception { File testJar = createJar(); doTest(testJar); - doTest(testJar, "-XDuseOptimizedZip=false"); } File createJar() throws Exception { diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/lambda/MethodReferenceStaticNotAccessibleTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/MethodReferenceStaticNotAccessibleTest.java Thu Dec 10 09:24:25 2015 -0800 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8136809 + * @summary Javac fails compiling Collectors.reducing with method reference combiner + * @compile MethodReferenceStaticNotAccessibleTest.java + */ + +import java.util.function.BinaryOperator; + +class MethodReferenceStaticNotAccessibleTest_Foo { + MethodReferenceStaticNotAccessibleTest_Foo m(MethodReferenceStaticNotAccessibleTest_Foo foo) { return null; } + private static void m(MethodReferenceStaticNotAccessibleTest_Foo foo1, MethodReferenceStaticNotAccessibleTest_Foo foo2) {} +} + +public class MethodReferenceStaticNotAccessibleTest { + void m(T t, BinaryOperator binop) {} + + void test(MethodReferenceStaticNotAccessibleTest_Foo foo) { + m(foo, MethodReferenceStaticNotAccessibleTest_Foo::m); + } +} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/lambda/T8145051.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/T8145051.java Thu Dec 10 09:24:25 2015 -0800 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8145051 + * @summary Wrong parameter name in synthetic lambda method leads to verifier error + * @compile pkg/T8145051.java + * @run main/othervm -Xverify:all T8145051 + */ + +public class T8145051 { + + public static void main(String [] args) { + pkg.T8145051 t8145051 = new pkg.T8145051(); + t8145051.new Sub(); + if (!t8145051.s.equals("Executed lambda")) + throw new AssertionError("Unexpected data"); + else + System.out.println("OK"); + } + +} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/lambda/methodReference/MethodRefToLocalClassMethodTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/methodReference/MethodRefToLocalClassMethodTest.java Thu Dec 10 09:24:25 2015 -0800 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8144673 + * @summary Suspect message regarding suitable enclosing instance not being in scope + * @run main MethodRefToLocalClassMethodTest + */ + + +import java.util.ArrayList; +import java.util.List; + +public class MethodRefToLocalClassMethodTest { + + public static void main(String[] args) { + new MethodRefToLocalClassMethodTest().foo(); + } + + public void foo() { + class LocalFoo { + LocalFoo(String in) { + if (!in.equals("Hello")) + throw new AssertionError("Unexpected data: " + in); + } + } + List ls = new ArrayList<>(); + ls.add("Hello"); + ls.stream().map(LocalFoo::new).forEach(x->{}); + } +} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/lambda/pkg/T8145051.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/pkg/T8145051.java Thu Dec 10 09:24:25 2015 -0800 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg; + +public class T8145051 { + + public String s; + + public static class Sup { + Sup(Runnable r) { + r.run(); + } + } + + public class Sub extends Sup { + public Sub() { + super(() -> { + s = "Executed lambda"; + }); + } + } +} diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/lib/DPrinter.java --- a/langtools/test/tools/javac/lib/DPrinter.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/lib/DPrinter.java Thu Dec 10 09:24:25 2015 -0800 @@ -1049,6 +1049,13 @@ return visitTree(node, null); } + public Void visitIndex(IndexTree node, Void p) { + printString("kind", node.getKind().name()); + printDocTree("term", node.getSearchTerm()); + printList("desc", node.getDescription()); + return visitInlineTag(node, p); + } + public Void visitInheritDoc(InheritDocTree node, Void p) { return visitInlineTag(node, null); } diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/options/modes/Tester.java --- a/langtools/test/tools/javac/options/modes/Tester.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/options/modes/Tester.java Thu Dec 10 09:24:25 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -136,8 +136,11 @@ } catch (IllegalArgumentException | IllegalStateException | IOException e) { tr.setThrown(e); } finally { - ((JavacFileManager) context.get(JavaFileManager.class)).close(); - tr.setLogs(sw.toString(), sysOut.close(), sysErr.close()); + try { + ((JavacFileManager) context.get(JavaFileManager.class)).close(); + tr.setLogs(sw.toString(), sysOut.close(), sysErr.close()); + } catch (IOException e) { + } } tr.setContext(context); tr.show(); @@ -149,6 +152,7 @@ class TestResult { final List args; Throwable thrown; + List suppressed = new ArrayList<>(); Object rc; // Number or Boolean Map logs; Context context; @@ -172,6 +176,10 @@ this.rc = ok ? 0 : 1; } + void setSuppressed(Throwable thrown) { + this.suppressed.add(thrown); + } + void setThrown(Throwable thrown) { this.thrown = thrown; } @@ -199,6 +207,11 @@ out.print("thrown:" + thrown); needSep = true; } + if (!suppressed.isEmpty()) { + if (needSep) out.print("; "); + out.print("suppressed:" + suppressed); + needSep = true; + } if (needSep) out.println(); logs.forEach((k, v) -> { diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/parser/T4910483.java --- a/langtools/test/tools/javac/parser/T4910483.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/parser/T4910483.java Thu Dec 10 09:24:25 2015 -0800 @@ -49,7 +49,7 @@ String testSrc = System.getProperty("test.src"); JavacFileManager fm = new JavacFileManager(new Context(), false, null); - JavaFileObject f = fm.getFileForInput(testSrc + File.separatorChar + "T4910483.java"); + JavaFileObject f = fm.getJavaFileObject(testSrc + File.separatorChar + "T4910483.java"); JCTree.JCCompilationUnit cu = compiler.parse(f); JCTree classDef = cu.getTypeDecls().head; diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/processing/TestMultipleErrors.java --- a/langtools/test/tools/javac/processing/TestMultipleErrors.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/processing/TestMultipleErrors.java Thu Dec 10 09:24:25 2015 -0800 @@ -1,29 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - -/* - * @test + * @test /nodynamiccopyright * @bug 8066843 * @summary Annotation processors should be able to print multiple errors at the same location. * @library /tools/javac/lib diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/processing/TestMultipleErrors.out --- a/langtools/test/tools/javac/processing/TestMultipleErrors.out Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/processing/TestMultipleErrors.out Thu Dec 10 09:24:25 2015 -0800 @@ -1,5 +1,5 @@ -TestMultipleErrors.java:42:8: compiler.err.proc.messager: error1 -TestMultipleErrors.java:42:8: compiler.err.proc.messager: error2 -TestMultipleErrors.java:42:8: compiler.err.proc.messager: error3 -TestMultipleErrors.java:42:8: compiler.err.proc.messager: error4 +TestMultipleErrors.java:18:8: compiler.err.proc.messager: error1 +TestMultipleErrors.java:18:8: compiler.err.proc.messager: error2 +TestMultipleErrors.java:18:8: compiler.err.proc.messager: error3 +TestMultipleErrors.java:18:8: compiler.err.proc.messager: error4 4 errors diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/processing/errors/CrashOnNonExistingAnnotation/Processor.java --- a/langtools/test/tools/javac/processing/errors/CrashOnNonExistingAnnotation/Processor.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/processing/errors/CrashOnNonExistingAnnotation/Processor.java Thu Dec 10 09:24:25 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,7 +88,7 @@ if (!testFile.canRead()) throw new IllegalStateException("Cannot read the test source"); JavacTool compiler = JavacTool.create(); JavacFileManager fm = compiler.getStandardFileManager(null, null, null); - testContent = fm.getRegularFile(testFile.toPath()).getCharContent(true).toString(); + testContent = fm.getJavaFileObject(testFile.toPath()).getCharContent(true).toString(); JavaFileObject testFileObject = new TestFO(new URI("mem://" + args[0]), testContent); TestFM testFileManager = new TestFM(fm); JavacTask task = compiler.getTask(null, diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/Processor.java --- a/langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/Processor.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/Processor.java Thu Dec 10 09:24:25 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,7 +71,7 @@ File inp = new File(sp, args[0]); if (inp.canRead()) { - testContent = fm.getRegularFile(inp.toPath()).getCharContent(true).toString(); + testContent = fm.getJavaFileObject(inp.toPath()).getCharContent(true).toString(); } } if (testContent == null) throw new IllegalStateException(); diff -r 9229cc3b3802 -r 8b372e28f106 langtools/test/tools/javac/warnings/suppress/VerifySuppressWarnings.java --- a/langtools/test/tools/javac/warnings/suppress/VerifySuppressWarnings.java Thu Dec 10 08:17:12 2015 -0800 +++ b/langtools/test/tools/javac/warnings/suppress/VerifySuppressWarnings.java Thu Dec 10 09:24:25 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,7 +74,7 @@ File inp = new File(sp, args[0]); if (inp.canRead()) { - testContent = fm.getRegularFile(inp.toPath()).getCharContent(true).toString(); + testContent = fm.getJavaFileObject(inp.toPath()).getCharContent(true).toString(); } } if (testContent == null) throw new IllegalStateException();