Merge branch 'master' of git-hosting.labs.intellij.net:idea-community

This commit is contained in:
Dmitry.Krasilschikov
2019-01-23 19:05:09 +02:00
34 changed files with 327 additions and 418 deletions
@@ -1,4 +1,4 @@
// Copyright 2000-2018 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.
// 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 com.intellij.ide.util.importProject;
import com.intellij.ide.highlighter.JavaFileType;
@@ -276,9 +276,8 @@ public class JavaModuleInsight extends ModuleInsight {
@Override
public void visitRequiresStatement(PsiRequiresStatement statement) {
super.visitRequiresStatement(statement);
PsiJavaModuleReferenceElement referenceElement = statement.getReferenceElement();
if (referenceElement != null) {
String referenceText = referenceElement.getReferenceText();
String referenceText = statement.getModuleName();
if (referenceText != null) {
myInfo.requiresModules.add(referenceText);
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2018 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.
// 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 com.intellij.codeInsight.daemon.impl.analysis;
import com.intellij.openapi.module.Module;
@@ -12,7 +12,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.java.stubs.index.JavaModuleNameIndex;
import com.intellij.psi.impl.light.LightJavaModule;
import com.intellij.psi.impl.source.PsiJavaModuleReference;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.ProjectScope;
import com.intellij.psi.util.CachedValueProvider.Result;
@@ -148,9 +147,15 @@ public class JavaModuleGraphUtil {
MultiMap<PsiJavaModule, PsiJavaModule> relations = MultiMap.create();
for (PsiJavaModule module : projectModules) {
for (PsiRequiresStatement statement : module.getRequires()) {
PsiJavaModule dependency = PsiJavaModuleReference.resolve(statement, statement.getModuleName(), true);
if (dependency != null && projectModules.contains(dependency)) {
relations.putValue(module, dependency);
PsiJavaModuleReference ref = statement.getModuleReference();
if (ref != null) {
ResolveResult[] results = ref.multiResolve(true);
if (results.length == 1) {
PsiJavaModule dependency = (PsiJavaModule)results[0].getElement();
if (dependency != null && projectModules.contains(dependency)) {
relations.putValue(module, dependency);
}
}
}
}
}
@@ -209,16 +214,20 @@ public class JavaModuleGraphUtil {
relations.putValues(module, Collections.emptyList());
boolean explicitJavaBase = false;
for (PsiRequiresStatement statement : module.getRequires()) {
String moduleName = statement.getModuleName();
if (PsiJavaModule.JAVA_BASE.equals(moduleName)) explicitJavaBase = true;
for (PsiJavaModule dependency : PsiJavaModuleReference.multiResolve(statement, moduleName, false)) {
relations.putValue(module, dependency);
if (statement.hasModifierProperty(PsiModifier.TRANSITIVE)) transitiveEdges.add(RequiresGraph.key(dependency, module));
visit(dependency, relations, transitiveEdges);
PsiJavaModuleReference ref = statement.getModuleReference();
if (ref != null) {
if (PsiJavaModule.JAVA_BASE.equals(ref.getCanonicalText())) explicitJavaBase = true;
for (ResolveResult result : ref.multiResolve(false)) {
PsiJavaModule dependency = (PsiJavaModule)result.getElement();
assert dependency != null : result;
relations.putValue(module, dependency);
if (statement.hasModifierProperty(PsiModifier.TRANSITIVE)) transitiveEdges.add(RequiresGraph.key(dependency, module));
visit(dependency, relations, transitiveEdges);
}
}
}
if (!explicitJavaBase) {
PsiJavaModule javaBase = PsiJavaModuleReference.resolve(module, PsiJavaModule.JAVA_BASE, false);
PsiJavaModule javaBase = JavaPsiFacade.getInstance(module.getProject()).findModule(PsiJavaModule.JAVA_BASE, module.getResolveScope());
if (javaBase != null) relations.putValue(module, javaBase);
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2018 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.
// 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 com.intellij.codeInsight.daemon.impl.analysis;
import com.intellij.codeInsight.daemon.JavaErrorMessages;
@@ -176,11 +176,24 @@ public class ModuleHighlightUtil {
static HighlightInfo checkModuleReference(@NotNull PsiRequiresStatement statement) {
PsiJavaModuleReferenceElement refElement = statement.getReferenceElement();
if (refElement != null) {
PsiPolyVariantReference ref = refElement.getReference();
PsiJavaModuleReference ref = refElement.getReference();
assert ref != null : refElement.getParent();
PsiElement target = ref.resolve();
if (!(target instanceof PsiJavaModule)) {
return moduleResolveError(refElement, ref);
PsiJavaModule target = ref.resolve();
if (target == null) {
if (ref.multiResolve(true).length == 0) {
String message = JavaErrorMessages.message("module.not.found", refElement.getReferenceText());
return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(refElement).descriptionAndTooltip(message).create();
}
else if (ref.multiResolve(false).length > 1) {
String message = JavaErrorMessages.message("module.ambiguous", refElement.getReferenceText());
return HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING).range(refElement).descriptionAndTooltip(message).create();
}
else {
String message = JavaErrorMessages.message("module.not.on.path", refElement.getReferenceText());
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(refElement).descriptionAndTooltip(message).create();
factory().registerOrderEntryFixes(new QuickFixActionRegistrarImpl(info), ref);
return info;
}
}
PsiJavaModule container = (PsiJavaModule)statement.getParent();
if (target == container) {
@@ -188,7 +201,7 @@ public class ModuleHighlightUtil {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(refElement).descriptionAndTooltip(message).create();
}
else {
Collection<PsiJavaModule> cycle = JavaModuleGraphUtil.findCycle((PsiJavaModule)target);
Collection<PsiJavaModule> cycle = JavaModuleGraphUtil.findCycle(target);
if (cycle != null && cycle.contains(container)) {
Stream<String> stream = cycle.stream().map(PsiJavaModule::getName);
if (ApplicationManager.getApplication().isUnitTestMode()) stream = stream.sorted();
@@ -266,13 +279,12 @@ public class ModuleHighlightUtil {
Set<String> targets = ContainerUtil.newTroveSet();
for (PsiJavaModuleReferenceElement refElement : statement.getModuleReferences()) {
String refText = refElement.getReferenceText();
PsiPolyVariantReference ref = refElement.getReference();
PsiJavaModuleReference ref = refElement.getReference();
assert ref != null : statement;
if (!targets.add(refText)) {
boolean exports = statement.getRole() == Role.EXPORTS;
String message = JavaErrorMessages.message(exports ? "module.duplicate.exports.target" : "module.duplicate.opens.target", refText);
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(refElement).descriptionAndTooltip(message).create();
QuickFixAction.registerQuickFixAction(info, factory().createDeleteFix(refElement, QuickFixBundle.message("delete.reference.fix.text")));
HighlightInfo info = duplicateReference(refElement, message);
results.add(info);
}
else if (ref.multiResolve(true).length == 0) {
@@ -315,8 +327,7 @@ public class ModuleHighlightUtil {
String refText = implRef.getQualifiedName();
if (!filter.add(refText)) {
String message = JavaErrorMessages.message("module.duplicate.impl", refText);
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(implRef).descriptionAndTooltip(message).create();
QuickFixAction.registerQuickFixAction(info, factory().createDeleteFix(implRef, QuickFixBundle.message("delete.reference.fix.text")));
HighlightInfo info = duplicateReference(implRef, message);
results.add(info);
continue;
}
@@ -397,23 +408,6 @@ public class ModuleHighlightUtil {
return null;
}
private static HighlightInfo moduleResolveError(PsiJavaModuleReferenceElement refElement, PsiPolyVariantReference ref) {
if (ref.multiResolve(true).length == 0) {
String message = JavaErrorMessages.message("module.not.found", refElement.getReferenceText());
return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(refElement).descriptionAndTooltip(message).create();
}
else if (ref.multiResolve(false).length > 1) {
String message = JavaErrorMessages.message("module.ambiguous", refElement.getReferenceText());
return HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING).range(refElement).descriptionAndTooltip(message).create();
}
else {
String message = JavaErrorMessages.message("module.not.on.path", refElement.getReferenceText());
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(refElement).descriptionAndTooltip(message).create();
factory().registerOrderEntryFixes(new QuickFixActionRegistrarImpl(info), ref);
return info;
}
}
private static QuickFixFactory factory() {
return QuickFixFactory.getInstance();
}
@@ -426,4 +420,10 @@ public class ModuleHighlightUtil {
private static PsiElement range(PsiJavaCodeReferenceElement refElement) {
return ObjectUtils.notNull(refElement.getReferenceNameElement(), refElement);
}
private static HighlightInfo duplicateReference(PsiElement refElement, String message) {
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(refElement).descriptionAndTooltip(message).create();
QuickFixAction.registerQuickFixAction(info, factory().createDeleteFix(refElement, QuickFixBundle.message("delete.reference.fix.text")));
return info;
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2017 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.
// 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 com.intellij.codeInsight.daemon.impl.quickfix
import com.intellij.codeInsight.daemon.QuickFixBundle
@@ -42,9 +42,9 @@ class AddExportsDirectiveFix(module: PsiJavaModule,
PsiUtil.addModuleStatement(module, PsiKeyword.EXPORTS + ' ' + packageName)
}
else if (!targetName.isEmpty()) {
val targets = existing.moduleReferences.map { it.referenceText }
val targets = existing.moduleNames
if (!targets.isEmpty() && targetName !in targets) {
existing.add(PsiElementFactory.SERVICE.getInstance(project).createModuleReferenceFromText(targetName))
existing.add(PsiElementFactory.SERVICE.getInstance(project).createModuleReferenceFromText(targetName, null))
}
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2017 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.
// 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 com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
@@ -45,7 +45,7 @@ public abstract class MergeModuleStatementsFix<T extends PsiStatement> extends L
LOG.assertTrue(!statementsToMerge.isEmpty());
final String text = getReplacementText(statementsToMerge);
final PsiStatement replacement = JavaPsiFacade.getElementFactory(project).createModuleStatementFromText(text);
final PsiStatement replacement = JavaPsiFacade.getElementFactory(project).createModuleStatementFromText(text, null);
final T firstStatement = statementsToMerge.get(0);
final CommentTracker commentTracker = new CommentTracker();
@@ -1,4 +1,4 @@
// Copyright 2000-2017 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.
// 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 com.intellij.codeInspection.java19modules;
import com.intellij.analysis.AnalysisScope;
@@ -12,7 +12,6 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiJavaModuleReference;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
@@ -104,10 +103,6 @@ public class Java9RedundantRequiresStatementInspection extends GlobalJavaBatchIn
return new RedundantRequiresStatementAnnotator();
}
private static PsiJavaModule resolveRequiredModule(PsiRequiresStatement requiresStatement) {
return PsiJavaModuleReference.resolve(requiresStatement, requiresStatement.getModuleName(), false);
}
private static class DeleteRedundantRequiresStatementFix implements LocalQuickFix {
private final String myRequiredModuleName;
private final Set<String> myImportedPackages;
@@ -153,7 +148,7 @@ public class Java9RedundantRequiresStatementInspection extends GlobalJavaBatchIn
.of(dependencyModule.getRequires().iterator())
.filter(statement -> statement.hasModifierProperty(PsiModifier.TRANSITIVE))
.filter(requiresStatement -> !directDependencies.contains(requiresStatement.getModuleName()))
.map(Java9RedundantRequiresStatementInspection::resolveRequiredModule)
.map(PsiRequiresStatement::resolve)
.nonNull()
.toList();
@@ -177,7 +172,7 @@ public class Java9RedundantRequiresStatementInspection extends GlobalJavaBatchIn
if (parent instanceof PsiJavaModule) {
PsiJavaModule currentModule = (PsiJavaModule)parent;
Optional.of(statementToDelete)
.map(Java9RedundantRequiresStatementInspection::resolveRequiredModule)
.map(PsiRequiresStatement::resolve)
.map(dependencyModule -> getReexportedDependencies(currentModule, dependencyModule))
.ifPresent(reexportedDependencies -> addReexportedDependencies(reexportedDependencies, currentModule, statementToDelete));
}
@@ -189,7 +184,7 @@ public class Java9RedundantRequiresStatementInspection extends GlobalJavaBatchIn
if (!reexportedDependencies.isEmpty()) {
PsiJavaParserFacade parserFacade = JavaPsiFacade.getInstance(currentModule.getProject()).getParserFacade();
for (String dependencyName : reexportedDependencies) {
PsiStatement requiresStatement = parserFacade.createModuleStatementFromText(PsiKeyword.REQUIRES + ' ' + dependencyName);
PsiStatement requiresStatement = parserFacade.createModuleStatementFromText(PsiKeyword.REQUIRES + ' ' + dependencyName, null);
currentModule.addAfter(requiresStatement, addingPlace);
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2018 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.
// 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 com.intellij.codeInspection.java19modules;
import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool;
@@ -7,7 +7,6 @@ import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.psi.*;
import com.intellij.psi.impl.light.LightJavaModule;
import com.intellij.psi.impl.source.PsiJavaModuleReference;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,13 +30,15 @@ public class JavaRequiresAutoModuleInspection extends AbstractBaseJavaLocalInspe
public void visitRequiresStatement(PsiRequiresStatement statement) {
super.visitRequiresStatement(statement);
PsiJavaModuleReferenceElement refElement = statement.getReferenceElement();
PsiJavaModule target = PsiJavaModuleReference.resolve(refElement);
if (target instanceof LightJavaModule) {
if (!TRANSITIVE_ONLY) {
holder.registerProblem(refElement, InspectionsBundle.message("inspection.requires.auto.module.message"));
}
else if (statement.hasModifierProperty(PsiModifier.TRANSITIVE)) {
holder.registerProblem(refElement, InspectionsBundle.message("inspection.requires.auto.module.transitive"));
if (refElement != null) {
PsiJavaModule target = statement.resolve();
if (target instanceof LightJavaModule) {
if (!TRANSITIVE_ONLY) {
holder.registerProblem(refElement, InspectionsBundle.message("inspection.requires.auto.module.message"));
}
else if (statement.hasModifierProperty(PsiModifier.TRANSITIVE)) {
holder.registerProblem(refElement, InspectionsBundle.message("inspection.requires.auto.module.transitive"));
}
}
}
}
@@ -1,25 +1,11 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// 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 com.intellij.codeInspection.reference;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.impl.java.stubs.index.JavaModuleNameIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashMap;
@@ -115,15 +101,12 @@ public class RefJavaModuleImpl extends RefElementImpl implements RefJavaModule {
private void buildRequiresReferences(PsiJavaModule javaModule) {
for (PsiRequiresStatement statement : javaModule.getRequires()) {
PsiJavaModuleReferenceElement referenceElement = statement.getReferenceElement();
if (referenceElement != null) {
PsiElement element = addReference(referenceElement.getReference());
if (element instanceof PsiJavaModule) {
PsiJavaModule requiredModule = (PsiJavaModule)element;
Map<String, List<String>> packagesExportedByModule = getPackagesExportedByModule(requiredModule);
if (myRequiredModules == null) myRequiredModules = new ArrayList<>(1);
myRequiredModules.add(new RequiredModule(requiredModule.getName(), packagesExportedByModule, statement.hasModifierProperty(PsiModifier.TRANSITIVE)));
}
PsiElement element = addReference(statement.getModuleReference());
if (element instanceof PsiJavaModule) {
PsiJavaModule requiredModule = (PsiJavaModule)element;
Map<String, List<String>> packagesExportedByModule = getPackagesExportedByModule(requiredModule);
if (myRequiredModules == null) myRequiredModules = new ArrayList<>(1);
myRequiredModules.add(new RequiredModule(requiredModule.getName(), packagesExportedByModule, statement.hasModifierProperty(PsiModifier.TRANSITIVE)));
}
}
}
@@ -256,10 +239,8 @@ public class RefJavaModuleImpl extends RefElementImpl implements RefJavaModule {
@Nullable
public static RefJavaModule moduleFromExternalName(@NotNull RefManagerImpl manager, @NotNull String fqName) {
PsiJavaModule javaModule = ContainerUtil.getFirstItem(JavaModuleNameIndex.getInstance().get(fqName,
manager.getProject(),
GlobalSearchScope.projectScope(manager.getProject())));
Project project = manager.getProject();
PsiJavaModule javaModule = JavaPsiFacade.getInstance(project).findModule(fqName, GlobalSearchScope.projectScope(project));
return javaModule == null ? null : new RefJavaModuleImpl(javaModule, manager);
}
@@ -1,4 +1,4 @@
// Copyright 2000-2017 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.
// 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 com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.application.options.ModuleListCellRenderer;
@@ -17,7 +17,7 @@ import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Couple;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiJavaModuleReference;
import com.intellij.psi.PsiJavaModuleReference;
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
import com.intellij.psi.util.PointersKt;
import com.intellij.util.containers.ContainerUtil;
@@ -64,11 +64,7 @@ class AddModuleDependencyFix extends OrderEntryFix {
return JavaResolveUtil.isAccessible(aClass, aClass.getContainingClass(), aClass.getModifierList(), refElement, aClass, null);
}
AddModuleDependencyFix(PsiJavaModuleReference reference,
Module currentModule,
Set<Module> modules,
DependencyScope scope,
boolean exported) {
AddModuleDependencyFix(PsiJavaModuleReference reference, Module currentModule, Set<Module> modules, DependencyScope scope, boolean exported) {
super(reference);
myCurrentModule = currentModule;
myModules = modules;
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// 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 com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.QuickFixActionRegistrar;
@@ -36,7 +22,7 @@ import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packageDependencies.DependencyValidationManager;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiJavaModuleReference;
import com.intellij.psi.PsiJavaModuleReference;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.psi.util.PsiUtil;
@@ -1,4 +1,4 @@
// Copyright 2000-2018 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.
// 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 com.intellij.psi.impl
import com.intellij.codeInsight.JavaModuleSystemEx
@@ -18,7 +18,6 @@ import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ProjectFileIndex
import com.intellij.psi.*
import com.intellij.psi.impl.light.LightJavaModule
import com.intellij.psi.impl.source.PsiJavaModuleReference
import com.intellij.psi.util.PsiUtil
/**
@@ -94,7 +93,7 @@ class JavaPlatformModuleSystem : JavaModuleSystemEx {
var isRoot = !targetName.startsWith("java.") || inAddedModules(module, targetName) || hasUpgrade(module, targetName, packageName, place)
if (!isRoot) {
val root = PsiJavaModuleReference.resolve(place, "java.se", false)
val root = JavaPsiFacade.getInstance(place.project).findModule("java.se", module.moduleWithLibrariesScope)
isRoot = root == null || JavaModuleGraphUtil.reads(root, targetModule)
}
if (!isRoot) {
@@ -1,4 +1,4 @@
// Copyright 2000-2018 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.
// 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 com.intellij.psi.impl;
import com.intellij.application.options.CodeStyle;
@@ -29,7 +29,6 @@ import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
import com.intellij.psi.codeStyle.arrangement.MemberOrderService;
import com.intellij.psi.impl.compiled.ClsClassImpl;
import com.intellij.psi.impl.compiled.ClsElementImpl;
import com.intellij.psi.impl.file.impl.JavaFileManager;
import com.intellij.psi.impl.source.codeStyle.ImportHelper;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
@@ -68,7 +67,7 @@ public class JavaPsiImplementationHelperImpl extends JavaPsiImplementationHelper
@NotNull
@Override
public PsiJavaModule getOriginalModule(@NotNull PsiJavaModule module) {
return findCompiledElement(module, scope -> JavaFileManager.getInstance(myProject).findModules(module.getName(), scope));
return findCompiledElement(module, scope -> JavaPsiFacade.getInstance(myProject).findModules(module.getName(), scope));
}
private <T extends PsiElement> T findCompiledElement(T original, Function<? super GlobalSearchScope, ? extends Collection<T>> candidateFinder) {
@@ -1,10 +1,10 @@
// Copyright 2000-2018 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.
// 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 com.intellij.refactoring.rename;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiJavaModule;
import com.intellij.psi.impl.java.stubs.index.JavaModuleNameIndex;
import com.intellij.psi.search.ProjectScope;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.usageView.UsageInfo;
@@ -26,7 +26,7 @@ public class RenameJavaModuleProcessor extends RenamePsiElementProcessor {
@NotNull Map<? extends PsiElement, String> allRenames,
@NotNull List<UsageInfo> result) {
Project project = element.getProject();
PsiJavaModule existing = ContainerUtil.getFirstItem(JavaModuleNameIndex.getInstance().get(newName, project, ProjectScope.getProjectScope(project)));
PsiJavaModule existing = ContainerUtil.getFirstItem(JavaPsiFacade.getInstance(project).findModules(newName, ProjectScope.getProjectScope(project)));
if (existing != null) {
result.add(new UnresolvableCollisionUsageInfo(element, existing) {
@Override
@@ -9,6 +9,8 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
/**
* @author max
*/
@@ -55,6 +57,18 @@ public abstract class JavaPsiFacade {
@Nullable
public abstract PsiPackage findPackage(@NonNls @NotNull String qualifiedName);
/**
* Searches the scope for a unique Java module with the given name.
*/
@Nullable
public abstract PsiJavaModule findModule(@NotNull String moduleName, @NotNull GlobalSearchScope scope);
/**
* Searches the scope for a Java modules with the given name.
*/
@NotNull
public abstract Collection<PsiJavaModule> findModules(@NotNull String moduleName, @NotNull GlobalSearchScope scope);
/**
* Returns the element factory for the project, which can be used to
* create instances of Java and XML PSI elements.
@@ -0,0 +1,8 @@
// 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 com.intellij.psi;
import org.jetbrains.annotations.Nullable;
public interface PsiJavaModuleReference extends PsiPolyVariantReference {
@Override @Nullable PsiJavaModule resolve();
}
@@ -1,4 +1,4 @@
// Copyright 2000-2018 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.
// 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 com.intellij.psi;
import org.jetbrains.annotations.NotNull;
@@ -11,6 +11,7 @@ import org.jetbrains.annotations.Nullable;
*/
public interface PsiJavaModuleReferenceElement extends PsiElement {
@NotNull String getReferenceText();
@Override
@Nullable PsiPolyVariantReference getReference();
@Nullable PsiJavaModuleReference getReference();
}
@@ -1,4 +1,4 @@
// Copyright 2000-2018 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.
// 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 com.intellij.psi;
import com.intellij.pom.java.LanguageLevel;
@@ -227,23 +227,27 @@ public interface PsiJavaParserFacade {
@NotNull
PsiType createPrimitiveTypeFromText(@NotNull String text) throws IncorrectOperationException;
/** @deprecated use {@link #createModuleFromText(String, PsiElement)} */
@Deprecated
default PsiJavaModule createModuleFromText(@NotNull String text) throws IncorrectOperationException {
return createModuleFromText(text, null);
}
/**
* Creates a Java module declaration from the specified text.
*/
@NotNull
PsiJavaModule createModuleFromText(@NotNull String text) throws IncorrectOperationException;
PsiJavaModule createModuleFromText(@NotNull String text, @Nullable PsiElement context) throws IncorrectOperationException;
/**
* Creates a Java module statement from the specified text.
*/
@NotNull
PsiStatement createModuleStatementFromText(@NotNull String text) throws IncorrectOperationException;
PsiStatement createModuleStatementFromText(@NotNull String text, @Nullable PsiElement context) throws IncorrectOperationException;
/**
* Creates a Java module reference from the specified text.
* Creates a Java module reference element from the specified text.
*/
@NotNull
default PsiJavaModuleReferenceElement createModuleReferenceFromText(@NotNull String text) throws IncorrectOperationException {
return createModuleFromText("module " + text + " {}").getNameIdentifier();
}
PsiJavaModuleReferenceElement createModuleReferenceFromText(@NotNull String text, @Nullable PsiElement context) throws IncorrectOperationException;
}
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// 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 com.intellij.psi;
import org.jetbrains.annotations.NotNull;
@@ -30,18 +16,11 @@ public interface PsiPackageAccessibilityStatement extends PsiStatement {
enum Role {EXPORTS, OPENS}
@NotNull
Role getRole();
@NotNull Role getRole();
@Nullable
PsiJavaCodeReferenceElement getPackageReference();
@Nullable PsiJavaCodeReferenceElement getPackageReference();
@Nullable String getPackageName();
@Nullable
String getPackageName();
@NotNull
Iterable<PsiJavaModuleReferenceElement> getModuleReferences();
@NotNull
List<String> getModuleNames();
@NotNull Iterable<PsiJavaModuleReferenceElement> getModuleReferences();
@NotNull List<String> getModuleNames();
}
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// 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 com.intellij.psi;
import org.jetbrains.annotations.Nullable;
@@ -26,5 +12,12 @@ public interface PsiRequiresStatement extends PsiModifierListOwner, PsiStatement
PsiRequiresStatement[] EMPTY_ARRAY = new PsiRequiresStatement[0];
@Nullable PsiJavaModuleReferenceElement getReferenceElement();
@Nullable String getModuleName();
@Nullable PsiJavaModuleReference getModuleReference();
default @Nullable PsiJavaModule resolve() {
PsiJavaModuleReference ref = getModuleReference();
return ref != null ? ref.resolve() : null;
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2018 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.
// 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 com.intellij.psi.util;
import com.intellij.lang.java.JavaLanguage;
@@ -1393,7 +1393,7 @@ public final class PsiUtil extends PsiUtilCore {
public static PsiElement addModuleStatement(@NotNull PsiJavaModule module, @NotNull String text) {
PsiJavaParserFacade facade = JavaPsiFacade.getInstance(module.getProject()).getParserFacade();
PsiStatement statement = facade.createModuleStatementFromText(text);
PsiStatement statement = facade.createModuleStatementFromText(text, null);
PsiElement anchor = SyntaxTraverser.psiTraverser().children(module).filter(statement.getClass()).last();
if (anchor == null) {
@@ -1,4 +1,4 @@
// Copyright 2000-2018 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.
// 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 com.intellij.psi.impl;
import com.intellij.lang.jvm.JvmClass;
@@ -45,6 +45,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
private final PsiConstantEvaluationHelper myConstantEvaluationHelper;
private final ConcurrentMap<String, PsiPackage> myPackageCache = ContainerUtil.createConcurrentSoftValueMap();
private final ConcurrentMap<GlobalSearchScope, Map<String, PsiClass>> myClassCache = ContainerUtil.createConcurrentWeakKeySoftValueMap();
private final Map<GlobalSearchScope, Map<String, Collection<PsiJavaModule>>> myModuleCache = ContainerUtil.createConcurrentWeakKeySoftValueMap();
private final Project myProject;
private final JavaFileManager myFileManager;
private final AtomicNotNullLazyValue<JvmFacadeImpl> myJvmFacade;
@@ -73,6 +74,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
if (lastTimeSeen != now) {
lastTimeSeen = now;
myPackageCache.clear();
myModuleCache.clear();
}
}
});
@@ -245,6 +247,20 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
return null;
}
@Override
public PsiJavaModule findModule(@NotNull String moduleName, @NotNull GlobalSearchScope scope) {
Collection<PsiJavaModule> modules = findModules(moduleName, scope);
return modules.size() == 1 ? modules.iterator().next() : null;
}
@NotNull
@Override
public Collection<PsiJavaModule> findModules(@NotNull String moduleName, @NotNull GlobalSearchScope scope) {
return myModuleCache
.computeIfAbsent(scope, k -> ContainerUtil.createConcurrentWeakValueMap())
.computeIfAbsent(moduleName, k -> JavaFileManager.getInstance(myProject).findModules(k, scope));
}
@NotNull
private List<PsiElementFinder> filteredFinders() {
return DumbService.getInstance(getProject()).filterByDumbAwareness(finders());
@@ -1,4 +1,4 @@
// Copyright 2000-2018 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.
// 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 com.intellij.psi.impl;
import com.intellij.ide.highlighter.JavaFileType;
@@ -321,8 +321,8 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade {
@NotNull
@Override
public PsiJavaModule createModuleFromText(@NotNull String text) throws IncorrectOperationException {
DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, MODULE, LanguageLevel.JDK_1_9), null);
public PsiJavaModule createModuleFromText(@NotNull String text, @Nullable PsiElement context) throws IncorrectOperationException {
DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, MODULE, LanguageLevel.JDK_1_9), context);
PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
if (!(element instanceof PsiJavaModule)) {
throw newException("Incorrect module declaration '" + text + "'", holder);
@@ -332,14 +332,20 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade {
@NotNull
@Override
public PsiStatement createModuleStatementFromText(@NotNull String text) throws IncorrectOperationException {
public PsiStatement createModuleStatementFromText(@NotNull String text, @Nullable PsiElement context) throws IncorrectOperationException {
String template = "module M { " + text + "; }";
PsiJavaModule module = createModuleFromText(template);
PsiJavaModule module = createModuleFromText(template, context);
PsiStatement statement = PsiTreeUtil.getChildOfType(module, PsiStatement.class);
if (statement == null) throw new IncorrectOperationException("Incorrect module statement '" + text + "'");
return statement;
}
@NotNull
@Override
public PsiJavaModuleReferenceElement createModuleReferenceFromText(@NotNull String text, @Nullable PsiElement context) throws IncorrectOperationException {
return createModuleFromText("module " + text + " {}", context).getNameIdentifier();
}
public static PsiPrimitiveType getPrimitiveType(String text) {
return PRIMITIVE_TYPES.get(text);
}
@@ -1,22 +1,8 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// 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 com.intellij.psi.impl.compiled;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiJavaModuleReference;
import com.intellij.psi.impl.source.PsiJavaModuleReferenceImpl;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.TreeElement;
import org.jetbrains.annotations.NotNull;
@@ -29,7 +15,7 @@ class ClsJavaModuleReferenceElementImpl extends ClsElementImpl implements PsiJav
ClsJavaModuleReferenceElementImpl(PsiElement parent, String text) {
myParent = parent;
myText = text;
myReference = myParent instanceof PsiJavaModule ? null : new PsiJavaModuleReference(this);
myReference = myParent instanceof PsiJavaModule ? null : new PsiJavaModuleReferenceImpl(this);
}
@NotNull
@@ -60,7 +46,7 @@ class ClsJavaModuleReferenceElementImpl extends ClsElementImpl implements PsiJav
}
@Override
public PsiPolyVariantReference getReference() {
public PsiJavaModuleReference getReference() {
return myReference;
}
@@ -1,23 +1,10 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// 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 com.intellij.psi.impl.compiled;
import com.intellij.openapi.util.AtomicNotNullLazyValue;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiJavaModuleReference;
import com.intellij.psi.PsiJavaModuleReferenceElement;
import com.intellij.psi.PsiModifierList;
import com.intellij.psi.PsiRequiresStatement;
@@ -53,6 +40,11 @@ public class ClsRequiresStatementImpl extends ClsRepositoryPsiElement<PsiRequire
return getStub().getModuleName();
}
@Override
public PsiJavaModuleReference getModuleReference() {
return myModuleReference.getValue().getReference();
}
@Override
public void appendMirrorText(int indentLevel, @NotNull StringBuilder buffer) {
StringUtil.repeatSymbol(buffer, ' ', indentLevel);
@@ -1,4 +1,4 @@
// Copyright 2000-2018 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.
// 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 com.intellij.psi.impl.light;
import com.intellij.lang.java.JavaLanguage;
@@ -178,9 +178,8 @@ public class LightJavaModule extends LightElement implements PsiJavaModule {
return myText;
}
@Nullable
@Override
public PsiPolyVariantReference getReference() {
public PsiJavaModuleReference getReference() {
return null;
}
@@ -1,6 +1,4 @@
/*
* Copyright 2000-2018 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.
*/
// 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 com.intellij.psi.impl.source;
import com.intellij.lang.ASTNode;
@@ -118,7 +116,7 @@ public class PsiJavaModuleImpl extends JavaStubPsiElement<PsiJavaModuleStub> imp
@Override
public PsiElement setName(@NotNull String name) throws IncorrectOperationException {
PsiJavaModuleReferenceElement newName = PsiElementFactory.SERVICE.getInstance(getProject()).createModuleReferenceFromText(name);
PsiJavaModuleReferenceElement newName = PsiElementFactory.SERVICE.getInstance(getProject()).createModuleReferenceFromText(name, null);
getNameIdentifier().replace(newName);
return this;
}
@@ -1,133 +0,0 @@
// Copyright 2000-2018 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 com.intellij.psi.impl.source;
import com.intellij.core.JavaCoreBundle;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.file.impl.JavaFileManager;
import com.intellij.psi.impl.source.resolve.ResolveCache;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
public class PsiJavaModuleReference extends PsiReferenceBase.Poly<PsiJavaModuleReferenceElement> {
public PsiJavaModuleReference(@NotNull PsiJavaModuleReferenceElement element) {
super(element, new TextRange(0, element.getTextLength()), false);
}
@NotNull
@Override
public String getCanonicalText() {
return getElement().getReferenceText();
}
@NotNull
@Override
public ResolveResult[] multiResolve(boolean incompleteCode) {
return ResolveCache.getInstance(getProject()).resolveWithCaching(this, Resolver.INSTANCE, false, incompleteCode);
}
@Override
public PsiElement handleElementRename(@NotNull String newName) throws IncorrectOperationException {
PsiJavaModuleReferenceElement element = getElement();
if (element instanceof PsiCompiledElement) {
throw new IncorrectOperationException(JavaCoreBundle.message("psi.error.attempt.to.edit.class.file", element.getContainingFile()));
}
PsiElement newElement = PsiElementFactory.SERVICE.getInstance(element.getProject()).createModuleReferenceFromText(newName);
return element.replace(newElement);
}
private Project getProject() {
return getElement().getProject();
}
private static class Resolver implements ResolveCache.PolyVariantResolver<PsiJavaModuleReference> {
private static final ResolveCache.PolyVariantResolver<PsiJavaModuleReference> INSTANCE = new Resolver();
@NotNull
@Override
public ResolveResult[] resolve(@NotNull PsiJavaModuleReference reference, boolean incompleteCode) {
PsiJavaModuleReferenceElement refElement = reference.getElement();
PsiFile file = refElement.getContainingFile();
String moduleName = reference.getCanonicalText();
if (file instanceof PsiJavaFile) {
PsiJavaModule module = ((PsiJavaFile)file).getModuleDeclaration();
if (module != null && module.getName().equals(moduleName)) {
return new ResolveResult[]{new PsiElementResolveResult(module)};
}
}
boolean global = incompleteCode || refElement.getParent() instanceof PsiPackageAccessibilityStatement;
Collection<PsiJavaModule> modules = findModules(file, moduleName, global);
if (!modules.isEmpty()) {
ResolveResult[] result = new ResolveResult[modules.size()];
int i = 0;
for (PsiJavaModule module : modules) result[i++] = new PsiElementResolveResult(module);
return result;
}
else {
return ResolveResult.EMPTY_ARRAY;
}
}
private static Collection<PsiJavaModule> findModules(PsiFile file, String moduleName, boolean global) {
Project project = file.getProject();
GlobalSearchScope scope = global ? GlobalSearchScope.allScope(project) : file.getResolveScope();
return JavaFileManager.getInstance(project).findModules(moduleName, scope);
}
}
private static final Key<CachedValue<Collection<PsiJavaModule>>> K_COMPLETE = Key.create("java.module.ref.text.resolve.complete");
private static final Key<CachedValue<Collection<PsiJavaModule>>> K_INCOMPLETE = Key.create("java.module.ref.text.resolve.incomplete");
@Nullable
@Contract("null -> null")
public static PsiJavaModule resolve(@Nullable PsiJavaModuleReferenceElement refElement) {
if (refElement != null) {
PsiPolyVariantReference ref = refElement.getReference();
if (ref != null) {
PsiElement result = ref.resolve();
if (result instanceof PsiJavaModule) {
return (PsiJavaModule)result;
}
}
}
return null;
}
@Nullable
public static PsiJavaModule resolve(@NotNull PsiElement refOwner, String refText, boolean incompleteCode) {
Collection<PsiJavaModule> modules = multiResolve(refOwner, refText, incompleteCode);
return modules.size() == 1 ? modules.iterator().next() : null;
}
@NotNull
public static Collection<PsiJavaModule> multiResolve(@NotNull PsiElement refOwner, String refText, boolean incompleteCode) {
if (StringUtil.isEmpty(refText)) return Collections.emptyList();
CachedValuesManager manager = CachedValuesManager.getManager(refOwner.getProject());
Key<CachedValue<Collection<PsiJavaModule>>> key = incompleteCode ? K_INCOMPLETE : K_COMPLETE;
return manager.getCachedValue(refOwner, key, () -> {
Collection<PsiJavaModule> modules = Resolver.findModules(refOwner.getContainingFile(), refText, incompleteCode);
return CachedValueProvider.Result.create(modules, cacheDependency());
}, false);
}
@SuppressWarnings("deprecation")
private static Object cacheDependency() {
return PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT;
}
}
@@ -1,21 +1,8 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// 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 com.intellij.psi.impl.source;
import com.intellij.psi.*;
import com.intellij.psi.PsiJavaModuleReference;
import com.intellij.psi.impl.source.tree.CompositePsiElement;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.util.CachedValueProvider;
@@ -40,12 +27,13 @@ public class PsiJavaModuleReferenceElementImpl extends CompositePsiElement imple
}
@Override
public PsiPolyVariantReference getReference() {
return CachedValuesManager.getCachedValue(this, () -> {
PsiJavaModuleReferenceElementImpl refElement = this;
PsiJavaModuleReference ref = refElement.getParent() instanceof PsiJavaModule ? null : new PsiJavaModuleReference(refElement);
return CachedValueProvider.Result.create(ref, refElement);
});
public PsiJavaModuleReference getReference() {
if (getParent() instanceof PsiJavaModule && !(getContainingFile() instanceof JavaDummyHolder)) {
return null; // module name identifier is not a reference
}
else {
return CachedValuesManager.getCachedValue(this, () -> CachedValueProvider.Result.create(new PsiJavaModuleReferenceImpl(this), this));
}
}
@Override
@@ -0,0 +1,84 @@
// 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 com.intellij.psi.impl.source;
import com.intellij.core.JavaCoreBundle;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.PsiJavaModuleReference;
import com.intellij.psi.impl.source.resolve.ResolveCache;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
public class PsiJavaModuleReferenceImpl extends PsiReferenceBase.Poly<PsiJavaModuleReferenceElement> implements PsiJavaModuleReference {
public PsiJavaModuleReferenceImpl(@NotNull PsiJavaModuleReferenceElement element) {
super(element, new TextRange(0, element.getTextLength()), false);
}
@NotNull
@Override
public String getCanonicalText() {
return getElement().getReferenceText();
}
@Override
public PsiJavaModule resolve() {
return (PsiJavaModule)super.resolve();
}
@NotNull
@Override
public ResolveResult[] multiResolve(boolean incompleteCode) {
return ResolveCache.getInstance(getProject()).resolveWithCaching(this, Resolver.INSTANCE, false, incompleteCode);
}
@Override
public PsiElement handleElementRename(@NotNull String newName) throws IncorrectOperationException {
PsiJavaModuleReferenceElement element = getElement();
if (element instanceof PsiCompiledElement) {
throw new IncorrectOperationException(JavaCoreBundle.message("psi.error.attempt.to.edit.class.file", element.getContainingFile()));
}
PsiElement newElement = PsiElementFactory.SERVICE.getInstance(element.getProject()).createModuleReferenceFromText(newName, null);
return element.replace(newElement);
}
private Project getProject() {
return getElement().getProject();
}
private static class Resolver implements ResolveCache.PolyVariantResolver<PsiJavaModuleReferenceImpl> {
private static final ResolveCache.PolyVariantResolver<PsiJavaModuleReferenceImpl> INSTANCE = new Resolver();
@NotNull
@Override
public ResolveResult[] resolve(@NotNull PsiJavaModuleReferenceImpl reference, boolean incompleteCode) {
PsiJavaModuleReferenceElement refElement = reference.getElement();
PsiFile file = refElement.getContainingFile();
String moduleName = reference.getCanonicalText();
if (file instanceof PsiJavaFile) {
PsiJavaModule module = ((PsiJavaFile)file).getModuleDeclaration();
if (module != null && module.getName().equals(moduleName)) {
return new ResolveResult[]{new PsiElementResolveResult(module)};
}
}
boolean global = incompleteCode || refElement.getParent() instanceof PsiPackageAccessibilityStatement;
Project project = file.getProject();
GlobalSearchScope scope = global ? GlobalSearchScope.allScope(project) : file.getResolveScope();
Collection<PsiJavaModule> modules = JavaPsiFacade.getInstance(project).findModules(moduleName, scope);
if (!modules.isEmpty()) {
ResolveResult[] result = new ResolveResult[modules.size()];
int i = 0;
for (PsiJavaModule module : modules) result[i++] = new PsiElementResolveResult(module);
return result;
}
else {
return ResolveResult.EMPTY_ARRAY;
}
}
}
}
@@ -1,30 +1,20 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// 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 com.intellij.psi.impl.source;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiJavaModuleReference;
import com.intellij.psi.*;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
import com.intellij.psi.impl.java.stubs.PsiRequiresStatementStub;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.reference.SoftReference;
import org.jetbrains.annotations.NotNull;
import static com.intellij.openapi.util.text.StringUtil.nullize;
public class PsiRequiresStatementImpl extends JavaStubPsiElement<PsiRequiresStatementStub> implements PsiRequiresStatement {
private SoftReference<PsiJavaModuleReference> myReference;
public PsiRequiresStatementImpl(@NotNull PsiRequiresStatementStub stub) {
super(stub, JavaStubElementTypes.REQUIRES_STATEMENT);
}
@@ -50,6 +40,26 @@ public class PsiRequiresStatementImpl extends JavaStubPsiElement<PsiRequiresStat
}
}
@Override
public PsiJavaModuleReference getModuleReference() {
PsiRequiresStatementStub stub = getStub();
if (stub != null) {
String refText = nullize(stub.getModuleName());
if (refText == null) return null;
PsiJavaModuleReference ref = SoftReference.dereference(myReference);
if (ref == null) {
ref = JavaPsiFacade.getInstance(getProject()).getParserFacade().createModuleReferenceFromText(refText, this).getReference();
myReference = new SoftReference<>(ref);
}
return ref;
}
else {
myReference = null;
PsiJavaModuleReferenceElement refElement = getReferenceElement();
return refElement != null ? refElement.getReference() : null;
}
}
@Override
public PsiModifierList getModifierList() {
return getStubOrPsiChild(JavaStubElementTypes.MODIFIER_LIST);
@@ -1,14 +1,12 @@
// Copyright 2000-2017 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.
// 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 com.intellij.java.codeInsight.daemon
import com.intellij.java.testFramework.fixtures.LightJava9ModulesCodeInsightFixtureTestCase
import com.intellij.java.testFramework.fixtures.MultiModuleJava9ProjectDescriptor.ModuleDescriptor.M2
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiJavaModule
import com.intellij.psi.impl.file.impl.JavaFileManager
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.refactoring.rename.RenameProcessor
import org.assertj.core.api.Assertions.assertThat
class ModuleRenameTest : LightJava9ModulesCodeInsightFixtureTestCase() {
fun testRename() {
@@ -27,11 +25,7 @@ class ModuleRenameTest : LightJava9ModulesCodeInsightFixtureTestCase() {
assertEquals("module M2 { exports pkg.m2 to M.other; opens pkg.m2.impl to M.other; }", fileText(file))
}
private fun findModule(name: String): PsiJavaModule {
val modules = JavaFileManager.getInstance(project).findModules(name, GlobalSearchScope.projectScope(project))
assertThat(modules).hasSize(1)
return modules.first()
}
private fun findModule(name: String) = JavaPsiFacade.getInstance(project).findModule(name, GlobalSearchScope.projectScope(project))!!
private fun fileText(file: VirtualFile) = myFixture.psiManager.findFile(file)!!.text
}
@@ -1,6 +1,4 @@
/*
* Copyright 2000-2018 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.
*/
// 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 com.intellij.java.psi
import com.intellij.openapi.command.WriteCommandAction
@@ -31,13 +29,13 @@ class JavaPsiTest extends LightCodeInsightFixtureTestCase {
def file = configureFile("module M { opens pkg; }")
def statement = file.moduleDeclaration.opens.first()
def facade = myFixture.javaFacade.parserFacade
runCommand { statement.add(facade.createModuleReferenceFromText("M1")) }
runCommand { statement.add(facade.createModuleReferenceFromText("M1", null)) }
assert statement.text == "opens pkg to M1;"
runCommand { statement.add(facade.createModuleReferenceFromText("M2")) }
runCommand { statement.add(facade.createModuleReferenceFromText("M2", null)) }
assert statement.text == "opens pkg to M1, M2;"
runCommand { statement.lastChild.delete() }
assert statement.text == "opens pkg to M1, M2"
runCommand { statement.add(facade.createModuleReferenceFromText("M3")) }
runCommand { statement.add(facade.createModuleReferenceFromText("M3", null)) }
assert statement.text == "opens pkg to M1, M2, M3"
}
@@ -1,9 +1,9 @@
// Copyright 2000-2018 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.
// 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 com.intellij.ui.components;
import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.basic.BasicListUI;
import java.awt.*;
/**
* @author Sergey.Malenkov
@@ -85,4 +85,12 @@ final class WideSelectionListUI extends BasicListUI {
}
return false;
}
@Override
public int locationToIndex(JList list, Point location) {
if (location.y <= list.getPreferredSize().height) {
return super.locationToIndex(list, location);
}
return -1;
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2018 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.
// 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.plugins.javaFX.execution;
import com.intellij.execution.CommonJavaRunConfigurationParameters;
@@ -18,7 +18,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiJavaModule;
import com.intellij.psi.impl.java.stubs.index.JavaModuleNameIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiUtilCore;
@@ -54,7 +53,7 @@ public class JavaFxRunConfigurationExtension extends RunConfigurationExtension {
if (sdkVersion != null &&
sdkVersion.isAtLeast(JavaSdkVersion.JDK_11) &&
params.getModulePath().isEmpty() &&
JavaModuleNameIndex.getInstance().get(JAVAFX_GRAPHICS, project, searchScope).stream().noneMatch(mod -> belongsToJdk(mod))) {
JavaPsiFacade.getInstance(project).findModules(JAVAFX_GRAPHICS, searchScope).stream().noneMatch(mod -> belongsToJdk(mod))) {
VirtualFile javaFxBase = getModuleJar(JAVAFX_BASE, project, searchScope);
VirtualFile javafxGraphics = getModuleJar(JAVAFX_GRAPHICS, project, searchScope);
@@ -72,12 +71,12 @@ public class JavaFxRunConfigurationExtension extends RunConfigurationExtension {
private static boolean belongsToJdk(PsiJavaModule mod) {
VirtualFile file = PsiUtilCore.getVirtualFile(mod);
return file != null &&
return file != null &&
ProjectRootManager.getInstance(mod.getProject()).getFileIndex().getOrderEntriesForFile(file).stream().anyMatch(e -> e instanceof JdkOrderEntry);
}
private static VirtualFile getModuleJar(String moduleName, Project project, GlobalSearchScope searchScope) {
Collection<PsiJavaModule> javaModules = JavaModuleNameIndex.getInstance().get(moduleName, project, searchScope);
Collection<PsiJavaModule> javaModules = JavaPsiFacade.getInstance(project).findModules(moduleName, searchScope);
return VfsUtilCore.getVirtualFileForJar(PsiUtilCore.getVirtualFile(ContainerUtil.getFirstItem(javaModules)));
}