mySessions = new HashMap<>();
@@ -449,7 +450,7 @@ public class DebuggerManagerImpl extends DebuggerManagerEx implements Persistent
}
final TransportServiceWrapper transportService = TransportServiceWrapper.getTransportService(useSockets);
- final String debugAddress = debuggerInServerMode && useSockets ? "127.0.0.1:" + address : address;
+ final String debugAddress = debuggerInServerMode && useSockets ? LOCALHOST_ADDRESS_FALLBACK + ":" + address : address;
String debuggeeRunProperties = "transport=" + transportService.transportId() + ",address=" + debugAddress;
if (debuggerInServerMode) {
debuggeeRunProperties += ",suspend=y,server=n";
@@ -498,7 +499,7 @@ public class DebuggerManagerImpl extends DebuggerManagerEx implements Persistent
parameters.getVMParametersList().replaceOrPrepend("-classic", forceClassicVM ? "-classic" : "");
});
- return new RemoteConnection(useSockets, "127.0.0.1", address, debuggerInServerMode);
+ return new RemoteConnection(useSockets, LOCALHOST_ADDRESS_FALLBACK, address, debuggerInServerMode);
}
private static boolean shouldForceNoJIT(Sdk jdk) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java
index 370819daa7d1..b2c0ed053d75 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java
@@ -42,7 +42,6 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.impl.java.stubs.index.JavaFullClassNameIndex;
import com.intellij.psi.jsp.JspFile;
import com.intellij.psi.search.EverythingGlobalScope;
import com.intellij.psi.search.GlobalSearchScope;
@@ -247,10 +246,10 @@ public class LineBreakpoint extends Breakpoi
final GlobalSearchScope scope = debugProcess.getSearchScope();
final boolean contains = scope.contains(breakpointFile);
List files = ContainerUtil.map(
- JavaFullClassNameIndex.getInstance().get(className.hashCode(), myProject, scope),
+ JavaPsiFacade.getInstance(myProject).findClasses(className, scope),
aClass -> aClass.getContainingFile().getVirtualFile());
List allFiles = ContainerUtil.map(
- JavaFullClassNameIndex.getInstance().get(className.hashCode(), myProject, new EverythingGlobalScope(myProject)),
+ JavaPsiFacade.getInstance(myProject).findClasses(className, new EverythingGlobalScope(myProject)),
aClass -> aClass.getContainingFile().getVirtualFile());
final VirtualFile contentRoot = fileIndex.getContentRootForFile(breakpointFile);
final Module module = fileIndex.getModuleForFile(breakpointFile);
@@ -264,7 +263,7 @@ public class LineBreakpoint extends Breakpoi
"; all possible files are: " + allFiles
);
}
-
+
return false;
}
}
@@ -357,7 +356,7 @@ public class LineBreakpoint
extends Breakpoi
final int dotIndex = className.lastIndexOf(".");
if (dotIndex >= 0 && !isFile) {
packageName = className.substring(0, dotIndex);
- className = className.substring(dotIndex + 1);
+ className = className.substring(dotIndex + 1);
}
if (totalTextLength != -1) {
@@ -369,7 +368,7 @@ public class LineBreakpoint
extends Breakpoi
}
}
}
-
+
info.append(className);
}
if(hasMethodInfo) {
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/StepSequence.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/StepSequence.java
index a58a9ada8aec..69163219ec28 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/StepSequence.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/StepSequence.java
@@ -22,6 +22,7 @@ import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.util.Pair;
+import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NonNls;
@@ -31,14 +32,14 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
public class StepSequence {
- private final List myCommonSteps = new ArrayList<>();
+ private final List myCommonSteps;
private final List>> myCommonFinishingSteps = new ArrayList<>();
private final MultiMap mySpecificSteps = new MultiMap<>();
@NonNls private List myTypes = new ArrayList<>();
private List mySelectedSteps;
public StepSequence(ModuleWizardStep... commonSteps) {
- myCommonSteps.addAll(Arrays.asList(commonSteps));
+ myCommonSteps = new SmartList<>(commonSteps);
}
public void addCommonStep(@NotNull ModuleWizardStep step){
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java
index cef3cc1ef0e3..ea3d73210855 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java
@@ -34,6 +34,7 @@ import com.intellij.openapi.roots.ui.configuration.LibrarySourceRootDetectorUtil
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileVisitor;
@@ -68,12 +69,16 @@ public class DefaultLibraryRootsComponentDescriptor extends LibraryRootsComponen
@Override
public List extends RootDetector> getRootDetectors() {
List results = new ArrayList<>();
- results.add(new FileTypeBasedRootFilter(OrderRootType.CLASSES, false, StdFileTypes.CLASS, "classes"));
- results.add(new FileTypeBasedRootFilter(OrderRootType.CLASSES, true, StdFileTypes.CLASS, "jar directory"));
+ results.add(new DescendentBasedRootFilter(OrderRootType.CLASSES, false, "classes",
+ file -> StdFileTypes.CLASS.equals(file.getFileType())
+ //some libraries store native libraries inside their JAR files and unpack them dynamically so we should detect such JARs as classes roots
+ || file.getFileSystem() instanceof JarFileSystem && isNativeLibrary(file)));
+ results.add(DescendentBasedRootFilter.createFileTypeBasedFilter(OrderRootType.CLASSES, true, StdFileTypes.CLASS, "jar directory"));
ContainerUtil.addAll(results, Extensions.getExtensions(LibrarySourceRootDetectorUtil.JAVA_SOURCE_ROOT_DETECTOR));
- results.add(new FileTypeBasedRootFilter(OrderRootType.SOURCES, true, StdFileTypes.JAVA, "source archive directory"));
+ results.add(DescendentBasedRootFilter.createFileTypeBasedFilter(OrderRootType.SOURCES, true, StdFileTypes.JAVA, "source archive directory"));
results.add(new JavadocRootDetector());
- results.add(new AnnotationsRootFilter());
+ results.add(new DescendentBasedRootFilter(AnnotationOrderRootType.getInstance(), false, "external annotations",
+ file -> ExternalAnnotationsManager.ANNOTATIONS_XML.equals(file.getName())));
results.add(new NativeLibraryRootFilter());
return results;
}
@@ -128,17 +133,6 @@ public class DefaultLibraryRootsComponentDescriptor extends LibraryRootsComponen
}
}
- private static class AnnotationsRootFilter extends FileTypeBasedRootFilter {
- private AnnotationsRootFilter() {
- super(AnnotationOrderRootType.getInstance(), false, StdFileTypes.XML, "external annotations");
- }
-
- @Override
- protected boolean isFileAccepted(VirtualFile virtualFile) {
- return super.isFileAccepted(virtualFile) && virtualFile.getName().equals(ExternalAnnotationsManager.ANNOTATIONS_XML);
- }
- }
-
private static class NativeLibraryRootFilter extends RootDetector {
private NativeLibraryRootFilter() {
super(NativeLibraryOrderRootType.getInstance(), false, "native library location");
diff --git a/java/idea-ui/testSrc/com/intellij/openapi/roots/ui/configuration/libraryEditor/JavaLibraryRootsDetectionTest.kt b/java/idea-ui/testSrc/com/intellij/openapi/roots/ui/configuration/libraryEditor/JavaLibraryRootsDetectionTest.kt
new file mode 100644
index 000000000000..3786241e3037
--- /dev/null
+++ b/java/idea-ui/testSrc/com/intellij/openapi/roots/ui/configuration/libraryEditor/JavaLibraryRootsDetectionTest.kt
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+package com.intellij.openapi.roots.ui.configuration.libraryEditor
+
+import com.intellij.openapi.fileTypes.StdFileTypes
+import com.intellij.openapi.progress.EmptyProgressIndicator
+import com.intellij.openapi.roots.NativeLibraryOrderRootType
+import com.intellij.openapi.roots.OrderRootType
+import com.intellij.openapi.roots.libraries.ui.impl.LibraryRootsDetectorImpl
+import com.intellij.openapi.vfs.JarFileSystem
+import com.intellij.testFramework.LightPlatformTestCase
+import com.intellij.util.io.DirectoryContentBuilder
+import com.intellij.util.io.directoryContent
+import com.intellij.util.io.generateInVirtualTempDir
+
+/**
+ * @author nik
+ */
+class JavaLibraryRootsDetectionTest : LightPlatformTestCase() {
+ fun `test JAR with classes`() {
+ assertRootType(OrderRootType.CLASSES, false) {
+ zip("classes.jar") {
+ file("A.class")
+ }
+ }
+ }
+
+ fun `test directory with classes`() {
+ assertRootType(OrderRootType.CLASSES, false) {
+ dir("classes") {
+ file("A.class")
+ }
+ }
+ }
+
+ fun `test directory with sources`() {
+ assertRootType(OrderRootType.SOURCES, false) {
+ dir("src") {
+ file("A.java", "class A {}")
+ }
+ }
+ }
+
+ fun `test JAR directory`() {
+ assertRootType(OrderRootType.CLASSES, true) {
+ dir("lib") {
+ zip("a.jar") {
+ file("A.class")
+ }
+ }
+ }
+ }
+
+ fun `test sources zip directory`() {
+ assertRootType(OrderRootType.SOURCES, true) {
+ dir("lib") {
+ zip("src.zip") {
+ file("A.java", "class A {}")
+ }
+ }
+ }
+ }
+
+ fun `test native library`() {
+ assertRootType(NativeLibraryOrderRootType.getInstance(), false) {
+ dir("lib") {
+ file("a.dll")
+ }
+ }
+ }
+
+ fun `test native library in JAR`() {
+ assertRootType(OrderRootType.CLASSES, false) {
+ zip("a.jar") {
+ file("a.dll")
+ }
+ }
+ }
+
+ private fun assertRootType(expectedType: OrderRootType, jarDirectory: Boolean, content: DirectoryContentBuilder.() -> Unit) {
+ val dir = directoryContent(content).generateInVirtualTempDir()
+ val detector = LibraryRootsDetectorImpl(DefaultLibraryRootsComponentDescriptor().rootDetectors)
+ val root = assertOneElement(dir.children.flatMap { file ->
+ val rootFile = if (file.fileType == StdFileTypes.ARCHIVE) JarFileSystem.getInstance().getJarRootForLocalFile(file)!! else file
+ detector.detectRoots(rootFile, EmptyProgressIndicator())
+ })
+ val type = assertOneElement(root.types)
+ assertEquals(expectedType, type.type)
+ assertEquals(jarDirectory, type.isJarDirectory)
+ }
+}
\ No newline at end of file
diff --git a/java/idea-ui/testSrc/com/intellij/openapi/roots/ui/configuration/projectRoot/ConvertToRepositoryLibraryActionTest.kt b/java/idea-ui/testSrc/com/intellij/openapi/roots/ui/configuration/projectRoot/ConvertToRepositoryLibraryActionTest.kt
index ce0c11d024f8..0b5fafbabed6 100644
--- a/java/idea-ui/testSrc/com/intellij/openapi/roots/ui/configuration/projectRoot/ConvertToRepositoryLibraryActionTest.kt
+++ b/java/idea-ui/testSrc/com/intellij/openapi/roots/ui/configuration/projectRoot/ConvertToRepositoryLibraryActionTest.kt
@@ -15,18 +15,72 @@
*/
package com.intellij.openapi.roots.ui.configuration.projectRoot
-import com.intellij.project.IntelliJProjectConfiguration
+import com.intellij.openapi.vfs.JarFileSystem
import com.intellij.testFramework.LightPlatformTestCase
+import com.intellij.util.io.directoryContent
+import com.intellij.util.io.generateInVirtualTempDir
/**
* @author nik
*/
class ConvertToRepositoryLibraryActionTest : LightPlatformTestCase() {
- fun `test read Maven coordinates`() {
- val file = IntelliJProjectConfiguration.getJarFromSingleJarProjectLibrary("commons-codec")
- val coordinates = assertOneElement(ConvertToRepositoryLibraryActionBase.detectMavenCoordinates(arrayOf(file!!)))
- assertEquals("commons-codec", coordinates.groupId)
- assertEquals("commons-codec", coordinates.artifactId)
- assertEquals("1.9", coordinates.version)
+ fun `test detect single coordinates`() {
+ val file = directoryContent {
+ zip("library.jar") {
+ dir("META-INF") {
+ dir("maven") {
+ dir("myGroupId") {
+ dir("myArtifactId") {
+ file("pom.properties", """
+ |version=1.0
+ |groupId=myGroupId
+ |artifactId=myArtifactId
+ """.trimMargin())
+ }
+ }
+ }
+ }
+ }
+ }.generateInVirtualTempDir().findChild("library.jar")!!
+ val jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(file)!!
+ val coordinates = assertOneElement(ConvertToRepositoryLibraryActionBase.detectMavenCoordinates(arrayOf(jarRoot)))
+ assertEquals("myGroupId", coordinates.groupId)
+ assertEquals("myArtifactId", coordinates.artifactId)
+ assertEquals("1.0", coordinates.version)
+ }
+
+ fun `test detect multiple coordinates`() {
+ val file = directoryContent {
+ zip("library2.jar") {
+ dir("META-INF") {
+ dir("maven") {
+ dir("myGroupId") {
+ dir("myArtifactId1") {
+ file("pom.properties", """
+ |version=1.0
+ |groupId=myGroupId
+ |artifactId=myArtifactId1
+ """.trimMargin())
+ }
+ dir("myArtifactId2") {
+ file("pom.properties", """
+ |version=1.0
+ |groupId=myGroupId
+ |artifactId=myArtifactId2
+ """.trimMargin())
+ }
+ }
+ }
+ }
+ }
+ }.generateInVirtualTempDir().findChild("library2.jar")!!
+ val jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(file)!!
+ val (coordinates1, coordinates2) = ConvertToRepositoryLibraryActionBase.detectMavenCoordinates(arrayOf(jarRoot)).sortedBy { it.artifactId }
+ assertEquals("myGroupId", coordinates1.groupId)
+ assertEquals("myArtifactId1", coordinates1.artifactId)
+ assertEquals("1.0", coordinates1.version)
+ assertEquals("myGroupId", coordinates2.groupId)
+ assertEquals("myArtifactId2", coordinates2.artifactId)
+ assertEquals("1.0", coordinates2.version)
}
}
\ No newline at end of file
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/JavaSoftKeywordHighlighting.kt b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/JavaSoftKeywordHighlighting.kt
index de77df2d9d58..171cff8d2934 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/JavaSoftKeywordHighlighting.kt
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/JavaSoftKeywordHighlighting.kt
@@ -35,7 +35,9 @@ class JavaSoftKeywordHighlightingPassFactory(project: Project, registrar: TextEd
}
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? {
- val visit = file is PsiJavaFile && file.name == PsiJavaModule.MODULE_INFO_FILE && file.languageLevel.isAtLeast(LanguageLevel.JDK_1_9)
+ val visit = file is PsiJavaFile &&
+ (file.name == PsiJavaModule.MODULE_INFO_FILE && file.languageLevel.isAtLeast(LanguageLevel.JDK_1_9) ||
+ file.languageLevel.isAtLeast(LanguageLevel.JDK_X))
return if (visit) JavaSoftKeywordHighlightingPass(file as PsiJavaFile, editor.document) else null
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/UnusedSymbolUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/UnusedSymbolUtil.java
index 376c4dd0db22..1a8b181e3cdd 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/UnusedSymbolUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/UnusedSymbolUtil.java
@@ -34,6 +34,7 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiSearchHelper;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
@@ -232,7 +233,7 @@ public class UnusedSymbolUtil {
}
if (member instanceof PsiMethod) {
- String propertyName = PropertyUtil.getPropertyName(member);
+ String propertyName = PropertyUtilBase.getPropertyName(member);
if (propertyName != null) {
SearchScope fileScope = containingFile.getUseScope();
if (fileScope instanceof GlobalSearchScope &&
@@ -286,7 +287,7 @@ public class UnusedSymbolUtil {
if (!(containingFile instanceof PsiJavaFile)) return true; // Groovy field can be referenced from Java by getter
if (member instanceof PsiField) return false; //Java field cannot be referenced by anything but its name
if (member instanceof PsiMethod) {
- return PropertyUtil.isSimplePropertyAccessor((PsiMethod)member); //Java accessors can be referenced by field name from Groovy
+ return PropertyUtilBase.isSimplePropertyAccessor((PsiMethod)member); //Java accessors can be referenced by field name from Groovy
}
return false;
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ErrorFixExtensionPoint.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ErrorFixExtensionPoint.java
index 4ff7f77570b1..f1f3aa129676 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ErrorFixExtensionPoint.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ErrorFixExtensionPoint.java
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.extensions.AbstractExtensionPointBean;
import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.psi.PsiElement;
import com.intellij.util.xmlb.annotations.Attribute;
import one.util.streamex.StreamEx;
@@ -48,7 +49,13 @@ public class ErrorFixExtensionPoint extends AbstractExtensionPointBean {
try {
return findClass(implementationClass).asSubclass(IntentionAction.class).getConstructor(PsiElement.class).newInstance(context);
}
- catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | ClassNotFoundException e) {
+ catch (InvocationTargetException e) {
+ if(e.getCause() instanceof ProcessCanceledException) {
+ throw ((ProcessCanceledException)e.getCause());
+ }
+ throw new RuntimeException("Error instantiating quick-fix " + implementationClass + " (error code: " + errorCode + ")", e.getCause());
+ }
+ catch (InstantiationException | IllegalAccessException | NoSuchMethodException | ClassNotFoundException e) {
throw new RuntimeException("Error instantiating quick-fix " + implementationClass + " (error code: " + errorCode + ")", e);
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
index 7a4ead47e763..5e10a8ee9915 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
@@ -3063,7 +3063,7 @@ public class HighlightUtil extends HighlightUtilBase {
final PsiClass containingClass = psiField.getContainingClass();
if (containingClass != null) {
if (PsiUtil.isOnAssignmentLeftHand((PsiExpression)place)) {
- final PsiMethod setterPrototype = PropertyUtil.generateSetterPrototype(psiField);
+ final PsiMethod setterPrototype = PropertyUtilBase.generateSetterPrototype(psiField);
final PsiMethod setter = containingClass.findMethodBySignature(setterPrototype, true);
if (setter != null && PsiUtil.isAccessible(setter, place, accessObjectClass)) {
final PsiElement element = PsiTreeUtil.skipParentsOfType(place, PsiParenthesizedExpression.class);
@@ -3073,7 +3073,7 @@ public class HighlightUtil extends HighlightUtilBase {
}
}
else if (PsiUtil.isAccessedForReading((PsiExpression)place)) {
- final PsiMethod getterPrototype = PropertyUtil.generateGetterPrototype(psiField);
+ final PsiMethod getterPrototype = PropertyUtilBase.generateGetterPrototype(psiField);
final PsiMethod getter = containingClass.findMethodBySignature(getterPrototype, true);
if (getter != null && PsiUtil.isAccessible(getter, place, accessObjectClass)) {
QuickFixAction.registerQuickFixAction(error, QUICK_FIX_FACTORY.createReplaceInaccessibleFieldWithGetterSetterFix(place, getter, false));
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/PostHighlightingVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/PostHighlightingVisitor.java
index d9a9a2340f9b..3876037ffa46 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/PostHighlightingVisitor.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/PostHighlightingVisitor.java
@@ -50,10 +50,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.impl.PsiClassImplUtil;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.psi.search.searches.SuperMethodsSearch;
-import com.intellij.psi.util.PropertyUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.psi.util.*;
import com.intellij.util.VisibilityUtil;
import com.intellij.util.containers.ConcurrentFactoryMap;
import com.intellij.codeInspection.unusedImport.UnusedImportInspection;
@@ -227,7 +224,7 @@ class PostHighlightingVisitor {
}
}
if (parent instanceof PsiMethod) {
- if (myUnusedSymbolInspection.isIgnoreAccessors() && PropertyUtil.isSimplePropertyAccessor((PsiMethod)parent)) {
+ if (myUnusedSymbolInspection.isIgnoreAccessors() && PropertyUtilBase.isSimplePropertyAccessor((PsiMethod)parent)) {
return null;
}
if (compareVisibilities((PsiModifierListOwner)parent, myUnusedSymbolInspection.getMethodVisibility())) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/CFGBuilder.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/CFGBuilder.java
index 6ff54eb7b78b..e39753cd7866 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/CFGBuilder.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/CFGBuilder.java
@@ -568,8 +568,33 @@ public class CFGBuilder {
}
}
+ /**
+ * Inlines given lambda. Lambda parameters are assumed to be assigned already (if necessary).
+ *
+ * Stack before: ...
+ *
+ * Stack after: ... lambdaResult
+ *
+ * @param lambda lambda to inline
+ * @param resultNullness a required return value nullness
+ * @return this builder
+ */
public CFGBuilder inlineLambda(PsiLambdaExpression lambda, Nullness resultNullness) {
- myAnalyzer.inlineLambda(lambda, resultNullness);
+ PsiElement body = lambda.getBody();
+ PsiExpression expression = LambdaUtil.extractSingleExpressionFromBody(body);
+ if (expression != null) {
+ pushExpression(expression);
+ boxUnbox(expression, LambdaUtil.getFunctionalInterfaceReturnType(lambda));
+ if(resultNullness == Nullness.NOT_NULL) {
+ checkNotNull(expression, NullabilityProblem.nullableFunctionReturn);
+ }
+ } else if(body instanceof PsiCodeBlock) {
+ PsiVariable variable = createTempVariable(LambdaUtil.getFunctionalInterfaceReturnType(lambda));
+ myAnalyzer.inlineBlock((PsiCodeBlock)body, resultNullness, variable);
+ push(getFactory().getVarFactory().createVariableValue(variable, false));
+ } else {
+ pushUnknown();
+ }
return this;
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
index 288a39f330f7..276a0482e5a7 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
@@ -63,8 +63,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
private final ExceptionTransfer myRuntimeException;
private final ExceptionTransfer myError;
private final PsiType myAssertionError;
- private PsiLambdaExpression myLambdaExpression = null;
- private boolean myForceNotNullLambdaResult = false;
+ private InlinedBlockContext myInlinedBlockContext;
ControlFlowAnalyzer(final DfaValueFactory valueFactory, @NotNull PsiElement codeFragment, boolean ignoreAssertions, boolean inlining) {
myInlining = inlining;
@@ -685,34 +684,42 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
startElement(statement);
PsiExpression returnValue = statement.getReturnValue();
- if (returnValue != null) {
- returnValue.accept(this);
- PsiMethod method = PsiTreeUtil.getParentOfType(statement, PsiMethod.class, true, PsiMember.class, PsiLambdaExpression.class);
- if (method != null) {
- generateBoxingUnboxingInstructionFor(returnValue, method.getReturnType());
- }
- else {
- final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(statement, PsiLambdaExpression.class, true, PsiMember.class);
- if (lambdaExpression != null) {
- generateBoxingUnboxingInstructionFor(returnValue, LambdaUtil.getFunctionalInterfaceReturnType(lambdaExpression));
- }
- }
- }
- if (myLambdaExpression == null) {
+ if (myInlinedBlockContext != null) {
if (returnValue != null) {
+ DfaVariableValue var = myFactory.getVarFactory().createVariableValue(myInlinedBlockContext.myTarget, false);
+ addInstruction(new PushInstruction(var, null, true));
+ returnValue.accept(this);
+ generateBoxingUnboxingInstructionFor(returnValue, var.getVariableType());
+ if (myInlinedBlockContext.myForceNonNullBlockResult) {
+ addInstruction(new CheckNotNullInstruction(returnValue, NullabilityProblem.nullableFunctionReturn));
+ }
+ addInstruction(new AssignInstruction(returnValue, null));
+ addInstruction(new PopInstruction());
+ }
+
+ controlTransfer(new InstructionTransfer(getEndOffset(myInlinedBlockContext.myCodeBlock), getVariablesInside(
+ myInlinedBlockContext.myCodeBlock)), myTrapStack);
+ } else {
+
+ if (returnValue != null) {
+ returnValue.accept(this);
+ PsiMethod method = PsiTreeUtil.getParentOfType(statement, PsiMethod.class, true, PsiMember.class, PsiLambdaExpression.class);
+ if (method != null) {
+ generateBoxingUnboxingInstructionFor(returnValue, method.getReturnType());
+ }
+ else {
+ final PsiLambdaExpression lambdaExpression =
+ PsiTreeUtil.getParentOfType(statement, PsiLambdaExpression.class, true, PsiMember.class);
+ if (lambdaExpression != null) {
+ generateBoxingUnboxingInstructionFor(returnValue, LambdaUtil.getFunctionalInterfaceReturnType(lambdaExpression));
+ }
+ }
addInstruction(new CheckReturnValueInstruction(returnValue));
}
+
addInstruction(new ReturnInstruction(myFactory.controlTransfer(ReturnTransfer.INSTANCE, myTrapStack), statement));
}
- else {
- if (returnValue == null) {
- pushUnknown();
- } else if (myForceNotNullLambdaResult) {
- addInstruction(new CheckNotNullInstruction(returnValue, NullabilityProblem.nullableFunctionReturn));
- }
- controlTransfer(new InstructionTransfer(getEndOffset(myLambdaExpression), getVariablesInside(myLambdaExpression)), myTrapStack);
- }
finishElement(statement);
}
@@ -1765,34 +1772,41 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
@Override public void visitClass(PsiClass aClass) {
}
- void inlineLambda(PsiLambdaExpression lambda, Nullness resultNullness) {
- PsiLambdaExpression oldLambda = myLambdaExpression;
- boolean oldForceNotNullLambdaResult = myForceNotNullLambdaResult;
+ /**
+ * Inline code block (lambda or method body) into this CFG. Incoming parameters are assumed to be handled already (if necessary)
+ *
+ * @param block block to inline
+ * @param resultNullness desired nullness returned by block return statement
+ * @param target a variable to store the block result (returned via {@code return} statement)
+ */
+ void inlineBlock(@NotNull PsiCodeBlock block, @NotNull Nullness resultNullness, @NotNull PsiVariable target) {
+ InlinedBlockContext oldBlock = myInlinedBlockContext;
// Transfer value is pushed to avoid emptying stack beyond this point
addInstruction(new PushInstruction(myFactory.controlTransfer(ReturnTransfer.INSTANCE, this.myTrapStack), null));
- myLambdaExpression = lambda;
- myForceNotNullLambdaResult = resultNullness == Nullness.NOT_NULL;
- startElement(lambda);
+ myInlinedBlockContext = new InlinedBlockContext(block, resultNullness == Nullness.NOT_NULL, target);
+ startElement(block);
try {
- PsiElement body = lambda.getBody();
- Objects.requireNonNull(body).accept(this);
- if (body instanceof PsiCodeBlock) {
- // return value for void or incomplete lambda
- pushUnknown();
- }
- else if (body instanceof PsiExpression) {
- generateBoxingUnboxingInstructionFor((PsiExpression)body, LambdaUtil.getFunctionalInterfaceReturnType(lambda));
- if (myForceNotNullLambdaResult) {
- addInstruction(new CheckNotNullInstruction((PsiExpression)body, NullabilityProblem.nullableFunctionReturn));
- }
- }
+ block.accept(this);
+ // return value for void or incomplete block
+ pushUnknown();
}
finally {
- finishElement(lambda);
- myLambdaExpression = oldLambda;
- myForceNotNullLambdaResult = oldForceNotNullLambdaResult;
- // Pop transfer value (which is second value in stack now)
- addInstruction(new SpliceInstruction(2, 0));
+ finishElement(block);
+ myInlinedBlockContext = oldBlock;
+ // Pop transfer value
+ addInstruction(new PopInstruction());
+ }
+ }
+
+ public static class InlinedBlockContext {
+ final PsiCodeBlock myCodeBlock;
+ final boolean myForceNonNullBlockResult;
+ final PsiVariable myTarget;
+
+ public InlinedBlockContext(PsiCodeBlock codeBlock, boolean forceNonNullBlockResult, PsiVariable target) {
+ myCodeBlock = codeBlock;
+ myForceNonNullBlockResult = forceNonNullBlockResult;
+ myTarget = target;
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaFactType.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaFactType.java
index c0a686327d6e..5d3b62aae1a0 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaFactType.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaFactType.java
@@ -133,6 +133,48 @@ public abstract class DfaFactType extends Key {
return fact.toString();
}
};
+ /**
+ * This fact represents a set of possible types of this value
+ * {@link TypeConstraint#EMPTY} value is equivalent to absent fact (not constrained)
+ */
+ public static final DfaFactType TYPE_CONSTRAINT = new DfaFactType("Type") {
+ @Nullable
+ @Override
+ TypeConstraint fromDfaValue(DfaValue value) {
+ if(value instanceof DfaTypeValue) {
+ TypeConstraint constraint = TypeConstraint.EMPTY.withInstanceofValue((DfaTypeValue)value);
+ return constraint == null || constraint.isEmpty() ? null : constraint;
+ }
+ return null;
+ }
+
+ @Override
+ boolean isSuper(@Nullable TypeConstraint superFact, @Nullable TypeConstraint subFact) {
+ return superFact == null || (subFact != null && superFact.isSuperStateOf(subFact));
+ }
+
+ @Nullable
+ @Override
+ TypeConstraint intersectFacts(@NotNull TypeConstraint left, @NotNull TypeConstraint right) {
+ for (DfaPsiType type : right.getInstanceofValues()) {
+ left = left.withInstanceofValue(type);
+ if (left == null) return null;
+ }
+ for (DfaPsiType type : right.getNotInstanceofValues()) {
+ left = left.withNotInstanceofValue(type);
+ if (left == null) return null;
+ }
+ return left;
+ }
+
+ @Nullable
+ @Override
+ TypeConstraint unionFacts(@NotNull TypeConstraint left, @NotNull TypeConstraint right) {
+ if(left.isSuperStateOf(right)) return left;
+ if(right.isSuperStateOf(left)) return right;
+ return null;
+ }
+ };
private DfaFactType(String name) {
super("DfaFactType: " + name);
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
index e59cf69e61d6..f8d8ef30ed02 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
@@ -19,7 +19,6 @@ import com.intellij.codeInspection.dataFlow.value.DfaConstValue;
import com.intellij.codeInspection.dataFlow.value.DfaRelationValue;
import com.intellij.codeInspection.dataFlow.value.DfaValue;
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
-import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -56,13 +55,6 @@ public interface DfaMemoryState {
@Nullable
T getValueFact(@NotNull DfaFactType factType, @NotNull DfaValue value);
- /**
- * @param value to determine its type
- * @return value type at this state if known (possibly erased)
- */
- @Nullable
- PsiType getValueType(DfaValue value);
-
void flushFields();
void flushVariable(DfaVariableValue variable);
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
index 3ea7c590c4df..ad60aab3cfff 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
@@ -1068,23 +1068,6 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
return factType.fromDfaValue(value);
}
- @Nullable
- @Override
- public PsiType getValueType(DfaValue value) {
- if (value instanceof DfaTypeValue) {
- return ((DfaTypeValue)value).getDfaType().getPsiType();
- }
- if (value instanceof DfaVariableValue) {
- DfaVariableState state = getVariableState((DfaVariableValue)value);
- Set values = state.getInstanceofValues();
- if (!values.isEmpty()) {
- return values.iterator().next().getPsiType();
- }
- return ((DfaVariableValue)value).getVariableType();
- }
- return null;
- }
-
@NotNull
private DfaValue resolveVariableValue(DfaVariableValue var) {
DfaConstValue constValue = getConstantValue(var);
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java
index a73f2330c532..aa565fb491f7 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java
@@ -20,117 +20,49 @@ import com.intellij.codeInspection.dataFlow.value.DfaPsiType;
import com.intellij.codeInspection.dataFlow.value.DfaTypeValue;
import com.intellij.codeInspection.dataFlow.value.DfaValue;
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiPrimitiveType;
-import com.intellij.util.containers.ContainerUtil;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.*;
+import java.util.Objects;
class DfaVariableState {
- @NotNull final Set myInstanceofValues;
- @NotNull final Set myNotInstanceofValues;
@NotNull final DfaFactMap myFactMap;
private final int myHash;
DfaVariableState(@NotNull DfaVariableValue dfaVar) {
- this(Collections.emptySet(), Collections.emptySet(), dfaVar.getInherentFacts());
+ this(dfaVar.getInherentFacts());
}
public boolean isSuperStateOf(DfaVariableState that) {
- if(!that.myNotInstanceofValues.containsAll(myNotInstanceofValues)) return false;
- if(!that.myInstanceofValues.containsAll(myInstanceofValues)) return false;
return myFactMap.isSuperStateOf(that.myFactMap);
}
- DfaVariableState(@NotNull Set instanceofValues,
- @NotNull Set notInstanceofValues,
- @NotNull DfaFactMap factMap) {
- myInstanceofValues = instanceofValues;
- myNotInstanceofValues = notInstanceofValues;
+ DfaVariableState(@NotNull DfaFactMap factMap) {
myFactMap = factMap;
- myHash = Objects.hash(myInstanceofValues, myNotInstanceofValues, myFactMap);
- }
-
- private boolean checkInstanceofValue(@NotNull DfaPsiType dfaType) {
- if (myInstanceofValues.contains(dfaType)) return true;
-
- for (DfaPsiType dfaTypeValue : myNotInstanceofValues) {
- if (dfaTypeValue.isAssignableFrom(dfaType)) return false;
- }
-
- for (DfaPsiType dfaTypeValue : myInstanceofValues) {
- if (!dfaType.isConvertibleFrom(dfaTypeValue)) return false;
- }
-
- return true;
+ myHash = myFactMap.hashCode();
}
@Nullable
DfaVariableState withInstanceofValue(@NotNull DfaTypeValue dfaType) {
if (dfaType.getDfaType().getPsiType() instanceof PsiPrimitiveType) return this;
-
- if (checkInstanceofValue(dfaType.getDfaType())) {
- DfaVariableState result = dfaType.isNullable() ? withFact(DfaFactType.CAN_BE_NULL, true) : this;
- List moreGeneric = ContainerUtil.newArrayList();
- for (DfaPsiType alreadyInstanceof : myInstanceofValues) {
- if (dfaType.getDfaType().isAssignableFrom(alreadyInstanceof)) {
- return result;
- }
- if (alreadyInstanceof.isAssignableFrom(dfaType.getDfaType())) {
- moreGeneric.add(alreadyInstanceof);
- }
- }
-
- HashSet newInstanceof = ContainerUtil.newHashSet(myInstanceofValues);
- newInstanceof.removeAll(moreGeneric);
- newInstanceof.add(dfaType.getDfaType());
- result = createCopy(newInstanceof, myNotInstanceofValues, result.myFactMap);
- return result;
- }
-
- return null;
+ TypeConstraint typeConstraint = getTypeConstraint();
+ TypeConstraint newTypeConstraint = typeConstraint.withInstanceofValue(dfaType);
+ if (newTypeConstraint == null) return null;
+ DfaVariableState result = dfaType.isNullable() ? withFact(DfaFactType.CAN_BE_NULL, true) : this;
+ return result.withFact(DfaFactType.TYPE_CONSTRAINT, newTypeConstraint);
}
@Nullable
DfaVariableState withNotInstanceofValue(@NotNull DfaTypeValue dfaType) {
- if (myNotInstanceofValues.contains(dfaType.getDfaType())) return this;
-
- for (DfaPsiType dfaTypeValue : myInstanceofValues) {
- if (dfaType.getDfaType().isAssignableFrom(dfaTypeValue)) return null;
- }
-
- List moreSpecific = ContainerUtil.newArrayList();
- for (DfaPsiType alreadyNotInstanceof : myNotInstanceofValues) {
- if (alreadyNotInstanceof.isAssignableFrom(dfaType.getDfaType())) {
- return this;
- }
- if (dfaType.getDfaType().isAssignableFrom(alreadyNotInstanceof)) {
- moreSpecific.add(alreadyNotInstanceof);
- }
- }
-
- HashSet newNotInstanceof = ContainerUtil.newHashSet(myNotInstanceofValues);
- newNotInstanceof.removeAll(moreSpecific);
- newNotInstanceof.add(dfaType.getDfaType());
- return createCopy(myInstanceofValues, newNotInstanceof, myFactMap);
+ TypeConstraint typeConstraint = getTypeConstraint();
+ TypeConstraint newTypeConstraint = typeConstraint.withNotInstanceofValue(dfaType);
+ return newTypeConstraint == null ? null : withFact(DfaFactType.TYPE_CONSTRAINT, newTypeConstraint);
}
@NotNull
DfaVariableState withoutType(@NotNull DfaPsiType type) {
- if (myInstanceofValues.contains(type)) {
- HashSet newInstanceof = ContainerUtil.newHashSet(myInstanceofValues);
- newInstanceof.remove(type);
- return createCopy(newInstanceof, myNotInstanceofValues, myFactMap);
- }
- if (myNotInstanceofValues.contains(type)) {
- HashSet newNotInstanceof = ContainerUtil.newHashSet(myNotInstanceofValues);
- newNotInstanceof.remove(type);
- return createCopy(myInstanceofValues, newNotInstanceof, myFactMap);
- }
- return this;
+ return withFact(DfaFactType.TYPE_CONSTRAINT, getTypeConstraint().withoutType(type));
}
public int hashCode() {
@@ -141,35 +73,16 @@ class DfaVariableState {
if (obj == this) return true;
if (!(obj instanceof DfaVariableState)) return false;
DfaVariableState aState = (DfaVariableState) obj;
- return myHash == aState.myHash &&
- myInstanceofValues.equals(aState.myInstanceofValues) &&
- myNotInstanceofValues.equals(aState.myNotInstanceofValues) &&
- Objects.equals(myFactMap, aState.myFactMap);
+ return myHash == aState.myHash && Objects.equals(myFactMap, aState.myFactMap);
}
@NotNull
- protected DfaVariableState createCopy(@NotNull Set instanceofValues,
- @NotNull Set notInstanceofValues,
- @NotNull DfaFactMap factMap) {
- return new DfaVariableState(instanceofValues, notInstanceofValues, factMap);
+ protected DfaVariableState createCopy(@NotNull DfaFactMap factMap) {
+ return new DfaVariableState(factMap);
}
public String toString() {
- @NonNls StringBuilder buf = new StringBuilder("State:");
-
- if (!myInstanceofValues.isEmpty()) {
- buf.append(" instanceof ").append(StringUtil.join(myInstanceofValues, ","));
- }
-
- if (!myNotInstanceofValues.isEmpty()) {
- buf.append(" not instanceof ").append(StringUtil.join(myNotInstanceofValues, ","));
- }
-
- String factString = myFactMap.toString();
- if(!factString.isEmpty()) {
- buf.append(" ").append(factString);
- }
- return buf.toString();
+ return "State: " + myFactMap;
}
@NotNull
@@ -189,7 +102,7 @@ class DfaVariableState {
@NotNull
DfaVariableState withFact(DfaFactType type, T value) {
DfaFactMap factMap = myFactMap.with(type, value);
- return myFactMap.equals(factMap) ? this : createCopy(myInstanceofValues, myNotInstanceofValues, factMap);
+ return myFactMap.equals(factMap) ? this : createCopy(factMap);
}
DfaVariableState withoutFact(DfaFactType type) {
@@ -199,9 +112,7 @@ class DfaVariableState {
@Nullable
DfaVariableState intersectFact(DfaFactType type, T value) {
DfaFactMap factMap = myFactMap.intersect(type, value);
- return factMap == null
- ? null
- : myFactMap.equals(factMap) ? this : createCopy(myInstanceofValues, myNotInstanceofValues, factMap);
+ return factMap == null ? null : myFactMap.equals(factMap) ? this : createCopy(factMap);
}
@NotNull
@@ -215,13 +126,9 @@ class DfaVariableState {
}
@NotNull
- public Set getInstanceofValues() {
- return myInstanceofValues;
- }
-
- @NotNull
- public Set getNotInstanceofValues() {
- return myNotInstanceofValues;
+ public TypeConstraint getTypeConstraint() {
+ TypeConstraint fact = getFact(DfaFactType.TYPE_CONSTRAINT);
+ return fact == null ? TypeConstraint.EMPTY : fact;
}
@Nullable
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullParameterConstraintChecker.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullParameterConstraintChecker.java
index 5c11c64277d5..7cb6b67b7753 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullParameterConstraintChecker.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullParameterConstraintChecker.java
@@ -33,7 +33,6 @@ import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
-import java.util.Collections;
import java.util.Set;
/**
@@ -138,8 +137,7 @@ class NullParameterConstraintChecker extends DataFlowRunner {
super(factory);
for (PsiParameter parameter : myPossiblyViolatedParameters) {
setVariableState(getFactory().getVarFactory().createVariableValue(parameter, false),
- new DfaVariableState(Collections.emptySet(), Collections.emptySet(),
- DfaFactMap.EMPTY.with(DfaFactType.CAN_BE_NULL, true)));
+ new DfaVariableState(DfaFactMap.EMPTY.with(DfaFactType.CAN_BE_NULL, true)));
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
index 957a3dc01807..f925ad9a9c88 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
@@ -23,6 +23,7 @@ import com.intellij.codeInspection.dataFlow.value.DfaRelationValue.RelationType;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
+import com.intellij.psi.impl.search.JavaOverridingMethodsSearcher;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
@@ -477,6 +478,26 @@ public class StandardInstructionVisitor extends InstructionVisitor {
}
}
+ @NotNull
+ private static PsiMethod findSpecificMethod(@NotNull PsiMethod method, @NotNull DfaMemoryState state, @Nullable DfaValue qualifier) {
+ if (qualifier == null || !PsiUtil.canBeOverridden(method)) {
+ return method;
+ }
+ TypeConstraint constraint = state.getValueFact(DfaFactType.TYPE_CONSTRAINT, qualifier);
+ PsiClass specificQualifierClass = PsiUtil.resolveClassInClassTypeOnly(constraint == null ? null : constraint.getPsiType());
+ PsiClass qualifierClass = method.getContainingClass();
+ if (specificQualifierClass != null && qualifierClass != null &&
+ !specificQualifierClass.equals(qualifierClass) &&
+ InheritanceUtil.isInheritorOrSelf(specificQualifierClass, qualifierClass, true)) {
+ PsiMethod realMethod =
+ JavaOverridingMethodsSearcher.findOverridingMethod(method.getProject(), specificQualifierClass, method, qualifierClass);
+ if (realMethod != null) {
+ return realMethod;
+ }
+ }
+ return method;
+ }
+
@NotNull
private static DfaValue getMethodResultValue(MethodCallInstruction instruction,
@Nullable DfaValue qualifierValue,
@@ -520,19 +541,13 @@ public class StandardInstructionVisitor extends InstructionVisitor {
Nullness nullability = instruction.getReturnNullability();
PsiMethod targetMethod = instruction.getTargetMethod();
if (targetMethod != null) {
- PsiClass specificQualifierClass = PsiUtil.resolveClassInClassTypeOnly(state.getValueType(qualifierValue));
- PsiClass qualifierClass = targetMethod.getContainingClass();
- if (specificQualifierClass != null && qualifierClass != null &&
- !specificQualifierClass.equals(qualifierClass) &&
- InheritanceUtil.isInheritorOrSelf(specificQualifierClass, qualifierClass, true)) {
- PsiMethod realMethod = specificQualifierClass.findMethodBySignature(targetMethod, true);
- if (realMethod != null && realMethod != targetMethod) {
- nullability = DfaPsiUtil.getElementNullability(type, realMethod);
- PsiType returnType = realMethod.getReturnType();
- if(returnType != null && TypeConversionUtil.erasure(type).isAssignableFrom(returnType)) {
- // possibly covariant return type
- type = returnType;
- }
+ PsiMethod realMethod = findSpecificMethod(targetMethod, state, qualifierValue);
+ if (realMethod != targetMethod) {
+ nullability = DfaPsiUtil.getElementNullability(type, realMethod);
+ PsiType returnType = realMethod.getReturnType();
+ if (returnType != null && TypeConversionUtil.erasure(type).isAssignableFrom(returnType)) {
+ // possibly covariant return type
+ type = returnType;
}
}
if (nullability == Nullness.UNKNOWN) {
@@ -700,7 +715,7 @@ public class StandardInstructionVisitor extends InstructionVisitor {
return checkComparisonWithKnownValue(instruction, runner, memState, relationType, leftValue, rightValue);
}
}
-
+
if (dfaRight instanceof DfaConstValue && dfaLeft instanceof DfaVariableValue) {
Object value = ((DfaConstValue)dfaRight).getValue();
if (value instanceof Number) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java
index b0f7d6172c4e..99ab239dccb3 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java
@@ -430,10 +430,11 @@ class StateMerger {
for (Map.Entry entry : states.entrySet()) {
DfaVariableValue var = entry.getKey();
DfaVariableState variableState = entry.getValue();
- for (DfaPsiType type : variableState.getInstanceofValues()) {
+ TypeConstraint typeConstraint = variableState.getTypeConstraint();
+ for (DfaPsiType type : typeConstraint.getInstanceofValues()) {
result.add(new InstanceofFact(var, true, type));
}
- for (DfaPsiType type : variableState.getNotInstanceofValues()) {
+ for (DfaPsiType type : typeConstraint.getNotInstanceofValues()) {
result.add(new InstanceofFact(var, false, type));
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TypeConstraint.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TypeConstraint.java
new file mode 100644
index 000000000000..363785b1c3ee
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TypeConstraint.java
@@ -0,0 +1,201 @@
+/*
+ * 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.
+ */
+package com.intellij.codeInspection.dataFlow;
+
+import com.intellij.codeInspection.dataFlow.value.DfaPsiType;
+import com.intellij.codeInspection.dataFlow.value.DfaTypeValue;
+import com.intellij.psi.PsiPrimitiveType;
+import com.intellij.psi.PsiType;
+import com.intellij.util.containers.ContainerUtil;
+import one.util.streamex.EntryStream;
+import one.util.streamex.StreamEx;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * Immutable class representing a number of non-primitive type constraints applied to some value.
+ * There are two types of constrains: value is instance of some type and value is not an instance of some type.
+ */
+public final class TypeConstraint {
+ /**
+ * An instance representing no constraints
+ */
+ public static final TypeConstraint EMPTY = new TypeConstraint(Collections.emptySet(), Collections.emptySet());
+
+ @NotNull private final Set myInstanceofValues;
+ @NotNull private final Set myNotInstanceofValues;
+
+ private TypeConstraint(@NotNull Set instanceofValues, @NotNull Set notInstanceofValues) {
+ myInstanceofValues = instanceofValues;
+ myNotInstanceofValues = notInstanceofValues;
+ }
+
+ private static TypeConstraint create(@NotNull Set instanceofValues, @NotNull Set notInstanceofValues) {
+ if (instanceofValues.isEmpty() && notInstanceofValues.isEmpty()) {
+ return EMPTY;
+ }
+ if (instanceofValues.isEmpty()) {
+ instanceofValues = Collections.emptySet();
+ }
+ else if (instanceofValues.size() == 1) {
+ instanceofValues = Collections.singleton(instanceofValues.iterator().next());
+ }
+ if (notInstanceofValues.isEmpty()) {
+ notInstanceofValues = Collections.emptySet();
+ }
+ else if (notInstanceofValues.size() == 1) {
+ notInstanceofValues = Collections.singleton(notInstanceofValues.iterator().next());
+ }
+ return new TypeConstraint(instanceofValues, notInstanceofValues);
+ }
+
+ boolean checkInstanceofValue(@NotNull DfaPsiType dfaType) {
+ if (myInstanceofValues.contains(dfaType)) return true;
+
+ for (DfaPsiType dfaTypeValue : myNotInstanceofValues) {
+ if (dfaTypeValue.isAssignableFrom(dfaType)) return false;
+ }
+
+ for (DfaPsiType dfaTypeValue : myInstanceofValues) {
+ if (!dfaType.isConvertibleFrom(dfaTypeValue)) return false;
+ }
+
+ return true;
+ }
+
+ @Nullable
+ TypeConstraint withInstanceofValue(@NotNull DfaTypeValue dfaType) {
+ return withInstanceofValue(dfaType.getDfaType());
+ }
+
+ @Nullable
+ TypeConstraint withInstanceofValue(@NotNull DfaPsiType type) {
+ if (type.getPsiType() instanceof PsiPrimitiveType) return this;
+
+ if (!checkInstanceofValue(type)) {
+ return null;
+ }
+ List moreGeneric = new ArrayList<>();
+ for (DfaPsiType alreadyInstanceof : myInstanceofValues) {
+ if (type.isAssignableFrom(alreadyInstanceof)) {
+ return this;
+ }
+ if (alreadyInstanceof.isAssignableFrom(type)) {
+ moreGeneric.add(alreadyInstanceof);
+ }
+ }
+
+ Set newInstanceof = ContainerUtil.newHashSet(myInstanceofValues);
+ newInstanceof.removeAll(moreGeneric);
+ newInstanceof.add(type);
+ return create(newInstanceof, myNotInstanceofValues);
+ }
+
+ @Nullable
+ TypeConstraint withNotInstanceofValue(@NotNull DfaTypeValue dfaType) {
+ return withNotInstanceofValue(dfaType.getDfaType());
+ }
+
+ @Nullable
+ TypeConstraint withNotInstanceofValue(DfaPsiType type) {
+ if (myNotInstanceofValues.contains(type)) return this;
+
+ for (DfaPsiType dfaTypeValue : myInstanceofValues) {
+ if (type.isAssignableFrom(dfaTypeValue)) return null;
+ }
+
+ List moreSpecific = new ArrayList<>();
+ for (DfaPsiType alreadyNotInstanceof : myNotInstanceofValues) {
+ if (alreadyNotInstanceof.isAssignableFrom(type)) {
+ return this;
+ }
+ if (type.isAssignableFrom(alreadyNotInstanceof)) {
+ moreSpecific.add(alreadyNotInstanceof);
+ }
+ }
+
+ Set newNotInstanceof = ContainerUtil.newHashSet(myNotInstanceofValues);
+ newNotInstanceof.removeAll(moreSpecific);
+ newNotInstanceof.add(type);
+ return create(myInstanceofValues, newNotInstanceof);
+ }
+
+ @NotNull
+ TypeConstraint withoutType(@NotNull DfaPsiType type) {
+ if (myInstanceofValues.contains(type)) {
+ HashSet newInstanceof = ContainerUtil.newHashSet(myInstanceofValues);
+ newInstanceof.remove(type);
+ return create(newInstanceof, myNotInstanceofValues);
+ }
+ if (myNotInstanceofValues.contains(type)) {
+ HashSet newNotInstanceof = ContainerUtil.newHashSet(myNotInstanceofValues);
+ newNotInstanceof.remove(type);
+ return create(myInstanceofValues, newNotInstanceof);
+ }
+ return this;
+ }
+
+ @Nullable
+ public PsiType getPsiType() {
+ if (myInstanceofValues.isEmpty()) {
+ return null;
+ }
+ return myInstanceofValues.iterator().next().getPsiType();
+ }
+
+ boolean isSuperStateOf(@NotNull TypeConstraint that) {
+ return that.myNotInstanceofValues.containsAll(myNotInstanceofValues) && that.myInstanceofValues.containsAll(myInstanceofValues);
+ }
+
+ @NotNull
+ public Set getInstanceofValues() {
+ return Collections.unmodifiableSet(myInstanceofValues);
+ }
+
+ @NotNull
+ public Set getNotInstanceofValues() {
+ return Collections.unmodifiableSet(myNotInstanceofValues);
+ }
+
+ public boolean isEmpty() {
+ return myInstanceofValues.isEmpty() && myNotInstanceofValues.isEmpty();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ TypeConstraint that = (TypeConstraint)o;
+ return Objects.equals(myInstanceofValues, that.myInstanceofValues) &&
+ Objects.equals(myNotInstanceofValues, that.myNotInstanceofValues);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(myInstanceofValues, myNotInstanceofValues);
+ }
+
+ @Override
+ public String toString() {
+ return EntryStream.of("instanceof ", myInstanceofValues,
+ "not instanceof ", myNotInstanceofValues)
+ .removeValues(Set::isEmpty)
+ .mapKeyValue((prefix, set) -> StreamEx.of(set).joining(",", prefix, ""))
+ .joining(" ");
+ }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java
index d0fe9b2518fc..a06ce2a04483 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java
@@ -16,7 +16,6 @@
package com.intellij.codeInspection.dataFlow;
-import com.intellij.codeInspection.dataFlow.value.DfaPsiType;
import com.intellij.codeInspection.dataFlow.value.DfaValue;
import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
@@ -25,8 +24,6 @@ import com.intellij.util.containers.FList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.Set;
-
/**
* @author Gregory.Shrago
*/
@@ -74,34 +71,30 @@ class ValuableDataFlowRunner extends DataFlowRunner {
myConcatenation = FList.emptyList();
}
- private ValuableDfaVariableState(Set instanceofValues,
- Set notInstanceofValues,
- DfaValue value,
+ private ValuableDfaVariableState(DfaValue value,
@NotNull FList concatenation,
@NotNull DfaFactMap factMap) {
- super(instanceofValues, notInstanceofValues, factMap);
+ super(factMap);
myValue = value;
myConcatenation = concatenation;
}
@NotNull
@Override
- protected DfaVariableState createCopy(@NotNull Set instanceofValues,
- @NotNull Set notInstanceofValues,
- @NotNull DfaFactMap factMap) {
- return new ValuableDfaVariableState(instanceofValues, notInstanceofValues, myValue, myConcatenation, factMap);
+ protected DfaVariableState createCopy(@NotNull DfaFactMap factMap) {
+ return new ValuableDfaVariableState(myValue, myConcatenation, factMap);
}
@NotNull
@Override
public DfaVariableState withValue(@Nullable final DfaValue value) {
if (value == myValue) return this;
- return new ValuableDfaVariableState(myInstanceofValues, myNotInstanceofValues, value, myConcatenation, myFactMap);
+ return new ValuableDfaVariableState(value, myConcatenation, myFactMap);
}
ValuableDfaVariableState withExpression(@NotNull final FList concatenation) {
if (concatenation == myConcatenation) return this;
- return new ValuableDfaVariableState(myInstanceofValues, myNotInstanceofValues, myValue, concatenation, myFactMap);
+ return new ValuableDfaVariableState(myValue, concatenation, myFactMap);
}
@Override
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspectionBase.java
index 5430b6dcc8f1..b4c1c6aad903 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspectionBase.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspectionBase.java
@@ -24,7 +24,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.*;
-import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
@@ -297,7 +297,7 @@ public class JavaDocLocalInspectionBase extends BaseJavaBatchLocalInspectionTool
if (IGNORE_DEPRECATED && isDeprecated(psiMethod)) {
return null;
}
- if (myIgnoreSimpleAccessors && PropertyUtil.isSimplePropertyAccessor(psiMethod)) {
+ if (myIgnoreSimpleAccessors && PropertyUtilBase.isSimplePropertyAccessor(psiMethod)) {
return null;
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java
index 7a1daea8dd16..b05cbaa64ce7 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java
@@ -384,7 +384,7 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo
NullableNotNullManager manager, final String anno, final List annoToRemove, @NotNull ProblemsHolder holder) {
String propName = JavaCodeStyleManager.getInstance(project).variableNameToPropertyName(field.getName(), VariableKind.FIELD);
final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
- final PsiMethod getter = PropertyUtil.findPropertyGetter(field.getContainingClass(), propName, isStatic, false);
+ final PsiMethod getter = PropertyUtilBase.findPropertyGetter(field.getContainingClass(), propName, isStatic, false);
final PsiIdentifier nameIdentifier = getter == null ? null : getter.getNameIdentifier();
if (nameIdentifier != null && nameIdentifier.isPhysical()) {
if (PropertyUtil.isSimpleGetter(getter)) {
@@ -406,7 +406,7 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo
}
final PsiClass containingClass = field.getContainingClass();
- final PsiMethod setter = PropertyUtil.findPropertySetter(containingClass, propName, isStatic, false);
+ final PsiMethod setter = PropertyUtilBase.findPropertySetter(containingClass, propName, isStatic, false);
if (setter != null && setter.isPhysical() && PropertyUtil.isSimpleSetter(setter)) {
final PsiParameter[] parameters = setter.getParameterList().getParameters();
assert parameters.length == 1 : setter.getText();
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/redundantCast/RedundantCastInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/redundantCast/RedundantCastInspection.java
index 7f3f83ad01b3..493364907e1d 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/redundantCast/RedundantCastInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/redundantCast/RedundantCastInspection.java
@@ -15,7 +15,6 @@
*/
package com.intellij.codeInspection.redundantCast;
-import com.intellij.codeInsight.NullableNotNullManager;
import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.miscGenerics.GenericsInspectionToolBase;
@@ -45,7 +44,6 @@ public class RedundantCastInspection extends GenericsInspectionToolBase {
private static final String DISPLAY_NAME = InspectionsBundle.message("inspection.redundant.cast.display.name");
@NonNls private static final String SHORT_NAME = "RedundantCast";
- public boolean IGNORE_ANNOTATED_METHODS;
public boolean IGNORE_SUSPICIOUS_METHOD_CALLS;
@@ -71,7 +69,7 @@ public class RedundantCastInspection extends GenericsInspectionToolBase {
@Override
public void writeSettings(@NotNull Element node) throws WriteExternalException {
- if (IGNORE_ANNOTATED_METHODS || IGNORE_SUSPICIOUS_METHOD_CALLS) {
+ if (IGNORE_SUSPICIOUS_METHOD_CALLS) {
super.writeSettings(node);
}
}
@@ -80,7 +78,6 @@ public class RedundantCastInspection extends GenericsInspectionToolBase {
public JComponent createOptionsPanel() {
final MultipleCheckboxOptionsPanel optionsPanel = new MultipleCheckboxOptionsPanel(this);
optionsPanel.addCheckbox("Ignore casts in suspicious collections method calls", "IGNORE_SUSPICIOUS_METHOD_CALLS");
- optionsPanel.addCheckbox("Ignore casts to invoke @NotNull method which overrides @Nullable", "IGNORE_ANNOTATED_METHODS");
return optionsPanel;
}
@@ -90,25 +87,7 @@ public class RedundantCastInspection extends GenericsInspectionToolBase {
PsiTypeElement castType = cast.getCastType();
if (operand == null || castType == null) return null;
PsiElement parent = PsiUtil.skipParenthesizedExprUp(cast.getParent());
- if (parent instanceof PsiReferenceExpression) {
- if (IGNORE_ANNOTATED_METHODS) {
- final PsiElement gParent = parent.getParent();
- if (gParent instanceof PsiMethodCallExpression) {
- final PsiMethod psiMethod = ((PsiMethodCallExpression)gParent).resolveMethod();
- if (psiMethod != null && NullableNotNullManager.isNotNull(psiMethod)) {
- final PsiClass superClass = PsiUtil.resolveClassInType(operand.getType());
- final PsiClass containingClass = psiMethod.getContainingClass();
- if (containingClass != null && superClass != null && containingClass.isInheritor(superClass, true)) {
- for (PsiMethod method : psiMethod.findSuperMethods(superClass)) {
- if (NullableNotNullManager.isNullable(method)) {
- return null;
- }
- }
- }
- }
- }
- }
- } else if (parent instanceof PsiExpressionList) {
+ if (parent instanceof PsiExpressionList) {
final PsiElement gParent = parent.getParent();
if (gParent instanceof PsiMethodCallExpression && IGNORE_SUSPICIOUS_METHOD_CALLS) {
final String message = SuspiciousMethodCallUtil
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/unneededThrows/RedundantThrowsDeclarationInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/unneededThrows/RedundantThrowsDeclarationInspection.java
index e2669f837062..f9216e6a3f14 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/unneededThrows/RedundantThrowsDeclarationInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/unneededThrows/RedundantThrowsDeclarationInspection.java
@@ -81,6 +81,7 @@ public class RedundantThrowsDeclarationInspection extends GlobalJavaBatchInspect
if (unThrown == null) return null;
PsiMethod psiMethod = (PsiMethod)refMethod.getElement();
+ if (psiMethod == null) return null;
PsiClassType[] throwsList = psiMethod.getThrowsList().getReferencedTypes();
PsiJavaCodeReferenceElement[] throwsRefs = psiMethod.getThrowsList().getReferenceElements();
List problems = null;
diff --git a/java/java-analysis-impl/src/org/jetbrains/java/generate/inspection/FieldNotUsedInToStringInspection.java b/java/java-analysis-impl/src/org/jetbrains/java/generate/inspection/FieldNotUsedInToStringInspection.java
index 7ad9b1e7f3cb..9117705794f9 100644
--- a/java/java-analysis-impl/src/org/jetbrains/java/generate/inspection/FieldNotUsedInToStringInspection.java
+++ b/java/java-analysis-impl/src/org/jetbrains/java/generate/inspection/FieldNotUsedInToStringInspection.java
@@ -19,6 +19,7 @@ import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.*;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -145,7 +146,7 @@ public class FieldNotUsedInToStringInspection extends AbstractToStringInspection
}
else {
myUnusedMethods.remove(method);
- final PsiField field = PropertyUtil.findPropertyFieldByMember(method);
+ final PsiField field = PropertyUtilBase.findPropertyFieldByMember(method);
myUnusedFields.remove(field);
}
}
diff --git a/java/java-analysis-impl/src/org/jetbrains/java/generate/psi/PsiAdapter.java b/java/java-analysis-impl/src/org/jetbrains/java/generate/psi/PsiAdapter.java
index 3c923deb54f5..6069c93e4458 100644
--- a/java/java-analysis-impl/src/org/jetbrains/java/generate/psi/PsiAdapter.java
+++ b/java/java-analysis-impl/src/org/jetbrains/java/generate/psi/PsiAdapter.java
@@ -25,7 +25,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
-import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
@@ -492,7 +492,7 @@ public class PsiAdapter {
if (!isGetterMethod(method)) {
return null;
}
- return PropertyUtil.getPropertyNameByGetter(method);
+ return PropertyUtilBase.getPropertyNameByGetter(method);
}
/**
diff --git a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java
index 366c2d997c17..dd5c8322cb1e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java
@@ -410,8 +410,8 @@ public class ExpectedTypesProvider {
private void visitMethodReturnType(final PsiMethod scopeMethod, PsiType type, boolean tailTypeSemicolon) {
if (type != null) {
NullableComputable expectedName;
- if (PropertyUtil.isSimplePropertyAccessor(scopeMethod)) {
- expectedName = () -> PropertyUtil.getPropertyName(scopeMethod);
+ if (PropertyUtilBase.isSimplePropertyAccessor(scopeMethod)) {
+ expectedName = () -> PropertyUtilBase.getPropertyName(scopeMethod);
}
else {
expectedName = ExpectedTypeInfoImpl.NULL;
diff --git a/java/java-impl/src/com/intellij/codeInsight/JavaTargetElementEvaluator.java b/java/java-impl/src/com/intellij/codeInsight/JavaTargetElementEvaluator.java
index 076c8b39aa6c..20be3f05a031 100644
--- a/java/java-impl/src/com/intellij/codeInsight/JavaTargetElementEvaluator.java
+++ b/java/java-impl/src/com/intellij/codeInsight/JavaTargetElementEvaluator.java
@@ -15,10 +15,14 @@
*/
package com.intellij.codeInsight;
+import com.intellij.codeInspection.dataFlow.CommonDataflow;
+import com.intellij.codeInspection.dataFlow.DfaFactType;
+import com.intellij.codeInspection.dataFlow.TypeConstraint;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
+import com.intellij.psi.impl.search.JavaOverridingMethodsSearcher;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
@@ -38,18 +42,19 @@ public class JavaTargetElementEvaluator extends TargetElementEvaluatorEx2 implem
public static final int NEW_AS_CONSTRUCTOR = 0x04;
public static final int THIS_ACCEPTED = 0x10;
public static final int SUPER_ACCEPTED = 0x20;
+ public static final int USE_DFA = 0x40;
@Override
public int getAllAdditionalFlags() {
- return NEW_AS_CONSTRUCTOR | THIS_ACCEPTED | SUPER_ACCEPTED;
+ return NEW_AS_CONSTRUCTOR | THIS_ACCEPTED | SUPER_ACCEPTED | USE_DFA;
}
/**
- * Accepts THIS or SUPER but not NEW_AS_CONSTRUCTOR.
+ * Accepts THIS or SUPER or USE_DFA but not NEW_AS_CONSTRUCTOR.
*/
@Override
public int getAdditionalDefinitionSearchFlags() {
- return THIS_ACCEPTED | SUPER_ACCEPTED;
+ return THIS_ACCEPTED | SUPER_ACCEPTED | USE_DFA;
}
/**
@@ -78,9 +83,31 @@ public class JavaTargetElementEvaluator extends TargetElementEvaluatorEx2 implem
return ((PsiClassType)type).resolve();
}
}
+ if (targetElement instanceof PsiMethod && BitUtil.isSet(flags, USE_DFA)) {
+ PsiElement realMethod = findOverridingMethod(editor, offset, (PsiMethod)targetElement);
+ if (realMethod != null) return realMethod;
+ }
return super.adjustTargetElement(editor, offset, flags, targetElement);
}
+ @Nullable
+ private static PsiElement findOverridingMethod(Editor editor, int offset, PsiMethod method) {
+ PsiClass qualifierClass = method.getContainingClass();
+ if (qualifierClass == null || !PsiUtil.canBeOverridden(method)) return null;
+ PsiReference reference = TargetElementUtil.findReference(editor, offset);
+ if (!(reference instanceof PsiReferenceExpression) || !reference.isReferenceTo(method)) return null;
+ PsiExpression qualifier = ((PsiReferenceExpression)reference).getQualifierExpression();
+ if (qualifier == null) return null;
+ TypeConstraint constraint = CommonDataflow.getExpressionFact(qualifier, DfaFactType.TYPE_CONSTRAINT);
+ if (constraint == null) return null;
+ PsiClass specificQualifierClass = PsiUtil.resolveClassInClassTypeOnly(constraint.getPsiType());
+ if (specificQualifierClass == null || specificQualifierClass.equals(qualifierClass) ||
+ !InheritanceUtil.isInheritorOrSelf(specificQualifierClass, qualifierClass, true)) {
+ return null;
+ }
+ return JavaOverridingMethodsSearcher.findOverridingMethod(method.getProject(), specificQualifierClass, method, qualifierClass);
+ }
+
@Override
public boolean isAcceptableNamedParent(@NotNull PsiElement parent) {
return !(parent instanceof PsiDocTag);
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/FunctionalExpressionCompletionProvider.java b/java/java-impl/src/com/intellij/codeInsight/completion/FunctionalExpressionCompletionProvider.java
index 08e308081606..21c05936c6c8 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/FunctionalExpressionCompletionProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/FunctionalExpressionCompletionProvider.java
@@ -23,6 +23,7 @@ import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
@@ -53,6 +54,7 @@ public class FunctionalExpressionCompletionProvider extends CompletionProvider FUNCTIONAL_EXPR_ITEM = Key.create("FUNCTIONAL_EXPR_ITEM");
private static boolean isLambdaContext(@NotNull PsiElement element) {
final PsiElement rulezzRef = element.getParent();
@@ -105,13 +107,16 @@ public class FunctionalExpressionCompletionProvider extends CompletionProvider {}")
.withTypeText(functionalInterfaceType.getPresentableText())
.withIcon(AllIcons.Nodes.Function);
- LookupElement lambdaElement = builder.withAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
- result.consume(smart ? lambdaElement : PrioritizedLookupElement.withPriority(lambdaElement, 1));
+ builder.putUserData(FUNCTIONAL_EXPR_ITEM, true);
+ result.consume(builder.withAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE));
}
addMethodReferenceVariants(
smart, addInheritors, parameters, matcher, functionalInterfaceType, functionalInterfaceMethod, params, originalPosition, substitutor,
- element -> result.consume(smart ? JavaSmartCompletionContributor.decorate(element, Arrays.asList(expectedTypes)) : element));
+ element -> {
+ element.putUserData(FUNCTIONAL_EXPR_ITEM, true);
+ result.consume(smart ? JavaSmartCompletionContributor.decorate(element, Arrays.asList(expectedTypes)) : element);
+ });
}
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
index 74f10b38b543..97f00f85661b 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
@@ -252,7 +252,7 @@ public class JavaCompletionContributor extends CompletionContributor {
PrefixMatcher matcher = result.getPrefixMatcher();
PsiElement parent = position.getParent();
- if (JavaKeywordCompletion.addWildcardExtendsSuper(result, position)) {
+ if (new JavaKeywordCompletion(parameters, session).addWildcardExtendsSuper(result, position)) {
return;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java
index 3eb7b1cb2b29..fe58d856404f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java
@@ -166,6 +166,7 @@ public class JavaKeywordCompletion {
private final JavaCompletionSession mySession;
private final PsiElement myPosition;
private final String myPrefix;
+ private final PrefixMatcher myKeywordMatcher;
private final List myResults = new ArrayList<>();
private final PsiElement myPrevLeaf;
@@ -173,6 +174,7 @@ public class JavaKeywordCompletion {
myParameters = parameters;
mySession = session;
myPrefix = session.getMatcher().getPrefix();
+ myKeywordMatcher = new FixingLayoutPlainMatcher(myPrefix);
myPosition = parameters.getPosition();
myPrevLeaf = prevSignificantLeaf(myPosition);
@@ -185,7 +187,7 @@ public class JavaKeywordCompletion {
}
private void addKeyword(LookupElement element) {
- if (element.getLookupString().startsWith(myPrefix)) {
+ if (myKeywordMatcher.isStartMatch(element.getLookupString())) {
myResults.add(element);
}
}
@@ -313,10 +315,10 @@ public class JavaKeywordCompletion {
addExtendsImplements();
}
- static boolean addWildcardExtendsSuper(CompletionResultSet result, PsiElement position) {
+ boolean addWildcardExtendsSuper(CompletionResultSet result, PsiElement position) {
if (JavaMemberNameCompletionContributor.INSIDE_TYPE_PARAMS_PATTERN.accepts(position)) {
for (String keyword : ContainerUtil.ar(PsiKeyword.EXTENDS, PsiKeyword.SUPER)) {
- if (keyword.startsWith(result.getPrefixMatcher().getPrefix())) {
+ if (myKeywordMatcher.isStartMatch(keyword)) {
LookupElement item = BasicExpressionCompletionContributor.createKeywordLookupItem(position, keyword);
result.addElement(new OverridableSpace(item, TailType.HUMBLE_SPACE_BEFORE_WORD));
}
@@ -394,7 +396,7 @@ public class JavaKeywordCompletion {
}
}
- if ((isInsideParameterList(myPosition) || isAtResourceVariableStart(myPosition) || isAtCatchVariableStart(myPosition)) &&
+ if ((isInsideParameterList(myPosition) || isAtCatchOrResourceVariableStart(myPosition)) &&
!psiElement().afterLeaf(PsiKeyword.FINAL).accepts(myPosition) &&
!AFTER_DOT.accepts(myPosition)) {
addKeyword(TailTypeDecorator.withTail(createKeyword(PsiKeyword.FINAL), TailType.HUMBLE_SPACE_BEFORE_WORD));
@@ -730,12 +732,14 @@ public class JavaKeywordCompletion {
info -> InheritanceUtil.isInheritor(info.getType(), CommonClassNames.JAVA_LANG_CLASS)) != null;
}
- private static boolean isAtResourceVariableStart(PsiElement position) {
- return psiElement().insideStarting(psiElement(PsiTypeElement.class).withParent(PsiResourceList.class)).accepts(position);
- }
-
- private static boolean isAtCatchVariableStart(PsiElement position) {
- return psiElement().insideStarting(psiElement(PsiTypeElement.class).withParent(PsiCatchSection.class)).accepts(position);
+ private static boolean isAtCatchOrResourceVariableStart(PsiElement position) {
+ PsiElement type = PsiTreeUtil.getParentOfType(position, PsiTypeElement.class);
+ if (type != null && type.getTextRange().getStartOffset() == position.getTextRange().getStartOffset()) {
+ PsiElement parent = type.getParent();
+ if (parent instanceof PsiVariable) parent = parent.getParent();
+ return parent instanceof PsiCatchSection || parent instanceof PsiResourceList;
+ }
+ return false;
}
private void addBreakContinue() {
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java
index 2819dddfb0a8..f79f0770b2f3 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * 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.
@@ -30,10 +30,7 @@ import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.SuggestedNameInfo;
import com.intellij.psi.codeStyle.VariableKind;
-import com.intellij.psi.util.PropertyUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.psi.util.*;
import com.intellij.refactoring.introduceField.InplaceIntroduceFieldPopup;
import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
import com.intellij.util.ArrayUtil;
@@ -112,7 +109,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
if (variableKind == VariableKind.PARAMETER) {
final PsiMethod method = PsiTreeUtil.getParentOfType(var, PsiMethod.class);
if (method != null) {
- propertyName = PropertyUtil.getPropertyName(method);
+ propertyName = PropertyUtilBase.getPropertyName(method);
}
if (method != null && method.getName().startsWith("with")) {
propertyName = StringUtil.decapitalize(method.getName().substring(4));
@@ -393,7 +390,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
if (staticContext && (modifierList != null && !modifierList.hasModifierProperty(PsiModifier.STATIC))) continue;
if (fieldType.equals(varType)) {
- final String getterName = PropertyUtil.suggestGetterName(field);
+ final String getterName = PropertyUtilBase.suggestGetterName(field);
if ((psiClass.findMethodsByName(getterName, true).length == 0 ||
psiClass.findMethodBySignature(GenerateMembersUtil.generateGetterPrototype(field), true) == null)) {
propertyHandlers.add(getterName);
@@ -401,7 +398,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
}
if (PsiType.VOID.equals(varType)) {
- final String setterName = PropertyUtil.suggestSetterName(field);
+ final String setterName = PropertyUtilBase.suggestSetterName(field);
if ((psiClass.findMethodsByName(setterName, true).length == 0 ||
psiClass.findMethodBySignature(GenerateMembersUtil.generateSetterPrototype(field), true) == null)) {
propertyHandlers.add(setterName);
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java
index dd34eb662dbc..7b6dbda1d7f9 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementWeigher;
+import com.intellij.codeInsight.lookup.TypedLookupItem;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Conditions;
import com.intellij.openapi.util.Key;
@@ -28,10 +29,7 @@ import com.intellij.patterns.ElementPattern;
import com.intellij.psi.*;
import com.intellij.psi.filters.getters.MembersGetter;
import com.intellij.psi.impl.source.tree.JavaElementType;
-import com.intellij.psi.util.InheritanceUtil;
-import com.intellij.psi.util.PropertyUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.*;
import com.intellij.psi.util.proximity.KnownElementWeigher;
import com.intellij.util.ThreeState;
import com.intellij.util.containers.ContainerUtil;
@@ -133,6 +131,8 @@ public class PreferByKindWeigher extends LookupElementWeigher {
annoMethod,
probableKeyword,
castVariable,
+ expectedTypeVariable,
+ funExpr,
variable,
getter,
qualifiedWithField,
@@ -171,13 +171,17 @@ public class PreferByKindWeigher extends LookupElementWeigher {
if (object instanceof PsiLocalVariable || object instanceof PsiParameter ||
object instanceof PsiThisExpression ||
object instanceof PsiField && !((PsiField)object).hasModifierProperty(PsiModifier.STATIC)) {
- return MyResult.variable;
+ return isExpectedTypeItem(item) ? MyResult.expectedTypeVariable : MyResult.variable;
}
if (object instanceof String && item.getUserData(JavaCompletionUtil.SUPER_METHOD_PARAMETERS) == Boolean.TRUE) {
return MyResult.superMethodParameters;
}
+ if (item.getUserData(FunctionalExpressionCompletionProvider.FUNCTIONAL_EXPR_ITEM) != null) {
+ return MyResult.funExpr;
+ }
+
if (object instanceof PsiMethod) {
PsiClass containingClass = ((PsiMethod)object).getContainingClass();
if (containingClass != null && CommonClassNames.JAVA_UTIL_COLLECTIONS.equals(containingClass.getQualifiedName())) {
@@ -248,6 +252,12 @@ public class PreferByKindWeigher extends LookupElementWeigher {
return MyResult.normal;
}
+ private boolean isExpectedTypeItem(@NotNull LookupElement item) {
+ TypedLookupItem typed = item.as(TypedLookupItem.CLASS_CONDITION_KEY);
+ PsiType itemType = typed == null ? null : typed.getType();
+ return itemType != null && Arrays.stream(myExpectedTypes).anyMatch(info -> info.getType().isAssignableFrom(itemType));
+ }
+
@NotNull
private ThreeState isProbableKeyword(String keyword) {
if (PsiKeyword.RETURN.equals(keyword)) {
@@ -315,7 +325,7 @@ public class PreferByKindWeigher extends LookupElementWeigher {
if (!(object instanceof PsiMethod)) return false;
PsiMethod method = (PsiMethod)object;
- if (!PropertyUtil.hasGetterName(method)) return false;
+ if (!PropertyUtilBase.hasGetterName(method)) return false;
return !KnownElementWeigher.isGetClass(method);
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java
index 0409c50d7233..2835852739e4 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -31,6 +31,7 @@ import com.intellij.psi.filters.element.ExcludeSillyAssignment;
import com.intellij.psi.impl.search.MethodDeepestSuperSearcher;
import com.intellij.psi.scope.ElementClassFilter;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.CommonProcessors;
import org.jetbrains.annotations.NotNull;
@@ -170,15 +171,15 @@ class RecursionWeigher extends LookupElementWeigher {
@Nullable
private String getSetterPropertyName(@Nullable PsiMethod calledMethod) {
- if (PropertyUtil.isSimplePropertySetter(calledMethod)) {
+ if (PropertyUtilBase.isSimplePropertySetter(calledMethod)) {
assert calledMethod != null;
- return PropertyUtil.getPropertyName(calledMethod);
+ return PropertyUtilBase.getPropertyName(calledMethod);
}
PsiReferenceExpression reference = ExcludeSillyAssignment.getAssignedReference(myPosition);
if (reference != null) {
PsiElement target = reference.resolve();
if (target instanceof PsiField) {
- return PropertyUtil.suggestPropertyName((PsiField)target);
+ return PropertyUtilBase.suggestPropertyName((PsiField)target);
}
}
return null;
@@ -189,12 +190,12 @@ class RecursionWeigher extends LookupElementWeigher {
if (prop == null) return false;
if (lookupObject instanceof PsiField &&
- prop.equals(PropertyUtil.suggestPropertyName((PsiField)lookupObject))) {
+ prop.equals(PropertyUtilBase.suggestPropertyName((PsiField)lookupObject))) {
return true;
}
if (lookupObject instanceof PsiMethod &&
- PropertyUtil.isSimplePropertyGetter((PsiMethod)lookupObject) &&
- prop.equals(PropertyUtil.getPropertyName((PsiMethod)lookupObject))) {
+ PropertyUtilBase.isSimplePropertyGetter((PsiMethod)lookupObject) &&
+ prop.equals(PropertyUtilBase.getPropertyName((PsiMethod)lookupObject))) {
return true;
}
return false;
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/SmartCastProvider.java b/java/java-impl/src/com/intellij/codeInsight/completion/SmartCastProvider.java
index 9b7b878a6146..7f3048553d0b 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/SmartCastProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/SmartCastProvider.java
@@ -125,7 +125,7 @@ class SmartCastProvider extends CompletionProvider {
if (info.getKind() == ExpectedTypeInfo.TYPE_OR_SUPERTYPE) {
InheritanceUtil.processSupers(infoClass, true, superClass -> {
if (!CommonClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) {
- result.consume(JavaPsiFacade.getElementFactory(superClass.getProject()).createType(superClass));
+ result.consume(JavaPsiFacade.getElementFactory(superClass.getProject()).createType(CompletionUtil.getOriginalOrSelf(superClass)));
}
return true;
});
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterOrSetterFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterOrSetterFix.java
index 88f8a1724d4d..73194b1ad888 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterOrSetterFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterOrSetterFix.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * 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.
@@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -47,7 +48,7 @@ public class CreateGetterOrSetterFix implements IntentionAction, LowPriorityActi
myCreateGetter = createGetter;
myCreateSetter = createSetter;
myField = field;
- myPropertyName = PropertyUtil.suggestPropertyName(field);
+ myPropertyName = PropertyUtilBase.suggestPropertyName(field);
}
@Override
@@ -86,13 +87,13 @@ public class CreateGetterOrSetterFix implements IntentionAction, LowPriorityActi
}
if (myCreateGetter){
- if (isStaticFinal(myField) || PropertyUtil.findPropertyGetter(aClass, myPropertyName, isStatic(myField), false) != null){
+ if (isStaticFinal(myField) || PropertyUtilBase.findPropertyGetter(aClass, myPropertyName, isStatic(myField), false) != null){
return false;
}
}
if (myCreateSetter){
- if(isFinal(myField) || PropertyUtil.findPropertySetter(aClass, myPropertyName, isStatic(myField), false) != null){
+ if(isFinal(myField) || PropertyUtilBase.findPropertySetter(aClass, myPropertyName, isStatic(myField), false) != null){
return false;
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterSetterPropertyFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterSetterPropertyFromUsageFix.java
index dea4567383b6..6825a380770a 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterSetterPropertyFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateGetterSetterPropertyFromUsageFix.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiField;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiMethodCallExpression;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -41,10 +42,10 @@ public class CreateGetterSetterPropertyFromUsageFix extends CreatePropertyFromUs
@Override
protected boolean checkTargetClasses(List classes, String methodName) {
- String propertyName = PropertyUtil.getPropertyName(methodName);
+ String propertyName = PropertyUtilBase.getPropertyName(methodName);
if (propertyName == null) return false;
- String getterName = PropertyUtil.suggestGetterName(propertyName, null);
- String setterName = PropertyUtil.suggestSetterName(propertyName);
+ String getterName = PropertyUtilBase.suggestGetterName(propertyName, null);
+ String setterName = PropertyUtilBase.suggestSetterName(propertyName);
for (PsiClass aClass : classes) {
if (aClass.findMethodsByName(getterName, false).length > 0 || aClass.findMethodsByName(setterName, false).length > 0) return false;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageFix.java
index 35afe19cde74..69f51adac58e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageFix.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * 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.
@@ -35,6 +35,7 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.util.RefactoringUtil;
@@ -84,7 +85,7 @@ public class CreatePropertyFromUsageFix extends CreateFromUsageBaseFix implement
PsiReferenceExpression ref = myMethodCall.getMethodExpression();
String methodName = myMethodCall.getMethodExpression().getReferenceName();
LOG.assertTrue(methodName != null);
- String propertyName = PropertyUtil.getPropertyName(methodName);
+ String propertyName = PropertyUtilBase.getPropertyName(methodName);
if (propertyName == null || propertyName.isEmpty()) return false;
String getterOrSetter = null;
@@ -321,7 +322,7 @@ public class CreatePropertyFromUsageFix extends CreateFromUsageBaseFix implement
private static String getVariableName(PsiMethodCallExpression methodCall, boolean isStatic) {
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(methodCall.getProject());
String methodName = methodCall.getMethodExpression().getReferenceName();
- String propertyName = PropertyUtil.getPropertyName(methodName);
+ String propertyName = PropertyUtilBase.getPropertyName(methodName);
if (propertyName != null && !propertyName.isEmpty()) {
VariableKind kind = isStatic ? VariableKind.STATIC_FIELD : VariableKind.FIELD;
return codeStyleManager.propertyNameToVariableName(propertyName, kind);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateFieldOrPropertyFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateFieldOrPropertyFix.java
index 58c451778094..0aa00b8975bb 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateFieldOrPropertyFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateFieldOrPropertyFix.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2016 JetBrains s.r.o.
+ * 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.
@@ -34,6 +34,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PropertyMemberType;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -126,7 +127,7 @@ public class CreateFieldOrPropertyFix implements IntentionAction, LocalQuickFix
boolean first = true;
@NonNls final String TYPE_NAME_VAR = "TYPE_NAME_VAR";
for (GenerationInfo prototype : prototypes) {
- final PsiTypeElement typeElement = PropertyUtil.getPropertyTypeElement(prototype.getPsiMember());
+ final PsiTypeElement typeElement = PropertyUtilBase.getPropertyTypeElement(prototype.getPsiMember());
if (first) {
first = false;
builder.replaceElement(typeElement, TYPE_NAME_VAR, expression, true);
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/IfConditionFixer.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/IfConditionFixer.java
index 108a68f6bb52..62f6c3e16a5e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/IfConditionFixer.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/IfConditionFixer.java
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.editorActions.smartEnter;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
/**
@@ -53,5 +54,13 @@ public class IfConditionFixer implements Fixer {
doc.insertString(condition.getTextRange().getEndOffset(), ")");
}
}
+ else if (psiElement instanceof PsiExpression && psiElement.getParent() instanceof PsiExpressionStatement) {
+ PsiElement prevLeaf = PsiTreeUtil.prevVisibleLeaf(psiElement);
+ if (prevLeaf != null && prevLeaf.textMatches(PsiKeyword.IF)) {
+ Document doc = editor.getDocument();
+ doc.insertString(psiElement.getTextRange().getEndOffset(), ")");
+ doc.insertString(psiElement.getTextRange().getStartOffset(), "(");
+ }
+ }
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateDelegateHandler.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateDelegateHandler.java
index c83cd6b59b67..10ea5acc23d8 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateDelegateHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateDelegateHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2016 JetBrains s.r.o.
+ * 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.
@@ -33,6 +33,7 @@ import com.intellij.psi.scope.processor.VariablesProcessor;
import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.util.*;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NonNls;
@@ -234,7 +235,7 @@ public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler
if (targetClass instanceof PsiTypeParameter) {
LinkedHashSet meths = new LinkedHashSet<>();
for (PsiClass superClass : targetClass.getSupers()) {
- meths.addAll(Arrays.asList(superClass.getAllMethods()));
+ ContainerUtil.addAll(meths, superClass.getAllMethods());
}
allMethods = meths.toArray(new PsiMethod[meths.size()]);
}
@@ -377,7 +378,7 @@ public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler
final PsiClass containingClass = method.getContainingClass();
if (containingClass == null || CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName())) continue;
final PsiType returnType = method.getReturnType();
- if (returnType != null && PropertyUtil.isSimplePropertyGetter(method) && helper.isAccessible(method, aClass, aClass) &&
+ if (returnType != null && PropertyUtilBase.isSimplePropertyGetter(method) && helper.isAccessible(method, aClass, aClass) &&
returnType instanceof PsiClassType && !(PsiTreeUtil.isAncestor(method, element, false) && targetClass != aClass)) {
result.add(new PsiMethodMember(method, TypeConversionUtil.getSuperClassSubstitutor( containingClass, aClass,PsiSubstitutor.EMPTY)));
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateFieldOrPropertyHandler.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateFieldOrPropertyHandler.java
index 79a39f38408e..d957084080e4 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateFieldOrPropertyHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateFieldOrPropertyHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -22,6 +22,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.util.PropertyMemberType;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -71,8 +72,8 @@ public class GenerateFieldOrPropertyHandler extends GenerateMembersHandlerBase {
for (GenerationInfo info : infos) {
PsiMember member = info.getPsiMember();
if (!(member instanceof PsiMethod)) continue;
- if (myMemberType == PropertyMemberType.GETTER && PropertyUtil.isSimplePropertyGetter((PsiMethod)member) ||
- myMemberType == PropertyMemberType.SETTER && PropertyUtil.isSimplePropertySetter((PsiMethod)member)) {
+ if (myMemberType == PropertyMemberType.GETTER && PropertyUtilBase.isSimplePropertyGetter((PsiMethod)member) ||
+ myMemberType == PropertyMemberType.SETTER && PropertyUtilBase.isSimplePropertySetter((PsiMethod)member)) {
targetMember = member;
break;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java
index 538d28a62bab..e4d227e3c07d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java
@@ -609,15 +609,15 @@ public class GenerateMembersUtil {
//java bean getters/setters
public static PsiMethod generateSimpleGetterPrototype(@NotNull PsiField field) {
- return generatePrototype(field, PropertyUtil.generateGetterPrototype(field));
+ return generatePrototype(field, PropertyUtilBase.generateGetterPrototype(field));
}
public static PsiMethod generateSimpleSetterPrototype(@NotNull PsiField field) {
- return generatePrototype(field, PropertyUtil.generateSetterPrototype(field));
+ return generatePrototype(field, PropertyUtilBase.generateSetterPrototype(field));
}
public static PsiMethod generateSimpleSetterPrototype(PsiField field, PsiClass targetClass) {
- return generatePrototype(field, PropertyUtil.generateSetterPrototype(field, targetClass));
+ return generatePrototype(field, PropertyUtilBase.generateSetterPrototype(field, targetClass));
}
//custom getters/setters
@@ -680,7 +680,7 @@ public class GenerateMembersUtil {
catch (IncorrectOperationException e) {
if (ignoreInvalidTemplate) {
LOG.info(e);
- result = isGetter ? PropertyUtil.generateGetterPrototype(field) : PropertyUtil.generateSetterPrototype(field);
+ result = isGetter ? PropertyUtilBase.generateGetterPrototype(field) : PropertyUtilBase.generateSetterPrototype(field);
assert result != null : field.getText();
}
else {
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GetterSetterPrototypeProvider.java b/java/java-impl/src/com/intellij/codeInsight/generation/GetterSetterPrototypeProvider.java
index 12a7e7cf9cef..af315591b188 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/GetterSetterPrototypeProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/GetterSetterPrototypeProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * 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.
@@ -22,6 +22,7 @@ import com.intellij.psi.PsiField;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
public abstract class GetterSetterPrototypeProvider {
public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.getterSetterProvider");
@@ -74,7 +75,7 @@ public abstract class GetterSetterPrototypeProvider {
if (getterSetter != null) return getterSetter;
}
}
- final PsiMethod propertyGetterSetter = PropertyUtil.findPropertyGetter(aClass, propertyName, isStatic, false);
+ final PsiMethod propertyGetterSetter = PropertyUtilBase.findPropertyGetter(aClass, propertyName, isStatic, false);
if (propertyGetterSetter != null) {
return new PsiMethod[] {propertyGetterSetter};
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java
index a5f6a3a0ef07..62135ecb3d38 100644
--- a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java
@@ -236,7 +236,10 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
return;
}
- int index = ParameterInfoUtils.getCurrentParameterIndex(o.getNode(), context.getOffset(), JavaTokenType.COMMA);
+ int offset = context.getOffset();
+ TextRange elRange = o.getTextRange();
+ int index = offset <= elRange.getStartOffset() || offset >= elRange.getEndOffset()
+ ? -1 : ParameterInfoUtils.getCurrentParameterIndex(o.getNode(), offset, JavaTokenType.COMMA);
context.setCurrentParameter(index);
Object[] candidates = context.getObjectsToView();
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/UnrollLoopAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/UnrollLoopAction.java
index 65dce6e74b89..97ac1938c530 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/UnrollLoopAction.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/UnrollLoopAction.java
@@ -33,8 +33,15 @@ import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Objects;
+import static com.siyeh.ig.callMatcher.CallMatcher.anyOf;
+import static com.siyeh.ig.callMatcher.CallMatcher.staticCall;
+
public class UnrollLoopAction extends PsiElementBaseIntentionAction {
- private static final CallMatcher LIST_CONSTRUCTOR = CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_ARRAYS, "asList");
+ private static final CallMatcher LIST_CONSTRUCTOR = anyOf(staticCall(CommonClassNames.JAVA_UTIL_ARRAYS, "asList"),
+ staticCall(CommonClassNames.JAVA_UTIL_LIST, "of"));
+ private static final CallMatcher SINGLETON_CONSTRUCTOR =
+ anyOf(staticCall(CommonClassNames.JAVA_UTIL_COLLECTIONS, "singleton", "singletonList").parameterCount(1),
+ staticCall(CommonClassNames.JAVA_UTIL_LIST, "of").parameterTypes("E"));
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull final PsiElement element) {
@@ -42,14 +49,17 @@ public class UnrollLoopAction extends PsiElementBaseIntentionAction {
if (loop == null) return false;
if (!(loop.getParent() instanceof PsiCodeBlock)) return false;
PsiExpression iteratedValue = ExpressionUtils.resolveExpression(loop.getIteratedValue());
+ PsiParameter iterationParameter = loop.getIterationParameter();
if (extractExpressions(iteratedValue).length == 0) return false;
PsiStatement[] statements = ControlFlowUtils.unwrapBlock(loop.getBody());
if (statements.length == 0) return false;
if (Arrays.stream(statements).anyMatch(PsiDeclarationStatement.class::isInstance)) return false;
- if (isBreakChain(loop)) {
- statements = Arrays.copyOfRange(statements, 0, statements.length - 1);
- }
+ if (VariableAccessUtils.variableIsAssigned(iterationParameter, loop)) return false;
+ //if (isBreakChain(loop)) {
+ // statements = Arrays.copyOfRange(statements, 0, statements.length - 1);
+ //}
for (PsiStatement statement : statements) {
+ if (isLoopBreak(statement)) continue;
boolean acceptable = PsiTreeUtil.processElements(statement, e -> {
if (e instanceof PsiBreakStatement && ((PsiBreakStatement)e).findExitedStatement() == loop) return false;
if (e instanceof PsiContinueStatement && ((PsiContinueStatement)e).findContinuedStatement() == loop) return false;
@@ -72,9 +82,15 @@ public class UnrollLoopAction extends PsiElementBaseIntentionAction {
}
if (expression instanceof PsiMethodCallExpression) {
PsiMethodCallExpression call = (PsiMethodCallExpression)expression;
- if (LIST_CONSTRUCTOR.test(call) && MethodCallUtils.isVarArgCall(call)) {
+ if (SINGLETON_CONSTRUCTOR.test(call)) {
return call.getArgumentList().getExpressions();
}
+ if (LIST_CONSTRUCTOR.test(call)) {
+ PsiExpression[] args = call.getArgumentList().getExpressions();
+ if (args.length > 1 || MethodCallUtils.isVarArgCall(call)) {
+ return args;
+ }
+ }
}
return PsiExpression.EMPTY_ARRAY;
}
@@ -96,7 +112,6 @@ public class UnrollLoopAction extends PsiElementBaseIntentionAction {
PsiForeachStatement loop = PsiTreeUtil.getParentOfType(element, PsiForeachStatement.class);
if (loop == null) return;
if (!(loop.getParent() instanceof PsiCodeBlock)) return;
- boolean breakChain = isBreakChain(loop);
PsiExpression iteratedValue = loop.getIteratedValue();
PsiExpression[] expressions = extractExpressions(ExpressionUtils.resolveExpression(iteratedValue));
if (expressions.length == 0) return;
@@ -115,22 +130,23 @@ public class UnrollLoopAction extends PsiElementBaseIntentionAction {
}
PsiStatement body = copy.getBody();
assert body != null;
+ PsiElement[] children;
if (body instanceof PsiBlockStatement) {
- PsiElement[] children = ((PsiBlockStatement)body).getCodeBlock().getChildren();
- PsiElement parent = anchor.getParent();
- PsiElement currentAnchor = anchor;
+ children = ((PsiBlockStatement)body).getCodeBlock().getChildren();
// Skip {braces}
- Arrays.stream(children, 1, children.length - 1).forEach(child -> parent.addBefore(child, currentAnchor));
+ children = Arrays.copyOfRange(children, 1, children.length-1);
+ } else {
+ children = new PsiElement[]{body};
}
- if (breakChain) {
- PsiStatement lastStatement = PsiTreeUtil.getPrevSiblingOfType(anchor, PsiStatement.class);
- if (lastStatement instanceof PsiIfStatement) {
- PsiIfStatement ifStatement = (PsiIfStatement)lastStatement;
+ for(PsiElement child : children) {
+ PsiElement added = anchor.getParent().addBefore(child, anchor);
+ if (added instanceof PsiIfStatement && isLoopBreak((PsiStatement)added)) {
+ PsiIfStatement ifStatement = (PsiIfStatement)added;
PsiExpression condition = Objects.requireNonNull(ifStatement.getCondition());
PsiStatement thenBranch = Objects.requireNonNull(ifStatement.getThenBranch());
String negated = BoolUtils.getNegatedExpressionText(condition);
condition.replace(factory.createExpressionFromText(negated, condition));
- PsiBlockStatement block = (PsiBlockStatement)thenBranch.replace(factory.createStatementFromText("{}", lastStatement));
+ PsiBlockStatement block = (PsiBlockStatement)thenBranch.replace(factory.createStatementFromText("{}", added));
anchor = block.getCodeBlock().getLastChild();
}
}
@@ -140,19 +156,11 @@ public class UnrollLoopAction extends PsiElementBaseIntentionAction {
ct.deleteAndRestoreComments(loop);
}
- /**
- * @param loop loop to test
- * @return true if the last statement is "if(...) break"
- */
- private static boolean isBreakChain(PsiForeachStatement loop) {
- PsiStatement lastStatement = loop.getBody();
- if (lastStatement instanceof PsiBlockStatement) {
- lastStatement = ControlFlowUtils.getLastStatementInBlock(((PsiBlockStatement)lastStatement).getCodeBlock());
- }
- if (!(lastStatement instanceof PsiIfStatement)) return false;
- PsiIfStatement ifStatement = (PsiIfStatement)lastStatement;
- return ifStatement.getElseBranch() == null &&
- ifStatement.getCondition() != null &&
- ControlFlowUtils.statementBreaksLoop(ControlFlowUtils.stripBraces(ifStatement.getThenBranch()), loop);
+ private static boolean isLoopBreak(PsiStatement statement) {
+ if (!(statement instanceof PsiIfStatement)) return false;
+ PsiIfStatement ifStatement = (PsiIfStatement)statement;
+ if (ifStatement.getElseBranch() != null || ifStatement.getCondition() == null) return false;
+ PsiStatement thenBranch = ControlFlowUtils.stripBraces(ifStatement.getThenBranch());
+ return thenBranch instanceof PsiBreakStatement && ((PsiBreakStatement)thenBranch).getLabelIdentifier() == null;
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/OptionalPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/OptionalPostfixTemplate.java
index 79c6e3558866..072bee170b61 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/OptionalPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/OptionalPostfixTemplate.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2016 JetBrains s.r.o.
+ * 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.
@@ -16,6 +16,8 @@
package com.intellij.codeInsight.template.postfix.templates;
import com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils;
+import com.intellij.codeInspection.dataFlow.Nullness;
+import com.intellij.codeInspection.dataFlow.NullnessUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiPrimitiveType;
@@ -35,23 +37,21 @@ public class OptionalPostfixTemplate extends StringBasedPostfixTemplate {
@Override
public String getTemplateString(@NotNull PsiElement element) {
String className = "Optional";
- String methodName = "ofNullable";
-
- if (element instanceof PsiExpression) {
- PsiType type = ((PsiExpression)element).getType();
- if (type instanceof PsiPrimitiveType) {
- if (PsiType.INT.equals(type)) {
- className = "OptionalInt";
- }
- else if (PsiType.DOUBLE.equals(type)) {
- className = "OptionalDouble";
- }
- else if (PsiType.LONG.equals(type)) {
- className = "OptionalLong";
- }
- methodName = "of";
+
+ PsiType type = ((PsiExpression)element).getType();
+ if (type instanceof PsiPrimitiveType) {
+ if (PsiType.INT.equals(type)) {
+ className = "OptionalInt";
+ }
+ else if (PsiType.DOUBLE.equals(type)) {
+ className = "OptionalDouble";
+ }
+ else if (PsiType.LONG.equals(type)) {
+ className = "OptionalLong";
}
}
+
+ String methodName = Nullness.NOT_NULL.equals(NullnessUtil.getExpressionNullness((PsiExpression)element)) ? "of" : "ofNullable";
return "java.util." + className + "." + methodName + "($expr$)";
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/StreamPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/StreamPostfixTemplate.java
index 13f49004a571..86fd754881e4 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/StreamPostfixTemplate.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/StreamPostfixTemplate.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2016 JetBrains s.r.o.
+ * 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.
@@ -16,15 +16,28 @@
package com.intellij.codeInsight.template.postfix.templates;
import com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils;
-import com.intellij.psi.PsiElement;
+import com.intellij.openapi.util.Condition;
+import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorAllExpressionsWithCurrentOffset;
public class StreamPostfixTemplate extends StringBasedPostfixTemplate {
+ private static final Condition IS_SUPPORTED_ARRAY = element -> {
+ if (!(element instanceof PsiExpression)) return false;
+
+ PsiType type = ((PsiExpression)element).getType();
+ if (!(type instanceof PsiArrayType)) return false;
+
+ PsiType componentType = ((PsiArrayType)type).getComponentType();
+ if (!(componentType instanceof PsiPrimitiveType)) return true;
+
+ return componentType.equals(PsiType.INT) || componentType.equals(PsiType.LONG) || componentType.equals(PsiType.DOUBLE);
+ };
+
public StreamPostfixTemplate() {
- super("stream", "Arrays.stream(expr)", JavaPostfixTemplatesUtils.atLeastJava8Selector(selectorAllExpressionsWithCurrentOffset(JavaPostfixTemplatesUtils.IS_ARRAY)));
+ super("stream", "Arrays.stream(expr)", JavaPostfixTemplatesUtils.atLeastJava8Selector(selectorAllExpressionsWithCurrentOffset(IS_SUPPORTED_ARRAY)));
}
@Nullable
diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java
index 3707f5b5fa82..dd8500f95c7c 100644
--- a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java
+++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java
@@ -42,6 +42,7 @@ import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.profile.codeInspection.ui.SingleInspectionProfilePanel;
import com.intellij.psi.*;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.safeDelete.SafeDeleteHandler;
import com.intellij.ui.HyperlinkAdapter;
@@ -520,7 +521,7 @@ public class UnusedDeclarationPresentation extends DefaultInspectionToolPresenta
//todo store in the graph
tool.isIgnoreAccessors()) {
final PsiModifierListOwner listOwner = ((RefMethod)element).getElement();
- if (listOwner instanceof PsiMethod && PropertyUtil.isSimplePropertyAccessor((PsiMethod)listOwner)) {
+ if (listOwner instanceof PsiMethod && PropertyUtilBase.isSimplePropertyAccessor((PsiMethod)listOwner)) {
return null;
}
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicConstantInspection.java b/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicConstantInspection.java
index 0a666ff45051..26d4bffd9a0e 100644
--- a/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicConstantInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicConstantInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2016 JetBrains s.r.o.
+ * 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.
@@ -465,7 +465,7 @@ public class MagicConstantInspection extends BaseJavaLocalInspectionTool {
if (!(initializer instanceof PsiLiteralExpression)) return null;
Object val = ((PsiLiteralExpression)initializer).getValue();
if (!(val instanceof String)) return null;
- PsiMethod setter = PropertyUtil.findPropertySetter(method.getContainingClass(), (String)val, false, false);
+ PsiMethod setter = PropertyUtilBase.findPropertySetter(method.getContainingClass(), (String)val, false, false);
if (setter == null) return null;
// try the @beaninfo of the corresponding setter
PsiElement navigationElement = setter.getNavigationElement();
@@ -482,12 +482,12 @@ public class MagicConstantInspection extends BaseJavaLocalInspectionTool {
PsiClass aClass = method.getContainingClass();
if (aClass == null) return null;
- if (PropertyUtil.isSimplePropertyGetter(method)) {
- List setters = PropertyUtil.getSetters(aClass, PropertyUtil.getPropertyNameByGetter(method));
+ if (PropertyUtilBase.isSimplePropertyGetter(method)) {
+ List setters = PropertyUtilBase.getSetters(aClass, PropertyUtilBase.getPropertyNameByGetter(method));
if (setters.size() != 1) return null;
method = setters.get(0);
}
- if (!PropertyUtil.isSimplePropertySetter(method)) return null;
+ if (!PropertyUtilBase.isSimplePropertySetter(method)) return null;
PsiDocComment doc = method.getDocComment();
if (doc == null) return null;
PsiDocTag beaninfo = doc.findTagByName("beaninfo");
diff --git a/java/java-impl/src/com/intellij/codeInspection/streamMigration/SimplifyForEachInspection.java b/java/java-impl/src/com/intellij/codeInspection/streamMigration/SimplifyForEachInspection.java
index 883681e1460f..3ef8f47217b6 100644
--- a/java/java-impl/src/com/intellij/codeInspection/streamMigration/SimplifyForEachInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/streamMigration/SimplifyForEachInspection.java
@@ -110,7 +110,7 @@ public class SimplifyForEachInspection extends BaseJavaBatchLocalInspectionTool
}
@Nullable
- static PsiLambdaExpression extractLambdaFromForEach(PsiMethodCallExpression call) {
+ static PsiLambdaExpression extractLambdaFromForEach(@NotNull PsiMethodCallExpression call) {
PsiExpression qualifier = call.getMethodExpression().getQualifierExpression();
if (qualifier == null || !(STREAM_FOREACH.test(call) || isCollectionForEach(call, qualifier))) return null;
PsiExpression arg = call.getArgumentList().getExpressions()[0];
@@ -195,7 +195,8 @@ public class SimplifyForEachInspection extends BaseJavaBatchLocalInspectionTool
return result;
}
- static SimplifyForEachContext from(PsiMethodCallExpression call) {
+ static SimplifyForEachContext from(@Nullable PsiMethodCallExpression call) {
+ if (call == null) return null;
PsiLambdaExpression lambda = extractLambdaFromForEach(call);
if (lambda == null) return null;
PsiElement lambdaBody = lambda.getBody();
diff --git a/java/java-impl/src/com/intellij/codeInspection/streamToLoop/SourceOperation.java b/java/java-impl/src/com/intellij/codeInspection/streamToLoop/SourceOperation.java
index 477c0bffc4a9..bfa9c3b839ce 100644
--- a/java/java-impl/src/com/intellij/codeInspection/streamToLoop/SourceOperation.java
+++ b/java/java-impl/src/com/intellij/codeInspection/streamToLoop/SourceOperation.java
@@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
+import java.util.Objects;
import java.util.function.Consumer;
import static com.intellij.codeInspection.streamToLoop.FunctionHelper.replaceVarReference;
@@ -106,6 +107,14 @@ abstract class SourceOperation extends Operation {
CommonClassNames.JAVA_UTIL_ARRAYS.equals(className)) {
return new ForEachSource(args[0]);
}
+ if (name.equals("stream") &&
+ args.length == 3 &&
+ CommonClassNames.JAVA_UTIL_ARRAYS.equals(className) &&
+ args[0].getType() != null &&
+ PsiType.INT.equals(args[1].getType()) &&
+ PsiType.INT.equals(args[2].getType())) {
+ return new ArraySliceSource(args[0], args[1], args[2]);
+ }
if (supportUnknownSources) {
PsiType type = StreamApiUtil.getStreamElementType(call.getType(), false);
if (type != null) {
@@ -320,6 +329,54 @@ abstract class SourceOperation extends Operation {
}
}
+ static class ArraySliceSource extends SourceOperation {
+ private @NotNull PsiExpression myArray;
+ private @NotNull PsiExpression myOrigin;
+ private @NotNull PsiExpression myBound;
+ private @NotNull PsiType myArrayType;
+
+ ArraySliceSource(@NotNull PsiExpression array, @NotNull PsiExpression origin, @NotNull PsiExpression bound) {
+ myOrigin = origin;
+ myBound = bound;
+ myArray = array;
+ myArrayType = Objects.requireNonNull(myArray.getType());
+ }
+
+ @Override
+ void rename(String oldName, String newName, StreamToLoopReplacementContext context) {
+ myOrigin = replaceVarReference(myOrigin, oldName, newName, context);
+ myBound = replaceVarReference(myBound, oldName, newName, context);
+ myArray = replaceVarReference(myArray, oldName, newName, context);
+ }
+
+ @Override
+ public void registerReusedElements(Consumer consumer) {
+ consumer.accept(myOrigin);
+ consumer.accept(myBound);
+ consumer.accept(myArray);
+ }
+
+ @Override
+ String wrap(StreamVariable outVar, String code, StreamToLoopReplacementContext context) {
+ String bound = myBound.getText();
+ String array = myArray.getText();
+ if (!ExpressionUtils.isSimpleExpression(context.createExpression(array))) {
+ array = context.declare("array", myArrayType.getCanonicalText(), array);
+ }
+ if (!ExpressionUtils.isSimpleExpression(context.createExpression(bound))) {
+ bound = context.declare("bound", "int", bound);
+ }
+ String loopVar = context.registerVarName(Arrays.asList("i", "j", "idx"));
+ String element = outVar.getDeclaration(array + "[" + loopVar + "]");
+ return context.getLoopLabel() +
+ "for(" + "int " + loopVar + " = " + myOrigin.getText() + ";" +
+ loopVar + "<" + bound + ";" +
+ loopVar + "++) {\n" +
+ element +
+ code + "}\n";
+ }
+ }
+
private static class StreamIteratorSource extends SourceOperation {
private final String myElementType;
private PsiMethodCallExpression myCall;
diff --git a/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValue.java b/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValue.java
index 0cdfd0ac57e3..fe32c0f5f132 100644
--- a/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValue.java
+++ b/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValue.java
@@ -25,6 +25,7 @@ import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiReference;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -54,7 +55,7 @@ public class UnusedReturnValue extends GlobalJavaBatchInspectionTool{
if (!refMethod.isReturnValueUsed()) {
final PsiMethod psiMethod = (PsiMethod)refMethod.getElement();
if (psiMethod == null) return null;
- if (IGNORE_BUILDER_PATTERN && PropertyUtil.isSimplePropertySetter(psiMethod)) return null;
+ if (IGNORE_BUILDER_PATTERN && PropertyUtilBase.isSimplePropertySetter(psiMethod)) return null;
final boolean isNative = psiMethod.hasModifierProperty(PsiModifier.NATIVE);
if (refMethod.isExternalOverride() && !isNative) return null;
diff --git a/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValueLocalInspection.java b/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValueLocalInspection.java
index 0191c56131d0..7ec7cffee589 100644
--- a/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValueLocalInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValueLocalInspection.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.patterns.PsiJavaPatterns;
import com.intellij.psi.*;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.siyeh.ig.psiutils.MethodUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -61,7 +62,7 @@ public class UnusedReturnValueLocalInspection extends BaseJavaLocalInspectionToo
public ProblemDescriptor[] checkMethod(@NotNull PsiMethod method, @NotNull InspectionManager manager, boolean isOnTheFly) {
if (method.isConstructor() ||
PsiType.VOID.equals(method.getReturnType()) ||
- myGlobal.IGNORE_BUILDER_PATTERN && PropertyUtil.isSimplePropertySetter(method) ||
+ myGlobal.IGNORE_BUILDER_PATTERN && PropertyUtilBase.isSimplePropertySetter(method) ||
method.hasModifierProperty(PsiModifier.NATIVE) ||
MethodUtils.hasSuper(method) ||
RefUtil.isImplicitRead(method)) return null;
diff --git a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java
index 8b56b0a431c6..cf8bf3f4ee5a 100644
--- a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java
+++ b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java
@@ -34,10 +34,7 @@ import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.FunctionalExpressionSearch;
import com.intellij.psi.search.searches.MethodReferencesSearch;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
-import com.intellij.psi.util.PropertyUtil;
-import com.intellij.psi.util.PsiSuperMethodUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.psi.util.*;
import com.intellij.refactoring.util.JavaNonCodeSearchElementDescriptionProvider;
import com.intellij.refactoring.util.NonCodeSearchDescriptionLocation;
import com.intellij.usageView.UsageInfo;
@@ -177,13 +174,13 @@ public class JavaFindUsagesHandler extends FindUsagesHandler{
final String propertyName = JavaCodeStyleManager.getInstance(getProject()).variableNameToPropertyName(fieldName, VariableKind.FIELD);
Set accessors = new THashSet<>();
boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
- PsiMethod getter = PropertyUtil.findPropertyGetterWithType(propertyName, isStatic, field.getType(),
- ContainerUtil.iterate(containingClass.getMethods()));
+ PsiMethod getter = PropertyUtilBase.findPropertyGetterWithType(propertyName, isStatic, field.getType(),
+ ContainerUtil.iterate(containingClass.getMethods()));
if (getter != null) accessors.add(getter);
- PsiMethod setter = PropertyUtil.findPropertySetterWithType(propertyName, isStatic, field.getType(),
- ContainerUtil.iterate(containingClass.getMethods()));
+ PsiMethod setter = PropertyUtilBase.findPropertySetterWithType(propertyName, isStatic, field.getType(),
+ ContainerUtil.iterate(containingClass.getMethods()));
if (setter != null) accessors.add(setter);
- accessors.addAll(PropertyUtil.getAccessors(containingClass, fieldName));
+ accessors.addAll(PropertyUtilBase.getAccessors(containingClass, fieldName));
if (!accessors.isEmpty()) {
boolean containsPhysical = ContainerUtil.find(accessors, psiMethod -> psiMethod.isPhysical()) != null;
final boolean doSearch = !containsPhysical || askShouldSearchAccessors(fieldName);
diff --git a/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java b/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java
index 13330c14052e..5a2afe6db2da 100644
--- a/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java
+++ b/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java
@@ -16,28 +16,20 @@
package com.intellij.openapi.projectRoots.impl;
import com.intellij.icons.AllIcons;
-import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.application.PathManager;
-import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.FileTypes;
-import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
-import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.projectRoots.*;
import com.intellij.openapi.roots.*;
-import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
-import com.intellij.openapi.util.EmptyRunnable;
-import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.jrt.JrtFileSystem;
-import com.intellij.util.IncorrectOperationException;
import com.intellij.util.PathUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
@@ -410,7 +402,7 @@ public class JavaSdkImpl extends JavaSdk {
addClasses(jdkHomeFile, sdkModificator, isJre);
addSources(jdkHomeFile, sdkModificator);
- return new MockSdk(jdkName, homePath, jdkName, roots, isJre);
+ return new MockSdk(jdkName, homePath, jdkName, roots, this);
}
private static void addClasses(@NotNull File file, @NotNull SdkModificator sdkModificator, boolean isJre) {
@@ -544,182 +536,4 @@ public class JavaSdkImpl extends JavaSdk {
type == JavadocOrderRootType.getInstance() ||
type == AnnotationOrderRootType.getInstance();
}
-
- private class MockSdk implements Sdk, SdkModificator {
- private String myJdkName;
- private String myHomePath;
- @NotNull private String myVersionString;
- private final MultiMap myRoots;
- private final boolean myIsJre;
-
- MockSdk(@NotNull String jdkName,
- @NotNull String homePath,
- @NotNull String versionString,
- @NotNull MultiMap roots,
- boolean isJre) {
- myJdkName = jdkName;
- myHomePath = homePath;
- myVersionString = versionString;
- myRoots = roots;
- myIsJre = isJre;
- }
-
- @NotNull
- @Override
- public SdkTypeId getSdkType() {
- return JavaSdkImpl.this;
- }
-
- @NotNull
- @Override
- public String getName() {
- return myJdkName;
- }
-
- @NotNull
- @Override
- public String getVersionString() {
- return myVersionString;
- }
-
- @Override
- public String getHomePath() {
- return myHomePath;
- }
-
- @Nullable
- @Override
- public VirtualFile getHomeDirectory() {
- return LocalFileSystem.getInstance().findFileByPath(myHomePath);
- }
-
- @Nullable
- @Override
- public SdkAdditionalData getSdkAdditionalData() {
- return null;
- }
-
- @NotNull
- @Override
- public Sdk clone() {
- return new MockSdk(myJdkName, myHomePath, myVersionString, new MultiMap<>(myRoots), myIsJre){
- @NotNull
- @Override
- public SdkModificator getSdkModificator() {
- return this;
- }
- };
- }
-
- @NotNull
- @Override
- public SdkModificator getSdkModificator() {
- throwReadOnly();
- return null;
- }
-
- @NotNull
- public VirtualFile[] getRoots(@NotNull OrderRootType rootType) {
- return myRoots.get(rootType).toArray(VirtualFile.EMPTY_ARRAY);
- }
-
- @Override
- public void setName(String name) {
- myJdkName = name;
- }
-
- @Override
- public void setHomePath(String path) {
- myHomePath = path;
- }
-
- @Override
- public void setVersionString(@NotNull String versionString) {
- myVersionString = versionString;
- }
-
- @Override
- public void setSdkAdditionalData(SdkAdditionalData data) {
- throwReadOnly();
- }
-
- @Override
- public void addRoot(@NotNull VirtualFile root, @NotNull OrderRootType rootType) {
- myRoots.putValue(rootType, root);
- }
-
- @Override
- public void removeRoot(@NotNull VirtualFile root, @NotNull OrderRootType rootType) {
- myRoots.remove(rootType, root);
- }
-
- @Override
- public void removeRoots(@NotNull OrderRootType rootType) {
- myRoots.remove(rootType);
- }
-
- @Override
- public void removeAllRoots() {
- myRoots.clear();
- }
-
- @Override
- public void commitChanges() {
- for (Project project : ProjectManager.getInstance().getOpenProjects()) {
- WriteAction.run(() -> ((ProjectRootManagerEx)ProjectRootManager.getInstance(project)).makeRootsChange(EmptyRunnable.getInstance(), false, true));
- }
- }
-
- @Override
- public boolean isWritable() {
- return true;
- }
-
- @NotNull
- @Override
- public RootProvider getRootProvider() {
- return new RootProvider() {
- @NotNull
- @Override
- public String[] getUrls(@NotNull OrderRootType rootType) {
- return ContainerUtil.map2Array(getFiles(rootType), String.class, VirtualFile::getUrl);
- }
-
- @NotNull
- @Override
- public VirtualFile[] getFiles(@NotNull OrderRootType rootType) {
- return getRoots(rootType);
- }
-
- @Override
- public void addRootSetChangedListener(@NotNull RootSetChangedListener listener) { }
-
- @Override
- public void addRootSetChangedListener(@NotNull RootSetChangedListener listener, @NotNull Disposable parentDisposable) { }
-
- @Override
- public void removeRootSetChangedListener(@NotNull RootSetChangedListener listener) { }
- };
- }
-
- private void throwReadOnly() {
- throw new IncorrectOperationException("Can't modify, MockJDK is read-only, consider calling .clone() first");
- }
-
- @Nullable
- @Override
- public T getUserData(@NotNull Key key) {
- return null;
- }
-
- @Override
- public void putUserData(@NotNull Key key, @Nullable T value) {
- throwReadOnly();
- }
-
- @Override
- public String toString() {
- return "MockSDK[" + myJdkName + "]";
- }
- }
}
\ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java
index 83b9b749a4fb..8df4fa8be2ec 100644
--- a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java
+++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java
@@ -24,6 +24,7 @@ import com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens;
import com.intellij.psi.search.searches.SuperMethodsSearch;
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Functions;
import com.intellij.util.containers.ContainerUtil;
@@ -427,13 +428,13 @@ public class JavaArrangementVisitor extends JavaRecursiveElementVisitor {
private void parseProperties(PsiMethod method, JavaElementArrangementEntry entry) {
String propertyName = null;
boolean getter = true;
- if (PropertyUtil.isSimplePropertyGetter(method)) {
+ if (PropertyUtilBase.isSimplePropertyGetter(method)) {
entry.addModifier(GETTER);
- propertyName = PropertyUtil.getPropertyNameByGetter(method);
+ propertyName = PropertyUtilBase.getPropertyNameByGetter(method);
}
- else if (PropertyUtil.isSimplePropertySetter(method)) {
+ else if (PropertyUtilBase.isSimplePropertySetter(method)) {
entry.addModifier(SETTER);
- propertyName = PropertyUtil.getPropertyNameBySetter(method);
+ propertyName = PropertyUtilBase.getPropertyNameBySetter(method);
getter = false;
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/beanProperties/BeanProperty.java b/java/java-impl/src/com/intellij/psi/impl/beanProperties/BeanProperty.java
index a21a9abae12f..b362aabca520 100644
--- a/java/java-impl/src/com/intellij/psi/impl/beanProperties/BeanProperty.java
+++ b/java/java-impl/src/com/intellij/psi/impl/beanProperties/BeanProperty.java
@@ -22,6 +22,7 @@ import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.PsiType;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -51,13 +52,13 @@ public class BeanProperty {
@NotNull
public String getName() {
- final String name = PropertyUtil.getPropertyName(myMethod);
+ final String name = PropertyUtilBase.getPropertyName(myMethod);
return name == null ? "" : name;
}
@NotNull
public PsiType getPropertyType() {
- PsiType type = PropertyUtil.getPropertyType(myMethod);
+ PsiType type = PropertyUtilBase.getPropertyType(myMethod);
assert type != null;
return type;
}
@@ -69,29 +70,29 @@ public class BeanProperty {
@Nullable
public PsiMethod getGetter() {
- if (PropertyUtil.isSimplePropertyGetter(myMethod)) {
+ if (PropertyUtilBase.isSimplePropertyGetter(myMethod)) {
return myMethod;
}
- return PropertyUtil.findPropertyGetter(myMethod.getContainingClass(), getName(), false, true);
+ return PropertyUtilBase.findPropertyGetter(myMethod.getContainingClass(), getName(), false, true);
}
@Nullable
public PsiMethod getSetter() {
- if (PropertyUtil.isSimplePropertySetter(myMethod)) {
+ if (PropertyUtilBase.isSimplePropertySetter(myMethod)) {
return myMethod;
}
- return PropertyUtil.findPropertySetter(myMethod.getContainingClass(), getName(), false, true);
+ return PropertyUtilBase.findPropertySetter(myMethod.getContainingClass(), getName(), false, true);
}
public void setName(String newName) throws IncorrectOperationException {
final PsiMethod setter = getSetter();
final PsiMethod getter = getGetter();
if (getter != null) {
- final String getterName = PropertyUtil.suggestGetterName(newName, getter.getReturnType());
+ final String getterName = PropertyUtilBase.suggestGetterName(newName, getter.getReturnType());
getter.setName(getterName);
}
if (setter != null) {
- final String setterName = PropertyUtil.suggestSetterName(newName);
+ final String setterName = PropertyUtilBase.suggestSetterName(newName);
setter.setName(setterName);
}
}
@@ -103,6 +104,6 @@ public class BeanProperty {
@Nullable
public static BeanProperty createBeanProperty(@NotNull PsiMethod method) {
- return PropertyUtil.isSimplePropertyAccessor(method) ? new BeanProperty(method) : null;
+ return PropertyUtilBase.isSimplePropertyAccessor(method) ? new BeanProperty(method) : null;
}
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/beanProperties/BeanPropertyElement.java b/java/java-impl/src/com/intellij/psi/impl/beanProperties/BeanPropertyElement.java
index 602db4863edd..8842925bfd3e 100644
--- a/java/java-impl/src/com/intellij/psi/impl/beanProperties/BeanPropertyElement.java
+++ b/java/java-impl/src/com/intellij/psi/impl/beanProperties/BeanPropertyElement.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * 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.
@@ -27,6 +27,7 @@ import com.intellij.psi.meta.PsiMetaData;
import com.intellij.psi.meta.PsiMetaOwner;
import com.intellij.psi.meta.PsiPresentableMetaData;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -48,7 +49,7 @@ public class BeanPropertyElement extends FakePsiElement implements PsiMetaOwner,
@Nullable
public PsiType getPropertyType() {
- return PropertyUtil.getPropertyType(myMethod);
+ return PropertyUtilBase.getPropertyType(myMethod);
}
@NotNull
diff --git a/java/java-impl/src/com/intellij/psi/impl/beanProperties/CreateJavaBeanPropertyFix.java b/java/java-impl/src/com/intellij/psi/impl/beanProperties/CreateJavaBeanPropertyFix.java
index e435264e8b76..176377c32915 100644
--- a/java/java-impl/src/com/intellij/psi/impl/beanProperties/CreateJavaBeanPropertyFix.java
+++ b/java/java-impl/src/com/intellij/psi/impl/beanProperties/CreateJavaBeanPropertyFix.java
@@ -28,6 +28,7 @@ import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -125,7 +126,7 @@ public class CreateJavaBeanPropertyFix implements LocalQuickFix, IntentionAction
private void createSetter(final boolean createField) throws IncorrectOperationException {
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(myPsiClass.getProject()).getElementFactory();
- final String methodName = PropertyUtil.suggestSetterName(myPropertyName);
+ final String methodName = PropertyUtilBase.suggestSetterName(myPropertyName);
final String typeName = myType.getCanonicalText();
@NonNls final String text;
@@ -154,7 +155,7 @@ public class CreateJavaBeanPropertyFix implements LocalQuickFix, IntentionAction
private void createGetter(final boolean createField) throws IncorrectOperationException {
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(myPsiClass.getProject()).getElementFactory();
- final String methodName = PropertyUtil.suggestGetterName(myPropertyName, myType);
+ final String methodName = PropertyUtilBase.suggestGetterName(myPropertyName, myType);
final String typeName = myType.getCanonicalText();
@NonNls final String text;
PsiClass psiClass = myPsiClass.getElement();
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/MethodPropertyReference.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/MethodPropertyReference.java
index 307d608ddbd8..96a513343cbb 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/MethodPropertyReference.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/MethodPropertyReference.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -18,6 +18,7 @@ package com.intellij.psi.impl.source.resolve.reference.impl.providers;
import com.intellij.psi.*;
import com.intellij.psi.jsp.JspSpiUtil;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlTag;
@@ -89,7 +90,7 @@ public class MethodPropertyReference extends BasicAttributeValueReference {
@Override
public PsiElement handleElementRename(String _newElementName) throws IncorrectOperationException {
- String newElementName = PropertyUtil.getPropertyName(_newElementName);
+ String newElementName = PropertyUtilBase.getPropertyName(_newElementName);
if (newElementName == null) newElementName = _newElementName;
return super.handleElementRename(newElementName);
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PsiPackageReference.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PsiPackageReference.java
index 658ea9b99826..6a7e652b46d1 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PsiPackageReference.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PsiPackageReference.java
@@ -20,9 +20,12 @@ import com.intellij.codeInsight.daemon.JavaErrorMessages;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
-import java.util.*;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
public class PsiPackageReference extends PsiPolyVariantReferenceBase implements EmptyResolveMessageProvider {
private final PackageReferenceSet myReferenceSet;
@@ -52,7 +55,7 @@ public class PsiPackageReference extends PsiPolyVariantReferenceBase
public Object[] getVariants() {
Set subPackages = new HashSet<>();
for (PsiPackage psiPackage : getContext()) {
- subPackages.addAll(Arrays.asList(psiPackage.getSubPackages(myReferenceSet.getResolveScope())));
+ ContainerUtil.addAll(subPackages, psiPackage.getSubPackages(myReferenceSet.getResolveScope()));
}
return subPackages.toArray();
}
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java
index 8860f67e1808..68e0f059fdcb 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java
@@ -35,10 +35,7 @@ import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.util.PropertyUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.psi.util.*;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.classMembers.MemberInfoBase;
@@ -257,7 +254,7 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor {
myInnerClass.add(outputField);
field = outputField;
} else {
- field = PropertyUtil.findPropertyField(myInnerClass, name, false);
+ field = PropertyUtilBase.findPropertyField(myInnerClass, name, false);
}
LOG.assertTrue(field != null, "i:" + i + "; output variables: " + Arrays.toString(outputVariables) + "; parameters: " + Arrays.toString(getMethod().getParameterList().getParameters()) + "; output field: " + outputField );
myInnerClass.add(GenerateMembersUtil.generateGetterPrototype(field));
diff --git a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java
index a100a5dafd31..90f8e168c163 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2016 JetBrains s.r.o.
+ * 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.
@@ -24,6 +24,7 @@ import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
@@ -33,10 +34,7 @@ import com.intellij.psi.javadoc.PsiDocTagValue;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.util.InheritanceUtil;
-import com.intellij.psi.util.PropertyUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.*;
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.RefactorJBundle;
import com.intellij.refactoring.extractclass.usageInfo.*;
@@ -602,7 +600,7 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
if (myGenerateAccessors) {
getter = GenerateMembersUtil.suggestGetterName(field);
} else {
- final PsiMethod fieldGetter = PropertyUtil.findPropertyGetter(sourceClass, field.getName(), false, false);
+ final PsiMethod fieldGetter = PropertyUtilBase.findPropertyGetter(sourceClass, field.getName(), false, false);
if (fieldGetter != null && isInMovedElement(fieldGetter)) {
getter = fieldGetter.getName();
}
@@ -612,7 +610,7 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
if (myGenerateAccessors) {
setter = GenerateMembersUtil.suggestSetterName(field);
} else {
- final PsiMethod fieldSetter = PropertyUtil.findPropertySetter(sourceClass, field.getName(), false, false);
+ final PsiMethod fieldSetter = PropertyUtilBase.findPropertySetter(sourceClass, field.getName(), false, false);
if (fieldSetter != null && isInMovedElement(fieldSetter)) {
setter = fieldSetter.getName();
}
@@ -707,7 +705,7 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
if (myMoveDestination != null) {
directory = myMoveDestination.getTargetDirectory(containingDirectory);
} else {
- final Module module = ModuleUtil.findModuleForPsiElement(containingFile);
+ final Module module = ModuleUtilCore.findModuleForPsiElement(containingFile);
assert module != null;
directory = PackageUtil.findOrCreateDirectoryForPackage(module, newPackageName, containingDirectory, false, true);
}
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/JavaIntroduceParameterObjectClassDescriptor.java b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/JavaIntroduceParameterObjectClassDescriptor.java
index 27d2b503261c..85a82a7ce492 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/JavaIntroduceParameterObjectClassDescriptor.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/JavaIntroduceParameterObjectClassDescriptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2016 JetBrains s.r.o.
+ * 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.
@@ -26,10 +26,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
-import com.intellij.psi.util.PropertyUtil;
-import com.intellij.psi.util.PsiTypesUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.psi.util.*;
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
import com.intellij.refactoring.introduceParameterObject.IntroduceParameterObjectClassDescriptor;
@@ -207,12 +204,12 @@ public class JavaIntroduceParameterObjectClassDescriptor extends IntroduceParame
bean.setField(field);
- final PsiMethod getterForField = PropertyUtil.findGetterForField(field);
+ final PsiMethod getterForField = PropertyUtilBase.findGetterForField(field);
if (getterForField != null) {
bean.setGetter(getterForField.getName());
}
- final PsiMethod setterForField = PropertyUtil.findSetterForField(field);
+ final PsiMethod setterForField = PropertyUtilBase.findSetterForField(field);
if (setterForField != null) {
bean.setSetter(setterForField.getName());
}
diff --git a/java/java-impl/src/com/intellij/refactoring/removemiddleman/RemoveMiddlemanProcessor.java b/java/java-impl/src/com/intellij/refactoring/removemiddleman/RemoveMiddlemanProcessor.java
index 0695ad6d34f1..aae5bd5cdcb8 100644
--- a/java/java-impl/src/com/intellij/refactoring/removemiddleman/RemoveMiddlemanProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/removemiddleman/RemoveMiddlemanProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
@@ -22,6 +22,7 @@ import com.intellij.psi.*;
import com.intellij.psi.presentation.java.SymbolPresentationUtil;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.refactoring.RefactorJBundle;
import com.intellij.refactoring.removemiddleman.usageInfo.DeleteMethod;
import com.intellij.refactoring.removemiddleman.usageInfo.InlineDelegatingCall;
@@ -48,9 +49,9 @@ public class RemoveMiddlemanProcessor extends FixableUsagesRefactoringProcessor
super(field.getProject());
this.field = field;
containingClass = field.getContainingClass();
- final String propertyName = PropertyUtil.suggestPropertyName(field);
+ final String propertyName = PropertyUtilBase.suggestPropertyName(field);
final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
- getter = PropertyUtil.findPropertyGetter(containingClass, propertyName, isStatic, false);
+ getter = PropertyUtilBase.findPropertyGetter(containingClass, propertyName, isStatic, false);
myDelegateMethodInfos = memberInfos;
}
diff --git a/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java b/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java
index 368309f84005..577b9392a0bc 100644
--- a/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
@@ -26,6 +26,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.impl.beanProperties.BeanProperty;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.refactoring.RenameRefactoring;
import com.intellij.refactoring.openapi.impl.JavaRenameRefactoringImpl;
import org.jetbrains.annotations.Contract;
@@ -91,7 +92,7 @@ public abstract class BeanPropertyRenameHandler implements RenameHandler {
final PsiElement setterSubstitutor = substituteElementToRename(setter, editor);
if (setterSubstitutor != null) {
if (setterSubstitutor == setter) {
- rename.addElement(setterSubstitutor, PropertyUtil.suggestSetterName(newName));
+ rename.addElement(setterSubstitutor, PropertyUtilBase.suggestSetterName(newName));
}
else {
rename.addElement(setterSubstitutor, newName);
@@ -110,7 +111,7 @@ public abstract class BeanPropertyRenameHandler implements RenameHandler {
final PsiElement getterSubstitutor = substituteElementToRename(getter, editor);
if (getterSubstitutor != null) {
if (getterSubstitutor == getter) {
- rename.addElement(getterSubstitutor, PropertyUtil.suggestGetterName(newName, getter.getReturnType()));
+ rename.addElement(getterSubstitutor, PropertyUtilBase.suggestGetterName(newName, getter.getReturnType()));
}
else {
rename.addElement(getterSubstitutor, newName);
diff --git a/java/java-impl/src/com/intellij/refactoring/rename/JavaNameSuggestionProvider.java b/java/java-impl/src/com/intellij/refactoring/rename/JavaNameSuggestionProvider.java
index fb4eedd640b5..87fdf3a194b4 100644
--- a/java/java-impl/src/com/intellij/refactoring/rename/JavaNameSuggestionProvider.java
+++ b/java/java-impl/src/com/intellij/refactoring/rename/JavaNameSuggestionProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -23,6 +23,7 @@ import com.intellij.psi.codeStyle.NameUtil;
import com.intellij.psi.codeStyle.SuggestedNameInfo;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.ArrayUtil;
@@ -48,7 +49,7 @@ public class JavaNameSuggestionProvider implements NameSuggestionProvider {
if (nameSuggestionContextParent instanceof PsiParameterList) {
final PsiElement parentOfParent = nameSuggestionContextParent.getParent();
if (parentOfParent instanceof PsiMethod) {
- final String propName = PropertyUtil.getPropertyName((PsiMethod)parentOfParent);
+ final String propName = PropertyUtilBase.getPropertyName((PsiMethod)parentOfParent);
if (propName != null) {
parameterName = propName;
}
diff --git a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java
index 507068fb4624..30c0218c56c2 100644
--- a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2016 JetBrains s.r.o.
+ * 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.
@@ -28,6 +28,7 @@ import com.intellij.psi.controlFlow.ControlFlowUtil;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.HelpID;
@@ -148,14 +149,14 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
Project project = field.getProject();
final JavaCodeStyleManager manager = JavaCodeStyleManager.getInstance(project);
- final String propertyName = PropertyUtil.suggestPropertyName(field, field.getName());
- final String newPropertyName = PropertyUtil.suggestPropertyName(field, newName);
+ final String propertyName = PropertyUtilBase.suggestPropertyName(field, field.getName());
+ final String newPropertyName = PropertyUtilBase.suggestPropertyName(field, newName);
boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
PsiMethod[] getters = GetterSetterPrototypeProvider.findGetters(aClass, propertyName, isStatic);
- PsiMethod setter = PropertyUtil.findPropertySetter(aClass, propertyName, isStatic, false);
+ PsiMethod setter = PropertyUtilBase.findPropertySetter(aClass, propertyName, isStatic, false);
boolean shouldRenameSetterParameter = false;
@@ -170,7 +171,7 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
String getterId = null;
if (newGetterName == null) {
getterId = getter.getName();
- newGetterName = PropertyUtil.suggestGetterName(newPropertyName, field.getType(), getterId);
+ newGetterName = PropertyUtilBase.suggestGetterName(newPropertyName, field.getType(), getterId);
}
if (newGetterName.equals(getterId)) {
continue;
@@ -192,7 +193,7 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
String newSetterName = "";
if (setter != null) {
- newSetterName = PropertyUtil.suggestSetterName(newPropertyName);
+ newSetterName = PropertyUtilBase.suggestSetterName(newPropertyName);
final String newSetterParameterName = manager.propertyNameToVariableName(newPropertyName, VariableKind.PARAMETER);
if (newSetterName.equals(setter.getName())) {
setter = null;
@@ -222,7 +223,7 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
for (PsiMethod getter : getters) {
String newGetterName = GetterSetterPrototypeProvider.suggestNewGetterName(propertyName, newPropertyName, getter);
if (newGetterName == null) {
- newGetterName = PropertyUtil.suggestGetterName(newPropertyName, field.getType(), getter.getName());
+ newGetterName = PropertyUtilBase.suggestGetterName(newPropertyName, field.getType(), getter.getName());
}
addOverriddenAndImplemented(getter, newGetterName, null, propertyName, manager, allRenames);
}
diff --git a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ParameterData.java b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ParameterData.java
index 5479ca9ecc02..b31cc605d279 100644
--- a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ParameterData.java
+++ b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ParameterData.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -22,6 +22,7 @@ import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.refactoring.util.RefactoringUtil;
import java.util.Map;
@@ -87,7 +88,7 @@ public class ParameterData {
parameterData = new ParameterData(paramName, parameter.getType());
parameterData.setFieldName(styleManager.suggestVariableName(VariableKind.FIELD, uniqueParamName, null, parameter.getType()).names[0]);
- parameterData.setSetterName(PropertyUtil.suggestSetterName(uniqueParamName, setterPrefix));
+ parameterData.setSetterName(PropertyUtilBase.suggestSetterName(uniqueParamName, setterPrefix));
result.put(uniqueParamName, parameterData);
}
diff --git a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderDialog.java b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderDialog.java
index fb8fb60d5d72..f14c7ebf5450 100644
--- a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderDialog.java
@@ -37,6 +37,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.refactoring.PackageWrapper;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.move.moveClassesOrPackages.DestinationFolderComboBox;
@@ -154,7 +155,7 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog {
final ParameterData data = myParametersMap.get(paramName);
paramName = data.getParamName();
final String propertyName = javaCodeStyleManager.variableNameToPropertyName(paramName, VariableKind.PARAMETER);
- data.setSetterName(PropertyUtil.suggestSetterName(propertyName, setterPrefix));
+ data.setSetterName(PropertyUtilBase.suggestSetterName(propertyName, setterPrefix));
}
myTable.revalidate();
myTable.repaint();
diff --git a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java
index c33335187fd8..3ab38492196f 100644
--- a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
@@ -19,6 +19,7 @@ import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.ide.util.PackageUtil;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Ref;
@@ -29,10 +30,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.util.PropertyUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.psi.util.*;
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.replaceConstructorWithBuilder.usageInfo.ReplaceConstructorWithSettersChainInfo;
import com.intellij.refactoring.util.FixableUsageInfo;
@@ -118,7 +116,7 @@ public class ReplaceConstructorWithBuilderProcessor extends FixableUsagesRefacto
if (myMoveDestination != null) {
directory = myMoveDestination.getTargetDirectory(containingDirectory);
} else {
- final Module module = ModuleUtil.findModuleForPsiElement(containingFile);
+ final Module module = ModuleUtilCore.findModuleForPsiElement(containingFile);
assert module != null;
directory = PackageUtil.findOrCreateDirectoryForPackage(module, myPackageName, containingDirectory, true, true);
}
@@ -178,7 +176,7 @@ public class ReplaceConstructorWithBuilderProcessor extends FixableUsagesRefacto
}
}
if (setter == null) {
- setter = PropertyUtil.generateSetterPrototype(field, builderClass, true);
+ setter = PropertyUtilBase.generateSetterPrototype(field, builderClass, true);
final PsiIdentifier nameIdentifier = setter.getNameIdentifier();
assert nameIdentifier != null;
nameIdentifier.replace(myElementFactory.createIdentifier(parameterData.getSetterName()));
@@ -217,7 +215,7 @@ public class ReplaceConstructorWithBuilderProcessor extends FixableUsagesRefacto
private void fixSetterReturnType(PsiClass builderClass, PsiField field, PsiMethod method) {
if (PsiUtil.resolveClassInType(method.getReturnType()) != builderClass) {
final PsiCodeBlock body = method.getBody();
- final PsiCodeBlock generatedBody = PropertyUtil.generateSetterPrototype(field, builderClass, true).getBody();
+ final PsiCodeBlock generatedBody = PropertyUtilBase.generateSetterPrototype(field, builderClass, true).getBody();
assert body != null;
assert generatedBody != null;
body.replace(generatedBody);
diff --git a/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java b/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java
index 4e501efbd4cd..964ee645f568 100644
--- a/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java
@@ -35,10 +35,7 @@ import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.FunctionalExpressionSearch;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.util.MethodSignatureUtil;
-import com.intellij.psi.util.PropertyUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.*;
import com.intellij.refactoring.JavaRefactoringSettings;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.changeSignature.inCallers.AbstractJavaMemberCallerChooser;
@@ -233,7 +230,7 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase {
getters = validGetters.isEmpty() ? null : validGetters.toArray(new PsiMethod[validGetters.size()]);
}
- PsiMethod setter = PropertyUtil.findPropertySetter(aClass, propertyName, isStatic, false);
+ PsiMethod setter = PropertyUtilBase.findPropertySetter(aClass, propertyName, isStatic, false);
if (allElementsToDelete.contains(setter) || setter != null && !setter.isPhysical()) setter = null;
if (askUser && (getters != null || setter != null)) {
final String message =
@@ -928,7 +925,7 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase {
return true;
});
- PsiMethod setterPrototype = PropertyUtil.generateSetterPrototype(psiField, psiField.getContainingClass());
+ PsiMethod setterPrototype = PropertyUtilBase.generateSetterPrototype(psiField, psiField.getContainingClass());
PsiParameter setterParameter = setterPrototype.getParameterList().getParameters()[0];
for (PsiParameter parameter : parameters) {
PsiElement scope = parameter.getDeclarationScope();
diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationStatementProcessor.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationStatementProcessor.java
index 26ee4011e98a..d10ab603419d 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationStatementProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationStatementProcessor.java
@@ -705,7 +705,8 @@ class TypeMigrationStatementProcessor extends JavaRecursiveElementVisitor {
PsiField field = (PsiField) resolved;
final NavigatablePsiElement containingMethod = PsiTreeUtil.getParentOfType(expression, PsiMethod.class, PsiLambdaExpression.class);
if (containingMethod instanceof PsiMethod) {
- final PsiMethod setter = PropertyUtil.findPropertySetter(field.getContainingClass(), field.getName(), field.hasModifierProperty(PsiModifier.STATIC), false);
+ final PsiMethod setter = PropertyUtilBase
+ .findPropertySetter(field.getContainingClass(), field.getName(), field.hasModifierProperty(PsiModifier.STATIC), false);
if (containingMethod.isEquivalentTo(setter)) {
return true;
}
diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java
index 155686ea8938..7c1dc1fd0004 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java
@@ -1401,14 +1401,14 @@ public class RefactoringUtil {
}
private static void collectTypeParametersInDependencies(Condition filter, Set used) {
- HashSet typeParametersInDependencies = new HashSet<>();
- for (PsiTypeParameter parameter : used) {
- collectTypeParameters(typeParametersInDependencies, parameter, filter);
- }
- typeParametersInDependencies.removeAll(used);
- if (!typeParametersInDependencies.isEmpty()) {
- collectTypeParametersInDependencies(filter, typeParametersInDependencies);
- used.addAll(typeParametersInDependencies);
+ Stack toProcess = new Stack<>();
+ toProcess.addAll(used);
+ while (!toProcess.isEmpty()) {
+ PsiTypeParameter parameter = toProcess.pop();
+ HashSet dependencies = new HashSet<>();
+ collectTypeParameters(dependencies, parameter, param -> filter.value(param) && !used.contains(param));
+ used.addAll(dependencies);
+ toProcess.addAll(dependencies);
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java b/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java
index e87ddf3a3994..1a85b1e5fe06 100644
--- a/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
@@ -31,6 +31,7 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.MoveDestination;
@@ -110,7 +111,7 @@ public class WrapReturnValueProcessor extends FixableUsagesRefactoringProcessor
return unboxedType.getCanonicalText() + "Value()";
}
- final PsiMethod getter = PropertyUtil.findGetterForField(myDelegateField);
+ final PsiMethod getter = PropertyUtilBase.findGetterForField(myDelegateField);
return getter != null ? getter.getName() : "";
}
return "";
diff --git a/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java b/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java
index 3a17ca5cc22b..dfcf46afc401 100644
--- a/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java
+++ b/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java
@@ -59,6 +59,7 @@ import com.intellij.testIntegration.TestFramework;
import com.intellij.testIntegration.TestIntegrationUtils;
import com.intellij.ui.*;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.JBUI;
import org.jetbrains.annotations.NotNull;
@@ -355,8 +356,7 @@ public class CreateTestDialog extends DialogWrapper {
final DefaultComboBoxModel model = (DefaultComboBoxModel)myLibrariesCombo.getModel();
- final List descriptors = new ArrayList<>();
- descriptors.addAll(Arrays.asList(Extensions.getExtensions(TestFramework.EXTENSION_NAME)));
+ final List descriptors = new SmartList<>(Extensions.getExtensions(TestFramework.EXTENSION_NAME));
descriptors.sort((d1, d2) -> Comparing.compare(d1.getName(), d2.getName()));
for (final TestFramework descriptor : descriptors) {
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaOverridingMethodsSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaOverridingMethodsSearcher.java
index 09eff7dbd55a..786401480ac4 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaOverridingMethodsSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaOverridingMethodsSearcher.java
@@ -147,10 +147,10 @@ public class JavaOverridingMethodsSearcher implements QueryExecutor 0) {
PsiMethod found = MethodSignatureUtil.findMethodBySuperSignature(inheritor, getSuperSignature(inheritor, methodContainingClass, method), false);
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/SimpleAccessorReferenceSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/SimpleAccessorReferenceSearcher.java
index 4d939ddd3e1b..71cd62b649b9 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/SimpleAccessorReferenceSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/SimpleAccessorReferenceSearcher.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -27,6 +27,7 @@ import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.UsageSearchContext;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
@@ -47,7 +48,7 @@ public class SimpleAccessorReferenceSearcher extends QueryExecutorBase modListInfo = parseModifierList(builder);
ReferenceParser.TypeInfo typeInfo = null;
if (typed) {
- int flags = ReferenceParser.EAT_LAST_DOT | ReferenceParser.WILDCARD;
- if (ellipsis) flags |= ReferenceParser.ELLIPSIS;
- if (disjunctiveType) flags |= ReferenceParser.DISJUNCTIONS;
+ int flags = ReferenceParser.EAT_LAST_DOT | ReferenceParser.WILDCARD | typeFlags;
typeInfo = myParser.getReferenceParser().parseTypeInfo(builder, flags);
if (typeInfo == null) {
diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java
index 1471eaaff3c8..58856a1e8502 100644
--- a/java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java
+++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.daemon.JavaErrorMessages;
import com.intellij.lang.PsiBuilder;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.JavaTokenType;
+import com.intellij.psi.PsiKeyword;
import com.intellij.psi.impl.source.tree.ElementType;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.tree.IElementType;
@@ -39,6 +40,7 @@ public class ReferenceParser {
public static final int DISJUNCTIONS = 0x10;
public static final int CONJUNCTIONS = 0x20;
public static final int INCOMPLETE_ANNO = 0x40;
+ public static final int VAR_TYPE = 0x80;
public static class TypeInfo {
public boolean isPrimitive;
@@ -94,12 +96,22 @@ public class ReferenceParser {
private TypeInfo parseTypeInfo(PsiBuilder builder, int flags, boolean badWildcard) {
if (builder.getTokenType() == null) return null;
- final TypeInfo typeInfo = new TypeInfo();
+ TypeInfo typeInfo = new TypeInfo();
PsiBuilder.Marker type = builder.mark();
PsiBuilder.Marker anno = myParser.getDeclarationParser().parseAnnotations(builder);
- final IElementType tokenType = builder.getTokenType();
+ IElementType tokenType = builder.getTokenType();
+ if (tokenType == JavaTokenType.IDENTIFIER &&
+ isSet(flags, VAR_TYPE) &&
+ PsiKeyword.VAR.equals(builder.getTokenText()) &&
+ getLanguageLevel(builder).isAtLeast(LanguageLevel.JDK_X)) {
+ builder.remapCurrentToken(tokenType = JavaTokenType.VAR_KEYWORD);
+ }
+ else if (tokenType == JavaTokenType.VAR_KEYWORD && !isSet(flags, VAR_TYPE)) {
+ builder.remapCurrentToken(tokenType = JavaTokenType.IDENTIFIER);
+ }
+
if (expect(builder, ElementType.PRIMITIVE_TYPE_BIT_SET)) {
typeInfo.isPrimitive = true;
}
@@ -117,6 +129,12 @@ public class ReferenceParser {
else if (tokenType == JavaTokenType.IDENTIFIER) {
parseJavaCodeReference(builder, isSet(flags, EAT_LAST_DOT), true, false, false, false, isSet(flags, DIAMONDS), typeInfo);
}
+ else if (tokenType == JavaTokenType.VAR_KEYWORD) {
+ builder.advanceLexer();
+ type.done(JavaElementType.TYPE);
+ typeInfo.marker = type;
+ return typeInfo;
+ }
else if (isSet(flags, DIAMONDS) && tokenType == JavaTokenType.GT) {
if (anno == null) {
emptyElement(builder, JavaElementType.DIAMOND_TYPE);
@@ -144,7 +162,7 @@ public class ReferenceParser {
type.done(JavaElementType.TYPE);
myParser.getDeclarationParser().parseAnnotations(builder);
- final PsiBuilder.Marker bracket = builder.mark();
+ PsiBuilder.Marker bracket = builder.mark();
if (!expect(builder, JavaTokenType.LBRACKET)) {
bracket.drop();
break;
diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/StatementParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/StatementParser.java
index 4c96f87178f3..0bcebeb31479 100644
--- a/java/java-psi-impl/src/com/intellij/lang/java/parser/StatementParser.java
+++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/StatementParser.java
@@ -319,7 +319,7 @@ public class StatementParser {
}
final PsiBuilder.Marker afterParenth = builder.mark();
- final PsiBuilder.Marker param = myParser.getDeclarationParser().parseParameter(builder, false, false);
+ final PsiBuilder.Marker param = myParser.getDeclarationParser().parseParameter(builder, false, false, true);
if (param == null || exprType(param) != JavaElementType.PARAMETER || builder.getTokenType() != JavaTokenType.COLON) {
afterParenth.rollbackTo();
return parseForLoopFromInitializer(builder, statement);
@@ -616,7 +616,7 @@ public class StatementParser {
return false;
}
- final PsiBuilder.Marker param = myParser.getDeclarationParser().parseParameter(builder, false, true);
+ final PsiBuilder.Marker param = myParser.getDeclarationParser().parseParameter(builder, false, true, false);
if (param == null) {
error(builder, JavaErrorMessages.message("expected.parameter"));
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java
index f8c923862f8f..37c90b0806b6 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java
@@ -62,7 +62,7 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade {
private static final JavaParserUtil.ParserWrapper PARAMETER = new JavaParserUtil.ParserWrapper() {
@Override
public void parse(final PsiBuilder builder) {
- JavaParser.INSTANCE.getDeclarationParser().parseParameter(builder, true, false);
+ JavaParser.INSTANCE.getDeclarationParser().parseParameter(builder, true, false, false);
}
};
@@ -76,8 +76,8 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade {
private static final JavaParserUtil.ParserWrapper TYPE = new JavaParserUtil.ParserWrapper() {
@Override
public void parse(final PsiBuilder builder) {
- JavaParser.INSTANCE.getReferenceParser().parseType(builder, ReferenceParser.EAT_LAST_DOT | ReferenceParser.ELLIPSIS |
- ReferenceParser.WILDCARD | ReferenceParser.DISJUNCTIONS);
+ int flags = ReferenceParser.EAT_LAST_DOT | ReferenceParser.ELLIPSIS | ReferenceParser.WILDCARD | ReferenceParser.DISJUNCTIONS | ReferenceParser.VAR_TYPE;
+ JavaParser.INSTANCE.getReferenceParser().parseType(builder, flags);
}
};
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsClassImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsClassImpl.java
index 1dd7b6591b97..d79094064755 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsClassImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsClassImpl.java
@@ -61,7 +61,7 @@ public class ClsClassImpl extends ClsMemberImpl> implements PsiE
@NotNull
public PsiElement[] getChildren() {
List children = ContainerUtil.newArrayList();
- ContainerUtil.addAll(children, getChildren(getDocComment(), getModifierList(), getNameIdentifier(), getExtendsList(), getImplementsList()));
+ ContainerUtil.addAll(children, getChildren(getDocComment(), getModifierListInternal(), getNameIdentifier(), getExtendsList(), getImplementsList()));
ContainerUtil.addAll(children, getOwnFields());
ContainerUtil.addAll(children, getOwnMethods());
ContainerUtil.addAll(children, getOwnInnerClasses());
@@ -84,23 +84,37 @@ public class ClsClassImpl extends ClsMemberImpl> implements PsiE
public String getQualifiedName() {
return getStub().getQualifiedName();
}
-
- boolean isAnonymousOrLocalClass() {
+
+ private boolean isLocalClass() {
PsiClassStub> stub = getStub();
- return !(stub instanceof PsiClassStubImpl) ||
- ((PsiClassStubImpl)stub).isAnonymousInner() ||
+ return stub instanceof PsiClassStubImpl &&
((PsiClassStubImpl)stub).isLocalClassInner();
}
+ private boolean isAnonymousClass() {
+ PsiClassStub> stub = getStub();
+ return stub instanceof PsiClassStubImpl &&
+ ((PsiClassStubImpl)stub).isAnonymousInner();
+ }
+
+ private boolean isAnonymousOrLocalClass() {
+ return isAnonymousClass() || isLocalClass();
+ }
+
@Override
- @NotNull
+ @Nullable
public PsiModifierList getModifierList() {
+ if (isAnonymousClass()) return null;
+ return getModifierListInternal();
+ }
+
+ private PsiModifierList getModifierListInternal() {
return getStub().findChildStubByType(JavaStubElementTypes.MODIFIER_LIST).getPsi();
}
@Override
public boolean hasModifierProperty(@NotNull String name) {
- return getModifierList().hasModifierProperty(name);
+ return getModifierListInternal().hasModifierProperty(name);
}
@Override
@@ -348,7 +362,7 @@ public class ClsClassImpl extends ClsMemberImpl> implements PsiE
public void appendMirrorText(final int indentLevel, @NotNull @NonNls final StringBuilder buffer) {
appendText(getDocComment(), indentLevel, buffer, NEXT_LINE);
- appendText(getModifierList(), indentLevel, buffer);
+ appendText(getModifierListInternal(), indentLevel, buffer);
buffer.append(isEnum() ? "enum " : isAnnotationType() ? "@interface " : isInterface() ? "interface " : "class ");
appendText(getNameIdentifier(), indentLevel, buffer, " ");
appendText(getTypeParameterList(), indentLevel, buffer, " ");
@@ -435,7 +449,8 @@ public class ClsClassImpl extends ClsMemberImpl> implements PsiE
setMirrorIfPresent(getDocComment(), mirror.getDocComment());
- setMirror(getModifierList(), mirror.getModifierList());
+ PsiModifierList modifierList = getModifierList();
+ if (modifierList != null) setMirror(modifierList, mirror.getModifierList());
setMirror(getNameIdentifier(), mirror.getNameIdentifier());
setMirror(getTypeParameterList(), mirror.getTypeParameterList());
setMirror(getExtendsList(), mirror.getExtendsList());
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java
index 523d070d19a5..5f7f2c9c80fe 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java
@@ -94,6 +94,15 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
String text = child.getText();
type = annotations.isEmpty() ? PsiJavaParserFacadeImpl.getPrimitiveType(text) : new PsiPrimitiveType(text, createProvider(annotations));
}
+ else if (PsiUtil.isJavaToken(child, JavaTokenType.VAR_KEYWORD)) {
+ assert type == null : this;
+ for (PsiElement e = this; e != null; e = e.getNextSibling()) {
+ if (e instanceof PsiExpression) {
+ type = ((PsiExpression)e).getType();
+ break;
+ }
+ }
+ }
else if (child instanceof PsiJavaCodeReferenceElement) {
assert type == null : this;
type = new PsiClassReferenceType(getReferenceComputable((PsiJavaCodeReferenceElement)child), null, createProvider(annotations));
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/ElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/ElementType.java
index f504d7c65281..f7d14ca03561 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/ElementType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/ElementType.java
@@ -36,7 +36,7 @@ public interface ElementType extends JavaTokenType, JavaDocTokenType, JavaElemen
SWITCH_KEYWORD, SYNCHRONIZED_KEYWORD, THIS_KEYWORD, THROW_KEYWORD, THROWS_KEYWORD, TRANSIENT_KEYWORD, TRY_KEYWORD, VOID_KEYWORD,
VOLATILE_KEYWORD, WHILE_KEYWORD,
OPEN_KEYWORD, MODULE_KEYWORD, REQUIRES_KEYWORD, EXPORTS_KEYWORD, OPENS_KEYWORD, USES_KEYWORD, PROVIDES_KEYWORD,
- TRANSITIVE_KEYWORD, TO_KEYWORD, WITH_KEYWORD);
+ TRANSITIVE_KEYWORD, TO_KEYWORD, WITH_KEYWORD, VAR_KEYWORD);
TokenSet LITERAL_BIT_SET = TokenSet.create(TRUE_KEYWORD, FALSE_KEYWORD, NULL_KEYWORD);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java
index 48537ada61fd..03e3aac370a6 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java
@@ -244,10 +244,8 @@ public interface JavaElementType {
private final JavaParserUtil.ParserWrapper myParser = new JavaParserUtil.ParserWrapper() {
@Override
public void parse(final PsiBuilder builder) {
- JavaParser.INSTANCE.getReferenceParser().parseType(builder, ReferenceParser.EAT_LAST_DOT |
- ReferenceParser.ELLIPSIS |
- ReferenceParser.WILDCARD |
- myFlags);
+ int flags = ReferenceParser.EAT_LAST_DOT | ReferenceParser.ELLIPSIS | ReferenceParser.WILDCARD | myFlags;
+ JavaParser.INSTANCE.getReferenceParser().parseType(builder, flags);
}
};
diff --git a/java/java-tests/testData/codeInsight/completeStatement/IfWithoutParentheses.java b/java/java-tests/testData/codeInsight/completeStatement/IfWithoutParentheses.java
new file mode 100644
index 000000000000..eac3d7a16a23
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completeStatement/IfWithoutParentheses.java
@@ -0,0 +1,6 @@
+
+class Foo {
+ public void foo() {
+ if 1 > 2
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completeStatement/IfWithoutParentheses_after.java b/java/java-tests/testData/codeInsight/completeStatement/IfWithoutParentheses_after.java
new file mode 100644
index 000000000000..a2ca520e169f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completeStatement/IfWithoutParentheses_after.java
@@ -0,0 +1,8 @@
+
+class Foo {
+ public void foo() {
+ if (1 > 2) {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/keywords/finalInCompleteCatch.java b/java/java-tests/testData/codeInsight/completion/keywords/finalInCompleteCatch.java
new file mode 100644
index 000000000000..b907799d7799
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/keywords/finalInCompleteCatch.java
@@ -0,0 +1,9 @@
+public class X {
+ {
+ try {
+
+ } catch ( AssertionError error) {
+
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/completion/keywords/finalInCompleteTryWithResources.java b/java/java-tests/testData/codeInsight/completion/keywords/finalInCompleteTryWithResources.java
new file mode 100644
index 000000000000..72ccabe6f4a3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/keywords/finalInCompleteTryWithResources.java
@@ -0,0 +1,5 @@
+public class Util {
+ void foo() {
+ try ( Type var = val)
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/completion/keywords/returnInRussian.java b/java/java-tests/testData/codeInsight/completion/keywords/returnInRussian.java
new file mode 100644
index 000000000000..ab34191503ae
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/keywords/returnInRussian.java
@@ -0,0 +1,5 @@
+public class Util {
+ int goo() {
+ куку
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/completion/normal/NoDuplicateInCast.java b/java/java-tests/testData/codeInsight/completion/normal/NoDuplicateInCast.java
new file mode 100644
index 000000000000..10b937f946b2
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normal/NoDuplicateInCast.java
@@ -0,0 +1,11 @@
+class X {
+ void foo(Object o){
+ if (o instanceof Foo) {
+ ((Foo) o).bar();
+ }
+ }
+
+ class Foo {
+ void bar() {}
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/smartType/PreferLambdaOverGenericGetter.java b/java/java-tests/testData/codeInsight/completion/smartType/PreferLambdaOverGenericGetter.java
new file mode 100644
index 000000000000..4421fd3667eb
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/smartType/PreferLambdaOverGenericGetter.java
@@ -0,0 +1,10 @@
+class Foo {
+ void processImports(java.util.function.Predicate pr) {}
+
+ {
+ processImports();
+ }
+
+ static T getSomeGenericValue(T t) {}
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/PreferVariableToLambda.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/PreferVariableToLambda.java
new file mode 100644
index 000000000000..a1d1673828ba
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/PreferVariableToLambda.java
@@ -0,0 +1,11 @@
+interface I {
+ void foo(String out);
+}
+
+class Foo {
+ I output;
+
+ {
+ I r = out
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/simplifyForEach/beforeCompilationCtor.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/simplifyForEach/beforeCompilationCtor.java
new file mode 100644
index 000000000000..ab1c59ed889a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/simplifyForEach/beforeCompilationCtor.java
@@ -0,0 +1,12 @@
+// "Avoid mutation using Stream API 'count()' operation" "false"
+
+import java.util.*;
+
+public class Main {
+ // EA-107550 - NPE: SimplifyForEachInspection.extractLambdaFromForEach
+ void test() {
+ int x = 0;
+ class X {X(Runnable r) {}}
+ new X(() -> x++);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamToLoop/afterArraySlice.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamToLoop/afterArraySlice.java
new file mode 100644
index 000000000000..6096ceba9bbc
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamToLoop/afterArraySlice.java
@@ -0,0 +1,13 @@
+// "Replace Stream API chain with loop" "true"
+
+import java.util.Arrays;
+
+public class Test {
+ public static void test(String[] arr) {
+ int bound = arr.length - 1;
+ for (int i = 1; i < bound; i++) {
+ String s = arr[i];
+ System.out.println(s);
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamToLoop/beforeArraySlice.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamToLoop/beforeArraySlice.java
new file mode 100644
index 000000000000..853dabd4c91e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamToLoop/beforeArraySlice.java
@@ -0,0 +1,9 @@
+// "Replace Stream API chain with loop" "true"
+
+import java.util.Arrays;
+
+public class Test {
+ public static void test(String[] arr) {
+ Arrays.stream(arr, 1, arr.length - 1).forEach(System.out::println);
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollBreak.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollBreak.java
new file mode 100644
index 000000000000..b0ba681d1014
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollBreak.java
@@ -0,0 +1,19 @@
+// "Unroll loop" "true"
+class Test {
+ void test() {
+ if (!(Math.random() > 0.5)) {
+ System.out.println((Object) "one");
+ if (!(Math.random() > 0.5)) {
+ System.out.println((Object) 1);
+ if (!(Math.random() > 0.5)) {
+ System.out.println((Object) 1.0);
+ if (!(Math.random() > 0.5)) {
+ System.out.println((Object) 1.0f);
+ }
+ }
+ }
+ }
+ }
+
+ void foo(boolean b) {}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollBreakMultiple.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollBreakMultiple.java
new file mode 100644
index 000000000000..35ac031146ad
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollBreakMultiple.java
@@ -0,0 +1,25 @@
+// "Unroll loop" "true"
+class Test {
+ void test(String s1, String s2, String s3) {
+ if (s1.length() <= 5) {
+ System.out.println("Long string: " + s1);
+ if (s1.length() <= 20) {
+ System.out.println("Very long string: " + s1);
+ if (s2.length() <= 5) {
+ System.out.println("Long string: " + s2);
+ if (s2.length() <= 20) {
+ System.out.println("Very long string: " + s2);
+ if (s3.length() <= 5) {
+ System.out.println("Long string: " + s3);
+ if (s3.length() <= 20) {
+ System.out.println("Very long string: " + s3);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ void foo(boolean b) {}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollBreakNoBraces.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollBreakNoBraces.java
new file mode 100644
index 000000000000..b187a26dae22
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollBreakNoBraces.java
@@ -0,0 +1,14 @@
+// "Unroll loop" "true"
+class Test {
+ void test(String s1, String s2, String s3) {
+ if ((i += s1.length()) <= 10) {
+ if ((i += s2.length()) <= 10) {
+ if ((i += s3.length()) <= 10) {
+ }
+ }
+ }
+ System.out.println(i);
+ }
+
+ void foo(boolean b) {}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollListJava9.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollListJava9.java
new file mode 100644
index 000000000000..1b6f3ebc77fb
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollListJava9.java
@@ -0,0 +1,19 @@
+// "Unroll loop" "true"
+import java.util.*;
+
+class Test {
+ void test() {
+ if (!"foo".isEmpty()) {
+ System.out.println("foo");
+ }
+ if (!"bar".isEmpty()) {
+ System.out.println("bar");
+ }
+ if (!"baz".isEmpty()) {
+ System.out.println("baz");
+ }
+ if (!"".isEmpty()) {
+ System.out.println("");
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollListOneJava9.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollListOneJava9.java
new file mode 100644
index 000000000000..6337da2ee8f8
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollListOneJava9.java
@@ -0,0 +1,10 @@
+// "Unroll loop" "true"
+import java.util.*;
+
+class Test {
+ void test() {
+ if (!"foo".isEmpty()) {
+ System.out.println("foo");
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollNoBraces.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollNoBraces.java
new file mode 100644
index 000000000000..9527ef8d105a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollNoBraces.java
@@ -0,0 +1,11 @@
+// "Unroll loop" "true"
+import java.util.Arrays;
+
+class Test {
+ void test() {
+ System.out.println("foo");
+ System.out.println("bar");
+ }
+
+ void foo(boolean b) {}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollSingleton.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollSingleton.java
new file mode 100644
index 000000000000..7e71a0a601f5
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/afterUnrollSingleton.java
@@ -0,0 +1,10 @@
+// "Unroll loop" "true"
+import java.util.*;
+
+class Test {
+ void test() {
+ if (!"xyz".isEmpty()) {
+ System.out.println("xyz");
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollBreak.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollBreak.java
index f078e3c89202..099bb21eb2ac 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollBreak.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollBreak.java
@@ -1,4 +1,4 @@
-// "Unroll loop" "false"
+// "Unroll loop" "true"
class Test {
void test() {
for(Object x : new Object[] {"one", 1, 1.0, 1.0f}) {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollBreakDeeper.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollBreakDeeper.java
new file mode 100644
index 000000000000..27fa41346ea4
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollBreakDeeper.java
@@ -0,0 +1,15 @@
+// "Unroll loop" "false"
+class Test {
+ void test(String s1, String s2, String s3) {
+ for(String s : new String[] {s1, s2, s3}) {
+ if (!s.isEmpty()) {
+ if(s.length() > 5) break;
+ }
+ System.out.println("Long string: "+s);
+ if(s.length() > 20) break;
+ System.out.println("Very long string: "+s);
+ }
+ }
+
+ void foo(boolean b) {}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollBreakMultiple.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollBreakMultiple.java
new file mode 100644
index 000000000000..5e0e81985378
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollBreakMultiple.java
@@ -0,0 +1,13 @@
+// "Unroll loop" "true"
+class Test {
+ void test(String s1, String s2, String s3) {
+ for(String s : new String[] {s1, s2, s3}) {
+ if(s.length() > 5) break;
+ System.out.println("Long string: "+s);
+ if(s.length() > 20) break;
+ System.out.println("Very long string: "+s);
+ }
+ }
+
+ void foo(boolean b) {}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollBreakNoBraces.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollBreakNoBraces.java
new file mode 100644
index 000000000000..56501d74fe58
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollBreakNoBraces.java
@@ -0,0 +1,10 @@
+// "Unroll loop" "true"
+class Test {
+ void test(String s1, String s2, String s3) {
+ for(String s : new String[] {s1, s2, s3})
+ if((i+=s.length()) > 10) break;
+ System.out.println(i);
+ }
+
+ void foo(boolean b) {}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollListArray.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollListArray.java
new file mode 100644
index 000000000000..6d2662f6a796
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollListArray.java
@@ -0,0 +1,12 @@
+// "Unroll loop" "false"
+import java.util.*;
+
+class Test {
+ void test(String[] data) {
+ for(String s : Arrays.asList(data)) {
+ if(!s.isEmpty()) {
+ System.out.println(s);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollListJava9.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollListJava9.java
new file mode 100644
index 000000000000..1e15d8a5d038
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollListJava9.java
@@ -0,0 +1,12 @@
+// "Unroll loop" "true"
+import java.util.*;
+
+class Test {
+ void test() {
+ for(String s : List.of("foo", "bar", "baz", "")) {
+ if(!s.isEmpty()) {
+ System.out.println(s);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollListOneJava9.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollListOneJava9.java
new file mode 100644
index 000000000000..e70d5216d71c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollListOneJava9.java
@@ -0,0 +1,12 @@
+// "Unroll loop" "true"
+import java.util.*;
+
+class Test {
+ void test() {
+ for(String s : List.of("foo")) {
+ if(!s.isEmpty()) {
+ System.out.println(s);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollNoBraces.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollNoBraces.java
new file mode 100644
index 000000000000..33e72ea029db
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollNoBraces.java
@@ -0,0 +1,10 @@
+// "Unroll loop" "true"
+import java.util.Arrays;
+
+class Test {
+ void test() {
+ for(String s : Arrays.asList("foo", "bar")) System.out.println(s);
+ }
+
+ void foo(boolean b) {}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollSingleton.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollSingleton.java
new file mode 100644
index 000000000000..c9da24336c0b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollSingleton.java
@@ -0,0 +1,12 @@
+// "Unroll loop" "true"
+import java.util.*;
+
+class Test {
+ void test() {
+ for(String s : Collections.singleton("xyz")) {
+ if(!s.isEmpty()) {
+ System.out.println(s);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollWritesVar.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollWritesVar.java
new file mode 100644
index 000000000000..e01c49a1ea1e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop/beforeUnrollWritesVar.java
@@ -0,0 +1,13 @@
+// "Unroll loop" "false"
+class Test {
+ void test() {
+ for(int x : new int[]{1, 2, 3}) {
+ System.out.println(x);
+ x = 6;
+ x++;
+ System.out.println(x);
+ }
+ }
+
+ void foo(boolean b) {}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/opt/notNullMethodCall.java b/java/java-tests/testData/codeInsight/template/postfix/templates/opt/notNullMethodCall.java
new file mode 100644
index 000000000000..f874970148fd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/template/postfix/templates/opt/notNullMethodCall.java
@@ -0,0 +1,12 @@
+import org.jetbrains.annotations.NotNull;
+
+class Test {
+ @NotNull
+ String foo() {
+ return "";
+ }
+
+ void m() {
+ foo().opt
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/opt/notNullMethodCall_after.java b/java/java-tests/testData/codeInsight/template/postfix/templates/opt/notNullMethodCall_after.java
new file mode 100644
index 000000000000..e5331c237e5e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/template/postfix/templates/opt/notNullMethodCall_after.java
@@ -0,0 +1,12 @@
+import org.jetbrains.annotations.NotNull;
+
+class Test {
+ @NotNull
+ String foo() {
+ return "";
+ }
+
+ void m() {
+ java.util.Optional.of(foo())
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/stream/notAvailable.java b/java/java-tests/testData/codeInsight/template/postfix/templates/stream/notAvailable.java
new file mode 100644
index 000000000000..1ea9a888d7e1
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/template/postfix/templates/stream/notAvailable.java
@@ -0,0 +1,5 @@
+class Test {
+ void m(byte[] ss) {
+ ss.stream
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/stream/notAvailable_after.java b/java/java-tests/testData/codeInsight/template/postfix/templates/stream/notAvailable_after.java
new file mode 100644
index 000000000000..492e02bfe8fd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/template/postfix/templates/stream/notAvailable_after.java
@@ -0,0 +1,5 @@
+class Test {
+ void m(byte[] ss) {
+ ss.stream
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/LambdaInlining.java b/java/java-tests/testData/inspection/dataFlow/fixture/LambdaInlining.java
index 4bc09bca8205..aff0995ad755 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/LambdaInlining.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/LambdaInlining.java
@@ -27,4 +27,20 @@ public class LambdaInlining {
System.out.println("oops");
}
}
+
+ void testLambdaTryFinally() {
+ int x = ((IntSupplier)() -> {
+ try {
+ return 10;
+ } finally {
+ return 20;
+ }
+ }).getAsInt();
+ if(x == 30) {
+ System.out.println("oops");
+ }
+ if(x < 30) {
+ System.out.println("always");
+ }
+ }
}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/StreamComparatorInlining.java b/java/java-tests/testData/inspection/dataFlow/fixture/StreamComparatorInlining.java
new file mode 100644
index 000000000000..36a50f657407
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/StreamComparatorInlining.java
@@ -0,0 +1,49 @@
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+import java.util.stream.*;
+
+public class StreamComparatorInlining {
+ static class Holder {
+ @Nullable String nullable;
+
+ @Nullable String getNullable() {
+ return nullable;
+ }
+ }
+
+ @Nullable String process(String s) {
+ return s.isEmpty() ? null : s;
+ }
+
+ void testMinMax(List list) {
+ list.stream().map(this::process).max(Comparator.naturalOrder());
+ list.stream().map(this::process).max(Comparator.nullsFirst(Comparator.naturalOrder()));
+ list.stream().map(this::process).max(Comparator.nullsFirst(Comparator.comparing(String::length)));
+ list.stream().map(this::process).min(Comparator.nullsLast(Comparator.comparing(String::length)));
+ list.stream().map(this::process).min(Comparator.comparing(String::length));
+ list.stream().map(this::process).min(Comparator.comparing(String::length).reversed());
+ }
+
+ void testSorted(List list) {
+ list.stream().sorted(Comparator.comparing(this::process, Comparator.reverseOrder())).collect(Collectors.toList());
+ list.stream().sorted(Comparator.comparing(this::process)).collect(Collectors.toList());
+ list.stream().sorted(Comparator.comparing(this::process, Comparator.nullsFirst(Comparator.naturalOrder()))).collect(Collectors.toList());
+ list.stream().map(this::process).sorted(Comparator.comparing(String::length)).collect(Collectors.toList());
+ list.stream().map(this::process).sorted().collect(Collectors.toList());
+ list.stream().map(this::process).sorted(String::compareToIgnoreCase).collect(Collectors.toList());
+ list.stream().map(this::process).sorted(String.CASE_INSENSITIVE_ORDER).collect(Collectors.toList());
+ }
+
+ void testSortedCheck(List holders) {
+ holders.stream().sorted(Comparator.comparing(h -> h.nullable)).toArray();
+ holders.stream().filter(h -> h.nullable != null).sorted(Comparator.comparing(h -> h.nullable)).toArray();
+
+ holders.stream().sorted(Comparator.comparing(h -> h.getNullable())).toArray();
+ holders.stream().filter(h -> h.getNullable() != null).sorted(Comparator.comparing(h -> h.getNullable())).toArray();
+
+ holders.stream().sorted(Comparator.comparing(Holder::getNullable)).toArray();
+ holders.stream().filter(h -> h.getNullable() != null).sorted(Comparator.comparing(Holder::getNullable)).toArray();
+ }
+}
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/StreamInlining.java b/java/java-tests/testData/inspection/dataFlow/fixture/StreamInlining.java
index d48cf36358b6..f38d46c725a6 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/StreamInlining.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/StreamInlining.java
@@ -38,11 +38,6 @@ public class StreamInlining {
static class Holder {
Object obj;
- @Nullable String nullable;
-
- @Nullable String getNullable() {
- return nullable;
- }
}
int hash(List holders) {
@@ -136,38 +131,4 @@ public class StreamInlining {
Stream.generate(() -> Optional.of("xyz")).filter(Optional::isPresent).forEach(System.out::println);
LongStream.generate(() -> 5).limit(10).filter(x -> x > 6).forEach(s -> System.out.println(s));
}
-
- @Nullable String process(String s) {
- return s.isEmpty() ? null : s;
- }
-
- void testMinMax(List list) {
- list.stream().map(this::process).max(Comparator.naturalOrder());
- list.stream().map(this::process).max(Comparator.nullsFirst(Comparator.naturalOrder()));
- list.stream().map(this::process).max(Comparator.nullsFirst(Comparator.comparing(String::length)));
- list.stream().map(this::process).min(Comparator.nullsLast(Comparator.comparing(String::length)));
- list.stream().map(this::process).min(Comparator.comparing(String::length));
- list.stream().map(this::process).min(Comparator.comparing(String::length).reversed());
- }
-
- void testSorted(List list) {
- list.stream().sorted(Comparator.comparing(this::process, Comparator.reverseOrder())).collect(Collectors.toList());
- list.stream().sorted(Comparator.comparing(this::process)).collect(Collectors.toList());
- list.stream().sorted(Comparator.comparing(this::process, Comparator.nullsFirst(Comparator.naturalOrder()))).collect(Collectors.toList());
- list.stream().map(this::process).sorted(Comparator.comparing(String::length)).collect(Collectors.toList());
- list.stream().map(this::process).sorted().collect(Collectors.toList());
- list.stream().map(this::process).sorted(String::compareToIgnoreCase).collect(Collectors.toList());
- list.stream().map(this::process).sorted(String.CASE_INSENSITIVE_ORDER).collect(Collectors.toList());
- }
-
- void testSortedCheck(List holders) {
- holders.stream().sorted(Comparator.comparing(h -> h.nullable)).toArray();
- holders.stream().filter(h -> h.nullable != null).sorted(Comparator.comparing(h -> h.nullable)).toArray();
-
- holders.stream().sorted(Comparator.comparing(h -> h.getNullable())).toArray();
- holders.stream().filter(h -> h.getNullable() != null).sorted(Comparator.comparing(h -> h.getNullable())).toArray();
-
- holders.stream().sorted(Comparator.comparing(Holder::getNullable)).toArray();
- holders.stream().filter(h -> h.getNullable() != null).sorted(Comparator.comparing(Holder::getNullable)).toArray();
- }
}
diff --git a/java/java-tests/testData/psi/parser-partial/statements/ForIncomplete10.txt b/java/java-tests/testData/psi/parser-partial/statements/ForIncomplete10.txt
new file mode 100644
index 000000000000..652024111714
--- /dev/null
+++ b/java/java-tests/testData/psi/parser-partial/statements/ForIncomplete10.txt
@@ -0,0 +1,16 @@
+PsiJavaFile:ForIncomplete10.java
+ PsiForStatement
+ PsiKeyword:for('for')
+ PsiJavaToken:LPARENTH('(')
+ PsiDeclarationStatement
+ PsiLocalVariable:x
+ PsiModifierList:
+
+ PsiTypeElement:var
+ PsiKeyword:var('var')
+ PsiWhiteSpace(' ')
+ PsiIdentifier:x('x')
+ PsiErrorElement:';' expected
+
+ PsiErrorElement:';' expected
+
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-partial/statements/ForNormal2.txt b/java/java-tests/testData/psi/parser-partial/statements/ForNormal2.txt
new file mode 100644
index 000000000000..59c8e2d141f6
--- /dev/null
+++ b/java/java-tests/testData/psi/parser-partial/statements/ForNormal2.txt
@@ -0,0 +1,24 @@
+PsiJavaFile:ForNormal2.java
+ PsiForStatement
+ PsiKeyword:for('for')
+ PsiJavaToken:LPARENTH('(')
+ PsiDeclarationStatement
+ PsiLocalVariable:x
+ PsiModifierList:
+
+ PsiTypeElement:var
+ PsiKeyword:var('var')
+ PsiWhiteSpace(' ')
+ PsiIdentifier:x('x')
+ PsiWhiteSpace(' ')
+ PsiJavaToken:EQ('=')
+ PsiWhiteSpace(' ')
+ PsiLiteralExpression:0
+ PsiJavaToken:INTEGER_LITERAL('0')
+ PsiJavaToken:SEMICOLON(';')
+ PsiWhiteSpace(' ')
+ PsiJavaToken:SEMICOLON(';')
+ PsiJavaToken:RPARENTH(')')
+ PsiWhiteSpace(' ')
+ PsiEmptyStatement
+ PsiJavaToken:SEMICOLON(';')
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-partial/statements/ForNormal3.txt b/java/java-tests/testData/psi/parser-partial/statements/ForNormal3.txt
new file mode 100644
index 000000000000..defbfafbafd8
--- /dev/null
+++ b/java/java-tests/testData/psi/parser-partial/statements/ForNormal3.txt
@@ -0,0 +1,22 @@
+PsiJavaFile:ForNormal3.java
+ PsiForeachStatement
+ PsiKeyword:for('for')
+ PsiJavaToken:LPARENTH('(')
+ PsiParameter:x
+ PsiModifierList:
+
+ PsiTypeElement:var
+ PsiKeyword:var('var')
+ PsiWhiteSpace(' ')
+ PsiIdentifier:x('x')
+ PsiWhiteSpace(' ')
+ PsiJavaToken:COLON(':')
+ PsiWhiteSpace(' ')
+ PsiReferenceExpression:list
+ PsiReferenceParameterList
+
+ PsiIdentifier:list('list')
+ PsiJavaToken:RPARENTH(')')
+ PsiWhiteSpace(' ')
+ PsiEmptyStatement
+ PsiJavaToken:SEMICOLON(';')
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-partial/statements/LocalVar3.txt b/java/java-tests/testData/psi/parser-partial/statements/LocalVar3.txt
new file mode 100644
index 000000000000..3ad05715f320
--- /dev/null
+++ b/java/java-tests/testData/psi/parser-partial/statements/LocalVar3.txt
@@ -0,0 +1,10 @@
+PsiJavaFile:LocalVar3.java
+ PsiDeclarationStatement
+ PsiLocalVariable:x
+ PsiModifierList:
+
+ PsiTypeElement:var
+ PsiKeyword:var('var')
+ PsiWhiteSpace(' ')
+ PsiIdentifier:x('x')
+ PsiJavaToken:SEMICOLON(';')
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-partial/statements/LocalVar4.txt b/java/java-tests/testData/psi/parser-partial/statements/LocalVar4.txt
new file mode 100644
index 000000000000..b3b2154111f3
--- /dev/null
+++ b/java/java-tests/testData/psi/parser-partial/statements/LocalVar4.txt
@@ -0,0 +1,11 @@
+PsiJavaFile:LocalVar4.java
+ PsiDeclarationStatement
+ PsiLocalVariable:x
+ PsiModifierList:final
+ PsiKeyword:final('final')
+ PsiWhiteSpace(' ')
+ PsiTypeElement:var
+ PsiKeyword:var('var')
+ PsiWhiteSpace(' ')
+ PsiIdentifier:x('x')
+ PsiJavaToken:SEMICOLON(';')
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-partial/statements/LocalVar5.txt b/java/java-tests/testData/psi/parser-partial/statements/LocalVar5.txt
new file mode 100644
index 000000000000..53da4881f962
--- /dev/null
+++ b/java/java-tests/testData/psi/parser-partial/statements/LocalVar5.txt
@@ -0,0 +1,18 @@
+PsiJavaFile:LocalVar5.java
+ PsiDeclarationStatement
+ PsiLocalVariable:x
+ PsiModifierList:@A
+ PsiAnnotation
+ PsiJavaToken:AT('@')
+ PsiJavaCodeReferenceElement:A
+ PsiIdentifier:A('A')
+ PsiReferenceParameterList
+
+ PsiAnnotationParameterList
+
+ PsiWhiteSpace(' ')
+ PsiTypeElement:var
+ PsiKeyword:var('var')
+ PsiWhiteSpace(' ')
+ PsiIdentifier:x('x')
+ PsiJavaToken:SEMICOLON(';')
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-partial/statements/TryIncomplete19.txt b/java/java-tests/testData/psi/parser-partial/statements/TryIncomplete19.txt
new file mode 100644
index 000000000000..1bf1d05e595c
--- /dev/null
+++ b/java/java-tests/testData/psi/parser-partial/statements/TryIncomplete19.txt
@@ -0,0 +1,18 @@
+PsiJavaFile:TryIncomplete19.java
+ PsiTryStatement
+ PsiKeyword:try('try')
+ PsiResourceList:(var r)
+ PsiJavaToken:LPARENTH('(')
+ PsiResourceVariable:r
+ PsiModifierList:
+
+ PsiTypeElement:var
+ PsiKeyword:var('var')
+ PsiWhiteSpace(' ')
+ PsiIdentifier:r('r')
+ PsiErrorElement:'=' expected
+
+ PsiJavaToken:RPARENTH(')')
+ PsiCodeBlock
+ PsiJavaToken:LBRACE('{')
+ PsiJavaToken:RBRACE('}')
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-partial/statements/TryNormal13.txt b/java/java-tests/testData/psi/parser-partial/statements/TryNormal13.txt
new file mode 100644
index 000000000000..a439c6100e6e
--- /dev/null
+++ b/java/java-tests/testData/psi/parser-partial/statements/TryNormal13.txt
@@ -0,0 +1,21 @@
+PsiJavaFile:TryNormal13.java
+ PsiTryStatement
+ PsiKeyword:try('try')
+ PsiResourceList:(var r = null)
+ PsiJavaToken:LPARENTH('(')
+ PsiResourceVariable:r
+ PsiModifierList:
+
+ PsiTypeElement:var
+ PsiKeyword:var('var')
+ PsiWhiteSpace(' ')
+ PsiIdentifier:r('r')
+ PsiWhiteSpace(' ')
+ PsiJavaToken:EQ('=')
+ PsiWhiteSpace(' ')
+ PsiLiteralExpression:null
+ PsiJavaToken:NULL_KEYWORD('null')
+ PsiJavaToken:RPARENTH(')')
+ PsiCodeBlock
+ PsiJavaToken:LBRACE('{')
+ PsiJavaToken:RBRACE('}')
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/extractMethod/TypeParamsListWithRecursiveDependencies.java b/java/java-tests/testData/refactoring/extractMethod/TypeParamsListWithRecursiveDependencies.java
new file mode 100644
index 000000000000..34c63819d3cd
--- /dev/null
+++ b/java/java-tests/testData/refactoring/extractMethod/TypeParamsListWithRecursiveDependencies.java
@@ -0,0 +1,6 @@
+class Test {
+
+ void f(C c) {
+ System.out.println(c);
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/extractMethod/TypeParamsListWithRecursiveDependencies_after.java b/java/java-tests/testData/refactoring/extractMethod/TypeParamsListWithRecursiveDependencies_after.java
new file mode 100644
index 000000000000..a7aaae5d3ed8
--- /dev/null
+++ b/java/java-tests/testData/refactoring/extractMethod/TypeParamsListWithRecursiveDependencies_after.java
@@ -0,0 +1,10 @@
+class Test {
+
+ void f(C c) {
+ newMethod(c);
+ }
+
+ private void newMethod(C c) {
+ System.out.println(c);
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/ex/InspectionProfileTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/ex/InspectionProfileTest.java
index 7bb8e8940107..b15119516f8f 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/ex/InspectionProfileTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/ex/InspectionProfileTest.java
@@ -32,6 +32,8 @@ import com.intellij.testFramework.InspectionsKt;
import com.intellij.testFramework.LightIdeaTestCase;
import com.intellij.util.JdomKt;
import com.intellij.util.SmartList;
+import com.siyeh.ig.naming.ClassNamingConvention;
+import com.siyeh.ig.naming.NewClassNamingConventionInspection;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NotNull;
@@ -222,42 +224,28 @@ public class InspectionProfileTest extends LightIdeaTestCase {
//settings to merge
- final Element unusedProfile = JdomKt.loadElement("\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- "");
+ String serialized =
+ "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "";
+ final Element unusedProfile = JdomKt.loadElement(serialized);
profile.readExternal(unusedProfile);
profile.getModifiableModel().commit();
- assertEquals("\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- "", serialize(profile));
+ assertEquals(serialized, serialize(profile));
//make them default
profile = createProfile(new InspectionProfileImpl("foo"));
@@ -302,6 +290,101 @@ public class InspectionProfileTest extends LightIdeaTestCase {
assertThat(importedProfile.writeScheme()).isEqualTo(mergedElement);
}
+
+ public void testMergeNamingConventions() throws Exception {
+ //no specific settings
+ final Element element = JdomKt.loadElement("\n" +
+ " \n" +
+ "");
+ InspectionProfileImpl profile = createProfile(new InspectionProfileImpl("foo"));
+ profile.readExternal(element);
+ profile.getModifiableModel().commit();
+ assertThat(profile.writeScheme()).isEqualTo(element);
+
+ String unchanged = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "";
+ final Element allEnabledProfile = JdomKt.loadElement(unchanged);
+ profile.readExternal(allEnabledProfile);
+ profile.getModifiableModel().commit();
+ assertEquals(unchanged, serialize(profile));
+
+ //make them default
+ profile = createProfile(new InspectionProfileImpl("foo"));
+ String customSettingsText = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "";
+ profile.readExternal(JdomKt.loadElement(customSettingsText));
+ assertEquals(customSettingsText, serialize(profile));
+ InspectionToolWrapper wrapper = profile.getInspectionTool("NewClassNamingConvention", getProject());
+ assertNotNull(wrapper);
+ NewClassNamingConventionInspection tool = (NewClassNamingConventionInspection)wrapper.getTool();
+ assertEquals(256, tool.getNamingConventionBean("AnnotationNamingConvention").m_maxLength);
+ assertEquals(1, tool.getNamingConventionBean("EnumeratedClassNamingConvention").m_minLength);
+ assertTrue(profile.isToolEnabled(HighlightDisplayKey.find("NewClassNamingConvention"), null));
+ assertFalse(tool.isConventionEnabled("TypeParameterNamingConvention"));
+ assertFalse(tool.isConventionEnabled(ClassNamingConvention.CLASS_NAMING_CONVENTION_SHORT_NAME));
+
+ Element toImportElement = profile.writeScheme();
+ final InspectionProfileImpl importedProfile =
+ InspectionProfileSchemesPanel.importInspectionProfile(toImportElement, getApplicationProfileManager(), getProject());
+
+ //check merged
+ Element mergedElement = JdomKt.loadElement(customSettingsText);
+ profile = createProfile(new InspectionProfileImpl("foo"));
+ profile.readExternal(mergedElement);
+ profile.getModifiableModel().commit();
+ assertThat(profile.writeScheme()).isEqualTo(mergedElement);
+
+ assertThat(importedProfile.writeScheme()).isEqualTo(mergedElement);
+ }
public void testStoredMemberVisibility() throws Exception {
InspectionProfileImpl profile = createProfile(new InspectionProfileImpl("foo"));
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/CompleteStatementTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/CompleteStatementTest.java
index 32d7f7472fa0..97157989428a 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/CompleteStatementTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/CompleteStatementTest.java
@@ -84,6 +84,7 @@ public class CompleteStatementTest extends EditorActionTestCase {
public void testForIncrementExpressionAndBody() { doTest(); }
public void testEmptyBeforeReturn() { doTest(); }
public void testIf() { doTest(); }
+ public void testIfWithoutParentheses() { doTest(); }
public void testBeforeStatement() { doTest(); }
public void testTry1() { doTest(); }
public void testInsideResourceVariable() { doTest(); }
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java
index 4d85f0afa7bd..51637736e17f 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java
@@ -610,6 +610,18 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase {
checkHintContents(null);
}
+ public void testPopupAfterCaretMovesOutsideOfParenthesis() throws Exception {
+ configureJava("class C { void m() { System.getPro } }");
+ complete("getProperty(String key, String def)");
+ waitForAllAsyncStuff();
+ checkHintContents("@NotNull String");
+ left();
+ left();
+ left();
+ waitForAllAsyncStuff();
+ checkHintContents(null);
+ }
+
private void checkResult(String text) {
myFixture.checkResult(text);
}
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/KeywordCompletionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/KeywordCompletionTest.java
index 2e26d7d90996..e90a9aafa7ee 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/KeywordCompletionTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/KeywordCompletionTest.java
@@ -132,13 +132,16 @@ public class KeywordCompletionTest extends LightCompletionTestCase {
public void testAbstractInInterface() { doTest(1, "abstract"); }
public void testCharInAnnotatedParameter() { doTest(1, "char"); }
public void testReturnInTernary() { doTest(1, "return"); }
+ public void testReturnInRussian() { doTest(1, "return"); }
public void testFinalAfterParameterAnno() { doTest(2, "final", "float", "class"); }
public void testFinalAfterParameterAnno2() { doTest(2, "final", "float", "class"); }
public void testFinalAfterCase() { doTest(3, "final", "float", "class"); }
public void testNoCaseInsideWhileInSwitch() { doTest(0, "case", "default"); }
public void testFinalInCatch() { doTest(1, "final"); }
public void testFinalInIncompleteCatch() { doTest(1, "final"); }
+ public void testFinalInCompleteCatch() { doTest(1, "final"); }
public void testFinalInTryWithResources() { doTest(1, "final", "float", "class"); }
+ public void testFinalInCompleteTryWithResources() { doTest(1, "final", "float", "class"); }
public void testFinalInLambda() { doTest(2, "final", "float"); }
public void testNoFinalAfterTryBody() { doTest(1, "final", "finally"); }
public void testClassInMethod() { doTest(2, "class", "char"); }
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/Normal8CompletionTest.groovy b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/Normal8CompletionTest.groovy
index ae0af6127049..5a86e5bc8502 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/Normal8CompletionTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/Normal8CompletionTest.groovy
@@ -106,8 +106,8 @@ class Test {
void bar(int i) {}
}"""
def items = myFixture.completeBasic()
- assert LookupElementPresentation.renderElement(items[0]).itemText == 'x -> {}'
- assert items.find { LookupElementPresentation.renderElement(it).itemText.contains('this::bar') } != null
+ assert items.any { LookupElementPresentation.renderElement(it).itemText == 'x -> {}' }
+ assert items.any { LookupElementPresentation.renderElement(it).itemText.contains('this::bar') }
}
void "test suggest receiver method reference"() {
@@ -301,6 +301,11 @@ class Test88 {
checkResultByFileName()
}
+ void testPreferVariableToLambda() {
+ configureByTestName()
+ myFixture.assertPreferredCompletionItems 0, 'output', 'out -> '
+ }
+
private checkResultByFileName() {
checkResultByFile(getTestName(false) + "_after.java")
}
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy
index 58b6ba2a6a2e..de50be614956 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy
@@ -1826,4 +1826,20 @@ class Bar {
assert myFixture.lookupElementStrings == ['web']
}
+ void testLocalClassPresentation() {
+ def cls = myFixture.addFileToProject('foo/Bar.java', """package foo;
+class Bar {{
+ class Local {}
+ Lox
+}}""")
+ myFixture.configureFromExistingVirtualFile(cls.containingFile.virtualFile)
+ def item = myFixture.completeBasic()[0]
+ assert LookupElementPresentation.renderElement(item).tailText.contains('local class')
+ }
+
+ void testNoDuplicateInCast() {
+ configure()
+ assert myFixture.lookupElementStrings == null
+ }
+
}
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/SmartType18CompletionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/SmartType18CompletionTest.java
index 9b34349f5730..e6d2792176ea 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/SmartType18CompletionTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/SmartType18CompletionTest.java
@@ -258,4 +258,8 @@ public void testConvertToObjectStream() {
public void testNewHashMapTypeArguments() { doTest(false); }
public void testNewMapTypeArguments() { doTest(false); }
+ public void testPreferLambdaOverGenericGetter() {
+ configureByTestName();
+ myFixture.assertPreferredCompletionItems(0, "isEmpty", "s -> ", "getSomeGenericValue");
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/JavadocHtmlLintInspectionTest.kt b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/JavadocHtmlLintInspectionTest.kt
index 8da63e0eedef..d02e4087647e 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/JavadocHtmlLintInspectionTest.kt
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/JavadocHtmlLintInspectionTest.kt
@@ -16,6 +16,9 @@
package com.intellij.java.codeInsight.daemon
import com.intellij.codeInspection.javaDoc.JavadocHtmlLintInspection
+import com.intellij.openapi.projectRoots.JavaSdk
+import com.intellij.openapi.projectRoots.impl.JavaSdkImpl
+import com.intellij.openapi.roots.ModuleRootModificationUtil
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import com.intellij.util.PathUtil
@@ -27,6 +30,9 @@ class JavadocHtmlLintInspectionTest : LightCodeInsightFixtureTestCase() {
val javaHome = System.getProperty("java.home")
val jdkHome = if (javaHome.endsWith("jre")) PathUtil.getParentPath(javaHome) else javaHome
VfsRootAccess.allowRootAccess(myFixture.testRootDisposable, jdkHome)
+
+ val jdk = (JavaSdk.getInstance() as JavaSdkImpl).createMockJdk("java version \"1.8.0\"", System.getProperty("java.home"), true)
+ ModuleRootModificationUtil.setModuleSdk(myModule, jdk);
}
fun testNoComment() = doTest("class C { }")
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/UnrollLoopActionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/UnrollLoopActionTest.java
index d69cc6541089..faae721a0282 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/UnrollLoopActionTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/UnrollLoopActionTest.java
@@ -16,11 +16,20 @@
package com.intellij.java.codeInsight.intention;
import com.intellij.codeInsight.daemon.LightIntentionActionTestCase;
+import com.intellij.testFramework.LightProjectDescriptor;
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
+import org.jetbrains.annotations.NotNull;
public class UnrollLoopActionTest extends LightIntentionActionTestCase {
public void test() { doAllTests(); }
+ @NotNull
+ @Override
+ protected LightProjectDescriptor getProjectDescriptor() {
+ return LightCodeInsightFixtureTestCase.JAVA_9;
+ }
+
@Override
protected String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/unrollLoop";
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/OptionalPostfixTemplateTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/OptionalPostfixTemplateTest.java
index de78213fb37e..e86e9e559c74 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/OptionalPostfixTemplateTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/OptionalPostfixTemplateTest.java
@@ -80,6 +80,12 @@ public class OptionalPostfixTemplateTest extends PostfixTemplateTestCase {
public void testLong() {
doTest();
}
+
+ public void testNotNullMethodCall() {
+ myFixture.addClass("package org.jetbrains.annotations;" +
+ "public @interface NotNull {}");
+ doTest();
+ }
public void testDoNotExpandOnJavaLess8() {
IdeaTestUtil.setModuleLanguageLevel(myModule, LanguageLevel.JDK_1_6, myFixture.getTestRootDisposable());
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/StreamPostfixTemplateTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/StreamPostfixTemplateTest.java
index 0a29265e4c1b..405c682fc189 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/StreamPostfixTemplateTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/StreamPostfixTemplateTest.java
@@ -57,6 +57,10 @@ public class StreamPostfixTemplateTest extends PostfixTemplateTestCase {
doTest();
}
+ public void testNotAvailable() {
+ doTest();
+ }
+
public void testDoNotExpandOnJavaLess8() {
IdeaTestUtil.setModuleLanguageLevel(myModule, LanguageLevel.JDK_1_6, myFixture.getTestRootDisposable());
doTest();
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java
index c38437578c7f..7cd89c5f7851 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java
@@ -195,6 +195,7 @@ public class DataFlowInspection8Test extends DataFlowInspectionTestCase {
doTest();
}
public void testStreamInlining() { doTest(); }
+ public void testStreamComparatorInlining() { doTest(); }
public void testStreamKnownSource() { doTest(); }
public void testMethodVsExpressionTypeAnnotationConflict() {
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantCast15Test.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantCast15Test.java
index 27ec322f5628..116dee125e3a 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantCast15Test.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantCast15Test.java
@@ -87,7 +87,6 @@ public class RedundantCast15Test extends InspectionTestCase {
public void testIgnore() {
final RedundantCastInspection castInspection = new RedundantCastInspection();
- castInspection.IGNORE_ANNOTATED_METHODS = true;
castInspection.IGNORE_SUSPICIOUS_METHOD_CALLS = true;
final LocalInspectionToolWrapper tool = new LocalInspectionToolWrapper(castInspection);
doTest("redundantCast/generics/" + getTestName(false), tool, "java 1.5");
diff --git a/java/java-tests/testSrc/com/intellij/java/navigation/ChooseByNameHddTest.groovy b/java/java-tests/testSrc/com/intellij/java/navigation/ChooseByNameHddTest.groovy
index 25d8b341a8ba..c0815c001c06 100644
--- a/java/java-tests/testSrc/com/intellij/java/navigation/ChooseByNameHddTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/java/navigation/ChooseByNameHddTest.groovy
@@ -18,8 +18,6 @@ package com.intellij.java.navigation
import com.intellij.ide.util.gotoByName.ChooseByNamePopup
import com.intellij.ide.util.gotoByName.GotoClassModel2
import com.intellij.ide.util.gotoByName.GotoFileModel
-import com.intellij.openapi.application.ApplicationManager
-import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.module.ModuleUtilCore
import com.intellij.openapi.module.StdModuleTypes
import com.intellij.openapi.roots.ModuleRootModificationUtil
@@ -27,7 +25,6 @@ import com.intellij.openapi.util.io.FileUtil
import com.intellij.psi.PsiElement
import com.intellij.testFramework.PsiTestUtil
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase
-import org.jetbrains.annotations.NotNull
/**
* @author peter
*/
@@ -37,15 +34,12 @@ class ChooseByNameHddTest extends JavaCodeInsightFixtureTestCase {
def vFile = psiFile.virtualFile
def path = vFile.path
- ApplicationManager.application.runReadAction {
- def model = new GotoFileModel(project)
- def popup = ChooseByNamePopup.createPopup(project, model, (PsiElement)null)
- assert ChooseByNameTest.calcPopupElements(popup, path) == [psiFile]
- assert ChooseByNameTest.calcPopupElements(popup, FileUtil.toSystemDependentName(path)) == [psiFile]
- assert ChooseByNameTest.calcPopupElements(popup, vFile.parent.path) == [psiFile.containingDirectory]
- assert ChooseByNameTest.calcPopupElements(popup, path + ':0') == [psiFile]
- popup.close(false)
- }
+ def popup = ChooseByNamePopup.createPopup(project, new GotoFileModel(project), (PsiElement)null)
+ assert ChooseByNameTest.calcPopupElements(popup, path) == [psiFile]
+ assert ChooseByNameTest.calcPopupElements(popup, FileUtil.toSystemDependentName(path)) == [psiFile]
+ assert ChooseByNameTest.calcPopupElements(popup, vFile.parent.path) == [psiFile.containingDirectory]
+ assert ChooseByNameTest.calcPopupElements(popup, path + ':0') == [psiFile]
+ popup.close(false)
}
void "test prefer same-named classes visible in current module"() {
@@ -57,7 +51,7 @@ class ChooseByNameHddTest extends JavaCodeInsightFixtureTestCase {
(0..moduleCount-1).each { myFixture.addFileToProject("mod$it/Foo.java", "class Foo {}") }
def place = myFixture.addClass("class A {}")
- def popup = ReadAction.compute { ChooseByNamePopup.createPopup(project, new GotoClassModel2(project), place) }
+ def popup = ChooseByNamePopup.createPopup(project, new GotoClassModel2(project), place)
def resultModules = ChooseByNameTest.calcPopupElements(popup, 'Foo').collect {
ModuleUtilCore.findModuleForPsiElement(it as PsiElement).name
}
@@ -69,20 +63,11 @@ class ChooseByNameHddTest extends JavaCodeInsightFixtureTestCase {
PsiTestUtil.addModule(project, StdModuleTypes.JAVA, 'm1', myFixture.tempDirFixture.findOrCreateDir("foo"))
PsiTestUtil.addModule(project, StdModuleTypes.JAVA, 'm2', myFixture.tempDirFixture.findOrCreateDir("foo/bar"))
def file = myFixture.addFileToProject('foo/bar/goo/doo.txt', '')
- def popup = ReadAction.compute { ChooseByNamePopup.createPopup(project, new GotoFileModel(project), file) }
+ def popup = ChooseByNamePopup.createPopup(project, new GotoFileModel(project), file)
assert ChooseByNameTest.calcPopupElements(popup, "doo", false) == [file]
assert ChooseByNameTest.calcPopupElements(popup, "goo/doo", false) == [file]
assert ChooseByNameTest.calcPopupElements(popup, "bar/goo/doo", false) == [file]
assert ChooseByNameTest.calcPopupElements(popup, "foo/bar/goo/doo", false) == [file]
}
- @Override
- protected boolean runInDispatchThread() {
- return false
- }
-
- @Override
- protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
- runnable.run()
- }
}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/java/navigation/ChooseByNameTest.groovy b/java/java-tests/testSrc/com/intellij/java/navigation/ChooseByNameTest.groovy
index 40fc43129ccc..7f963b7a2143 100644
--- a/java/java-tests/testSrc/com/intellij/java/navigation/ChooseByNameTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/java/navigation/ChooseByNameTest.groovy
@@ -19,23 +19,19 @@ import com.intellij.codeInsight.JavaProjectCodeInsightSettings
import com.intellij.ide.util.gotoByName.*
import com.intellij.lang.java.JavaLanguage
import com.intellij.openapi.Disposable
-import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState
-import com.intellij.openapi.application.ReadAction
-import com.intellij.openapi.util.Computable
import com.intellij.openapi.util.Disposer
import com.intellij.psi.CommonClassNames
+import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.search.ProjectScope
+import com.intellij.testFramework.PlatformTestUtil
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import com.intellij.util.Consumer
import com.intellij.util.concurrency.Semaphore
-import org.jetbrains.annotations.NotNull
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile
-import javax.swing.*
-
import static com.intellij.testFramework.EdtTestUtil.runInEdtAndWait
/**
* @author peter
@@ -106,13 +102,11 @@ class Impl extends Intf {
def elements = getPopupElements(new GotoSymbolModel2(project), "xxx")
- ReadAction.run {
- assert intf.findMethodsByName('xxx1', false)[0] in elements
- assert intf.findMethodsByName('xxx2', false)[0] in elements
+ assert intf.findMethodsByName('xxx1', false)[0] in elements
+ assert intf.findMethodsByName('xxx2', false)[0] in elements
- assert impl.findMethodsByName('xxx3', false)[0] in elements
- assert !(impl.findMethodsByName('xxx1', false)[0] in elements)
- }
+ assert impl.findMethodsByName('xxx3', false)[0] in elements
+ assert !(impl.findMethodsByName('xxx1', false)[0] in elements)
}
void "test disprefer underscore"() {
@@ -161,12 +155,12 @@ class Intf {
assert elements == files
}
- void "test middle matching for directories"() {
+ void "test middle matching for files and directories"() {
def fooIndex = myFixture.addFileToProject("foo/index.html", "foo")
def ooIndex = myFixture.addFileToProject("oo/index.html", "oo")
def fooBarIndex = myFixture.addFileToProject("foo/bar/index.html", "foo bar")
- def elements = getPopupElements(new GotoFileModel(project), "oo/index")
- assert elements == [ooIndex, fooIndex, fooBarIndex]
+ assert getPopupElements(new GotoFileModel(project), "oo/index") == [ooIndex, fooIndex, fooBarIndex]
+ assert getPopupElements(new GotoFileModel(project), "ndex.html") == [fooIndex, ooIndex, fooBarIndex]
}
void "test prefer files from current directory"() {
@@ -229,7 +223,7 @@ class Intf {
void "test find method by qualified name"() {
def clazz = myFixture.addClass("package foo.bar; class Goo { void zzzZzz() {} }")
- def method = ApplicationManager.application.runReadAction( { clazz.methods[0] } as Computable)
+ def method = clazz.methods[0]
assert getPopupElements(new GotoSymbolModel2(project), 'zzzZzz') == [method]
assert getPopupElements(new GotoSymbolModel2(project), 'goo.zzzZzz') == [method]
assert getPopupElements(new GotoSymbolModel2(project), 'foo.bar.goo.zzzZzz') == [method]
@@ -261,7 +255,7 @@ class Intf {
void "test dollar"() {
def bar = myFixture.addClass("package foo; class Bar { class Foo {} }")
- def foo = ApplicationManager.application.runReadAction( { bar.innerClasses[0] } as Computable)
+ def foo = bar.innerClasses[0]
myFixture.addClass("package goo; class Goo { }")
assert getPopupElements(new GotoClassModel2(project), 'Bar$Foo') == [foo]
assert getPopupElements(new GotoClassModel2(project), 'foo.Bar$Foo') == [foo]
@@ -295,9 +289,7 @@ class Intf {
}
private static filterJavaItems(List