mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-08 15:09:39 +07:00
JpsJavacFileManager: add filtering for ZipEntries according to the requested file kind (IDEA-206390)
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
<orderEntry type="module" module-name="intellij.spellchecker" scope="RUNTIME" />
|
||||
<orderEntry type="module" module-name="intellij.platform.jps.model.impl" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.platform.testExtensions" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.platform.jps.build.javac.rt" scope="TEST" />
|
||||
</component>
|
||||
<component name="copyright">
|
||||
<Base>
|
||||
|
||||
@@ -5,12 +5,19 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.io.Compressor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.javac.JpsJavacFileManager;
|
||||
import org.jetbrains.jps.javac.OutputFileObject;
|
||||
|
||||
import javax.tools.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.intellij.util.io.TestFileSystemItem.fs;
|
||||
|
||||
@@ -41,6 +48,64 @@ public class JavaCompilerBasicTest extends BaseCompilerTestCase {
|
||||
assertOutput(module, fs().file("B.class"));
|
||||
}
|
||||
|
||||
public void testFilterSourcesFromLibraries() throws IOException {
|
||||
final VirtualFile libJavaFile = createFile("lib/ppp/B.java", "package ppp; public class B {}");
|
||||
final VirtualFile libClsFile = createFile("lib/ppp/B.class", "package ppp; public class B {}");
|
||||
final File jarFile = new File(libJavaFile.getParent().getParent().getPath(), "lib.jar");
|
||||
try (Compressor.Jar jar = new Compressor.Jar(jarFile)) {
|
||||
jar.addFile("ppp/B.java", new File(libJavaFile.getPath()));
|
||||
jar.addFile("ppp/B.class", new File(libClsFile.getPath()));
|
||||
}
|
||||
final VirtualFile srcFile = createFile("src/A.java", "import ppp.B; public class A { B b; }");
|
||||
|
||||
final StandardJavaFileManager stdFileManager = ToolProvider.getSystemJavaCompiler().getStandardFileManager(new DiagnosticListener<JavaFileObject>() {
|
||||
@Override
|
||||
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||
}
|
||||
}, Locale.US, null);
|
||||
final JpsJavacFileManager fileManager = new JpsJavacFileManager(new JpsJavacFileManager.Context() {
|
||||
@Override
|
||||
public boolean isCanceled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public StandardJavaFileManager getStandardFileManager() {
|
||||
return stdFileManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consumeOutputFile(@NotNull OutputFileObject obj) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportMessage(Diagnostic.Kind kind, String message) {
|
||||
|
||||
}
|
||||
}, true, Collections.emptyList());
|
||||
|
||||
fileManager.setLocation(StandardLocation.CLASS_PATH, Collections.singleton(jarFile));
|
||||
fileManager.setLocation(StandardLocation.SOURCE_PATH, Collections.emptyList());
|
||||
|
||||
final File src = new File(srcFile.getPath());
|
||||
final Iterable<? extends JavaFileObject> sources = fileManager.getJavaFileObjectsFromFiles(Collections.singleton(src));
|
||||
final Iterator<? extends JavaFileObject> it = sources.iterator();
|
||||
assertTrue(it.hasNext());
|
||||
final JavaFileObject srcFileObject = it.next();
|
||||
assertFalse(it.hasNext());
|
||||
assertEquals(JavaFileObject.Kind.SOURCE, srcFileObject.getKind());
|
||||
assertEquals(src.toURI().getPath(), srcFileObject.toUri().getPath());
|
||||
|
||||
final Iterable<JavaFileObject> libClasses = fileManager.list(StandardLocation.CLASS_PATH, "ppp", Collections.singleton(JavaFileObject.Kind.CLASS), false);
|
||||
final Iterator<JavaFileObject> clsIterator = libClasses.iterator();
|
||||
assertTrue(clsIterator.hasNext());
|
||||
final JavaFileObject aClass = clsIterator.next();
|
||||
assertEquals(JavaFileObject.Kind.CLASS, aClass.getKind());
|
||||
assertEquals(jarFile.toURI().getPath() + "!/ppp/B.class", aClass.toUri().getPath());
|
||||
assertFalse(clsIterator.hasNext());
|
||||
}
|
||||
|
||||
|
||||
public void testSymlinksInSources() throws IOException {
|
||||
final VirtualFile file = createFile("src/A.java", "public class A {}");
|
||||
|
||||
@@ -160,6 +160,12 @@ class DefaultFileOperations implements FileOperations {
|
||||
private final ZipFile myZip;
|
||||
private final Map<String, Collection<ZipEntry>> myPaths = new THashMap<String, Collection<ZipEntry>>();
|
||||
private final Function<ZipEntry, JavaFileObject> myToFileObjectConverter;
|
||||
private static final FileObjectKindFilter<ZipEntry> ourEntryFilter = new FileObjectKindFilter<ZipEntry>(new Function<ZipEntry, String>() {
|
||||
@Override
|
||||
public String fun(ZipEntry zipEntry) {
|
||||
return zipEntry.getName();
|
||||
}
|
||||
});
|
||||
|
||||
ZipArchive(final File root, final String encodingName) throws IOException {
|
||||
myZip = new ZipFile(root, ZipFile.OPEN_READ);
|
||||
@@ -184,7 +190,6 @@ class DefaultFileOperations implements FileOperations {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterable<JavaFileObject> list(final String relPath, Set<JavaFileObject.Kind> kinds, boolean recurse) throws IOException{
|
||||
@@ -206,9 +211,9 @@ class DefaultFileOperations implements FileOperations {
|
||||
}
|
||||
}
|
||||
}
|
||||
return JpsJavacFileManager.convert(JpsJavacFileManager.merge(allChildren), myToFileObjectConverter);
|
||||
return JpsJavacFileManager.convert(JpsJavacFileManager.filter(JpsJavacFileManager.merge(allChildren), ourEntryFilter.getFor(kinds)), myToFileObjectConverter);
|
||||
}
|
||||
return JpsJavacFileManager.convert(entries, myToFileObjectConverter);
|
||||
return JpsJavacFileManager.convert(JpsJavacFileManager.filter(entries, ourEntryFilter.getFor(kinds)), myToFileObjectConverter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.jps.javac;
|
||||
|
||||
import com.intellij.util.BooleanFunction;
|
||||
import com.intellij.util.Function;
|
||||
|
||||
import javax.tools.JavaFileObject;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: 11-Feb-19
|
||||
*/
|
||||
public class FileObjectKindFilter<T> {
|
||||
private final Function<? super T, String> myToNameConverter;
|
||||
private final Map<JavaFileObject.Kind, BooleanFunction<T>> myFilterMap;
|
||||
|
||||
public FileObjectKindFilter(Function<? super T, String> toNameConverter) {
|
||||
myToNameConverter = toNameConverter;
|
||||
final EnumMap<JavaFileObject.Kind, BooleanFunction<T>> filterMap = new EnumMap<JavaFileObject.Kind, BooleanFunction<T>>(JavaFileObject.Kind.class);
|
||||
for (final JavaFileObject.Kind kind : JavaFileObject.Kind.values()) {
|
||||
if (kind == JavaFileObject.Kind.OTHER) {
|
||||
filterMap.put(kind, new BooleanFunction<T>() {
|
||||
@Override
|
||||
public boolean fun(T data) {
|
||||
return JpsFileObject.findKind(myToNameConverter.fun(data)) == JavaFileObject.Kind.OTHER;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
filterMap.put(kind, new BooleanFunction<T>() {
|
||||
@Override
|
||||
public boolean fun(T data) {
|
||||
return myToNameConverter.fun(data).endsWith(kind.extension);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
myFilterMap = Collections.unmodifiableMap(filterMap);
|
||||
}
|
||||
|
||||
public BooleanFunction<T> getFor(final Set<JavaFileObject.Kind> kinds) {
|
||||
// optimization for a single-element collection
|
||||
final Iterator<JavaFileObject.Kind> it = kinds.iterator();
|
||||
if (it.hasNext()) {
|
||||
final JavaFileObject.Kind kind = it.next();
|
||||
if (!it.hasNext()) {
|
||||
return myFilterMap.get(kind);
|
||||
}
|
||||
}
|
||||
// OR-filter, quite rare case
|
||||
return new BooleanFunction<T>() {
|
||||
@Override
|
||||
public boolean fun(T data) {
|
||||
for (JavaFileObject.Kind kind : kinds) {
|
||||
if (myFilterMap.get(kind).fun(data)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -37,6 +37,12 @@ public class JpsJavacFileManager extends ForwardingJavaFileManager<StandardJavaF
|
||||
StandardLocation.SOURCE_PATH,
|
||||
StandardLocation.ANNOTATION_PROCESSOR_PATH
|
||||
);
|
||||
private static final FileObjectKindFilter<File> ourKindFilter = new FileObjectKindFilter<File>(new Function<File, String>() {
|
||||
@Override
|
||||
public String fun(File file) {
|
||||
return file.getName();
|
||||
}
|
||||
});
|
||||
private final Context myContext;
|
||||
private final boolean myJavacBefore9;
|
||||
private final Collection<JavaSourceTransformer> mySourceTransformers;
|
||||
@@ -242,7 +248,7 @@ public class JpsJavacFileManager extends ForwardingJavaFileManager<StandardJavaF
|
||||
return name.toString().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
interface Context {
|
||||
public interface Context {
|
||||
boolean isCanceled();
|
||||
|
||||
@NotNull
|
||||
@@ -430,20 +436,14 @@ public class JpsJavacFileManager extends ForwardingJavaFileManager<StandardJavaF
|
||||
else {
|
||||
// is a directory or does not exist
|
||||
final File dir = new File(root, packageName.replace('.', '/'));
|
||||
final BooleanFunction<File> filter = recurse?
|
||||
new BooleanFunction<File>() {
|
||||
@Override
|
||||
public boolean fun(File file) {
|
||||
return kinds.contains(getKind(file.getName()));
|
||||
}
|
||||
}:
|
||||
new BooleanFunction<File>() {
|
||||
final boolean acceptUnknownFiles = kinds.contains(JavaFileObject.Kind.OTHER);
|
||||
@Override
|
||||
public boolean fun(File file) {
|
||||
return kinds.contains(getKind(file.getName())) && (!acceptUnknownFiles || myFileOperations.isFile(file));
|
||||
}
|
||||
};
|
||||
final BooleanFunction<File> kindsFilter = ourKindFilter.getFor(kinds);
|
||||
final boolean acceptUnknownFiles = kinds.contains(JavaFileObject.Kind.OTHER);
|
||||
final BooleanFunction<File> filter = recurse || !acceptUnknownFiles? kindsFilter : new BooleanFunction<File>() {
|
||||
@Override
|
||||
public boolean fun(File file) {
|
||||
return kindsFilter.fun(dir) && myFileOperations.isFile(file);
|
||||
}
|
||||
};
|
||||
result.add(convert(filter(myFileOperations.listFiles(dir, recurse), filter), myFileToInputFileObjectConverter));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user