[java] resolve into multi-release modular libs

This commit is contained in:
Roman Shevchenko
2016-11-29 15:04:00 +01:00
parent 4b0d49ae8c
commit cfffd966fb
4 changed files with 52 additions and 1 deletions

View File

@@ -20,16 +20,26 @@
package com.intellij.psi.impl.java.stubs.index;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiJavaModule;
import com.intellij.psi.impl.search.JavaSourceFilterScope;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.stubs.StringStubIndexExtension;
import com.intellij.psi.stubs.StubIndex;
import com.intellij.psi.stubs.StubIndexKey;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.indexing.FileBasedIndex;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static com.intellij.openapi.util.text.StringUtil.compareVersionNumbers;
public class JavaModuleNameIndex extends StringStubIndexExtension<PsiJavaModule> {
private static final JavaModuleNameIndex ourInstance = new JavaModuleNameIndex();
@@ -51,7 +61,46 @@ public class JavaModuleNameIndex extends StringStubIndexExtension<PsiJavaModule>
@Override
public Collection<PsiJavaModule> get(@NotNull String name, @NotNull Project project, @NotNull GlobalSearchScope scope) {
return StubIndex.getElements(getKey(), name, project, new JavaSourceFilterScope(scope), PsiJavaModule.class);
Collection<PsiJavaModule> modules = StubIndex.getElements(getKey(), name, project, new JavaSourceFilterScope(scope), PsiJavaModule.class);
if (modules.size() > 1) {
modules = filterVersions(project, modules);
}
return modules;
}
private static Collection<PsiJavaModule> filterVersions(Project project, Collection<PsiJavaModule> modules) {
Map<VirtualFile, PsiJavaModule> filter = ContainerUtil.newHashMap();
Set<PsiJavaModule> screened = ContainerUtil.newHashSet();
ProjectFileIndex index = ProjectFileIndex.SERVICE.getInstance(project);
for (PsiJavaModule module : modules) {
VirtualFile file = module.getContainingFile().getVirtualFile();
if (index.isInLibraryClasses(file)) {
VirtualFile classRoot = index.getClassRootForFile(file);
if (classRoot != null) {
PsiJavaModule previous = filter.get(classRoot);
if (previous == null) {
filter.put(classRoot, module);
}
else if (compareVersionNumbers(fileVersion(file), fileVersion(previous.getContainingFile().getVirtualFile())) < 0) {
filter.put(classRoot, module);
screened.add(previous);
}
else {
screened.add(module);
}
}
}
}
return screened.isEmpty() ? modules : modules.stream().filter(module -> !screened.contains(module)).collect(Collectors.toList());
}
private static final Pattern MULTI_RESOLVE_VERSION = Pattern.compile("/META-INF/versions/([^/]+)/" + PsiJavaModule.MODULE_INFO_CLS_FILE);
private static String fileVersion(VirtualFile file) {
Matcher matcher = MULTI_RESOLVE_VERSION.matcher(file.getPath());
return matcher.find() ? matcher.group(1) : "0";
}
@Override

View File

@@ -73,6 +73,7 @@ class ModuleHighlightingTest : LightJava9ModulesCodeInsightFixtureTestCase() {
requires <error descr="Cyclic dependence: M1, M2">M2</error>;
requires <error descr="Module is not in dependencies: M3">M3</error>;
requires <warning descr="Ambiguous module reference: lib.auto">lib.auto</warning>;
requires lib.multi.release;
}""".trimIndent())
}

View File

@@ -75,6 +75,7 @@ object MultiModuleJava9ProjectDescriptor : DefaultLightProjectDescriptor() {
ModuleRootModificationUtil.addModuleLibrary(main, "${libDir}/lib-named-1.0.jar!/")
ModuleRootModificationUtil.addModuleLibrary(main, "${libDir}/lib-auto-1.0.jar!/")
ModuleRootModificationUtil.addModuleLibrary(main, "${libDir}/lib-auto-2.0.jar!/")
ModuleRootModificationUtil.addModuleLibrary(main, "${libDir}/lib-multi-release.jar!/")
}
}