Snapshot 568f05589922685b8c8f9a2f2f465043b8128542 from master branch of git://git.jetbrains.org/idea/community.git
Change-Id: I47fe8cb5d8a3c9876cd4c313dca1a8cc531288ec
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
index e64ff40..12d4f5b 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
@@ -1959,8 +1959,7 @@
finally {
CompilerUtil.refreshIOFiles(filesToRefresh);
if (!generatedFiles.isEmpty()) {
- DumbService.getInstance(myProject).waitForSmartMode();
- List<VirtualFile> vFiles = ApplicationManager.getApplication().runReadAction(new Computable<List<VirtualFile>>() {
+ List<VirtualFile> vFiles = DumbService.getInstance(myProject).runReadActionInSmartMode(new Computable<List<VirtualFile>>() {
public List<VirtualFile> compute() {
final ArrayList<VirtualFile> vFiles = new ArrayList<VirtualFile>(generatedFiles.size());
for (File generatedFile : generatedFiles) {
@@ -2162,8 +2161,7 @@
final List<FileProcessingCompiler.ProcessingItem> toProcess = new ArrayList<FileProcessingCompiler.ProcessingItem>();
final Set<String> allUrls = new HashSet<String>();
final IOException[] ex = {null};
- DumbService.getInstance(myProject).waitForSmartMode();
- ApplicationManager.getApplication().runReadAction(new Runnable() {
+ DumbService.getInstance(myProject).runReadActionInSmartMode(new Runnable() {
public void run() {
try {
for (FileProcessingCompiler.ProcessingItem item : items) {
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java b/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java
index 6cbb54b..38468aa 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java
@@ -64,11 +64,10 @@
final List<FileProcessingCompiler.ProcessingItem> toProcess = new ArrayList<FileProcessingCompiler.ProcessingItem>();
final Ref<IOException> ex = new Ref<IOException>(null);
- DumbService.getInstance(project).waitForSmartMode();
final FileProcessingCompilerStateCache cache = CompilerCacheManager.getInstance(project).getFileProcessingCompilerCache(myCompiler);
final boolean isMake = context.isMake();
- ApplicationManager.getApplication().runReadAction(new Runnable() {
+ DumbService.getInstance(project).runReadActionInSmartMode(new Runnable() {
public void run() {
try {
for (FileProcessingCompiler.ProcessingItem item : items) {
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java b/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java
index 3cba065..36021fd 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java
@@ -186,9 +186,8 @@
final List<GenericCompilerProcessingItem<Item, SourceState, OutputState>> toProcess = new ArrayList<GenericCompilerProcessingItem<Item,SourceState,OutputState>>();
final THashSet<Key> keySet = new THashSet<Key>(new SourceItemHashingStrategy<Key>(compiler));
final Ref<IOException> exception = Ref.create(null);
- DumbService.getInstance(myProject).waitForSmartMode();
final Map<Item, SourceState> sourceStates = new HashMap<Item,SourceState>();
- ApplicationManager.getApplication().runReadAction(new Runnable() {
+ DumbService.getInstance(myProject).runReadActionInSmartMode(new Runnable() {
@Override
public void run() {
try {
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/ChangedConstantsDependencyProcessor.java b/java/compiler/impl/src/com/intellij/compiler/make/ChangedConstantsDependencyProcessor.java
index bd919a6..ade4034 100644
--- a/java/compiler/impl/src/com/intellij/compiler/make/ChangedConstantsDependencyProcessor.java
+++ b/java/compiler/impl/src/com/intellij/compiler/make/ChangedConstantsDependencyProcessor.java
@@ -24,7 +24,6 @@
import com.intellij.compiler.impl.ExitException;
import com.intellij.compiler.impl.ExitStatus;
import com.intellij.lang.StdLanguages;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
@@ -73,9 +72,7 @@
public void run() throws CacheCorruptedException, ExitException {
final Ref<CacheCorruptedException> _ex = new Ref<CacheCorruptedException>();
final Ref<ExitException> exitException = new Ref<ExitException>(null);
- DumbService.getInstance(myProject).waitForSmartMode(); // ensure running in smart mode
-
- ApplicationManager.getApplication().runReadAction(new Runnable() {
+ DumbService.getInstance(myProject).runReadActionInSmartMode(new Runnable() {
public void run() {
try {
final String qName = myDependencyCache.resolve(myQName);
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompilerInstance.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompilerInstance.java
index 1edb774..d0c7c23 100644
--- a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompilerInstance.java
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompilerInstance.java
@@ -151,12 +151,12 @@
return Collections.emptyList();
}
- DumbService.getInstance(getProject()).waitForSmartMode();
- new ReadAction() {
- protected void run(final Result result) {
+ DumbService.getInstance(getProject()).runReadActionInSmartMode(new Runnable() {
+ @Override
+ public void run() {
collectItems(artifact, outputPath);
}
- }.execute();
+ });
return new ArrayList<ArtifactCompilerCompileItem>(myBuilderContext.getProcessingItems());
}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactPropertiesEditor.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactPropertiesEditor.java
index 220b079..f0f15f2 100644
--- a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactPropertiesEditor.java
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactPropertiesEditor.java
@@ -16,6 +16,7 @@
package com.intellij.packaging.ui;
import com.intellij.openapi.options.UnnamedConfigurable;
+import org.jetbrains.annotations.Nullable;
/**
* @author nik
@@ -28,4 +29,9 @@
public abstract String getTabName();
public abstract void apply();
+
+ @Nullable
+ public String getHelpId() {
+ return null;
+ }
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
index 9074ae6..084f458 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
@@ -762,6 +762,7 @@
getManagerThread().close();
}
finally {
+ final VirtualMachineProxyImpl vm = myVirtualMachineProxy;
myVirtualMachineProxy = null;
myPositionManager = null;
myReturnValueWatcher = null;
@@ -774,6 +775,13 @@
}
finally {
setBreakpointsMuted(false);
+ if (vm != null) {
+ try {
+ vm.dispose(); // to be on the safe side ensure that VM mirror, if present, is disposed and invalidated
+ }
+ catch (Throwable ignored) {
+ }
+ }
myWaitFor.up();
}
}
@@ -1343,8 +1351,12 @@
else {
// some VM's (like IBM VM 1.4.2 bundled with WebSpere) does not
// resume threads on dispose() like it should
- virtualMachineProxy.resume();
- virtualMachineProxy.dispose();
+ try {
+ virtualMachineProxy.resume();
+ }
+ finally {
+ virtualMachineProxy.dispose();
+ }
}
}
else {
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java
index e7ef657..aeadbf7 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java
@@ -23,6 +23,7 @@
import com.intellij.codeInsight.daemon.JavaErrorMessages;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.engine.ContextUtil;
@@ -1029,7 +1030,8 @@
if (castType != null && operandType != null && !TypeConversionUtil.areTypesConvertible(operandType, castType)) {
throw new EvaluateRuntimeException(
- new EvaluateException(JavaErrorMessages.message("inconvertible.type.cast", HighlightUtil.formatType(operandType), HighlightUtil.formatType(castType)))
+ new EvaluateException(JavaErrorMessages.message("inconvertible.type.cast", JavaHighlightUtil.formatType(operandType), JavaHighlightUtil
+ .formatType(castType)))
);
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form
index 206aef2..b2e86d4 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form
@@ -36,7 +36,7 @@
</children>
</grid>
<grid id="763d0" layout-manager="GridLayoutManager" row-count="1" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
- <margin top="0" left="5" bottom="0" right="0"/>
+ <margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
</constraints>
@@ -173,7 +173,7 @@
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
- <text value="&Temporary"/>
+ <text value="&Remove once hit"/>
</properties>
</component>
</children>
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java
index f70c6ce..1217e16 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java
@@ -43,7 +43,6 @@
import com.intellij.psi.PsiElement;
import com.intellij.ui.FieldPanel;
import com.intellij.ui.MultiLineTooltipUI;
-import com.intellij.ui.components.JBCheckBox;
import com.intellij.ui.popup.util.DetailView;
import com.intellij.util.IJSwingUtilities;
import com.intellij.xdebugger.impl.DebuggerSupport;
@@ -533,13 +532,22 @@
myLogMessageCheckBox.setSelected(breakpoint.LOG_ENABLED);
myTemporaryCheckBox.setSelected(breakpoint.REMOVE_AFTER_HIT);
myEnabledCheckbox.setSelected(breakpoint.ENABLED);
- myEnabledCheckbox.setText(breakpoint.getDisplayName());
+ myEnabledCheckbox.setText(breakpoint.getShortName() + " enabled");
+
+ DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().addBreakpointManagerListener(new BreakpointManagerListener() {
+ @Override
+ public void breakpointsChanged() {
+ myEnabledCheckbox.setSelected(myBreakpoint.ENABLED);
+ }
+ });
+
myEnabledCheckbox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
if (myBreakpoint.ENABLED != myEnabledCheckbox.isSelected()) {
myBreakpoint.ENABLED = myEnabledCheckbox.isSelected();
getBreakpointManager(myProject).fireBreakpointChanged(myBreakpoint);
+ myBreakpoint.updateUI();
}
}
});
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java
index abd786f..2da2753 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java
@@ -26,11 +26,9 @@
import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.debugger.ui.JavaDebuggerSupport;
-import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.colors.EditorColorsManager;
@@ -52,8 +50,6 @@
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.xdebugger.impl.DebuggerSupport;
import com.intellij.xdebugger.impl.actions.EditBreakpointAction;
-import com.intellij.xdebugger.impl.actions.ViewBreakpointsAction;
-import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.ui.DebuggerColors;
import com.intellij.xml.util.XmlStringUtil;
import com.sun.jdi.ReferenceType;
@@ -346,6 +342,7 @@
if (debugProcess == null || !debugProcess.isAttached()) {
updateCaches(null);
updateGutter();
+
afterUpdate.run();
}
else {
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java
index 5b94044..052cfd7 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java
@@ -139,6 +139,8 @@
@Override
public void setEnabled(boolean state) {
myBreakpoint.ENABLED = state;
+ myBreakpoint.updateUI();
+ DebuggerManagerEx.getInstanceEx(myBreakpoint.getProject()).getBreakpointManager().fireBreakpointChanged(myBreakpoint);
}
@Override
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 2be7f16..76f1b79 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
@@ -125,6 +125,9 @@
protected void createRequestForPreparedClass(final DebugProcessImpl debugProcess, final ReferenceType classType) {
if (!isInScopeOf(debugProcess, classType.name())) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(classType.name() + " is out of debug-process scope, breakpoint request won't be created for line " + getLineIndex());
+ }
return;
}
try {
@@ -186,10 +189,16 @@
if (breakpointFile != null && fileIndex.isInSourceContent(breakpointFile)) {
// apply filtering to breakpoints from content sources only, not for sources attached to libraries
final Collection<VirtualFile> candidates = findClassCandidatesInSourceContent(className, debugProcess.getSearchScope(), fileIndex);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Found "+ (candidates == null? "null" : candidates.size()) + " candidate containing files for class " + className);
+ }
if (candidates == null) {
return true;
}
for (VirtualFile classFile : candidates) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Breakpoint file: " + breakpointFile.getPath()+ "; candidate file: " + classFile.getPath());
+ }
if (breakpointFile.equals(classFile)) {
return true;
}
@@ -208,12 +217,30 @@
@Nullable
public Collection<VirtualFile> compute() {
final PsiClass[] classes = JavaPsiFacade.getInstance(myProject).findClasses(topLevelClassName, scope);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Found "+ classes.length + " classes " + topLevelClassName + " in scope");
+ }
if (classes.length == 0) {
return null;
}
final List<VirtualFile> list = new ArrayList<VirtualFile>(classes.length);
for (PsiClass aClass : classes) {
final PsiFile psiFile = aClass.getContainingFile();
+
+ if (LOG.isDebugEnabled()) {
+ final StringBuilder msg = new StringBuilder();
+ msg.append("Checking class ").append(aClass.getQualifiedName());
+ msg.append("\n\t").append("PsiFile=").append(psiFile);
+ if (psiFile != null) {
+ final VirtualFile vFile = psiFile.getVirtualFile();
+ msg.append("\n\t").append("VirtualFile=").append(vFile);
+ if (vFile != null) {
+ msg.append("\n\t").append("isInSourceContent=").append(fileIndex.isInSourceContent(vFile));
+ }
+ }
+ LOG.debug(msg.toString());
+ }
+
if (psiFile != null) {
final VirtualFile vFile = psiFile.getVirtualFile();
if (vFile != null && fileIndex.isInSourceContent(vFile)) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java
index c23bcfe..32ace10 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java
@@ -324,6 +324,9 @@
}
else {
showMessage(session != null? session.getStateDescription() : DebuggerBundle.message("status.debug.stopped"));
+ if (session == null || session.isStopped()) {
+ getNodeFactory().clearHistory(); // save memory by clearing references on JDI objects
+ }
}
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java
index 905f7b0..53e820d 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java
@@ -122,10 +122,14 @@
}
public void dispose() {
- myHistories.clear();
+ clearHistory();
super.dispose();
}
+ public void clearHistory() {
+ myHistories.clear();
+ }
+
private DebuggerTree getTree() {
return myDebuggerTree;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
index 3e11145..098c42c 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
@@ -217,6 +217,9 @@
}
catch (ClassNotLoadedException ignored) {
}
+ catch (Throwable e) {
+ LOG.info(e); // catch all exceptions to ensure the method returns gracefully
+ }
}
return exceptionObj;
}
diff --git a/java/execution/impl/src/com/intellij/execution/ui/AlternativeJREPanel.java b/java/execution/impl/src/com/intellij/execution/ui/AlternativeJREPanel.java
index 1fe5df7..6052487 100644
--- a/java/execution/impl/src/com/intellij/execution/ui/AlternativeJREPanel.java
+++ b/java/execution/impl/src/com/intellij/execution/ui/AlternativeJREPanel.java
@@ -22,6 +22,7 @@
import com.intellij.openapi.ui.ComponentWithBrowseButton;
import com.intellij.openapi.ui.TextComponentAccessor;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.GuiUtils;
import com.intellij.ui.InsertPathAction;
import com.intellij.ui.PanelWithAnchor;
@@ -49,6 +50,12 @@
myFieldWithHistory = new TextFieldWithHistory();
final ArrayList<String> foundJDKs = new ArrayList<String>();
+ for (JreProvider provider : JreProvider.EP_NAME.getExtensions()) {
+ String path = provider.getJrePath();
+ if (!StringUtil.isEmpty(path)) {
+ foundJDKs.add(path);
+ }
+ }
final Sdk[] allJDKs = ProjectJdkTable.getInstance().getAllJdks();
for (Sdk jdk : allJDKs) {
foundJDKs.add(jdk.getHomePath());
diff --git a/java/execution/impl/src/com/intellij/execution/ui/JreProvider.java b/java/execution/impl/src/com/intellij/execution/ui/JreProvider.java
new file mode 100644
index 0000000..9b70053
--- /dev/null
+++ b/java/execution/impl/src/com/intellij/execution/ui/JreProvider.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2013 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.execution.ui;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Extension point for providing custom jre to be shown at run configuration control.
+ *
+ * @author Denis Zhdanov
+ * @since 5/9/13 10:04 PM
+ */
+public interface JreProvider {
+
+ ExtensionPointName<JreProvider> EP_NAME = new ExtensionPointName<JreProvider>("com.intellij.jreProvider");
+
+ @NotNull
+ String getJrePath();
+}
diff --git a/java/idea-ui/src/com/intellij/framework/FrameworkGroup.java b/java/idea-ui/src/com/intellij/framework/FrameworkGroup.java
index bd626e5..02bf071 100644
--- a/java/idea-ui/src/com/intellij/framework/FrameworkGroup.java
+++ b/java/idea-ui/src/com/intellij/framework/FrameworkGroup.java
@@ -9,7 +9,7 @@
/**
* @author nik
*/
-public abstract class FrameworkGroup {
+public abstract class FrameworkGroup<V extends FrameworkGroupVersion> {
private final String myId;
public FrameworkGroup(String id) {
@@ -28,7 +28,7 @@
public abstract Icon getIcon();
@NotNull
- public List<String> getGroupVersions() {
+ public List<V> getGroupVersions() {
return Collections.emptyList();
}
}
diff --git a/java/idea-ui/src/com/intellij/framework/FrameworkGroupVersion.java b/java/idea-ui/src/com/intellij/framework/FrameworkGroupVersion.java
new file mode 100644
index 0000000..ea0f310
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/framework/FrameworkGroupVersion.java
@@ -0,0 +1,11 @@
+package com.intellij.framework;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public interface FrameworkGroupVersion {
+ @NotNull String getId();
+ @NotNull String getPresentableName();
+}
diff --git a/java/idea-ui/src/com/intellij/framework/FrameworkTypeEx.java b/java/idea-ui/src/com/intellij/framework/FrameworkTypeEx.java
index 4c8e59e..02c0298 100644
--- a/java/idea-ui/src/com/intellij/framework/FrameworkTypeEx.java
+++ b/java/idea-ui/src/com/intellij/framework/FrameworkTypeEx.java
@@ -31,7 +31,7 @@
}
@Nullable
- public FrameworkGroup getParentGroup() {
+ public FrameworkGroup<?> getParentGroup() {
return null;
}
diff --git a/java/idea-ui/src/com/intellij/framework/library/impl/DownloadableLibraryServiceImpl.java b/java/idea-ui/src/com/intellij/framework/library/impl/DownloadableLibraryServiceImpl.java
index f5e3304..dbaa6d0 100644
--- a/java/idea-ui/src/com/intellij/framework/library/impl/DownloadableLibraryServiceImpl.java
+++ b/java/idea-ui/src/com/intellij/framework/library/impl/DownloadableLibraryServiceImpl.java
@@ -15,11 +15,14 @@
*/
package com.intellij.framework.library.impl;
-import com.intellij.framework.library.DownloadableLibraryDescription;
-import com.intellij.framework.library.DownloadableLibraryService;
-import com.intellij.framework.library.DownloadableLibraryType;
-import com.intellij.framework.library.LibraryVersionProperties;
+import com.intellij.facet.frameworks.beans.Artifact;
+import com.intellij.facet.frameworks.beans.RequiredFrameworkVersion;
+import com.intellij.framework.FrameworkGroup;
+import com.intellij.framework.FrameworkGroupVersion;
+import com.intellij.framework.library.*;
import com.intellij.ide.util.frameworkSupport.CustomLibraryDescriptionImpl;
+import com.intellij.ide.util.frameworkSupport.FrameworkSupportModel;
+import com.intellij.ide.util.newProjectWizard.impl.FrameworkSupportModelBase;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.roots.libraries.LibraryType;
import com.intellij.openapi.roots.libraries.ui.LibraryEditorComponent;
@@ -37,8 +40,18 @@
@NotNull
@Override
- public DownloadableLibraryDescription createLibraryDescription(@NotNull String groupId, @NotNull URL... localUrls) {
- return new LibraryVersionsFetcher(groupId, localUrls);
+ public DownloadableLibraryDescription createLibraryDescription(@NotNull String groupId, @NotNull final URL... localUrls) {
+ return new LibraryVersionsFetcher(groupId, localUrls) {
+ //todo[nik] pull up this method after moving corresponding API to lang-api
+ @NotNull
+ protected FrameworkAvailabilityFilter createAvailabilityFilter(Artifact version) {
+ RequiredFrameworkVersion groupVersion = version.getRequiredFrameworkVersion();
+ if (groupVersion != null) {
+ return new FrameworkLibraryAvailabilityFilter(groupVersion.myGroupId, groupVersion.myVersion);
+ }
+ return FrameworkAvailabilityFilter.ALWAYS;
+ }
+ };
}
@NotNull
@@ -56,4 +69,26 @@
@NotNull DownloadableLibraryType libraryType) {
return new DownloadableLibraryPropertiesEditor(description, editorComponent, libraryType);
}
+
+ private static class FrameworkLibraryAvailabilityFilter extends FrameworkAvailabilityFilter {
+ private final String myGroupId;
+ private final String myVersionId;
+
+ public FrameworkLibraryAvailabilityFilter(String groupId, String versionId) {
+ myGroupId = groupId;
+ myVersionId = versionId;
+ }
+
+ @Override
+ public boolean isAvailable(@NotNull FrameworkSupportModel model) {
+ FrameworkSupportModelBase modelBase = (FrameworkSupportModelBase)model;
+ for (FrameworkGroup<?> group : modelBase.getFrameworkGroups()) {
+ if (group.getId().equals(myGroupId)) {
+ FrameworkGroupVersion selectedVersion = modelBase.getSelectedVersion(group);
+ return selectedVersion != null && myVersionId.equals(selectedVersion.getId());
+ }
+ }
+ return true;
+ }
+ }
}
diff --git a/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/OldCustomLibraryDescription.java b/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/OldCustomLibraryDescription.java
index 7e53c09..1adad9b 100644
--- a/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/OldCustomLibraryDescription.java
+++ b/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/OldCustomLibraryDescription.java
@@ -20,6 +20,7 @@
import com.intellij.facet.ui.libraries.LibraryInfo;
import com.intellij.framework.library.DownloadableLibraryDescription;
import com.intellij.framework.library.DownloadableLibraryFileDescription;
+import com.intellij.framework.library.FrameworkAvailabilityFilter;
import com.intellij.framework.library.FrameworkLibraryVersion;
import com.intellij.framework.library.impl.DownloadableLibraryDescriptionImpl;
import com.intellij.framework.library.impl.DownloadableLibraryFileDescriptionImpl;
@@ -61,7 +62,7 @@
downloadingInfo.getFileNameSuffix(), null, null, false));
}
}
- libraryVersions.add(new FrameworkLibraryVersionImpl(version.getVersionName(), downloads, version.getLibraryName()));
+ libraryVersions.add(new FrameworkLibraryVersionImpl(version.getVersionName(), FrameworkAvailabilityFilter.ALWAYS, downloads, version.getLibraryName()));
}
myDownloadableDescription = !libraryVersions.isEmpty() ? new DownloadableLibraryDescriptionImpl(libraryVersions) : null;
}
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddSupportForFrameworksPanel.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddSupportForFrameworksPanel.java
index bb54043..7cccf0a 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddSupportForFrameworksPanel.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddSupportForFrameworksPanel.java
@@ -34,14 +34,11 @@
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer;
-import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.Splitter;
-import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.Comparing;
import com.intellij.ui.CheckedTreeNode;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.ui.FormBuilder;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -69,7 +66,7 @@
private final JPanel myOptionsPanel;
private final FrameworksTree myFrameworksTree;
private final Map<FrameworkSupportNode, FrameworkSupportOptionsComponent> myInitializedOptionsComponents = new HashMap<FrameworkSupportNode, FrameworkSupportOptionsComponent>();
- private final Map<FrameworkGroup, JPanel> myInitializedGroupPanels = new HashMap<FrameworkGroup, JPanel>();
+ private final Map<FrameworkGroup<?>, JPanel> myInitializedGroupPanels = new HashMap<FrameworkGroup<?>, JPanel>();
private FrameworkSupportNodeBase myLastSelectedNode;
public AddSupportForFrameworksPanel(final List<FrameworkSupportInModuleProvider> providers, final FrameworkSupportModelBase model) {
@@ -151,7 +148,7 @@
frameworkSupportNode.getConfigurable().onFrameworkSelectionChanged(node.isChecked());
}
else if (node instanceof FrameworkGroupNode) {
- FrameworkGroup group = ((FrameworkGroupNode)node).getGroup();
+ FrameworkGroup<?> group = ((FrameworkGroupNode)node).getGroup();
initializeGroupPanel(group);
showCard(group.getId());
}
@@ -160,19 +157,11 @@
}
}
- private void initializeGroupPanel(FrameworkGroup group) {
+ private void initializeGroupPanel(FrameworkGroup<?> group) {
if (!myInitializedGroupPanels.containsKey(group)) {
- JPanel panel = new JPanel(new VerticalFlowLayout());
- List<String> versions = group.getGroupVersions();
- if (!versions.isEmpty()) {
- ComboBox versionsBox = new ComboBox();
- for (String version : versions) {
- versionsBox.addItem(version);
- }
- panel.add(FormBuilder.createFormBuilder().addLabeledComponent("Version:", versionsBox).getPanel());
- }
- myInitializedGroupPanels.put(group, panel);
- myOptionsPanel.add(group.getId(), panel);
+ FrameworkGroupOptionsComponent component = new FrameworkGroupOptionsComponent(group, myModel);
+ myInitializedGroupPanels.put(group, component.getMainPanel());
+ myOptionsPanel.add(group.getId(), component.getMainPanel());
}
}
@@ -188,6 +177,9 @@
if (parentNode instanceof FrameworkSupportNode) {
initializeOptionsPanel((FrameworkSupportNode)parentNode);
}
+ else if (parentNode instanceof FrameworkGroupNode) {
+ initializeGroupPanel(((FrameworkGroupNode)parentNode).getGroup());
+ }
FrameworkSupportOptionsComponent optionsComponent = new FrameworkSupportOptionsComponent(myModel, myLibrariesContainer, this,
node.getProvider(), node.getConfigurable());
@@ -227,7 +219,7 @@
private void createNodes() {
Map<String, FrameworkSupportNode> nodes = new HashMap<String, FrameworkSupportNode>();
- Map<FrameworkGroup, FrameworkGroupNode> groups = new HashMap<FrameworkGroup, FrameworkGroupNode>();
+ Map<FrameworkGroup<?>, FrameworkGroupNode> groups = new HashMap<FrameworkGroup<?>, FrameworkGroupNode>();
List<FrameworkSupportNodeBase> roots = new ArrayList<FrameworkSupportNodeBase>();
for (FrameworkSupportInModuleProvider provider : myProviders) {
createNode(provider, nodes, groups, roots);
@@ -239,13 +231,13 @@
@Nullable
private FrameworkSupportNode createNode(final FrameworkSupportInModuleProvider provider, final Map<String, FrameworkSupportNode> nodes,
- final Map<FrameworkGroup, FrameworkGroupNode> groupNodes,
+ final Map<FrameworkGroup<?>, FrameworkGroupNode> groupNodes,
List<FrameworkSupportNodeBase> roots) {
FrameworkSupportNode node = nodes.get(provider.getFrameworkType().getId());
if (node == null) {
String underlyingTypeId = provider.getFrameworkType().getUnderlyingFrameworkTypeId();
FrameworkSupportNodeBase parentNode = null;
- final FrameworkGroup group = provider.getFrameworkType().getParentGroup();
+ final FrameworkGroup<?> group = provider.getFrameworkType().getParentGroup();
if (underlyingTypeId != null) {
FrameworkSupportInModuleProvider parentProvider = FrameworkSupportUtil.findProvider(underlyingTypeId, myProviders);
if (parentProvider == null) {
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkGroupNode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkGroupNode.java
index 2a513d3..807110f 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkGroupNode.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkGroupNode.java
@@ -9,14 +9,14 @@
* @author nik
*/
public class FrameworkGroupNode extends FrameworkSupportNodeBase {
- private final FrameworkGroup myGroup;
+ private final FrameworkGroup<?> myGroup;
- public FrameworkGroupNode(@NotNull FrameworkGroup group, FrameworkSupportNodeBase parent) {
+ public FrameworkGroupNode(@NotNull FrameworkGroup<?> group, FrameworkSupportNodeBase parent) {
super(group, parent);
myGroup = group;
}
- public FrameworkGroup getGroup() {
+ public FrameworkGroup<?> getGroup() {
return myGroup;
}
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkGroupOptionsComponent.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkGroupOptionsComponent.java
new file mode 100644
index 0000000..b83dd0c
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkGroupOptionsComponent.java
@@ -0,0 +1,53 @@
+package com.intellij.ide.util.newProjectWizard;
+
+import com.intellij.framework.FrameworkGroup;
+import com.intellij.framework.FrameworkGroupVersion;
+import com.intellij.ide.util.newProjectWizard.impl.FrameworkSupportModelBase;
+import com.intellij.openapi.ui.ComboBox;
+import com.intellij.openapi.ui.VerticalFlowLayout;
+import com.intellij.ui.ListCellRendererWrapper;
+import com.intellij.util.ui.FormBuilder;
+
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class FrameworkGroupOptionsComponent {
+ private final JPanel myMainPanel;
+
+ public FrameworkGroupOptionsComponent(final FrameworkGroup<?> group, final FrameworkSupportModelBase model) {
+ JPanel panel = new JPanel(new VerticalFlowLayout());
+ List<? extends FrameworkGroupVersion> versions = group.getGroupVersions();
+ if (!versions.isEmpty()) {
+ final ComboBox versionsBox = new ComboBox();
+ versionsBox.setRenderer(new ListCellRendererWrapper<FrameworkGroupVersion>() {
+ @Override
+ public void customize(JList list, FrameworkGroupVersion value, int index, boolean selected, boolean hasFocus) {
+ setText(value != null ? value.getPresentableName() : "");
+ }
+ });
+ versionsBox.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ model.setSelectedVersion(group, (FrameworkGroupVersion)versionsBox.getSelectedItem());
+ }
+ });
+ for (FrameworkGroupVersion version : versions) {
+ versionsBox.addItem(version);
+ }
+ FrameworkGroupVersion latestVersion = versions.get(versions.size() - 1);
+ versionsBox.setSelectedItem(latestVersion);
+ model.setSelectedVersion(group, latestVersion);
+ panel.add(FormBuilder.createFormBuilder().addLabeledComponent("Version:", versionsBox).getPanel());
+ }
+ myMainPanel = panel;
+ }
+
+ public JPanel getMainPanel() {
+ return myMainPanel;
+ }
+}
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportOptionsComponent.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportOptionsComponent.java
index 6b5e1f7..0f84009 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportOptionsComponent.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportOptionsComponent.java
@@ -19,6 +19,9 @@
import com.intellij.facet.impl.ui.libraries.LibraryOptionsPanel;
import com.intellij.framework.addSupport.FrameworkSupportInModuleConfigurable;
import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider;
+import com.intellij.framework.library.FrameworkLibraryVersion;
+import com.intellij.framework.library.FrameworkLibraryVersionFilter;
+import com.intellij.framework.library.impl.FrameworkLibraryVersionImpl;
import com.intellij.ide.util.frameworkSupport.FrameworkSupportConfigurableListener;
import com.intellij.ide.util.frameworkSupport.FrameworkSupportModelAdapter;
import com.intellij.ide.util.newProjectWizard.impl.FrameworkSupportModelBase;
@@ -29,6 +32,7 @@
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.SeparatorFactory;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -82,7 +86,7 @@
final CustomLibraryDescription description = myConfigurable.createLibraryDescription();
if (description != null) {
- myLibraryOptionsPanel = new LibraryOptionsPanel(description, myModel.getBaseDirectoryForLibrariesPath(), myConfigurable.getLibraryVersionFilter(),
+ myLibraryOptionsPanel = new LibraryOptionsPanel(description, myModel.getBaseDirectoryForLibrariesPath(), createLibraryVersionFilter(),
container, !myConfigurable.isOnlyLibraryAdded());
Disposer.register(myConfigurable, myLibraryOptionsPanel);
if (addSeparator) {
@@ -98,11 +102,20 @@
public void updateLibrariesPanel() {
if (myLibraryOptionsPanel != null) {
myLibraryOptionsPanel.changeBaseDirectoryPath(myModel.getBaseDirectoryForLibrariesPath());
- myLibraryOptionsPanel.setVersionFilter(myConfigurable.getLibraryVersionFilter());
+ myLibraryOptionsPanel.setVersionFilter(createLibraryVersionFilter());
myLibraryOptionsPanelWrapper.setVisible(myConfigurable.isVisible());
}
}
+ private FrameworkLibraryVersionFilter createLibraryVersionFilter() {
+ return new FrameworkLibraryVersionFilter() {
+ @Override
+ public boolean isAccepted(@NotNull FrameworkLibraryVersion version) {
+ return myConfigurable.getLibraryVersionFilter().isAccepted(version) && ((FrameworkLibraryVersionImpl)version).getAvailabilityFilter().isAvailable(myModel);
+ }
+ };
+ }
+
public JPanel getMainPanel() {
return myMainPanel;
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java
index afb5c60..cfdcf81 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java
@@ -305,7 +305,6 @@
@Override
public void addSettingsField(@NotNull String label, @NotNull JComponent field) {
-
JPanel panel = myWizardContext.isCreatingNewProject() ? myNamePathComponent : myModulePanel;
addField(label, field, panel);
}
@@ -321,8 +320,9 @@
@Override
public void addSettingsComponent(@NotNull JComponent component) {
- myNamePathComponent.add(component, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0, GridBagConstraints.NORTHWEST,
- GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
+ JPanel panel = myWizardContext.isCreatingNewProject() ? myNamePathComponent : myModulePanel;
+ panel.add(component, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0, GridBagConstraints.NORTHWEST,
+ GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
}
@Override
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java
index e82e67e..acfa5e8 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java
@@ -15,24 +15,26 @@
*/
package com.intellij.ide.util.newProjectWizard.impl;
+import com.intellij.framework.FrameworkGroup;
+import com.intellij.framework.FrameworkGroupVersion;
import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider;
import com.intellij.ide.util.frameworkSupport.FrameworkSupportConfigurable;
import com.intellij.ide.util.frameworkSupport.FrameworkSupportModel;
import com.intellij.ide.util.frameworkSupport.FrameworkSupportModelListener;
import com.intellij.ide.util.frameworkSupport.FrameworkSupportProvider;
-import com.intellij.ide.util.newProjectWizard.FrameworkSupportNode;
-import com.intellij.ide.util.newProjectWizard.FrameworkSupportOptionsComponent;
-import com.intellij.ide.util.newProjectWizard.OldFrameworkSupportProviderWrapper;
+import com.intellij.ide.util.newProjectWizard.*;
import com.intellij.ide.util.projectWizard.ModuleBuilder;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.util.EventDispatcher;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -46,6 +48,7 @@
private final EventDispatcher<FrameworkSupportModelListener> myDispatcher = EventDispatcher.create(FrameworkSupportModelListener.class);
private final Map<String, FrameworkSupportNode> mySettingsMap = new HashMap<String, FrameworkSupportNode>();
private final Map<String, FrameworkSupportOptionsComponent> myOptionsComponentsMap = new HashMap<String, FrameworkSupportOptionsComponent>();
+ private final Map<FrameworkGroup<?>, FrameworkGroupVersion> mySelectedVersions = new HashMap<FrameworkGroup<?>, FrameworkGroupVersion>();
public FrameworkSupportModelBase(final @Nullable Project project, @Nullable ModuleBuilder builder, @NotNull LibrariesContainer librariesContainer) {
myProject = project;
@@ -123,6 +126,36 @@
return ((OldFrameworkSupportProviderWrapper.FrameworkSupportConfigurableWrapper)node.getConfigurable()).getConfigurable();
}
+ public void setSelectedVersion(@NotNull FrameworkGroup<?> group, @Nullable FrameworkGroupVersion version) {
+ FrameworkGroupVersion oldVersion = mySelectedVersions.put(group, version);
+ if (!Comparing.equal(oldVersion, version)) {
+ for (Map.Entry<String, FrameworkSupportNode> entry : mySettingsMap.entrySet()) {
+ FrameworkGroup<?> parentGroup = getParentGroup(entry.getValue());
+ if (group.equals(parentGroup)) {
+ updateFrameworkLibraryComponent(entry.getKey());
+ }
+ }
+ }
+ }
+
+ @Nullable
+ private static FrameworkGroup<?> getParentGroup(final FrameworkSupportNode node) {
+ FrameworkSupportNodeBase current = node;
+ while (current instanceof FrameworkSupportNode) {
+ current = current.getParentNode();
+ }
+ return current instanceof FrameworkGroupNode ? ((FrameworkGroupNode)current).getGroup() : null;
+ }
+
+ public Collection<FrameworkGroup<?>> getFrameworkGroups() {
+ return mySelectedVersions.keySet();
+ }
+
+ @Nullable
+ public <V extends FrameworkGroupVersion> V getSelectedVersion(@NotNull FrameworkGroup<V> group) {
+ return (V)mySelectedVersions.get(group);
+ }
+
public void onFrameworkSelectionChanged(FrameworkSupportNode node) {
final FrameworkSupportModelListener multicaster = myDispatcher.getMulticaster();
final FrameworkSupportInModuleProvider provider = node.getProvider();
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java
index cb66981..e8f8c90 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java
@@ -22,12 +22,9 @@
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
-import com.intellij.openapi.util.Condition;
-import com.intellij.platform.DirectoryProjectGenerator;
import com.intellij.platform.ProjectTemplate;
import com.intellij.platform.ProjectTemplatesFactory;
import com.intellij.platform.templates.LocalArchivedTemplate;
-import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -44,12 +41,6 @@
*/
public class CreateFromTemplateMode extends WizardMode {
- private static final Condition<ProjectTemplate> TEMPLATE_CONDITION = new Condition<ProjectTemplate>() {
- @Override
- public boolean value(ProjectTemplate template) {
- return !(template instanceof DirectoryProjectGenerator);
- }
- };
private SelectTemplateStep mySelectTemplateStep;
public static MultiMap<TemplatesGroup, ProjectTemplate> getTemplatesMap(WizardContext context) {
@@ -58,8 +49,7 @@
for (ProjectTemplatesFactory factory : factories) {
for (String group : factory.getGroups()) {
ProjectTemplate[] templates = factory.createTemplates(group, context);
- List<ProjectTemplate> values = context.isCreatingNewProject() ? Arrays.asList(templates) : ContainerUtil.filter(templates,
- TEMPLATE_CONDITION);
+ List<ProjectTemplate> values = Arrays.asList(templates);
if (!values.isEmpty()) {
Icon icon = factory.getGroupIcon(group);
TemplatesGroup templatesGroup = new TemplatesGroup(group, null, icon, factory.getGroupWeight(group));
diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/ProjectWizardUtil.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/ProjectWizardUtil.java
index 8f380dd..0f8e3c3 100644
--- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/ProjectWizardUtil.java
+++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/ProjectWizardUtil.java
@@ -46,7 +46,7 @@
if (!dir.exists()) {
if (promptUser) {
final int answer = Messages.showOkCancelDialog(IdeBundle.message("promot.projectwizard.directory.does.not.exist", promptPrefix,
- dir.getPath(), ApplicationNamesInfo.getInstance().getProductName()),
+ dir.getPath(), ApplicationNamesInfo.getInstance().getFullProductName()),
IdeBundle.message("title.directory.does.not.exist"), Messages.getQuestionIcon());
if (answer != 0) {
return false;
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java
index cdea51f..47e9015 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java
@@ -189,7 +189,16 @@
ModuleConfigurationEditorProvider[] providers = collectProviders(module);
ModuleConfigurationState state = createModuleConfigurationState();
for (ModuleConfigurationEditorProvider provider : providers) {
- ContainerUtil.addAll(myEditors, provider.createEditors(state));
+ ModuleConfigurationEditor[] editors = provider.createEditors(state);
+ if (editors.length > 0 && provider instanceof ModuleConfigurationEditorProviderEx &&
+ ((ModuleConfigurationEditorProviderEx)provider).isCompleteEditorSet()) {
+ myEditors.clear();
+ ContainerUtil.addAll(myEditors, editors);
+ break;
+ }
+ else {
+ ContainerUtil.addAll(myEditors, editors);
+ }
}
for (final Configurable moduleConfigurable : myModule.getComponents(Configurable.class)) {
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java
index 8fe693c..f3c4102 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java
@@ -554,7 +554,7 @@
if (tab == 0) {
return "reference.project.structure.artifacts.output";
}
- String helpId = ArtifactPropertiesEditors.getHelpId(myTabbedPane.getSelectedTitle());
+ String helpId = myPropertiesEditors.getHelpId(myTabbedPane.getSelectedTitle());
return helpId != null ? helpId : "reference.settingsdialog.project.structure.artifacts";
}
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactPropertiesEditors.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactPropertiesEditors.java
index 53b0bc1..1828daa 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactPropertiesEditors.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactPropertiesEditors.java
@@ -108,7 +108,7 @@
}
@Nullable
- public static String getHelpId(String title) {
+ public String getHelpId(String title) {
if (ArtifactPropertiesEditor.VALIDATION_TAB.equals(title)) {
return "reference.project.structure.artifacts.validation";
}
@@ -118,6 +118,12 @@
else if (ArtifactPropertiesEditor.POST_PROCESSING_TAB.equals(title)) {
return "reference.project.structure.artifacts.postprocessing";
}
+ for (PropertiesEditorInfo editorInfo : myEditors) {
+ final ArtifactPropertiesEditor editor = editorInfo.myEditor;
+ if (editor.getTabName().equals(title)) {
+ return editor.getHelpId();
+ }
+ }
return null;
}
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java
index b5881c1..0614771 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java
@@ -330,8 +330,7 @@
return moduleStructureExtension.getNodeComparator();
}
});
- comparators.add(NODE_COMPARATOR);
- return new MergingComparator<MyNode>(comparators);
+ return new MergingComparator<MyNode>(ContainerUtil.concat(comparators, Collections.singletonList(NODE_COMPARATOR)));
}
@Override
@@ -678,7 +677,7 @@
extension.copy(configurable, TREE_UPDATER);
}
}
-
+
private class MyDataProviderWrapper extends JPanel implements DataProvider {
public MyDataProviderWrapper(final JComponent component) {
super(new BorderLayout());
diff --git a/java/idea-ui/src/com/intellij/platform/templates/ArchivedProjectTemplate.java b/java/idea-ui/src/com/intellij/platform/templates/ArchivedProjectTemplate.java
index f11f627..adc9ddd 100644
--- a/java/idea-ui/src/com/intellij/platform/templates/ArchivedProjectTemplate.java
+++ b/java/idea-ui/src/com/intellij/platform/templates/ArchivedProjectTemplate.java
@@ -36,7 +36,7 @@
protected final String myDisplayName;
- public ArchivedProjectTemplate(String displayName) {
+ public ArchivedProjectTemplate(@NotNull String displayName) {
myDisplayName = displayName;
}
diff --git a/java/idea-ui/src/com/intellij/platform/templates/LocalArchivedTemplate.java b/java/idea-ui/src/com/intellij/platform/templates/LocalArchivedTemplate.java
index 00563cf..1b9f3c2 100644
--- a/java/idea-ui/src/com/intellij/platform/templates/LocalArchivedTemplate.java
+++ b/java/idea-ui/src/com/intellij/platform/templates/LocalArchivedTemplate.java
@@ -51,8 +51,9 @@
private List<WizardInputField> myInputFields = Collections.emptyList();
private Icon myIcon;
- public LocalArchivedTemplate(String displayName,
- URL archivePath, ClassLoader classLoader) {
+ public LocalArchivedTemplate(@NotNull String displayName,
+ @NotNull URL archivePath,
+ @NotNull ClassLoader classLoader) {
super(displayName);
myArchivePath = archivePath;
diff --git a/java/idea-ui/src/com/intellij/platform/templates/ManageProjectTemplatesDialog.java b/java/idea-ui/src/com/intellij/platform/templates/ManageProjectTemplatesDialog.java
index 81d9b7f..3a8a97b 100644
--- a/java/idea-ui/src/com/intellij/platform/templates/ManageProjectTemplatesDialog.java
+++ b/java/idea-ui/src/com/intellij/platform/templates/ManageProjectTemplatesDialog.java
@@ -35,7 +35,6 @@
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.File;
-import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
@@ -61,11 +60,7 @@
super.remove(index);
if (template instanceof LocalArchivedTemplate) {
URL path = ((LocalArchivedTemplate)template).getArchivePath();
- try {
- new File(path.toURI()).delete();
- }
- catch (URISyntaxException ignore) {
- }
+ new File(path.getPath()).delete();
}
}
};
diff --git a/java/idea-ui/src/com/intellij/platform/templates/PlainModuleTemplatesFactory.java b/java/idea-ui/src/com/intellij/platform/templates/PlainModuleTemplatesFactory.java
index 3ce17ab..adea904 100644
--- a/java/idea-ui/src/com/intellij/platform/templates/PlainModuleTemplatesFactory.java
+++ b/java/idea-ui/src/com/intellij/platform/templates/PlainModuleTemplatesFactory.java
@@ -28,6 +28,7 @@
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -47,8 +48,9 @@
return builder.getGroupName();
}
});
- groups.add(OTHER_GROUP);
- return ArrayUtil.toStringArray(groups);
+ HashSet<String> set = new HashSet<String>(groups);
+ set.add(OTHER_GROUP);
+ return ArrayUtil.toStringArray(set);
}
@NotNull
diff --git a/java/java-analysis-api/src/com/intellij/codeInspection/BatchSuppressManager.java b/java/java-analysis-api/src/com/intellij/codeInspection/BatchSuppressManager.java
index 1c96c8d..6a5d840 100644
--- a/java/java-analysis-api/src/com/intellij/codeInspection/BatchSuppressManager.java
+++ b/java/java-analysis-api/src/com/intellij/codeInspection/BatchSuppressManager.java
@@ -26,6 +26,8 @@
import java.util.Collection;
public interface BatchSuppressManager {
+ String SUPPRESS_INSPECTIONS_ANNOTATION_NAME = "java.lang.SuppressWarnings";
+
class SERVICE {
public static BatchSuppressManager getInstance() {
return ServiceManager.getService(BatchSuppressManager.class);
diff --git a/java/java-psi-api/src/com/intellij/openapi/module/EffectiveLanguageLevelUtil.java b/java/java-analysis-api/src/com/intellij/openapi/module/EffectiveLanguageLevelUtil.java
similarity index 87%
rename from java/java-psi-api/src/com/intellij/openapi/module/EffectiveLanguageLevelUtil.java
rename to java/java-analysis-api/src/com/intellij/openapi/module/EffectiveLanguageLevelUtil.java
index 9a0fb12..1bf588c 100644
--- a/java/java-psi-api/src/com/intellij/openapi/module/EffectiveLanguageLevelUtil.java
+++ b/java/java-analysis-api/src/com/intellij/openapi/module/EffectiveLanguageLevelUtil.java
@@ -25,7 +25,8 @@
@NotNull
public static LanguageLevel getEffectiveLanguageLevel(@NotNull final Module module) {
ApplicationManager.getApplication().assertReadAccessAllowed();
- LanguageLevel level = LanguageLevelModuleExtension.getInstance(module).getLanguageLevel();
+ LanguageLevelModuleExtension moduleLevel = LanguageLevelModuleExtension.getInstance(module);
+ LanguageLevel level = moduleLevel == null ? null : moduleLevel.getLanguageLevel();
if (level != null) return level;
return LanguageLevelProjectExtension.getInstance(module.getProject()).getLanguageLevel();
}
diff --git a/java/java-psi-api/src/com/intellij/openapi/roots/LanguageLevelModuleExtension.java b/java/java-analysis-api/src/com/intellij/openapi/roots/LanguageLevelModuleExtension.java
similarity index 100%
rename from java/java-psi-api/src/com/intellij/openapi/roots/LanguageLevelModuleExtension.java
rename to java/java-analysis-api/src/com/intellij/openapi/roots/LanguageLevelModuleExtension.java
diff --git a/java/java-analysis-impl/java-analysis-impl.iml b/java/java-analysis-impl/java-analysis-impl.iml
index d4756de..ad06d8c 100644
--- a/java/java-analysis-impl/java-analysis-impl.iml
+++ b/java/java-analysis-impl/java-analysis-impl.iml
@@ -12,6 +12,7 @@
<orderEntry type="module" module-name="java-psi-impl" exported="" />
<orderEntry type="module" module-name="projectModel-impl" exported="" />
<orderEntry type="module" module-name="java-analysis-api" exported="" />
+ <orderEntry type="module" module-name="resources-en" />
</component>
</module>
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java
new file mode 100644
index 0000000..8e29318
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright 2000-2013 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.codeInsight.daemon.impl.analysis;
+
+import com.intellij.codeInsight.AnnotationUtil;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Iterator;
+
+public class JavaGenericsUtil {
+ public static boolean isReifiableType(PsiType type) {
+ if (type instanceof PsiArrayType) {
+ return isReifiableType(((PsiArrayType)type).getComponentType());
+ }
+
+ if (type instanceof PsiPrimitiveType) {
+ return true;
+ }
+
+ if (PsiUtil.resolveClassInType(type) instanceof PsiTypeParameter) {
+ return false;
+ }
+
+ if (type instanceof PsiClassType) {
+ final PsiClassType classType = (PsiClassType)PsiUtil.convertAnonymousToBaseType(type);
+ if (classType.isRaw()) {
+ return true;
+ }
+ PsiType[] parameters = classType.getParameters();
+
+ for (PsiType parameter : parameters) {
+ if (parameter instanceof PsiWildcardType && ((PsiWildcardType)parameter).getBound() == null) {
+ return true;
+ }
+ }
+ final PsiClass resolved = ((PsiClassType)PsiUtil.convertAnonymousToBaseType(classType)).resolve();
+ if (resolved instanceof PsiTypeParameter) {
+ return false;
+ }
+ if (parameters.length == 0) {
+ if (resolved != null && !resolved.hasModifierProperty(PsiModifier.STATIC)) {
+ final PsiClass containingClass = resolved.getContainingClass();
+ if (containingClass != null) {
+ final PsiTypeParameter[] containingClassTypeParameters = containingClass.getTypeParameters();
+ if (containingClassTypeParameters.length > 0) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static boolean isUncheckedWarning(PsiJavaCodeReferenceElement expression, JavaResolveResult resolveResult) {
+ final PsiElement resolve = resolveResult.getElement();
+ if (resolve instanceof PsiMethod) {
+ final PsiMethod psiMethod = (PsiMethod)resolve;
+
+ final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(expression);
+
+ if (psiMethod.isVarArgs()) {
+ if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_7) || !AnnotationUtil.isAnnotated(psiMethod, "java.lang.SafeVarargs", false)) {
+ final int parametersCount = psiMethod.getParameterList().getParametersCount();
+ final PsiParameter varargParameter =
+ psiMethod.getParameterList().getParameters()[parametersCount - 1];
+ final PsiType componentType = ((PsiEllipsisType)varargParameter.getType()).getComponentType();
+ if (!isReifiableType(resolveResult.getSubstitutor().substitute(componentType))) {
+ final PsiElement parent = expression.getParent();
+ if (parent instanceof PsiCall) {
+ final PsiExpressionList argumentList = ((PsiCall)parent).getArgumentList();
+ if (argumentList != null) {
+ final PsiExpression[] args = argumentList.getExpressions();
+ if (args.length == parametersCount) {
+ final PsiExpression lastArg = args[args.length - 1];
+ if (lastArg instanceof PsiReferenceExpression) {
+ final PsiElement lastArgsResolve = ((PsiReferenceExpression)lastArg).resolve();
+ if (lastArgsResolve instanceof PsiParameter) {
+ if (((PsiParameter)lastArgsResolve).getType() instanceof PsiArrayType) {
+ return false;
+ }
+ }
+ }
+ else if (lastArg instanceof PsiMethodCallExpression) {
+ if (lastArg.getType() instanceof PsiArrayType) {
+ return false;
+ }
+ }
+ }
+ for (int i = parametersCount - 1; i < args.length; i++) {
+ if (!isReifiableType(resolveResult.getSubstitutor().substitute(args[i].getType()))) {
+ return true;
+ }
+ }
+ return args.length < parametersCount;
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ public static boolean isUncheckedCast(PsiType castType, PsiType operandType) {
+ if (TypeConversionUtil.isAssignable(castType, operandType, false)) return false;
+
+ castType = castType.getDeepComponentType();
+ if (castType instanceof PsiClassType) {
+ final PsiClassType castClassType = (PsiClassType)castType;
+ operandType = operandType.getDeepComponentType();
+
+ if (!(operandType instanceof PsiClassType)) return false;
+ final PsiClassType operandClassType = (PsiClassType)operandType;
+ final PsiClassType.ClassResolveResult castResult = castClassType.resolveGenerics();
+ final PsiClassType.ClassResolveResult operandResult = operandClassType.resolveGenerics();
+ final PsiClass operandClass = operandResult.getElement();
+ final PsiClass castClass = castResult.getElement();
+
+ if (operandClass == null || castClass == null) return false;
+ if (castClass instanceof PsiTypeParameter) return true;
+
+ if (castClassType.hasNonTrivialParameters()) {
+ if (operandClassType.isRaw()) return true;
+ if (castClass.isInheritor(operandClass, true)) {
+ PsiSubstitutor castSubstitutor = castResult.getSubstitutor();
+ PsiElementFactory factory = JavaPsiFacade.getInstance(castClass.getProject()).getElementFactory();
+ for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(castClass)) {
+ PsiSubstitutor modifiedSubstitutor = castSubstitutor.put(typeParameter, null);
+ PsiClassType otherType = factory.createType(castClass, modifiedSubstitutor);
+ if (TypeConversionUtil.isAssignable(operandType, otherType, false)) return true;
+ }
+ for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(operandClass)) {
+ final PsiType operand = operandResult.getSubstitutor().substitute(typeParameter);
+ if (operand instanceof PsiCapturedWildcardType) return true;
+ }
+ return false;
+ }
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static boolean isRawToGeneric(PsiType lType, PsiType rType) {
+ if (lType instanceof PsiPrimitiveType || rType instanceof PsiPrimitiveType) return false;
+ if (lType.equals(rType)) return false;
+ if (lType instanceof PsiArrayType && rType instanceof PsiArrayType) {
+ return isRawToGeneric(((PsiArrayType)lType).getComponentType(), ((PsiArrayType)rType).getComponentType());
+ }
+ if (lType instanceof PsiArrayType || rType instanceof PsiArrayType) return false;
+
+ if (rType instanceof PsiIntersectionType) {
+ for (PsiType type : ((PsiIntersectionType)rType).getConjuncts()) {
+ if (isRawToGeneric(lType, type)) return true;
+ }
+ return false;
+ }
+ if (lType instanceof PsiIntersectionType) {
+ for (PsiType type : ((PsiIntersectionType)lType).getConjuncts()) {
+ if (isRawToGeneric(type, rType)) return true;
+ }
+ return false;
+ }
+
+ if (!(lType instanceof PsiClassType) || !(rType instanceof PsiClassType)) return false;
+
+ PsiClassType.ClassResolveResult lResolveResult = ((PsiClassType)lType).resolveGenerics();
+ PsiClassType.ClassResolveResult rResolveResult = ((PsiClassType)rType).resolveGenerics();
+ PsiClass lClass = lResolveResult.getElement();
+ PsiClass rClass = rResolveResult.getElement();
+
+ if (rClass instanceof PsiAnonymousClass) {
+ return isRawToGeneric(lType, ((PsiAnonymousClass)rClass).getBaseClassType());
+ }
+
+ PsiSubstitutor lSubstitutor = lResolveResult.getSubstitutor();
+ PsiSubstitutor rSubstitutor = rResolveResult.getSubstitutor();
+ if (lClass == null || rClass == null) return false;
+ if (lClass instanceof PsiTypeParameter &&
+ !InheritanceUtil.isInheritorOrSelf(rClass, lClass, true)) {
+ return true;
+ }
+
+ if (!lClass.getManager().areElementsEquivalent(lClass, rClass)) {
+ if (lClass.isInheritor(rClass, true)) {
+ lSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(rClass, lClass, lSubstitutor);
+ lClass = rClass;
+ }
+ else if (rClass.isInheritor(lClass, true)) {
+ rSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(lClass, rClass, rSubstitutor);
+ rClass = lClass;
+ }
+ else {
+ return false;
+ }
+ }
+
+ Iterator<PsiTypeParameter> lIterator = PsiUtil.typeParametersIterator(lClass);
+ Iterator<PsiTypeParameter> rIterator = PsiUtil.typeParametersIterator(rClass);
+ while (lIterator.hasNext()) {
+ if (!rIterator.hasNext()) return false;
+ PsiTypeParameter lParameter = lIterator.next();
+ PsiTypeParameter rParameter = rIterator.next();
+ PsiType lTypeArg = lSubstitutor.substitute(lParameter);
+ PsiType rTypeArg = rSubstitutor.substituteWithBoundsPromotion(rParameter);
+ if (lTypeArg == null) continue;
+ if (rTypeArg == null) {
+ if (lTypeArg instanceof PsiWildcardType && ((PsiWildcardType)lTypeArg).getBound() == null) {
+ continue;
+ }
+ else {
+ return true;
+ }
+ }
+ if (!TypeConversionUtil.typesAgree(lTypeArg, rTypeArg, true)) return true;
+ }
+ return false;
+ }
+
+ @Nullable
+ public static PsiType getCollectionItemType(@NotNull PsiExpression expression) {
+ final PsiType type = expression.getType();
+ if (type == null) return null;
+ return getCollectionItemType(type, expression.getResolveScope());
+ }
+
+ @Nullable
+ public static PsiType getCollectionItemType(final PsiType type, final GlobalSearchScope scope) {
+ if (type instanceof PsiArrayType) {
+ return ((PsiArrayType)type).getComponentType();
+ }
+ if (type instanceof PsiClassType) {
+ final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)type).resolveGenerics();
+ PsiClass aClass = resolveResult.getElement();
+ if (aClass == null) return null;
+ final PsiManager manager = aClass.getManager();
+ final String qName = aClass.getQualifiedName();
+ PsiSubstitutor substitutor = resolveResult.getSubstitutor();
+ JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());
+ if (qName != null) {
+ PsiClass myClass = facade.findClass(qName, scope);
+ if (myClass != null && myClass != aClass) {
+ //different JDKs
+ PsiTypeParameter thisTypeParameter = getIterableTypeParameter(facade, myClass);
+ if (thisTypeParameter == null) return null;
+ PsiTypeParameter thatTypeParameter = getIterableTypeParameter(facade, aClass);
+ if (thatTypeParameter != null) { //it can be null if we reference collection in JDK1.4 module from JDK5 source
+ substitutor = substitutor.put(thisTypeParameter, substitutor.substitute(thatTypeParameter));
+ }
+ aClass = myClass;
+ }
+ }
+ PsiTypeParameter typeParameter = getIterableTypeParameter(facade, aClass);
+ if (typeParameter == null) return null;
+ PsiClass owner = (PsiClass)typeParameter.getOwner();
+ if (owner == null) return null;
+ PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getClassSubstitutor(owner, aClass, PsiSubstitutor.EMPTY);
+ if (superClassSubstitutor == null) return null;
+ PsiType itemType = superClassSubstitutor.substitute(typeParameter);
+ itemType = substitutor.substitute(itemType);
+ return itemType == null ? PsiType.getJavaLangObject(manager, aClass.getResolveScope()) : itemType;
+ }
+ return null;
+ }
+
+ @Nullable
+ private static PsiTypeParameter getIterableTypeParameter(final JavaPsiFacade facade, final PsiClass context) {
+ PsiClass iterable = facade.findClass("java.lang.Iterable", context.getResolveScope());
+ if (iterable == null) return null;
+ PsiTypeParameter[] typeParameters = iterable.getTypeParameters();
+ if (typeParameters.length != 1) return null;
+ return typeParameters[0];
+ }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaHighlightUtil.java
new file mode 100644
index 0000000..c1e2b18
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaHighlightUtil.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2000-2013 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.codeInsight.daemon.impl.analysis;
+
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiFormatUtil;
+import com.intellij.psi.util.PsiFormatUtilBase;
+import com.intellij.psi.util.TypeConversionUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class JavaHighlightUtil {
+ public static boolean isSerializable(@NotNull PsiClass aClass) {
+ PsiManager manager = aClass.getManager();
+ PsiClass serializableClass = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.io.Serializable", aClass.getResolveScope());
+ return serializableClass != null && aClass.isInheritor(serializableClass, true);
+ }
+
+ public static boolean isSerializationRelatedMethod(PsiMethod method, PsiClass containingClass) {
+ if (containingClass == null || method.isConstructor()) return false;
+ if (method.hasModifierProperty(PsiModifier.STATIC)) return false;
+ @NonNls String name = method.getName();
+ PsiParameter[] parameters = method.getParameterList().getParameters();
+ PsiType returnType = method.getReturnType();
+ if ("readObjectNoData".equals(name)) {
+ return parameters.length == 0 && TypeConversionUtil.isVoidType(returnType) && isSerializable(containingClass);
+ }
+ if ("readObject".equals(name)) {
+ return parameters.length == 1
+ && parameters[0].getType().equalsToText("java.io.ObjectInputStream")
+ && TypeConversionUtil.isVoidType(returnType) && method.hasModifierProperty(PsiModifier.PRIVATE)
+ && isSerializable(containingClass);
+ }
+ if ("readResolve".equals(name)) {
+ return parameters.length == 0
+ && returnType != null
+ && returnType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)
+ && (containingClass.hasModifierProperty(PsiModifier.ABSTRACT) || isSerializable(containingClass));
+ }
+ if ("writeReplace".equals(name)) {
+ return parameters.length == 0
+ && returnType != null
+ && returnType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)
+ && (containingClass.hasModifierProperty(PsiModifier.ABSTRACT) || isSerializable(containingClass));
+ }
+ if ("writeObject".equals(name)) {
+ return parameters.length == 1
+ && TypeConversionUtil.isVoidType(returnType)
+ && parameters[0].getType().equalsToText("java.io.ObjectOutputStream")
+ && method.hasModifierProperty(PsiModifier.PRIVATE)
+ && isSerializable(containingClass);
+ }
+ return false;
+ }
+
+ @NotNull
+ public static String formatType(@Nullable PsiType type) {
+ if (type == null) return PsiKeyword.NULL;
+ String text = type.getInternalCanonicalText();
+ return text == null ? PsiKeyword.NULL : text;
+ }
+
+ @Nullable
+ private static PsiType getArrayInitializerType(@NotNull final PsiArrayInitializerExpression element) {
+ final PsiType typeCheckResult = sameType(element.getInitializers());
+ if (typeCheckResult != null) {
+ return typeCheckResult.createArrayType();
+ }
+ return null;
+ }
+
+ @Nullable
+ public static PsiType sameType(@NotNull PsiExpression[] expressions) {
+ PsiType type = null;
+ for (PsiExpression expression : expressions) {
+ final PsiType currentType;
+ if (expression instanceof PsiArrayInitializerExpression) {
+ currentType = getArrayInitializerType((PsiArrayInitializerExpression)expression);
+ }
+ else {
+ currentType = expression.getType();
+ }
+ if (type == null) {
+ type = currentType;
+ }
+ else if (!type.equals(currentType)) {
+ return null;
+ }
+ }
+ return type;
+ }
+
+ @NotNull
+ public static String formatMethod(@NotNull PsiMethod method) {
+ return PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS,
+ PsiFormatUtilBase.SHOW_TYPE);
+ }
+
+ public static boolean isSuperOrThisCall(PsiStatement statement, boolean testForSuper, boolean testForThis) {
+ if (!(statement instanceof PsiExpressionStatement)) return false;
+ PsiExpression expression = ((PsiExpressionStatement)statement).getExpression();
+ if (!(expression instanceof PsiMethodCallExpression)) return false;
+ final PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)expression).getMethodExpression();
+ if (testForSuper) {
+ if ("super".equals(methodExpression.getText())) return true;
+ }
+ if (testForThis) {
+ if ("this".equals(methodExpression.getText())) return true;
+ }
+
+ return false;
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodThrowsFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodThrowsFix.java
similarity index 84%
rename from java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodThrowsFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodThrowsFix.java
index 3ebfb21..61adfb6 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodThrowsFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodThrowsFix.java
@@ -17,10 +17,9 @@
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
+import com.intellij.codeInspection.LocalQuickFixOnPsiElement;
import com.intellij.openapi.command.undo.UndoUtil;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
@@ -28,16 +27,15 @@
import com.intellij.psi.util.PsiFormatUtilBase;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-public class MethodThrowsFix extends LocalQuickFixAndIntentionActionOnPsiElement {
+public class MethodThrowsFix extends LocalQuickFixOnPsiElement {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.MethodThrowsFix");
private final String myThrowsCanonicalText;
private final boolean myShouldThrow;
private final String myMethodName;
- public MethodThrowsFix(PsiMethod method, PsiClassType exceptionType, boolean shouldThrow, boolean showContainingClass) {
+ public MethodThrowsFix(@NotNull PsiMethod method, @NotNull PsiClassType exceptionType, boolean shouldThrow, boolean showContainingClass) {
super(method);
myThrowsCanonicalText = exceptionType.getCanonicalText();
myShouldThrow = shouldThrow;
@@ -73,11 +71,7 @@
}
@Override
- public void invoke(@NotNull Project project,
- @NotNull PsiFile file,
- @Nullable("is null when called from inspection") Editor editor,
- @NotNull PsiElement startElement,
- @NotNull PsiElement endElement) {
+ public void invoke(@NotNull Project project, @NotNull PsiFile file, @NotNull PsiElement startElement, @NotNull PsiElement endElement) {
final PsiMethod myMethod = (PsiMethod)startElement;
if (!FileModificationService.getInstance().prepareFileForWrite(myMethod.getContainingFile())) return;
PsiJavaCodeReferenceElement[] referenceElements = myMethod.getThrowsList().getReferenceElements();
@@ -100,7 +94,8 @@
myMethod.getThrowsList().add(ref);
}
UndoUtil.markPsiFileForUndo(file);
- } catch (IncorrectOperationException e) {
+ }
+ catch (IncorrectOperationException e) {
LOG.error(e);
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableUtil.java
new file mode 100644
index 0000000..4515cc8
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableUtil.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2000-2013 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.codeInsight.daemon.impl.quickfix;
+
+import com.intellij.psi.*;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.IncorrectOperationException;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+public class RemoveUnusedVariableUtil {
+ public static final int MAKE_STATEMENT = 1;
+ public static final int DELETE_ALL = 2;
+ public static final int CANCEL = 0;
+ private static final Set<String> ourSideEffectFreeClasses = new THashSet<String>();
+ static {
+ ourSideEffectFreeClasses.add(Object.class.getName());
+ ourSideEffectFreeClasses.add(Short.class.getName());
+ ourSideEffectFreeClasses.add(Character.class.getName());
+ ourSideEffectFreeClasses.add(Byte.class.getName());
+ ourSideEffectFreeClasses.add(Integer.class.getName());
+ ourSideEffectFreeClasses.add(Long.class.getName());
+ ourSideEffectFreeClasses.add(Float.class.getName());
+ ourSideEffectFreeClasses.add(Double.class.getName());
+ ourSideEffectFreeClasses.add(String.class.getName());
+ ourSideEffectFreeClasses.add(StringBuffer.class.getName());
+ ourSideEffectFreeClasses.add(Boolean.class.getName());
+
+ ourSideEffectFreeClasses.add(ArrayList.class.getName());
+ ourSideEffectFreeClasses.add(Date.class.getName());
+ ourSideEffectFreeClasses.add(HashMap.class.getName());
+ ourSideEffectFreeClasses.add(HashSet.class.getName());
+ ourSideEffectFreeClasses.add(Hashtable.class.getName());
+ ourSideEffectFreeClasses.add(LinkedHashMap.class.getName());
+ ourSideEffectFreeClasses.add(LinkedHashSet.class.getName());
+ ourSideEffectFreeClasses.add(LinkedList.class.getName());
+ ourSideEffectFreeClasses.add(Stack.class.getName());
+ ourSideEffectFreeClasses.add(TreeMap.class.getName());
+ ourSideEffectFreeClasses.add(TreeSet.class.getName());
+ ourSideEffectFreeClasses.add(Vector.class.getName());
+ ourSideEffectFreeClasses.add(WeakHashMap.class.getName());
+ }
+
+ static boolean isSideEffectFreeConstructor(PsiNewExpression newExpression) {
+ PsiJavaCodeReferenceElement classReference = newExpression.getClassReference();
+ PsiClass aClass = classReference == null ? null : (PsiClass)classReference.resolve();
+ String qualifiedName = aClass == null ? null : aClass.getQualifiedName();
+ if (qualifiedName == null) return false;
+ if (ourSideEffectFreeClasses.contains(qualifiedName)) return true;
+
+ PsiFile file = aClass.getContainingFile();
+ PsiDirectory directory = file.getContainingDirectory();
+ PsiPackage classPackage = JavaDirectoryService.getInstance().getPackage(directory);
+ String packageName = classPackage == null ? null : classPackage.getQualifiedName();
+
+ // all Throwable descendants from java.lang are side effects free
+ if ("java.lang".equals(packageName) || "java.io".equals(packageName)) {
+ PsiClass throwableClass = JavaPsiFacade.getInstance(aClass.getProject()).findClass("java.lang.Throwable", aClass.getResolveScope());
+ if (throwableClass != null && InheritanceUtil.isInheritorOrSelf(aClass, throwableClass, true)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean checkSideEffects(PsiElement element, PsiVariable variable, List<PsiElement> sideEffects) {
+ if (sideEffects == null || element == null) return false;
+ if (element instanceof PsiMethodCallExpression) {
+ final PsiMethod psiMethod = ((PsiMethodCallExpression)element).resolveMethod();
+ if (psiMethod == null || !PropertyUtil.isSimpleGetter(psiMethod) && !PropertyUtil.isSimpleSetter(psiMethod)) {
+ sideEffects.add(element);
+ return true;
+ }
+ }
+ if (element instanceof PsiNewExpression) {
+ PsiNewExpression newExpression = (PsiNewExpression)element;
+ if (newExpression.getArrayDimensions().length == 0
+ && newExpression.getArrayInitializer() == null
+ && !isSideEffectFreeConstructor(newExpression)) {
+ sideEffects.add(element);
+ return true;
+ }
+ }
+ if (element instanceof PsiAssignmentExpression
+ && !(((PsiAssignmentExpression)element).getLExpression() instanceof PsiReferenceExpression
+ && ((PsiReferenceExpression)((PsiAssignmentExpression)element).getLExpression()).resolve() == variable)) {
+ sideEffects.add(element);
+ return true;
+ }
+ PsiElement[] children = element.getChildren();
+
+ for (PsiElement child : children) {
+ checkSideEffects(child, variable, sideEffects);
+ }
+ return !sideEffects.isEmpty();
+}
+
+ static PsiElement replaceElementWithExpression(PsiExpression expression,
+ PsiElementFactory factory,
+ PsiElement element) throws IncorrectOperationException {
+ PsiElement elementToReplace = element;
+ PsiElement expressionToReplaceWith = expression;
+ if (element.getParent() instanceof PsiExpressionStatement) {
+ elementToReplace = element.getParent();
+ expressionToReplaceWith =
+ factory.createStatementFromText((expression == null ? "" : expression.getText()) + ";", null);
+ }
+ else if (element.getParent() instanceof PsiDeclarationStatement) {
+ expressionToReplaceWith =
+ factory.createStatementFromText((expression == null ? "" : expression.getText()) + ";", null);
+ }
+ return elementToReplace.replace(expressionToReplaceWith);
+ }
+
+ static PsiElement createStatementIfNeeded(PsiExpression expression,
+ PsiElementFactory factory,
+ PsiElement element) throws IncorrectOperationException {
+ // if element used in expression, subexpression will do
+ if (!(element.getParent() instanceof PsiExpressionStatement) &&
+ !(element.getParent() instanceof PsiDeclarationStatement)) {
+ return expression;
+ }
+ return factory.createStatementFromText((expression == null ? "" : expression.getText()) + ";", null);
+ }
+
+ static void deleteWholeStatement(PsiElement element, PsiElementFactory factory)
+ throws IncorrectOperationException {
+ // just delete it altogether
+ if (element.getParent() instanceof PsiExpressionStatement) {
+ PsiExpressionStatement parent = (PsiExpressionStatement)element.getParent();
+ if (parent.getParent() instanceof PsiCodeBlock) {
+ parent.delete();
+ }
+ else {
+ // replace with empty statement (to handle with 'if (..) i=0;' )
+ parent.replace(createStatementIfNeeded(null, factory, element));
+ }
+ }
+ else {
+ element.delete();
+ }
+ }
+
+ static void deleteReferences(PsiVariable variable, List<PsiElement> references, int mode) throws IncorrectOperationException {
+ for (PsiElement expression : references) {
+ processUsage(expression, variable, null, mode);
+ }
+ }
+
+ static void collectReferences(@NotNull PsiElement context, final PsiVariable variable, final List<PsiElement> references) {
+ context.accept(new JavaRecursiveElementWalkingVisitor() {
+ @Override public void visitReferenceExpression(PsiReferenceExpression expression) {
+ if (expression.resolve() == variable) references.add(expression);
+ super.visitReferenceExpression(expression);
+ }
+ });
+ }
+
+ /**
+ * @param sideEffects if null, delete usages, otherwise collect side effects
+ * @return true if there are at least one unrecoverable side effect found, false if no side effects,
+ * null if read usage found (may happen if interval between fix creation in invoke() call was long enough)
+ * @throws com.intellij.util.IncorrectOperationException
+ */
+ static Boolean processUsage(PsiElement element, PsiVariable variable, List<PsiElement> sideEffects, int deleteMode)
+ throws IncorrectOperationException {
+ if (!element.isValid()) return null;
+ PsiElementFactory factory = JavaPsiFacade.getInstance(variable.getProject()).getElementFactory();
+ while (element != null) {
+ if (element instanceof PsiAssignmentExpression) {
+ PsiAssignmentExpression expression = (PsiAssignmentExpression)element;
+ PsiExpression lExpression = expression.getLExpression();
+ // there should not be read access to the variable, otherwise it is not unused
+ if (!(lExpression instanceof PsiReferenceExpression) || variable != ((PsiReferenceExpression)lExpression).resolve()) {
+ return null;
+ }
+ PsiExpression rExpression = expression.getRExpression();
+ rExpression = PsiUtil.deparenthesizeExpression(rExpression);
+ if (rExpression == null) return true;
+ // replace assignment with expression and resimplify
+ boolean sideEffectFound = checkSideEffects(rExpression, variable, sideEffects);
+ if (!(element.getParent() instanceof PsiExpressionStatement) || PsiUtil.isStatement(rExpression)) {
+ if (deleteMode == MAKE_STATEMENT ||
+ deleteMode == DELETE_ALL && !(element.getParent() instanceof PsiExpressionStatement)) {
+ element = replaceElementWithExpression(rExpression, factory, element);
+ while (element.getParent() instanceof PsiParenthesizedExpression) {
+ element = element.getParent().replace(element);
+ }
+ List<PsiElement> references = new ArrayList<PsiElement>();
+ collectReferences(element, variable, references);
+ deleteReferences(variable, references, deleteMode);
+ }
+ else if (deleteMode == DELETE_ALL) {
+ deleteWholeStatement(element, factory);
+ }
+ return true;
+ }
+ else {
+ if (deleteMode != CANCEL) {
+ deleteWholeStatement(element, factory);
+ }
+ return !sideEffectFound;
+ }
+ }
+ else if (element instanceof PsiExpressionStatement && deleteMode != CANCEL) {
+ element.delete();
+ break;
+ }
+ else if (element instanceof PsiVariable && element == variable) {
+ PsiExpression expression = variable.getInitializer();
+ if (expression != null) {
+ expression = PsiUtil.deparenthesizeExpression(expression);
+ }
+ boolean sideEffectsFound = checkSideEffects(expression, variable, sideEffects);
+ if (expression != null && PsiUtil.isStatement(expression) && variable instanceof PsiLocalVariable
+ &&
+ !(variable.getParent() instanceof PsiDeclarationStatement &&
+ ((PsiDeclarationStatement)variable.getParent()).getDeclaredElements().length > 1)) {
+ if (deleteMode == MAKE_STATEMENT) {
+ element = element.replace(createStatementIfNeeded(expression, factory, element));
+ List<PsiElement> references = new ArrayList<PsiElement>();
+ collectReferences(element, variable, references);
+ deleteReferences(variable, references, deleteMode);
+ }
+ else if (deleteMode == DELETE_ALL) {
+ element.delete();
+ }
+ return true;
+ }
+ else {
+ if (deleteMode != CANCEL) {
+ if (element instanceof PsiField) {
+ ((PsiField)element).normalizeDeclaration();
+ }
+ element.delete();
+ }
+ return !sideEffectsFound;
+ }
+ }
+ element = element.getParent();
+ }
+ return true;
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java
similarity index 90%
rename from java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java
index 83395ef..612c6c6 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java
@@ -21,9 +21,9 @@
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.codeInspection.LocalQuickFixOnPsiElement;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
@@ -40,45 +40,54 @@
import java.util.ArrayList;
import java.util.List;
-public class SimplifyBooleanExpressionFix implements IntentionAction {
+public class SimplifyBooleanExpressionFix extends LocalQuickFixOnPsiElement {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.SimplifyBooleanExpression");
+ public static final String FAMILY_NAME = QuickFixBundle.message("simplify.boolean.expression.family");
- private final PsiExpression mySubExpression;
private final Boolean mySubExpressionValue;
// subExpressionValue == Boolean.TRUE or Boolean.FALSE if subExpression evaluates to boolean constant and needs to be replaced
// otherwise subExpressionValue= null and we starting to simplify expression without any further knowledge
- public SimplifyBooleanExpressionFix(PsiExpression subExpression, Boolean subExpressionValue) {
- mySubExpression = subExpression;
+ public SimplifyBooleanExpressionFix(@NotNull PsiExpression subExpression, Boolean subExpressionValue) {
+ super(subExpression);
mySubExpressionValue = subExpressionValue;
}
@Override
@NotNull
public String getText() {
- return QuickFixBundle.message("simplify.boolean.expression.text", mySubExpression.getText(), mySubExpressionValue);
+ PsiExpression expression = getSubExpression();
+ return QuickFixBundle.message("simplify.boolean.expression.text", expression.getText(), mySubExpressionValue);
}
@Override
@NotNull
public String getFamilyName() {
- return QuickFixBundle.message("simplify.boolean.expression.family");
+ return FAMILY_NAME;
}
@Override
- public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
- return mySubExpression.isValid()
- && mySubExpression.getManager().isInProject(mySubExpression)
- && !PsiUtil.isAccessedForWriting(mySubExpression)
- ;
+ public boolean isAvailable() {
+ PsiExpression expression = getSubExpression();
+ return super.isAvailable()
+ && expression != null
+ && expression.isValid()
+ && expression.getManager().isInProject(expression)
+ && !PsiUtil.isAccessedForWriting(expression);
}
@Override
- public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
- if (!isAvailable(project, editor, file)) return;
- LOG.assertTrue(mySubExpression.isValid());
- if (!FileModificationService.getInstance().preparePsiElementForWrite(mySubExpression)) return;
- simplifyExpression(project, mySubExpression, mySubExpressionValue);
+ public void invoke(@NotNull final Project project, @NotNull PsiFile file, @NotNull PsiElement startElement, @NotNull PsiElement endElement) {
+ if (!isAvailable()) return;
+ final PsiExpression expression = getSubExpression();
+ LOG.assertTrue(expression.isValid());
+ if (!FileModificationService.getInstance().preparePsiElementForWrite(expression)) return;
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ simplifyExpression(project, expression, mySubExpressionValue);
+ }
+ });
}
public static void simplifyExpression(Project project, final PsiExpression subExpression, final Boolean subExpressionValue) {
@@ -226,6 +235,11 @@
return canBeSimplified.get().booleanValue();
}
+ private PsiExpression getSubExpression() {
+ PsiElement element = getStartElement();
+ return element instanceof PsiExpression ? (PsiExpression)element : null;
+ }
+
private static class ExpressionVisitor extends JavaElementVisitor {
private PsiExpression resultExpression;
private final PsiExpression trueExpression;
@@ -420,9 +434,4 @@
String text = operand.getText();
return PsiKeyword.TRUE.equals(text) ? Boolean.TRUE : PsiKeyword.FALSE.equals(text) ? Boolean.FALSE : null;
}
-
- @Override
- public boolean startInWriteAction() {
- return true;
- }
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableArrayTypeFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableArrayTypeFix.java
similarity index 83%
rename from java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableArrayTypeFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableArrayTypeFix.java
index 0b87b3d..1087e2e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableArrayTypeFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableArrayTypeFix.java
@@ -17,18 +17,20 @@
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
+import com.intellij.codeInspection.LocalQuickFixOnPsiElement;
+import com.intellij.ide.TypePresentationService;
+import com.intellij.lang.findUsages.FindUsagesProvider;
+import com.intellij.lang.findUsages.LanguageFindUsages;
import com.intellij.openapi.command.undo.UndoUtil;
-import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public class VariableArrayTypeFix extends LocalQuickFixAndIntentionActionOnPsiElement {
-
+public class VariableArrayTypeFix extends LocalQuickFixOnPsiElement {
@NotNull
private final PsiArrayType myTargetType;
private final String myName;
@@ -48,12 +50,22 @@
PsiVariable myVariable = getVariableLocal(arrayInitializer);
myName = myVariable == null ? null : myTargetType.equals(myVariable.getType()) && myNewExpression != null ?
QuickFixBundle.message("change.new.operator.type.text", getNewText(myNewExpression,arrayInitializer), myTargetType.getCanonicalText(), "") :
- QuickFixBundle.message("fix.variable.type.text", myVariable.getName(), myTargetType.getCanonicalText());
+ QuickFixBundle.message("fix.variable.type.text", formatType(myVariable), myVariable.getName(), myTargetType.getCanonicalText());
myFamilyName = myVariable == null ? null : myTargetType.equals(myVariable.getType()) && myNewExpression != null ?
QuickFixBundle.message("change.new.operator.type.family") :
QuickFixBundle.message("fix.variable.type.family");
}
+ private static String formatType(@NotNull PsiVariable variable) {
+ FindUsagesProvider provider = LanguageFindUsages.INSTANCE.forLanguage(variable.getLanguage());
+ final String type = provider.getType(variable);
+ if (StringUtil.isNotEmpty(type)) {
+ return type;
+ }
+
+ return TypePresentationService.getService().getTypePresentableName(variable.getClass());
+ }
+
private static PsiArrayInitializerExpression getInitializer(PsiArrayInitializerExpression initializer) {
PsiArrayInitializerExpression arrayInitializer = initializer;
while (arrayInitializer.getParent() instanceof PsiArrayInitializerExpression) {
@@ -63,7 +75,7 @@
return arrayInitializer;
}
- private static PsiVariable getVariableLocal(PsiArrayInitializerExpression initializer) {
+ private static PsiVariable getVariableLocal(@NotNull PsiArrayInitializerExpression initializer) {
PsiVariable variableLocal = null;
final PsiElement parent = initializer.getParent();
@@ -86,14 +98,15 @@
return variableLocal;
}
- private static PsiNewExpression getNewExpressionLocal(PsiArrayInitializerExpression initializer) {
+ private static PsiNewExpression getNewExpressionLocal(@NotNull PsiArrayInitializerExpression initializer) {
PsiNewExpression newExpressionLocal = null;
final PsiElement parent = initializer.getParent();
if (parent instanceof PsiVariable) {
- } else if (parent instanceof PsiNewExpression) {
- newExpressionLocal = (PsiNewExpression) parent;
+ }
+ else if (parent instanceof PsiNewExpression) {
+ newExpressionLocal = (PsiNewExpression)parent;
}
return newExpressionLocal;
@@ -143,11 +156,7 @@
}
@Override
- public void invoke(@NotNull Project project,
- @NotNull PsiFile file,
- @Nullable("is null when called from inspection") Editor editor,
- @NotNull PsiElement startElement,
- @NotNull PsiElement endElement) {
+ public void invoke(@NotNull Project project, @NotNull PsiFile file, @NotNull PsiElement startElement, @NotNull PsiElement endElement) {
final PsiArrayInitializerExpression myInitializer = (PsiArrayInitializerExpression)startElement;
final PsiVariable myVariable = getVariableLocal(myInitializer);
if (myVariable == null) return;
diff --git a/java/java-impl/src/com/intellij/codeInsight/guess/GuessManager.java b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/GuessManager.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInsight/guess/GuessManager.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/guess/GuessManager.java
diff --git a/java/java-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java
similarity index 94%
rename from java/java-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java
index 9e30492..7a74783 100644
--- a/java/java-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java
@@ -15,8 +15,9 @@
*/
package com.intellij.codeInsight.guess.impl;
-import com.intellij.codeInsight.CodeInsightUtil;
+import com.intellij.codeInsight.JavaPsiEquivalenceUtil;
import com.intellij.codeInspection.dataFlow.DfaMemoryStateImpl;
+import com.intellij.codeInspection.dataFlow.value.DfaInstanceofValue;
import com.intellij.codeInspection.dataFlow.value.DfaValue;
import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
import com.intellij.openapi.diagnostic.Logger;
@@ -41,7 +42,7 @@
@Override
public boolean equals(PsiExpression o1, PsiExpression o2) {
- if (CodeInsightUtil.areExpressionsEquivalent(o1, o2)) {
+ if (JavaPsiEquivalenceUtil.areExpressionsEquivalent(o1, o2)) {
if (computeHashCode(o1) != computeHashCode(o2)) {
LOG.error("different hashCodes: " + o1 + "; " + o2 + "; " + computeHashCode(o1) + "!=" + computeHashCode(o2));
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java
similarity index 98%
rename from java/java-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java
index c6716c3..39d7520 100644
--- a/java/java-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.codeInspection.dataFlow.instructions.TypeCastInstruction;
import com.intellij.codeInspection.dataFlow.instructions.InstanceofInstruction;
import com.intellij.codeInspection.dataFlow.instructions.MethodCallInstruction;
+import com.intellij.codeInspection.dataFlow.value.DfaInstanceofValue;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
@@ -140,7 +141,7 @@
@Nullable
private static Map<PsiExpression, PsiType> buildDataflowTypeMap(PsiExpression forPlace) {
- PsiElement scope = DfaUtil.getTopmostBlockInSameClass(forPlace);
+ PsiElement scope = DfaPsiUtil.getTopmostBlockInSameClass(forPlace);
if (scope == null) {
PsiFile file = forPlace.getContainingFile();
if (!(file instanceof PsiCodeFragment)) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/guess/impl/MethodPattern.java b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/MethodPattern.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInsight/guess/impl/MethodPattern.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/MethodPattern.java
diff --git a/java/java-impl/src/com/intellij/codeInsight/guess/impl/MethodPatternMap.java b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/MethodPatternMap.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInsight/guess/impl/MethodPatternMap.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/MethodPatternMap.java
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java
similarity index 100%
rename from java/java-psi-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNotNullAnnotationFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNotNullAnnotationFix.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNotNullAnnotationFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNotNullAnnotationFix.java
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableAnnotationFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableAnnotationFix.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableAnnotationFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableAnnotationFix.java
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java
similarity index 88%
rename from java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java
index 8ab713b..6684613 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java
@@ -23,14 +23,14 @@
package com.intellij.codeInsight.intention.impl;
import com.intellij.codeInsight.AnnotationUtil;
-import com.intellij.codeInsight.intention.AddAnnotationFix;
+import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
-public class AddNullableNotNullAnnotationFix extends AddAnnotationFix {
+public class AddNullableNotNullAnnotationFix extends AddAnnotationPsiFix {
public AddNullableNotNullAnnotationFix(@NotNull String fqn, @NotNull PsiModifierListOwner owner, @NotNull String... annotationToRemove) {
- super(fqn, owner, annotationToRemove);
+ super(fqn, owner, PsiNameValuePair.EMPTY_ARRAY, annotationToRemove);
}
@Override
@@ -38,7 +38,7 @@
@NotNull PsiFile file,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
- if (!super.isAvailable(project, file, startElement, endElement)) {
+ if (!super.isAvailable(project, file, startElement, endElement)) {
return false;
}
PsiModifierListOwner owner = getContainer(startElement);
diff --git a/java/java-impl/src/com/intellij/codeInspection/AddAssertStatementFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AddAssertStatementFix.java
similarity index 96%
rename from java/java-impl/src/com/intellij/codeInspection/AddAssertStatementFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/AddAssertStatementFix.java
index d57631f..4bdf058 100644
--- a/java/java-impl/src/com/intellij/codeInspection/AddAssertStatementFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AddAssertStatementFix.java
@@ -54,7 +54,7 @@
PsiElement anchorElement = PsiTreeUtil.getParentOfType(element, PsiStatement.class);
LOG.assertTrue(anchorElement != null);
PsiElement prev = PsiTreeUtil.skipSiblingsBackward(anchorElement, PsiWhiteSpace.class);
- if (prev instanceof PsiComment && SuppressManager.getInstance().getSuppressedInspectionIdsIn(prev) != null) {
+ if (prev instanceof PsiComment && JavaSuppressionUtil.getSuppressedInspectionIdsIn(prev) != null) {
anchorElement = prev;
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java
similarity index 73%
rename from java/java-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java
index 45e8c7b..6d4ac0c 100644
--- a/java/java-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java
@@ -17,20 +17,18 @@
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.FileModificationService;
-import com.intellij.codeInsight.intention.AddAnnotationFix;
+import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
import com.intellij.openapi.command.undo.UndoUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiModifier;
+import com.intellij.psi.PsiNameValuePair;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.psi.util.ClassUtil;
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
@@ -45,7 +43,7 @@
protected final String myAnnotation;
private final String[] myAnnotationsToRemove;
- public AnnotateMethodFix(final String fqn, String... annotationsToRemove) {
+ public AnnotateMethodFix(@NotNull String fqn, @NotNull String... annotationsToRemove) {
myAnnotation = fqn;
myAnnotationsToRemove = annotationsToRemove;
}
@@ -68,7 +66,7 @@
for (MethodSignatureBackedByPsiMethod superMethodSignature : superMethodSignatures) {
PsiMethod superMethod = superMethodSignature.getMethod();
if (!AnnotationUtil.isAnnotated(superMethod, myAnnotation, false, false) && superMethod.getManager().isInProject(superMethod)) {
- int ret = annotateBaseMethod(method, superMethod, project);
+ int ret = shouldAnnotateBaseMethod(method, superMethod, project);
if (ret != 0 && ret != 1) return;
if (ret == 0) {
toAnnotate.add(superMethod);
@@ -91,15 +89,9 @@
UndoUtil.markPsiFileForUndo(method.getContainingFile());
}
- public int annotateBaseMethod(final PsiMethod method, final PsiMethod superMethod, final Project project) {
- String implement = !method.hasModifierProperty(PsiModifier.ABSTRACT) && superMethod.hasModifierProperty(PsiModifier.ABSTRACT)
- ? InspectionsBundle.message("inspection.annotate.quickfix.implements")
- : InspectionsBundle.message("inspection.annotate.quickfix.overrides");
- String message = InspectionsBundle.message("inspection.annotate.quickfix.overridden.method.messages",
- UsageViewUtil.getDescriptiveName(method), implement,
- UsageViewUtil.getDescriptiveName(superMethod));
- String title = InspectionsBundle.message("inspection.annotate.quickfix.overridden.method.warning");
- return Messages.showYesNoCancelDialog(project, message, title, Messages.getQuestionIcon());
+ // 0-annotate, 1-do not annotate, 2- cancel
+ public int shouldAnnotateBaseMethod(final PsiMethod method, final PsiMethod superMethod, final Project project) {
+ return 0;
}
protected boolean annotateOverriddenMethods() {
@@ -114,7 +106,8 @@
private void annotateMethod(@NotNull PsiMethod method) {
try {
- new AddAnnotationFix(myAnnotation, method, myAnnotationsToRemove).invoke(method.getProject(), null, method.getContainingFile());
+ AddAnnotationPsiFix fix = new AddAnnotationPsiFix(myAnnotation, method, PsiNameValuePair.EMPTY_ARRAY, myAnnotationsToRemove);
+ fix.invoke(method.getProject(), method.getContainingFile(), method, method);
}
catch (IncorrectOperationException e) {
LOG.error(e);
diff --git a/java/java-impl/src/com/intellij/codeInspection/DeleteThrowsFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/DeleteThrowsFix.java
similarity index 78%
rename from java/java-impl/src/com/intellij/codeInspection/DeleteThrowsFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/DeleteThrowsFix.java
index a8203d7..1a3ce0b 100644
--- a/java/java-impl/src/com/intellij/codeInspection/DeleteThrowsFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/DeleteThrowsFix.java
@@ -19,9 +19,10 @@
import com.intellij.codeInsight.daemon.impl.quickfix.MethodThrowsFix;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClassType;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiElement;
+import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
/**
@@ -30,7 +31,7 @@
public class DeleteThrowsFix implements LocalQuickFix {
private final MethodThrowsFix myQuickFix;
- public DeleteThrowsFix(PsiMethod method, PsiClassType exceptionClass) {
+ public DeleteThrowsFix(@NotNull PsiMethod method, PsiClassType exceptionClass) {
myQuickFix = new MethodThrowsFix(method, exceptionClass, false, false);
}
@@ -49,10 +50,11 @@
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement element = descriptor.getPsiElement();
- if (element == null) return;
- final PsiFile psiFile = element.getContainingFile();
- if (myQuickFix.isAvailable(project, null, psiFile)) {
- myQuickFix.invoke(project, null, psiFile);
+ PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
+ if (method == null) return;
+ final PsiFile psiFile = method.getContainingFile();
+ if (myQuickFix.isAvailable(project, psiFile, method, method)) {
+ myQuickFix.invoke(project, psiFile, method, method);
}
}
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java
similarity index 98%
rename from java/java-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java
index 5f5b0e2..e4c583d 100644
--- a/java/java-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java
@@ -28,7 +28,7 @@
* User: anna
* Date: 1/28/11
*/
-public class ExplicitTypeCanBeDiamondInspection extends BaseJavaLocalInspectionTool {
+public class ExplicitTypeCanBeDiamondInspection extends BaseJavaBatchLocalInspectionTool {
public static final Logger LOG = Logger.getInstance("#" + ExplicitTypeCanBeDiamondInspection.class.getName());
@Nls
diff --git a/java/java-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java
similarity index 91%
rename from java/java-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java
index 565ebbd..b49f7e3 100644
--- a/java/java-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java
@@ -17,8 +17,8 @@
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInsight.daemon.impl.analysis.GenericsHighlightUtil;
-import com.intellij.codeInsight.intention.AddAnnotationFix;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
+import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.pom.java.LanguageLevel;
@@ -33,7 +33,7 @@
* User: anna
* Date: 1/28/11
*/
-public class PossibleHeapPollutionVarargsInspection extends BaseJavaLocalInspectionTool {
+public class PossibleHeapPollutionVarargsInspection extends BaseJavaBatchLocalInspectionTool {
public static final Logger LOG = Logger.getInstance("#" + PossibleHeapPollutionVarargsInspection.class.getName());
@Nls
@NotNull
@@ -110,7 +110,7 @@
if (psiElement instanceof PsiIdentifier) {
final PsiMethod psiMethod = (PsiMethod)psiElement.getParent();
if (psiMethod != null) {
- new AddAnnotationFix("java.lang.SafeVarargs", psiMethod).applyFix(project, descriptor);
+ new AddAnnotationPsiFix("java.lang.SafeVarargs", psiMethod, PsiNameValuePair.EMPTY_ARRAY).applyFix(project, descriptor);
}
}
}
@@ -135,13 +135,12 @@
if (psiElement instanceof PsiIdentifier) {
final PsiMethod psiMethod = (PsiMethod)psiElement.getParent();
psiMethod.getModifierList().setModifierProperty(PsiModifier.FINAL, true);
- new AddAnnotationFix("java.lang.SafeVarargs", psiMethod).applyFix(project, descriptor);
+ new AddAnnotationPsiFix("java.lang.SafeVarargs", psiMethod, PsiNameValuePair.EMPTY_ARRAY).applyFix(project, descriptor);
}
}
}
- public static abstract class HeapPollutionVisitor extends JavaElementVisitor {
-
+ public abstract static class HeapPollutionVisitor extends JavaElementVisitor {
@Override
public void visitMethod(PsiMethod method) {
super.visitMethod(method);
@@ -151,7 +150,7 @@
final PsiParameter psiParameter = method.getParameterList().getParameters()[method.getParameterList().getParametersCount() - 1];
final PsiType componentType = ((PsiEllipsisType)psiParameter.getType()).getComponentType();
- if (GenericsHighlightUtil.isReifiableType(componentType)) {
+ if (JavaGenericsUtil.isReifiableType(componentType)) {
return;
}
for (PsiReference reference : ReferencesSearch.search(psiParameter)) {
diff --git a/java/java-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java
similarity index 97%
rename from java/java-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java
index 04d6533..fdb547c 100644
--- a/java/java-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java
@@ -19,10 +19,8 @@
import com.intellij.codeInsight.intention.HighPriorityAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.util.Function;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -30,7 +28,7 @@
/**
* User: anna
*/
-public class RedundantLambdaCodeBlockInspection extends BaseJavaLocalInspectionTool {
+public class RedundantLambdaCodeBlockInspection extends BaseJavaBatchLocalInspectionTool {
public static final Logger LOG = Logger.getInstance("#" + RedundantLambdaCodeBlockInspection.class.getName());
@Nls
diff --git a/java/java-impl/src/com/intellij/codeInspection/RemoveAnnotationQuickFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/RemoveAnnotationQuickFix.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/RemoveAnnotationQuickFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/RemoveAnnotationQuickFix.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java
similarity index 79%
rename from java/java-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java
index d492b7b..212662f 100644
--- a/java/java-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java
@@ -16,14 +16,12 @@
package com.intellij.codeInspection;
import com.intellij.codeInsight.FileModificationService;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.ScrollType;
+import com.intellij.ide.SelectInEditorManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.TextRange;
+import com.intellij.pom.Navigatable;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.util.PsiTypesUtil;
-import com.intellij.psi.util.PsiUtilBase;
import org.jetbrains.annotations.NotNull;
/**
@@ -66,24 +64,15 @@
final PsiFile file = expression.getContainingFile();
if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;
- final PsiConditionalExpression conditionalExpression = replaceWthConditionalExpression(project, myText + "!=null", expression, suggestDefaultValue(expression));
+ PsiConditionalExpression conditionalExpression = replaceWthConditionalExpression(project, myText + "!=null", expression, suggestDefaultValue(expression));
- final PsiExpression elseExpression = conditionalExpression.getElseExpression();
+ PsiExpression elseExpression = conditionalExpression.getElseExpression();
if (elseExpression != null) {
- selectInEditor(elseExpression);
+ ((Navigatable)elseExpression).navigate(true);
+ SelectInEditorManager.getInstance(project).selectInEditor(file.getVirtualFile(), elseExpression.getTextRange().getStartOffset(), elseExpression.getTextRange().getEndOffset(), false, true);
}
}
- private static void selectInEditor(@NotNull PsiElement element) {
- final Editor editor = PsiUtilBase.findEditor(element);
- if (editor == null) return;
-
- final TextRange expressionRange = element.getTextRange();
- editor.getCaretModel().moveToOffset(expressionRange.getStartOffset());
- editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
- editor.getSelectionModel().setSelection(expressionRange.getStartOffset(), expressionRange.getEndOffset());
- }
-
@NotNull
private static PsiConditionalExpression replaceWthConditionalExpression(@NotNull Project project,
@NotNull String condition,
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/accessStaticViaInstance/AccessStaticViaInstanceBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/accessStaticViaInstance/AccessStaticViaInstanceBase.java
new file mode 100644
index 0000000..6c75f8b
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/accessStaticViaInstance/AccessStaticViaInstanceBase.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2000-2013 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.accessStaticViaInstance;
+
+import com.intellij.codeInsight.daemon.JavaErrorMessages;
+import com.intellij.codeInsight.daemon.impl.analysis.HighlightMessageUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
+import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableUtil;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
+import com.intellij.codeInspection.InspectionsBundle;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.ProblemsHolder;
+import com.intellij.psi.*;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+
+public class AccessStaticViaInstanceBase extends BaseJavaBatchLocalInspectionTool {
+ @NonNls public static final String ACCESS_STATIC_VIA_INSTANCE = "AccessStaticViaInstance";
+
+ @Override
+ @NotNull
+ public String getGroupDisplayName() {
+ return "";
+ }
+
+ @Override
+ @NotNull
+ public String getDisplayName() {
+ return InspectionsBundle.message("access.static.via.instance");
+ }
+
+ @Override
+ @NotNull
+ @NonNls
+ public String getShortName() {
+ return ACCESS_STATIC_VIA_INSTANCE;
+ }
+
+ @Override
+ public String getAlternativeID() {
+ return "static-access";
+ }
+
+ @Override
+ public boolean isEnabledByDefault() {
+ return true;
+ }
+
+ @Override
+ @NotNull
+ public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
+ return new JavaElementVisitor() {
+ @Override public void visitReferenceExpression(PsiReferenceExpression expression) {
+ checkAccessStaticMemberViaInstanceReference(expression, holder, isOnTheFly);
+ }
+ };
+ }
+
+ private void checkAccessStaticMemberViaInstanceReference(PsiReferenceExpression expr, ProblemsHolder holder, boolean onTheFly) {
+ JavaResolveResult result = expr.advancedResolve(false);
+ PsiElement resolved = result.getElement();
+
+ if (!(resolved instanceof PsiMember)) return;
+ PsiExpression qualifierExpression = expr.getQualifierExpression();
+ if (qualifierExpression == null) return;
+
+ if (qualifierExpression instanceof PsiReferenceExpression) {
+ final PsiElement qualifierResolved = ((PsiReferenceExpression)qualifierExpression).resolve();
+ if (qualifierResolved instanceof PsiClass || qualifierResolved instanceof PsiPackage) {
+ return;
+ }
+ }
+ if (!((PsiMember)resolved).hasModifierProperty(PsiModifier.STATIC)) return;
+
+ String description = JavaErrorMessages.message("static.member.accessed.via.instance.reference",
+ JavaHighlightUtil.formatType(qualifierExpression.getType()),
+ HighlightMessageUtil.getSymbolName(resolved, result.getSubstitutor()));
+ if (!onTheFly) {
+ if (RemoveUnusedVariableUtil.checkSideEffects(qualifierExpression, null, new ArrayList<PsiElement>())) {
+ holder.registerProblem(expr, description);
+ return;
+ }
+ }
+ holder.registerProblem(expr, description, createAccessStaticViaInstanceFix(expr, onTheFly, result));
+ }
+
+ protected LocalQuickFix createAccessStaticViaInstanceFix(PsiReferenceExpression expr,
+ boolean onTheFly,
+ JavaResolveResult result) {
+ return null;
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalHandler.java b/java/java-analysis-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalHandler.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalHandler.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalHandler.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/FieldAccessNotGuardedInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/FieldAccessNotGuardedInspection.java
similarity index 97%
rename from java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/FieldAccessNotGuardedInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/FieldAccessNotGuardedInspection.java
index 458cc0f..2586344 100644
--- a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/FieldAccessNotGuardedInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/FieldAccessNotGuardedInspection.java
@@ -16,7 +16,7 @@
package com.intellij.codeInspection.concurrencyAnnotations;
import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
@@ -24,7 +24,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public class FieldAccessNotGuardedInspection extends BaseJavaLocalInspectionTool {
+public class FieldAccessNotGuardedInspection extends BaseJavaBatchLocalInspectionTool {
@Override
@NotNull
diff --git a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/InstanceGuardedByStaticInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/InstanceGuardedByStaticInspection.java
similarity index 95%
rename from java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/InstanceGuardedByStaticInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/InstanceGuardedByStaticInspection.java
index 9c66ee5..2c87a58 100644
--- a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/InstanceGuardedByStaticInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/InstanceGuardedByStaticInspection.java
@@ -16,7 +16,7 @@
package com.intellij.codeInspection.concurrencyAnnotations;
import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocTag;
@@ -24,7 +24,7 @@
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
-public class InstanceGuardedByStaticInspection extends BaseJavaLocalInspectionTool {
+public class InstanceGuardedByStaticInspection extends BaseJavaBatchLocalInspectionTool {
@Override
@NotNull
diff --git a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalFieldInImmutableInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalFieldInImmutableInspection.java
similarity index 95%
rename from java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalFieldInImmutableInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalFieldInImmutableInspection.java
index 4f3bb97..d3bcce5 100644
--- a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalFieldInImmutableInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalFieldInImmutableInspection.java
@@ -16,13 +16,13 @@
package com.intellij.codeInspection.concurrencyAnnotations;
import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.*;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
-public class NonFinalFieldInImmutableInspection extends BaseJavaLocalInspectionTool {
+public class NonFinalFieldInImmutableInspection extends BaseJavaBatchLocalInspectionTool {
@Override
@NotNull
diff --git a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalGuardInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalGuardInspection.java
similarity index 95%
rename from java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalGuardInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalGuardInspection.java
index 33ac244..ef4d0d5 100644
--- a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalGuardInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalGuardInspection.java
@@ -16,7 +16,7 @@
package com.intellij.codeInspection.concurrencyAnnotations;
import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocTag;
@@ -24,7 +24,7 @@
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
-public class NonFinalGuardInspection extends BaseJavaLocalInspectionTool {
+public class NonFinalGuardInspection extends BaseJavaBatchLocalInspectionTool {
@Override
@NotNull
diff --git a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/StaticGuardedByInstanceInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/StaticGuardedByInstanceInspection.java
similarity index 95%
rename from java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/StaticGuardedByInstanceInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/StaticGuardedByInstanceInspection.java
index 9a8ed2b..d267fcd 100644
--- a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/StaticGuardedByInstanceInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/StaticGuardedByInstanceInspection.java
@@ -16,7 +16,7 @@
package com.intellij.codeInspection.concurrencyAnnotations;
import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocTag;
@@ -24,7 +24,7 @@
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
-public class StaticGuardedByInstanceInspection extends BaseJavaLocalInspectionTool {
+public class StaticGuardedByInstanceInspection extends BaseJavaBatchLocalInspectionTool {
@Override
@NotNull
diff --git a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/UnknownGuardInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/UnknownGuardInspection.java
similarity index 97%
rename from java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/UnknownGuardInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/UnknownGuardInspection.java
index b64bdb0..431bb40 100644
--- a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/UnknownGuardInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/UnknownGuardInspection.java
@@ -16,7 +16,7 @@
package com.intellij.codeInspection.concurrencyAnnotations;
import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
@@ -30,7 +30,7 @@
/**
* check locks according to http://www.javaconcurrencyinpractice.com/annotations/doc/net/jcip/annotations/GuardedBy.html
*/
-public class UnknownGuardInspection extends BaseJavaLocalInspectionTool {
+public class UnknownGuardInspection extends BaseJavaBatchLocalInspectionTool {
@Override
@NotNull
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/AnnotationsAwareDataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/AnnotationsAwareDataFlowRunner.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/AnnotationsAwareDataFlowRunner.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/AnnotationsAwareDataFlowRunner.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java
similarity index 93%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java
index 537d656..8f901b6 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java
@@ -19,7 +19,7 @@
* User: max
* Date: Jan 11, 2002
* Time: 3:05:34 PM
- * To change template for new class use
+ * To change template for new class use
* Code Style | Class Templates options (Tools | IDE Options).
*/
package com.intellij.codeInspection.dataFlow;
@@ -33,9 +33,10 @@
import gnu.trove.TObjectIntHashMap;
import java.util.ArrayList;
+import java.util.List;
public class ControlFlow {
- private final ArrayList<Instruction> myInstructions = new ArrayList<Instruction>();
+ private final List<Instruction> myInstructions = new ArrayList<Instruction>();
private final TObjectIntHashMap<PsiElement> myElementToStartOffsetMap = new TObjectIntHashMap<PsiElement>();
private final TObjectIntHashMap<PsiElement> myElementToEndOffsetMap = new TObjectIntHashMap<PsiElement>();
private DfaVariableValue[] myFields;
@@ -92,7 +93,7 @@
public String toString() {
StringBuilder result = new StringBuilder();
- final ArrayList<Instruction> instructions = myInstructions;
+ final List<Instruction> instructions = myInstructions;
for (int i = 0; i < instructions.size(); i++) {
Instruction instruction = instructions.get(i);
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
similarity index 98%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
index 664ffe4..369f6ec 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
@@ -25,11 +25,7 @@
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.util.InheritanceUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.TypeConversionUtil;
-import com.intellij.refactoring.psi.PropertyUtils;
+import com.intellij.psi.util.*;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NonNls;
@@ -182,6 +178,11 @@
generateDefaultBinOp(lExpr, rExpr, type);
}
}
+ else if (op == JavaTokenType.PLUSEQ && type != null && type.equalsToText(JAVA_LANG_STRING)) {
+ lExpr.accept(this);
+ rExpr.accept(this);
+ addInstruction(new BinopInstruction(JavaTokenType.PLUS, null, lExpr.getProject()));
+ }
else {
generateDefaultBinOp(lExpr, rExpr, type);
}
@@ -1050,10 +1051,10 @@
PsiType exprType = expression.getType();
if (TypeConversionUtil.isPrimitiveAndNotNull(expectedType) && TypeConversionUtil.isPrimitiveWrapper(exprType)) {
- addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.UNBOXING));
+ addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.UNBOXING, expectedType));
}
else if (TypeConversionUtil.isPrimitiveWrapper(expectedType) && TypeConversionUtil.isPrimitiveAndNotNull(exprType)) {
- addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.BOXING));
+ addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.BOXING, expectedType));
}
else if (exprType != expectedType &&
TypeConversionUtil.isPrimitiveAndNotNull(exprType) &&
@@ -1253,11 +1254,7 @@
}
}
- MethodCallInstruction callInstruction = new MethodCallInstruction(expression, createChainedVariableValue(expression));
- if (!DfaValueFactory.isEffectivelyUnqualified(methodExpression)) {
- callInstruction.setShouldFlushFields(false);
- }
- addInstruction(callInstruction);
+ addInstruction(new MethodCallInstruction(expression, createChainedVariableValue(expression)));
if (!myCatchStack.isEmpty()) {
addMethodThrows(expression.resolveMethod());
@@ -1347,7 +1344,7 @@
} else if (type == ConditionChecker.Type.IS_NULL_METHOD || type == ConditionChecker.Type.IS_NOT_NULL_METHOD) {
addInstruction(new PushInstruction(myFactory.getConstFactory().getNull(), null));
addInstruction(new BinopInstruction(type == ConditionChecker.Type.IS_NULL_METHOD ? JavaTokenType.EQEQ : JavaTokenType.NE, null, expression.getProject()));
-
+
ConditionalGotoInstruction ifFails = new ConditionalGotoInstruction(-1, true, null);
GotoInstruction gotoEnd = new GotoInstruction(exitPoint);
@@ -1576,7 +1573,7 @@
}
if (dfaValue == null) {
PsiType type = expression.getType();
- return myFactory.createTypeValueWithNullability(type, DfaUtil.getElementNullability(type, field));
+ return myFactory.createTypeValueWithNullability(type, DfaPsiUtil.getElementNullability(type, field));
}
return dfaValue;
}
@@ -1613,7 +1610,7 @@
return result;
}
- if (DfaUtil.isFinalField(var) || DfaUtil.isPlainMutableField(var)) {
+ if (DfaPsiUtil.isFinalField(var) || DfaPsiUtil.isPlainMutableField(var)) {
DfaVariableValue qualifierValue = createChainedVariableValue(qualifier);
if (qualifierValue != null) {
return myFactory.getVarFactory().createVariableValue(var, refExpr.getType(), false, qualifierValue, isCall || qualifierValue.isViaMethods());
@@ -1630,8 +1627,8 @@
}
if (target instanceof PsiMethod) {
PsiMethod method = (PsiMethod)target;
- if (PropertyUtils.isSimpleGetter(method)) {
- return PropertyUtils.getSimplyReturnedField(method, PropertyUtils.getSingleReturnValue(method));
+ if (PropertyUtil.isSimpleGetter(method)) {
+ return PropertyUtil.getSimplyReturnedField(method, PropertyUtil.getSingleReturnValue(method));
}
}
return null;
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java
new file mode 100644
index 0000000..391fa1b
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java
@@ -0,0 +1,590 @@
+/*
+ * Copyright 2000-2012 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.
+ */
+
+/*
+ * Created by IntelliJ IDEA.
+ * User: max
+ * Date: Dec 24, 2001
+ * Time: 2:46:32 PM
+ * To change template for new class use
+ * Code Style | Class Templates options (Tools | IDE Options).
+ */
+package com.intellij.codeInspection.dataFlow;
+
+import com.intellij.codeInsight.AnnotationUtil;
+import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInsight.NullableNotNullManager;
+import com.intellij.codeInsight.daemon.GroupNames;
+import com.intellij.codeInsight.daemon.impl.quickfix.SimplifyBooleanExpressionFix;
+import com.intellij.codeInsight.intention.impl.AddNullableAnnotationFix;
+import com.intellij.codeInspection.*;
+import com.intellij.codeInspection.dataFlow.instructions.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Pair;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.SmartList;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.*;
+
+public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.DataFlowInspection");
+ @NonNls private static final String SHORT_NAME = "ConstantConditions";
+ public boolean SUGGEST_NULLABLE_ANNOTATIONS = false;
+ public boolean DONT_REPORT_TRUE_ASSERT_STATEMENTS = false;
+
+ @Override
+ public JComponent createOptionsPanel() {
+ throw new RuntimeException("no UI in headless mode");
+ }
+
+ @Override
+ @NotNull
+ public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
+ return new JavaElementVisitor() {
+ @Override
+ public void visitField(PsiField field) {
+ analyzeCodeBlock(field, holder);
+ }
+
+ @Override
+ public void visitMethod(PsiMethod method) {
+ analyzeCodeBlock(method.getBody(), holder);
+ }
+
+ @Override
+ public void visitClassInitializer(PsiClassInitializer initializer) {
+ analyzeCodeBlock(initializer.getBody(), holder);
+ }
+ };
+ }
+
+ private void analyzeCodeBlock(@Nullable final PsiElement scope, ProblemsHolder holder) {
+ if (scope == null) return;
+ final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner(SUGGEST_NULLABLE_ANNOTATIONS);
+ final StandardInstructionVisitor visitor = new DataFlowInstructionVisitor(dfaRunner);
+ final RunnerResult rc = dfaRunner.analyzeMethod(scope, visitor);
+ if (rc == RunnerResult.OK) {
+ if (dfaRunner.problemsDetected(visitor)) {
+ createDescription(dfaRunner, holder, visitor);
+ }
+ }
+ else if (rc == RunnerResult.TOO_COMPLEX) {
+ if (scope.getParent() instanceof PsiMethod) {
+ PsiMethod method = (PsiMethod)scope.getParent();
+ final PsiIdentifier name = method.getNameIdentifier();
+ if (name != null) { // Might be null for synthetic methods like JSP page.
+ holder.registerProblem(name, InspectionsBundle.message("dataflow.too.complex"), ProblemHighlightType.WEAK_WARNING);
+ }
+ }
+ }
+ }
+
+ @Nullable
+ private LocalQuickFix[] createNPEFixes(PsiExpression qualifier, PsiExpression expression) {
+ if (qualifier == null || expression == null) return null;
+ if (qualifier instanceof PsiMethodCallExpression) return null;
+ if (qualifier instanceof PsiLiteralExpression && ((PsiLiteralExpression)qualifier).getValue() == null) return null;
+
+ try {
+ final List<LocalQuickFix> fixes = new SmartList<LocalQuickFix>();
+
+ if (PsiUtil.getLanguageLevel(qualifier).isAtLeast(LanguageLevel.JDK_1_4)) {
+ final Project project = qualifier.getProject();
+ final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
+ final PsiBinaryExpression binary = (PsiBinaryExpression)elementFactory.createExpressionFromText("a != null", null);
+ binary.getLOperand().replace(qualifier);
+ fixes.add(new AddAssertStatementFix(binary));
+ }
+
+ addSurroundWithIfFix(qualifier, fixes);
+
+ if (ReplaceWithTernaryOperatorFix.isAvailable(qualifier, expression)) {
+ fixes.add(new ReplaceWithTernaryOperatorFix(qualifier));
+ }
+ return fixes.toArray(new LocalQuickFix[fixes.size()]);
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ return null;
+ }
+ }
+
+ protected void addSurroundWithIfFix(PsiExpression qualifier, List<LocalQuickFix> fixes) {
+ }
+
+ private void createDescription(StandardDataFlowRunner runner, ProblemsHolder holder, StandardInstructionVisitor visitor) {
+ Pair<Set<Instruction>, Set<Instruction>> constConditions = runner.getConstConditionalExpressions();
+ Set<Instruction> trueSet = constConditions.getFirst();
+ Set<Instruction> falseSet = constConditions.getSecond();
+
+ ArrayList<Instruction> allProblems = new ArrayList<Instruction>();
+ allProblems.addAll(trueSet);
+ allProblems.addAll(falseSet);
+ allProblems.addAll(runner.getNPEInstructions());
+ allProblems.addAll(runner.getCCEInstructions());
+ allProblems.addAll(StandardDataFlowRunner.getRedundantInstanceofs(runner, visitor));
+
+ Collections.sort(allProblems, new Comparator<Instruction>() {
+ @Override
+ public int compare(Instruction i1, Instruction i2) {
+ return i1.getIndex() - i2.getIndex();
+ }
+ });
+
+ HashSet<PsiElement> reportedAnchors = new HashSet<PsiElement>();
+
+ for (Instruction instruction : allProblems) {
+ if (instruction instanceof MethodCallInstruction) {
+ reportCallMayProduceNpe(holder, (MethodCallInstruction)instruction);
+ }
+ else if (instruction instanceof FieldReferenceInstruction) {
+ reportFieldAccessMayProduceNpe(holder, (FieldReferenceInstruction)instruction);
+ }
+ else if (instruction instanceof TypeCastInstruction) {
+ reportCastMayFail(holder, (TypeCastInstruction)instruction);
+ }
+ else if (instruction instanceof BranchingInstruction) {
+ handleBranchingInstruction(holder, visitor, trueSet, falseSet, reportedAnchors, (BranchingInstruction)instruction);
+ }
+ }
+
+ reportNullableArguments(runner, holder);
+ reportNullableAssignments(runner, holder);
+ reportUnboxedNullables(runner, holder);
+ reportNullableReturns(runner, holder);
+ reportNullableArgumentsPassedToNonAnnotated(runner, holder);
+ }
+
+ private void reportNullableArgumentsPassedToNonAnnotated(StandardDataFlowRunner runner, ProblemsHolder holder) {
+ Set<PsiExpression> exprs = runner.getNullableArgumentsPassedToNonAnnotatedParam();
+ for (PsiExpression expr : exprs) {
+ final String text = isNullLiteralExpression(expr)
+ ? "Passing <code>null</code> argument to non annotated parameter"
+ : "Argument <code>#ref</code> #loc might be null but passed to non annotated parameter";
+ LocalQuickFix[] fixes = createNPEFixes(expr, expr);
+ final PsiElement parent = expr.getParent();
+ if (parent instanceof PsiExpressionList) {
+ final int idx = ArrayUtil.find(((PsiExpressionList)parent).getExpressions(), expr);
+ if (idx > -1) {
+ final PsiElement gParent = parent.getParent();
+ if (gParent instanceof PsiCallExpression) {
+ final PsiMethod psiMethod = ((PsiCallExpression)gParent).resolveMethod();
+ if (psiMethod != null && psiMethod.getManager().isInProject(psiMethod) && AnnotationUtil.isAnnotatingApplicable(psiMethod)) {
+ final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
+ if (idx < parameters.length) {
+ final AddNullableAnnotationFix addNullableAnnotationFix = new AddNullableAnnotationFix(parameters[idx]);
+ fixes = fixes == null ? new LocalQuickFix[]{addNullableAnnotationFix} : ArrayUtil.append(fixes, addNullableAnnotationFix);
+ holder.registerProblem(expr, text, fixes);
+ }
+ }
+ }
+ }
+ }
+
+ }
+ }
+
+ private void reportCallMayProduceNpe(ProblemsHolder holder, MethodCallInstruction mcInstruction) {
+ if (mcInstruction.getCallExpression() instanceof PsiMethodCallExpression) {
+ PsiMethodCallExpression callExpression = (PsiMethodCallExpression)mcInstruction.getCallExpression();
+ LocalQuickFix[] fix = createNPEFixes(callExpression.getMethodExpression().getQualifierExpression(), callExpression);
+
+ holder.registerProblem(callExpression,
+ InspectionsBundle.message("dataflow.message.npe.method.invocation"),
+ fix);
+ }
+ }
+
+ private void reportFieldAccessMayProduceNpe(ProblemsHolder holder, FieldReferenceInstruction frInstruction) {
+ PsiElement elementToAssert = frInstruction.getElementToAssert();
+ PsiExpression expression = frInstruction.getExpression();
+ if (expression instanceof PsiArrayAccessExpression) {
+ LocalQuickFix[] fix = createNPEFixes((PsiExpression)elementToAssert, expression);
+ holder.registerProblem(expression,
+ InspectionsBundle.message("dataflow.message.npe.array.access"),
+ fix);
+ }
+ else {
+ LocalQuickFix[] fix = createNPEFixes((PsiExpression)elementToAssert, expression);
+ holder.registerProblem(elementToAssert,
+ InspectionsBundle.message("dataflow.message.npe.field.access"),
+ fix);
+ }
+ }
+
+ private static void reportCastMayFail(ProblemsHolder holder, TypeCastInstruction instruction) {
+ PsiTypeCastExpression typeCast = instruction.getCastExpression();
+ holder.registerProblem(typeCast.getCastType(),
+ InspectionsBundle.message("dataflow.message.cce", typeCast.getOperand().getText()));
+ }
+
+ private void handleBranchingInstruction(ProblemsHolder holder,
+ StandardInstructionVisitor visitor,
+ Set<Instruction> trueSet,
+ Set<Instruction> falseSet, HashSet<PsiElement> reportedAnchors, BranchingInstruction instruction) {
+ PsiElement psiAnchor = instruction.getPsiAnchor();
+ boolean underBinary = isAtRHSOfBooleanAnd(psiAnchor);
+ if (instruction instanceof InstanceofInstruction && visitor.isInstanceofRedundant((InstanceofInstruction)instruction)) {
+ if (visitor.canBeNull((BinopInstruction)instruction)) {
+ holder.registerProblem(psiAnchor,
+ InspectionsBundle.message("dataflow.message.redundant.instanceof"),
+ new RedundantInstanceofFix());
+ }
+ else {
+ final LocalQuickFix localQuickFix = createSimplifyBooleanExpressionFix(psiAnchor, true);
+ holder.registerProblem(psiAnchor,
+ InspectionsBundle.message(underBinary ? "dataflow.message.constant.condition.when.reached" : "dataflow.message.constant.condition", Boolean.toString(true)),
+ localQuickFix == null ? null : new LocalQuickFix[]{localQuickFix});
+ }
+ }
+ else if (psiAnchor instanceof PsiSwitchLabelStatement) {
+ if (falseSet.contains(instruction)) {
+ holder.registerProblem(psiAnchor,
+ InspectionsBundle.message("dataflow.message.unreachable.switch.label"));
+ }
+ }
+ else if (psiAnchor != null && !reportedAnchors.contains(psiAnchor) && !isCompileConstantInIfCondition(psiAnchor)) {
+ boolean evaluatesToTrue = trueSet.contains(instruction);
+ if (onTheLeftSideOfConditionalAssignemnt(psiAnchor)) {
+ holder.registerProblem(
+ psiAnchor,
+ InspectionsBundle.message("dataflow.message.pointless.assignment.expression", Boolean.toString(evaluatesToTrue)),
+ createSimplifyToAssignmentFix()
+ );
+ }
+ else if (!skipReportingConstantCondition(visitor, psiAnchor, evaluatesToTrue)) {
+ final LocalQuickFix fix = createSimplifyBooleanExpressionFix(psiAnchor, evaluatesToTrue);
+ String message = InspectionsBundle.message(underBinary ?
+ "dataflow.message.constant.condition.when.reached" :
+ "dataflow.message.constant.condition", Boolean.toString(evaluatesToTrue));
+ holder.registerProblem(psiAnchor, message, fix == null ? null : new LocalQuickFix[]{fix});
+ }
+ reportedAnchors.add(psiAnchor);
+ }
+ }
+
+ private boolean skipReportingConstantCondition(StandardInstructionVisitor visitor, PsiElement psiAnchor, boolean evaluatesToTrue) {
+ return DONT_REPORT_TRUE_ASSERT_STATEMENTS && isAssertionEffectively(psiAnchor, evaluatesToTrue) ||
+ visitor.silenceConstantCondition(psiAnchor);
+ }
+
+ private void reportNullableArguments(StandardDataFlowRunner runner, ProblemsHolder holder) {
+ Set<PsiExpression> exprs = runner.getNullableArguments();
+ for (PsiExpression expr : exprs) {
+ final String text = isNullLiteralExpression(expr)
+ ? InspectionsBundle.message("dataflow.message.passing.null.argument")
+ : InspectionsBundle.message("dataflow.message.passing.nullable.argument");
+ LocalQuickFix[] fixes = createNPEFixes(expr, expr);
+ holder.registerProblem(expr, text, fixes);
+ }
+ }
+
+ private static void reportNullableAssignments(StandardDataFlowRunner runner, ProblemsHolder holder) {
+ for (PsiExpression expr : runner.getNullableAssignments()) {
+ final String text = isNullLiteralExpression(expr)
+ ? InspectionsBundle.message("dataflow.message.assigning.null")
+ : InspectionsBundle.message("dataflow.message.assigning.nullable");
+ holder.registerProblem(expr, text);
+ }
+ }
+
+ private static void reportUnboxedNullables(StandardDataFlowRunner runner, ProblemsHolder holder) {
+ for (PsiExpression expr : runner.getUnboxedNullables()) {
+ holder.registerProblem(expr, InspectionsBundle.message("dataflow.message.unboxing"));
+ }
+ }
+
+ private static void reportNullableReturns(StandardDataFlowRunner runner, ProblemsHolder holder) {
+ for (PsiReturnStatement statement : runner.getNullableReturns()) {
+ final PsiExpression expr = statement.getReturnValue();
+ if (runner.isInNotNullMethod()) {
+ final String text = isNullLiteralExpression(expr)
+ ? InspectionsBundle.message("dataflow.message.return.null.from.notnull")
+ : InspectionsBundle.message("dataflow.message.return.nullable.from.notnull");
+ holder.registerProblem(expr, text);
+ }
+ else if (AnnotationUtil.isAnnotatingApplicable(statement)) {
+ final String text = isNullLiteralExpression(expr)
+ ? InspectionsBundle.message("dataflow.message.return.null.from.notnullable")
+ : InspectionsBundle.message("dataflow.message.return.nullable.from.notnullable");
+ final NullableNotNullManager manager = NullableNotNullManager.getInstance(expr.getProject());
+ holder.registerProblem(expr, text, new AnnotateMethodFix(manager.getDefaultNullable(), ArrayUtil.toStringArray(manager.getNotNulls())){
+ @Override
+ public int shouldAnnotateBaseMethod(PsiMethod method, PsiMethod superMethod, Project project) {
+ return 1;
+ }
+ });
+ }
+ }
+ }
+
+ private static boolean isAssertionEffectively(PsiElement psiAnchor, boolean evaluatesToTrue) {
+ PsiElement parent = psiAnchor.getParent();
+ if (parent instanceof PsiAssertStatement) {
+ return evaluatesToTrue;
+ }
+ if (parent instanceof PsiIfStatement && psiAnchor == ((PsiIfStatement)parent).getCondition()) {
+ PsiStatement thenBranch = ((PsiIfStatement)parent).getThenBranch();
+ if (thenBranch instanceof PsiThrowStatement) {
+ return !evaluatesToTrue;
+ }
+ if (thenBranch instanceof PsiBlockStatement) {
+ PsiStatement[] statements = ((PsiBlockStatement)thenBranch).getCodeBlock().getStatements();
+ if (statements.length == 1 && statements[0] instanceof PsiThrowStatement) {
+ return !evaluatesToTrue;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static boolean isAtRHSOfBooleanAnd(PsiElement expr) {
+ PsiElement cur = expr;
+
+ while (cur != null && !(cur instanceof PsiMember)) {
+ PsiElement parent = cur.getParent();
+
+ if (parent instanceof PsiBinaryExpression && cur == ((PsiBinaryExpression)parent).getROperand()) {
+ return true;
+ }
+
+ cur = parent;
+ }
+
+ return false;
+ }
+
+ private static boolean isCompileConstantInIfCondition(PsiElement element) {
+ if (!(element instanceof PsiReferenceExpression)) return false;
+ PsiElement resolved = ((PsiReferenceExpression)element).resolve();
+ if (!(resolved instanceof PsiField)) return false;
+ PsiField field = (PsiField)resolved;
+
+ if (!field.hasModifierProperty(PsiModifier.FINAL)) return false;
+ if (!field.hasModifierProperty(PsiModifier.STATIC)) return false;
+
+ PsiElement parent = element.getParent();
+ if (parent instanceof PsiPrefixExpression && ((PsiPrefixExpression)parent).getOperationTokenType() == JavaTokenType.EXCL) {
+ element = parent;
+ parent = parent.getParent();
+ }
+ return parent instanceof PsiIfStatement && ((PsiIfStatement)parent).getCondition() == element;
+ }
+
+ private static boolean isNullLiteralExpression(PsiExpression expr) {
+ if (expr instanceof PsiLiteralExpression) {
+ final PsiLiteralExpression literalExpression = (PsiLiteralExpression)expr;
+ return PsiType.NULL.equals(literalExpression.getType());
+ }
+ return false;
+ }
+
+ private static boolean onTheLeftSideOfConditionalAssignemnt(final PsiElement psiAnchor) {
+ final PsiElement parent = psiAnchor.getParent();
+ if (parent instanceof PsiAssignmentExpression) {
+ final PsiAssignmentExpression expression = (PsiAssignmentExpression)parent;
+ if (expression.getLExpression() == psiAnchor) return true;
+ }
+ return false;
+ }
+
+ @Nullable
+ private static LocalQuickFix createSimplifyBooleanExpressionFix(PsiElement element, final boolean value) {
+ SimplifyBooleanExpressionFix fix = createIntention(element, value);
+ if (fix == null) return null;
+ final String text = fix.getText();
+ return new LocalQuickFix() {
+ @Override
+ @NotNull
+ public String getName() {
+ return text;
+ }
+
+ @Override
+ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+ final PsiElement psiElement = descriptor.getPsiElement();
+ if (psiElement == null) return;
+ final SimplifyBooleanExpressionFix fix = createIntention(psiElement, value);
+ if (fix == null) return;
+ try {
+ LOG.assertTrue(psiElement.isValid());
+ fix.applyFix();
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
+ }
+
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return InspectionsBundle.message("inspection.data.flow.simplify.boolean.expression.quickfix");
+ }
+ };
+ }
+
+ @NotNull
+ private static LocalQuickFix createSimplifyToAssignmentFix() {
+ return new LocalQuickFix() {
+ @NotNull
+ @Override
+ public String getName() {
+ return InspectionsBundle.message("inspection.data.flow.simplify.to.assignment.quickfix.name");
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return InspectionsBundle.message("inspection.data.flow.simplify.boolean.expression.quickfix");
+ }
+
+ @Override
+ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+ final PsiElement psiElement = descriptor.getPsiElement();
+ if (psiElement == null) return;
+
+ final PsiAssignmentExpression assignmentExpression = PsiTreeUtil.getParentOfType(psiElement, PsiAssignmentExpression.class);
+ if (assignmentExpression == null) {
+ return;
+ }
+
+ final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
+ final String lExpressionText = assignmentExpression.getLExpression().getText();
+ final PsiExpression rExpression = assignmentExpression.getRExpression();
+ final String rExpressionText = rExpression != null ? rExpression.getText() : "";
+ assignmentExpression.replace(factory.createExpressionFromText(lExpressionText + " = " + rExpressionText, psiElement));
+ }
+ };
+ }
+
+ private static SimplifyBooleanExpressionFix createIntention(PsiElement element, boolean value) {
+ if (!(element instanceof PsiExpression)) return null;
+ final PsiExpression expression = (PsiExpression)element;
+ while (element.getParent() instanceof PsiExpression) {
+ element = element.getParent();
+ }
+ final SimplifyBooleanExpressionFix fix = new SimplifyBooleanExpressionFix(expression, value);
+ // simplify intention already active
+ if (!fix.isAvailable() ||
+ SimplifyBooleanExpressionFix.canBeSimplified((PsiExpression)element)) {
+ return null;
+ }
+ return fix;
+ }
+
+ private static class RedundantInstanceofFix implements LocalQuickFix {
+ @Override
+ @NotNull
+ public String getName() {
+ return InspectionsBundle.message("inspection.data.flow.redundant.instanceof.quickfix");
+ }
+
+ @Override
+ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+ if (!FileModificationService.getInstance().preparePsiElementForWrite(descriptor.getPsiElement())) return;
+ final PsiElement psiElement = descriptor.getPsiElement();
+ if (psiElement instanceof PsiInstanceOfExpression) {
+ try {
+ final PsiExpression compareToNull = JavaPsiFacade.getInstance(psiElement.getProject()).getElementFactory().
+ createExpressionFromText(((PsiInstanceOfExpression)psiElement).getOperand().getText() + " != null", psiElement.getParent());
+ psiElement.replace(compareToNull);
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
+ }
+ }
+
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
+ }
+
+
+ @Override
+ @NotNull
+ public String getDisplayName() {
+ return InspectionsBundle.message("inspection.data.flow.display.name");
+ }
+
+ @Override
+ @NotNull
+ public String getGroupDisplayName() {
+ return GroupNames.BUGS_GROUP_NAME;
+ }
+
+ @Override
+ @NotNull
+ public String getShortName() {
+ return SHORT_NAME;
+ }
+
+ private static class DataFlowInstructionVisitor extends StandardInstructionVisitor {
+ private final StandardDataFlowRunner myRunner;
+
+ private DataFlowInstructionVisitor(StandardDataFlowRunner runner) {
+ myRunner = runner;
+ }
+
+ @Override
+ protected void onAssigningToNotNullableVariable(AssignInstruction instruction) {
+ myRunner.onAssigningToNotNullableVariable(instruction.getRExpression());
+ }
+
+ @Override
+ protected void onNullableReturn(CheckReturnValueInstruction instruction) {
+ myRunner.onNullableReturn(instruction.getReturn());
+ }
+
+ @Override
+ protected void onInstructionProducesCCE(TypeCastInstruction instruction) {
+ myRunner.onInstructionProducesCCE(instruction);
+ }
+
+ @Override
+ protected void onInstructionProducesNPE(Instruction instruction) {
+ if (instruction instanceof MethodCallInstruction &&
+ ((MethodCallInstruction)instruction).getMethodType() == MethodCallInstruction.MethodType.UNBOXING) {
+ myRunner.onUnboxingNullable(((MethodCallInstruction)instruction).getContext());
+ }
+ else {
+ myRunner.onInstructionProducesNPE(instruction);
+ }
+ }
+
+ @Override
+ protected void onPassingNullParameter(PsiExpression arg) {
+ myRunner.onPassingNullParameter(arg);
+ }
+
+ @Override
+ protected void onPassingNullParameterToNonAnnotated(DataFlowRunner runner, PsiExpression arg) {
+ myRunner.onPassingNullParameterToNonAnnotated(arg);
+ }
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
similarity index 97%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
index 0340029..4e30cdd 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
@@ -19,7 +19,7 @@
* User: max
* Date: Jan 28, 2002
* Time: 10:16:39 PM
- * To change template for new class use
+ * To change template for new class use
* Code Style | Class Templates options (Tools | IDE Options).
*/
package com.intellij.codeInspection.dataFlow;
@@ -73,7 +73,7 @@
PsiClass containingClass = PsiTreeUtil.getParentOfType(psiBlock, PsiClass.class);
if (containingClass != null && PsiUtil.isLocalOrAnonymousClass(containingClass)) {
final PsiElement parent = containingClass.getParent();
- final PsiCodeBlock block = DfaUtil.getTopmostBlockInSameClass(parent);
+ final PsiCodeBlock block = DfaPsiUtil.getTopmostBlockInSameClass(parent);
if ((parent instanceof PsiNewExpression || parent instanceof PsiDeclarationStatement) && block != null) {
final EnvironmentalInstructionVisitor envVisitor = new EnvironmentalInstructionVisitor(visitor, parent);
final RunnerResult result = analyzeMethod(block, envVisitor);
@@ -151,6 +151,7 @@
if (LOG.isDebugEnabled()) {
LOG.debug(instructionState.toString());
}
+ //System.out.println(instructionState.toString());
DfaInstructionState[] after = instruction.accept(this, instructionState.getMemoryState(), visitor);
if (after != null) {
@@ -256,7 +257,7 @@
private void checkEnvironment(DataFlowRunner runner, DfaMemoryState memState, @Nullable PsiElement anchor) {
if (myClassParent == anchor) {
DfaMemoryStateImpl copy = (DfaMemoryStateImpl)memState.createCopy();
- copy.flushFields(runner);
+ copy.flushFields(runner.getFields());
Set<DfaVariableValue> vars = new HashSet<DfaVariableValue>(copy.getVariableStates().keySet());
for (DfaVariableValue value : vars) {
copy.flushDependencies(value);
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DelegatingInstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DelegatingInstructionVisitor.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/DelegatingInstructionVisitor.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DelegatingInstructionVisitor.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaInstructionState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaInstructionState.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaInstructionState.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaInstructionState.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
similarity index 93%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
index 8117a7a..455aaf3 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
@@ -47,7 +47,7 @@
boolean applyNotNull(DfaValue value);
- void flushFields(DataFlowRunner runner);
+ void flushFields(DfaVariableValue[] fields);
void flushVariable(DfaVariableValue variable);
@@ -57,5 +57,4 @@
boolean isNotNull(DfaVariableValue dfaVar);
- void flushVariableOutOfScope(DfaVariableValue variable);
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
similarity index 90%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
index bb30b78..b7a0b51 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
@@ -25,12 +25,9 @@
package com.intellij.codeInspection.dataFlow;
import com.intellij.codeInspection.dataFlow.value.*;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.JavaTokenType;
-import com.intellij.psi.PsiPrimitiveType;
-import com.intellij.psi.PsiType;
+import com.intellij.psi.*;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
@@ -43,15 +40,15 @@
public class DfaMemoryStateImpl implements DfaMemoryState {
- private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.DfaMemoryStateImpl");
private final DfaValueFactory myFactory;
- private final ArrayList<SortedIntSet> myEqClasses = new ArrayList<SortedIntSet>();
+ private final List<SortedIntSet> myEqClasses = new ArrayList<SortedIntSet>();
private int myStateSize = 0;
private final Stack<DfaValue> myStack = new Stack<DfaValue>();
private TIntStack myOffsetStack = new TIntStack(1);
private final TLongHashSet myDistinctClasses = new TLongHashSet();
private final THashMap<DfaVariableValue,DfaVariableState> myVariableStates = new THashMap<DfaVariableValue, DfaVariableState>();
+ private final THashSet<DfaVariableValue> myUnknownVariables = new THashSet<DfaVariableValue>();
public DfaMemoryStateImpl(final DfaValueFactory factory) {
myFactory = factory;
@@ -69,9 +66,9 @@
public DfaMemoryStateImpl createCopy() {
DfaMemoryStateImpl newState = createNew();
- //noinspection unchecked
newState.myStack.addAll(myStack);
newState.myDistinctClasses.addAll(myDistinctClasses.toArray());
+ newState.myUnknownVariables.addAll(myUnknownVariables);
newState.myStateSize = myStateSize;
newState.myOffsetStack = new TIntStack(myOffsetStack);
@@ -97,6 +94,7 @@
if (!myStack.equals(that.myStack)) return false;
if (!myOffsetStack.equals(that.myOffsetStack)) return false;
if (!myVariableStates.equals(that.myVariableStates)) return false;
+ if (!myUnknownVariables.equals(that.myUnknownVariables)) return false;
int[] permutation = getPermutationToSortedState();
int[] thatPermutation = that.getPermutationToSortedState();
@@ -174,7 +172,7 @@
public int hashCode() {
return 0;
- //return myEqClasses.hashCode() + myStack.hashCode() + myVariableStates.hashCode();
+ //return ((myEqClasses.hashCode() * 31 + myStack.hashCode()) * 31 + myVariableStates.hashCode()) * 31 + myUnknownVariables.hashCode();
}
private void appendClass(StringBuffer buf, int aClassIndex) {
@@ -201,25 +199,34 @@
appendClass(result, i);
}
- result.append(" distincts: ");
- List<String> distincs = new ArrayList<String>();
- long[] dclasses = myDistinctClasses.toArray();
- for (long pair : dclasses) {
- StringBuffer one = new StringBuffer();
- one.append("{");
- appendClass(one, low(pair));
- one.append(", ");
- appendClass(one, high(pair));
- one.append("}");
- distincs.add(one.toString());
+ if (!myDistinctClasses.isEmpty()) {
+ result.append("\n distincts: ");
+ List<String> distincs = new ArrayList<String>();
+ long[] dclasses = myDistinctClasses.toArray();
+ for (long pair : dclasses) {
+ StringBuffer one = new StringBuffer();
+ one.append("{");
+ appendClass(one, low(pair));
+ one.append(", ");
+ appendClass(one, high(pair));
+ one.append("}");
+ distincs.add(one.toString());
+ }
+ Collections.sort(distincs);
+ result.append(StringUtil.join(distincs, " "));
}
- Collections.sort(distincs);
- result.append(StringUtil.join(distincs, " "));
- result.append(" stack: ").append(StringUtil.join(myStack, ","));
- result.append(" vars: ");
- for (Map.Entry<DfaVariableValue, DfaVariableState> entry : myVariableStates.entrySet()) {
- result.append("[").append(entry.getKey()).append("->").append(entry.getValue()).append("]");
+ if (!myStack.isEmpty()) {
+ result.append("\n stack: ").append(StringUtil.join(myStack, ","));
+ }
+ if (!myVariableStates.isEmpty()) {
+ result.append("\n vars: ");
+ for (Map.Entry<DfaVariableValue, DfaVariableState> entry : myVariableStates.entrySet()) {
+ result.append("[").append(entry.getKey()).append("->").append(entry.getValue()).append("]");
+ }
+ }
+ if (!myUnknownVariables.isEmpty()) {
+ result.append("\n unknowns: ").append(new HashSet<DfaVariableValue>(myUnknownVariables));
}
result.append('>');
return result.toString();
@@ -684,7 +691,7 @@
private static boolean isMaybeBoxedConstant(DfaValue val) {
return val instanceof DfaConstValue ||
- (val instanceof DfaBoxedValue && ((DfaBoxedValue)val).getWrappedValue() instanceof DfaConstValue);
+ val instanceof DfaBoxedValue && ((DfaBoxedValue)val).getWrappedValue() instanceof DfaConstValue;
}
private boolean checkCompareWithBooleanLiteral(DfaValue dfaLeft, DfaValue dfaRight, boolean negated) {
@@ -713,6 +720,10 @@
}
private boolean applyRelation(@NotNull final DfaValue dfaLeft, @NotNull final DfaValue dfaRight, boolean isNegated) {
+ if (isUnknownState(dfaLeft) || isUnknownState(dfaRight)) {
+ return true;
+ }
+
// DfaConstValue || DfaVariableValue
Integer c1Index = getOrCreateEqClassIndex(dfaLeft);
Integer c2Index = getOrCreateEqClassIndex(dfaRight);
@@ -732,6 +743,10 @@
return true;
}
+ private boolean isUnknownState(DfaValue val) {
+ return val instanceof DfaVariableValue && (myUnknownVariables.contains(val) || myUnknownVariables.contains(val.createNegated()));
+ }
+
@Override
public boolean checkNotNullable(DfaValue value) {
if (value == myFactory.getConstFactory().getNull()) return false;
@@ -765,11 +780,16 @@
if (state == null) {
state = createVariableState(dfaVar);
- myVariableStates.put(dfaVar, state);
PsiType type = dfaVar.getVariableType();
if (type != null) {
state.setInstanceofValue(myFactory.getTypeFactory().create(type));
}
+ if (isUnknownState(dfaVar)) {
+ state.setNullable(false);
+ return state;
+ }
+
+ myVariableStates.put(dfaVar, state);
}
return state;
@@ -784,12 +804,21 @@
}
@Override
- public void flushFields(DataFlowRunner runner) {
- for (DfaVariableValue field : runner.getFields()) {
- if (myVariableStates.containsKey(field) || getEqClassIndex(field) >= 0) {
- if (!DfaUtil.isFinalField(field.getPsiVariable())) {
- flushVariable(field);
- getVariableState(field).setNullable(false);
+ public void flushFields(DfaVariableValue[] fields) {
+ Set<DfaVariableValue> allVars = new HashSet<DfaVariableValue>(myVariableStates.keySet());
+ Collections.addAll(allVars, fields);
+
+ Set<DfaVariableValue> dependencies = new HashSet<DfaVariableValue>();
+ for (DfaVariableValue variableValue : allVars) {
+ dependencies.addAll(myFactory.getVarFactory().getAllQualifiedBy(variableValue));
+ }
+ allVars.addAll(dependencies);
+
+ for (DfaVariableValue value : allVars) {
+ if (myVariableStates.containsKey(value) || getEqClassIndex(value) >= 0) {
+ if (value.isFlushableByCalls()) {
+ doFlush(value);
+ myUnknownVariables.add(value);
}
}
}
@@ -799,11 +828,8 @@
public void flushVariable(@NotNull DfaVariableValue variable) {
doFlush(variable);
flushDependencies(variable);
- }
-
- @Override
- public void flushVariableOutOfScope(DfaVariableValue variable) {
- flushVariable(variable);
+ myUnknownVariables.remove(variable);
+ myUnknownVariables.removeAll(myFactory.getVarFactory().getAllQualifiedBy(variable));
}
public void flushDependencies(DfaVariableValue variable) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java
new file mode 100644
index 0000000..da25f91
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2000-2013 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.codeInsight.NullableNotNullManager;
+import com.intellij.openapi.util.Ref;
+import com.intellij.psi.*;
+import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.NullableFunction;
+import com.intellij.util.Processor;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.Stack;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+public class DfaPsiUtil {
+ public static boolean isPlainMutableField(PsiVariable var) {
+ return !var.hasModifierProperty(PsiModifier.FINAL) && !var.hasModifierProperty(PsiModifier.TRANSIENT) && !var.hasModifierProperty(PsiModifier.VOLATILE) && var instanceof PsiField;
+ }
+
+ public static boolean isFinalField(PsiVariable var) {
+ return var.hasModifierProperty(PsiModifier.FINAL) && !var.hasModifierProperty(PsiModifier.TRANSIENT) && var instanceof PsiField;
+ }
+
+ static PsiElement getEnclosingCodeBlock(final PsiVariable variable, final PsiElement context) {
+ PsiElement codeBlock;
+ if (variable instanceof PsiParameter) {
+ codeBlock = ((PsiParameter)variable).getDeclarationScope();
+ if (codeBlock instanceof PsiMethod) {
+ codeBlock = ((PsiMethod)codeBlock).getBody();
+ }
+ }
+ else if (variable instanceof PsiLocalVariable) {
+ codeBlock = PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class);
+ }
+ else {
+ codeBlock = PsiTreeUtil.getParentOfType(context, PsiCodeBlock.class);
+ }
+ while (codeBlock != null) {
+ PsiAnonymousClass anon = PsiTreeUtil.getParentOfType(codeBlock, PsiAnonymousClass.class);
+ if (anon == null) break;
+ codeBlock = PsiTreeUtil.getParentOfType(anon, PsiCodeBlock.class);
+ }
+ return codeBlock;
+ }
+
+ @NotNull
+ public static Nullness getElementNullability(@Nullable PsiType resultType, @Nullable PsiModifierListOwner owner) {
+ if (owner == null) {
+ return Nullness.UNKNOWN;
+ }
+
+ if (NullableNotNullManager.isNullable(owner)) {
+ return Nullness.NULLABLE;
+ }
+ if (NullableNotNullManager.isNotNull(owner)) {
+ return Nullness.NOT_NULL;
+ }
+
+ if (resultType != null) {
+ NullableNotNullManager nnn = NullableNotNullManager.getInstance(owner.getProject());
+ for (PsiAnnotation annotation : resultType.getAnnotations()) {
+ String qualifiedName = annotation.getQualifiedName();
+ if (nnn.getNullables().contains(qualifiedName)) {
+ return Nullness.NULLABLE;
+ }
+ if (nnn.getNotNulls().contains(qualifiedName)) {
+ return Nullness.NOT_NULL;
+ }
+ }
+ }
+
+ return Nullness.UNKNOWN;
+ }
+
+ public static List<PsiExpression> findAllConstructorInitializers(PsiField field) {
+ final List<PsiExpression> result = ContainerUtil.createLockFreeCopyOnWriteList();
+ ContainerUtil.addIfNotNull(result, field.getInitializer());
+
+ PsiClass containingClass = field.getContainingClass();
+ if (containingClass != null) {
+ LocalSearchScope scope = new LocalSearchScope(containingClass.getConstructors());
+ ReferencesSearch.search(field, scope, false).forEach(new Processor<PsiReference>() {
+ @Override
+ public boolean process(PsiReference reference) {
+ final PsiElement element = reference.getElement();
+ if (element instanceof PsiReferenceExpression) {
+ final PsiAssignmentExpression assignment = getAssignmentExpressionIfOnAssignmentLhs(element);
+ final PsiMethod method = PsiTreeUtil.getParentOfType(assignment, PsiMethod.class);
+ if (method != null && method.isConstructor() && assignment != null) {
+ ContainerUtil.addIfNotNull(result, assignment.getRExpression());
+ }
+ }
+ return true;
+ }
+ });
+ }
+ return result;
+ }
+
+ @Nullable
+ private static PsiAssignmentExpression getAssignmentExpressionIfOnAssignmentLhs(PsiElement expression) {
+ PsiElement parent = PsiTreeUtil.skipParentsOfType(expression, PsiParenthesizedExpression.class);
+ if (!(parent instanceof PsiAssignmentExpression)) {
+ return null;
+ }
+ final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)parent;
+ if (!PsiTreeUtil.isAncestor(assignmentExpression.getLExpression(), expression, false)) {
+ return null;
+ }
+ return assignmentExpression;
+ }
+
+ public static boolean isNullableInitialized(PsiVariable var, boolean nullable) {
+ if (!isFinalField(var)) {
+ return false;
+ }
+
+ List<PsiExpression> initializers = findAllConstructorInitializers((PsiField)var);
+ if (initializers.isEmpty()) {
+ return false;
+ }
+
+ for (PsiExpression expression : initializers) {
+ if (!(expression instanceof PsiReferenceExpression)) {
+ return false;
+ }
+ PsiElement target = ((PsiReferenceExpression)expression).resolve();
+ if (!(target instanceof PsiParameter)) {
+ return false;
+ }
+ if (nullable && NullableNotNullManager.isNullable((PsiParameter)target)) {
+ return true;
+ }
+ if (!nullable && !NullableNotNullManager.isNotNull((PsiParameter)target)) {
+ return false;
+ }
+ }
+ return !nullable;
+ }
+
+ @Nullable
+ public static PsiCodeBlock getTopmostBlockInSameClass(@NotNull PsiElement position) {
+ PsiCodeBlock block = PsiTreeUtil.getParentOfType(position, PsiCodeBlock.class, false, PsiMember.class, PsiFile.class);
+ if (block == null) {
+ return null;
+ }
+
+ PsiCodeBlock lastBlock = block;
+ while (true) {
+ block = PsiTreeUtil.getParentOfType(block, PsiCodeBlock.class, true, PsiMember.class, PsiFile.class);
+ if (block == null) {
+ return lastBlock;
+ }
+ lastBlock = block;
+ }
+ }
+
+ @NotNull
+ public static Collection<PsiExpression> getVariableAssignmentsInFile(@NotNull PsiVariable psiVariable,
+ final boolean literalsOnly,
+ final PsiElement place) {
+ final Ref<Boolean> modificationRef = Ref.create(Boolean.FALSE);
+ final PsiCodeBlock codeBlock = place == null? null : getTopmostBlockInSameClass(place);
+ final int placeOffset = codeBlock != null? place.getTextRange().getStartOffset() : 0;
+ List<PsiExpression> list = ContainerUtil.mapNotNull(
+ ReferencesSearch.search(psiVariable, new LocalSearchScope(new PsiElement[] {psiVariable.getContainingFile()}, null, true)).findAll(),
+ new NullableFunction<PsiReference, PsiExpression>() {
+ @Override
+ public PsiExpression fun(final PsiReference psiReference) {
+ if (modificationRef.get()) return null;
+ final PsiElement parent = psiReference.getElement().getParent();
+ if (parent instanceof PsiAssignmentExpression) {
+ final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)parent;
+ final IElementType operation = assignmentExpression.getOperationTokenType();
+ if (assignmentExpression.getLExpression() == psiReference) {
+ if (JavaTokenType.EQ.equals(operation)) {
+ final PsiExpression rValue = assignmentExpression.getRExpression();
+ if (!literalsOnly || allOperandsAreLiterals(rValue)) {
+ // if there's a codeBlock omit the values assigned later
+ if (codeBlock != null && PsiTreeUtil.isAncestor(codeBlock, parent, true)
+ && placeOffset < parent.getTextRange().getStartOffset()) {
+ return null;
+ }
+ return rValue;
+ }
+ else {
+ modificationRef.set(Boolean.TRUE);
+ }
+ }
+ else if (JavaTokenType.PLUSEQ.equals(operation)) {
+ modificationRef.set(Boolean.TRUE);
+ }
+ }
+ }
+ return null;
+ }
+ });
+ if (modificationRef.get()) return Collections.emptyList();
+ PsiExpression initializer = psiVariable.getInitializer();
+ if (initializer != null && (!literalsOnly || allOperandsAreLiterals(initializer))) {
+ list = ContainerUtil.concat(list, Collections.singletonList(initializer));
+ }
+ return list;
+ }
+
+ public static boolean allOperandsAreLiterals(@Nullable final PsiExpression expression) {
+ if (expression == null) return false;
+ if (expression instanceof PsiLiteralExpression) return true;
+ if (expression instanceof PsiPolyadicExpression) {
+ Stack<PsiExpression> stack = new Stack<PsiExpression>();
+ stack.add(expression);
+ while (!stack.isEmpty()) {
+ PsiExpression psiExpression = stack.pop();
+ if (psiExpression instanceof PsiPolyadicExpression) {
+ PsiPolyadicExpression binaryExpression = (PsiPolyadicExpression)psiExpression;
+ for (PsiExpression op : binaryExpression.getOperands()) {
+ stack.push(op);
+ }
+ }
+ else if (!(psiExpression instanceof PsiLiteralExpression)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java
new file mode 100644
index 0000000..808872f
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2000-2009 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.instructions.AssignInstruction;
+import com.intellij.codeInspection.dataFlow.instructions.Instruction;
+import com.intellij.codeInspection.dataFlow.instructions.PushInstruction;
+import com.intellij.codeInspection.dataFlow.value.DfaValue;
+import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.MultiValuesMap;
+import com.intellij.psi.*;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.CachedValue;
+import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.psi.util.CachedValuesManager;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * @author Gregory.Shrago
+ */
+public class DfaUtil {
+ private static final Key<CachedValue<MultiValuesMap<PsiVariable, PsiExpression>>> DFA_VARIABLE_INFO_KEY = Key.create("DFA_VARIABLE_INFO_KEY");
+
+ private DfaUtil() {
+ }
+
+ private static final MultiValuesMap<PsiVariable, PsiExpression> TOO_COMPLEX = new MultiValuesMap<PsiVariable, PsiExpression>();
+ @Nullable("null means DFA analysis has failed (too complex to analyze)")
+ public static Collection<PsiExpression> getCachedVariableValues(@Nullable final PsiVariable variable, @Nullable final PsiElement context) {
+ if (variable == null || context == null) return Collections.emptyList();
+
+ CachedValue<MultiValuesMap<PsiVariable, PsiExpression>> cachedValue = context.getUserData(DFA_VARIABLE_INFO_KEY);
+ if (cachedValue == null) {
+ final PsiElement codeBlock = DfaPsiUtil.getEnclosingCodeBlock(variable, context);
+ cachedValue = CachedValuesManager.getManager(context.getProject()).createCachedValue(new CachedValueProvider<MultiValuesMap<PsiVariable, PsiExpression>>() {
+ @Override
+ public Result<MultiValuesMap<PsiVariable, PsiExpression>> compute() {
+ final MultiValuesMap<PsiVariable, PsiExpression> result;
+ if (codeBlock == null) {
+ result = null;
+ }
+ else {
+ final ValuableInstructionVisitor visitor = new ValuableInstructionVisitor(context);
+ RunnerResult runnerResult = new ValuableDataFlowRunner().analyzeMethod(codeBlock, visitor);
+ if (runnerResult == RunnerResult.OK) {
+ result = visitor.myValues;
+ }
+ else {
+ result = TOO_COMPLEX;
+ }
+ }
+ return new Result<MultiValuesMap<PsiVariable, PsiExpression>>(result, codeBlock);
+ }
+ }, false);
+ context.putUserData(DFA_VARIABLE_INFO_KEY, cachedValue);
+ }
+ final MultiValuesMap<PsiVariable, PsiExpression> value = cachedValue.getValue();
+ if (value == TOO_COMPLEX) return null;
+ final Collection<PsiExpression> expressions = value == null ? null : value.get(variable);
+ return expressions == null ? Collections.<PsiExpression>emptyList() : expressions;
+ }
+
+ @NotNull
+ public static Nullness checkNullness(@Nullable final PsiVariable variable, @Nullable final PsiElement context) {
+ if (variable == null || context == null) return Nullness.UNKNOWN;
+
+ final PsiElement codeBlock = DfaPsiUtil.getEnclosingCodeBlock(variable, context);
+ if (codeBlock == null) {
+ return Nullness.UNKNOWN;
+ }
+ final ValuableInstructionVisitor visitor = new ValuableInstructionVisitor(context);
+ RunnerResult result = new ValuableDataFlowRunner().analyzeMethod(codeBlock, visitor);
+ if (result != RunnerResult.OK) {
+ return Nullness.UNKNOWN;
+ }
+ if (visitor.myNulls.contains(variable) && !visitor.myNotNulls.contains(variable)) return Nullness.NULLABLE;
+ if (visitor.myNotNulls.contains(variable) && !visitor.myNulls.contains(variable)) return Nullness.NOT_NULL;
+ return Nullness.UNKNOWN;
+ }
+
+ @NotNull
+ public static Collection<? extends PsiElement> getPossibleInitializationElements(final PsiElement qualifierExpression) {
+ if (qualifierExpression instanceof PsiMethodCallExpression) {
+ return Collections.singletonList(qualifierExpression);
+ }
+ if (qualifierExpression instanceof PsiReferenceExpression) {
+ final PsiElement targetElement = ((PsiReferenceExpression)qualifierExpression).resolve();
+ if (!(targetElement instanceof PsiVariable)) {
+ return Collections.emptyList();
+ }
+ final Collection<? extends PsiElement> variableValues = getCachedVariableValues((PsiVariable)targetElement, qualifierExpression);
+ if (variableValues == null || variableValues.isEmpty()) {
+ return DfaPsiUtil.getVariableAssignmentsInFile((PsiVariable)targetElement, false, qualifierExpression);
+ }
+ return variableValues;
+ }
+ if (qualifierExpression instanceof PsiLiteralExpression) {
+ return Collections.singletonList(qualifierExpression);
+ }
+ return Collections.emptyList();
+ }
+
+ private static class ValuableInstructionVisitor extends StandardInstructionVisitor {
+ final MultiValuesMap<PsiVariable, PsiExpression> myValues = new MultiValuesMap<PsiVariable, PsiExpression>(true);
+ final Set<PsiVariable> myNulls = new THashSet<PsiVariable>();
+ final Set<PsiVariable> myNotNulls = new THashSet<PsiVariable>();
+ private final PsiElement myContext;
+
+ public ValuableInstructionVisitor(@NotNull PsiElement context) {
+ myContext = context;
+ }
+
+ @Override
+ public DfaInstructionState[] visitPush(PushInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
+ if (myContext == instruction.getPlace()) {
+ final Map<DfaVariableValue,DfaVariableState> map = ((ValuableDataFlowRunner.MyDfaMemoryState)memState).getVariableStates();
+ for (Map.Entry<DfaVariableValue, DfaVariableState> entry : map.entrySet()) {
+ ValuableDataFlowRunner.ValuableDfaVariableState state = (ValuableDataFlowRunner.ValuableDfaVariableState)entry.getValue();
+ DfaVariableValue variableValue = entry.getKey();
+ final PsiExpression psiExpression = state.myExpression;
+ if (psiExpression != null && variableValue.getQualifier() == null) {
+ myValues.put(variableValue.getPsiVariable(), psiExpression);
+ }
+ }
+ DfaValue value = instruction.getValue();
+ if (value instanceof DfaVariableValue && ((DfaVariableValue)value).getQualifier() == null) {
+ if (memState.isNotNull((DfaVariableValue)value)) {
+ myNotNulls.add(((DfaVariableValue)value).getPsiVariable());
+ }
+ if (memState.isNull(value)) {
+ myNulls.add(((DfaVariableValue)value).getPsiVariable());
+ }
+ }
+ }
+ return super.visitPush(instruction, runner, memState);
+ }
+
+ @Override
+ public DfaInstructionState[] visitAssign(AssignInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
+ final Instruction nextInstruction = runner.getInstruction(instruction.getIndex() + 1);
+
+ final DfaValue dfaSource = memState.pop();
+ final DfaValue dfaDest = memState.pop();
+
+ if (dfaDest instanceof DfaVariableValue) {
+ DfaVariableValue var = (DfaVariableValue)dfaDest;
+ final PsiExpression rightValue = instruction.getRExpression();
+ final PsiElement parent = rightValue == null ? null : rightValue.getParent();
+ final IElementType type = parent instanceof PsiAssignmentExpression
+ ? ((PsiAssignmentExpression)parent).getOperationTokenType() : JavaTokenType.EQ;
+ // store current value - to use in case of '+='
+ final PsiExpression prevValue = ((ValuableDataFlowRunner.ValuableDfaVariableState)((ValuableDataFlowRunner.MyDfaMemoryState)memState).getVariableState(var)).myExpression;
+ memState.setVarValue(var, dfaSource);
+ // state may have been changed so re-retrieve it
+ final ValuableDataFlowRunner.ValuableDfaVariableState curState = (ValuableDataFlowRunner.ValuableDfaVariableState)((ValuableDataFlowRunner.MyDfaMemoryState)memState).getVariableState(var);
+ final PsiExpression curValue = curState.myExpression;
+ final PsiExpression nextValue;
+ if (type == JavaTokenType.PLUSEQ && prevValue != null) {
+ PsiExpression tmpExpression;
+ try {
+ tmpExpression = JavaPsiFacade.getElementFactory(myContext.getProject())
+ .createExpressionFromText(prevValue.getText() + "+" + rightValue.getText(), rightValue);
+ }
+ catch (Exception e) {
+ tmpExpression = curValue == null ? rightValue : curValue;
+ }
+ nextValue = tmpExpression;
+ }
+ else {
+ nextValue = curValue == null ? rightValue : curValue;
+ }
+ curState.myExpression = nextValue;
+ }
+ memState.push(dfaDest);
+ return new DfaInstructionState[]{new DfaInstructionState(nextInstruction, memState)};
+ }
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java
similarity index 98%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java
index 6d8d8d6..b1d3203 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java
@@ -119,9 +119,9 @@
public DfaInstructionState[] visitFlushVariable(FlushVariableInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
final DfaVariableValue variable = instruction.getVariable();
if (variable != null) {
- memState.flushVariableOutOfScope(variable);
+ memState.flushVariable(variable);
} else {
- memState.flushFields(runner);
+ memState.flushFields(runner.getFields());
}
return nextInstruction(instruction, runner, memState);
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/Nullness.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/Nullness.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/Nullness.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/Nullness.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/RunnerResult.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/RunnerResult.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/RunnerResult.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/RunnerResult.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/SortedIntSet.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/SortedIntSet.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/SortedIntSet.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/SortedIntSet.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
similarity index 97%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
index 54df852..fc10e2e 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
@@ -55,7 +55,7 @@
return Nullness.NOT_NULL;
}
- return callExpression != null ? DfaUtil.getElementNullability(key.getResultType(), callExpression.resolveMethod()) : null;
+ return callExpression != null ? DfaPsiUtil.getElementNullability(key.getResultType(), callExpression.resolveMethod()) : null;
}
};
@@ -74,7 +74,7 @@
Map<PsiExpression, Nullness> map = ContainerUtil.newHashMap();
for (int i = 0; i < checkedCount; i++) {
- map.put(args[i], DfaUtil.getElementNullability(substitutor.substitute(parameters[i].getType()), parameters[i]));
+ map.put(args[i], DfaPsiUtil.getElementNullability(substitutor.substitute(parameters[i].getType()), parameters[i]));
}
return map;
}
@@ -112,7 +112,7 @@
if (dfaDest instanceof DfaVariableValue) {
DfaVariableValue var = (DfaVariableValue) dfaDest;
final PsiVariable psiVariable = var.getPsiVariable();
- if (DfaUtil.getElementNullability(var.getVariableType(), psiVariable) == Nullness.NOT_NULL) {
+ if (DfaPsiUtil.getElementNullability(var.getVariableType(), psiVariable) == Nullness.NOT_NULL) {
if (!memState.applyNotNull(dfaSource)) {
onAssigningToNotNullableVariable(instruction);
}
@@ -215,7 +215,7 @@
finally {
memState.push(getMethodResultValue(instruction, qualifier, runner.getFactory()));
if (instruction.shouldFlushFields()) {
- memState.flushFields(runner);
+ memState.flushFields(runner.getFields());
}
}
}
@@ -229,9 +229,6 @@
final PsiType type = instruction.getResultType();
final MethodCallInstruction.MethodType methodType = instruction.getMethodType();
- if (type != null && (type instanceof PsiClassType || type.getArrayDimensions() > 0)) {
- return factory.createTypeValueWithNullability(type, myReturnTypeNullability.get(instruction));
- }
if (methodType == MethodCallInstruction.MethodType.UNBOXING) {
return factory.getBoxedFactory().createUnboxed(qualifierValue);
@@ -239,7 +236,7 @@
if (methodType == MethodCallInstruction.MethodType.BOXING) {
DfaValue boxed = factory.getBoxedFactory().createBoxed(qualifierValue);
- return boxed == null ? DfaUnknownValue.getInstance() : boxed;
+ return boxed == null ? factory.getNotNullFactory().create(type) : boxed;
}
if (methodType == MethodCallInstruction.MethodType.CAST) {
@@ -248,6 +245,10 @@
}
return qualifierValue;
}
+
+ if (type != null && (type instanceof PsiClassType || type.getArrayDimensions() > 0)) {
+ return factory.createTypeValueWithNullability(type, myReturnTypeNullability.get(instruction));
+ }
return DfaUnknownValue.getInstance();
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/WorkingTimeMeasurer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/WorkingTimeMeasurer.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/WorkingTimeMeasurer.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/WorkingTimeMeasurer.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/AssignInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/AssignInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/AssignInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/AssignInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/CheckReturnValueInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/CheckReturnValueInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/CheckReturnValueInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/CheckReturnValueInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/DupInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/DupInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/DupInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/DupInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/EmptyInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/EmptyInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/EmptyInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/EmptyInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/EmptyStackInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/EmptyStackInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/EmptyStackInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/EmptyStackInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/FieldReferenceInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/FieldReferenceInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/FieldReferenceInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/FieldReferenceInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/FlushVariableInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/FlushVariableInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/FlushVariableInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/FlushVariableInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/InstanceofInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/InstanceofInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/InstanceofInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/InstanceofInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java
similarity index 94%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java
index 505deaa..5514268 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java
@@ -19,7 +19,7 @@
* User: max
* Date: Jan 26, 2002
* Time: 10:46:40 PM
- * To change template for new class use
+ * To change template for new class use
* Code Style | Class Templates options (Tools | IDE Options).
*/
package com.intellij.codeInspection.dataFlow.instructions;
@@ -31,10 +31,11 @@
import com.intellij.openapi.progress.ProgressManager;
import java.util.ArrayList;
+import java.util.List;
public abstract class Instruction {
private int myIndex;
- private final ArrayList<DfaMemoryState> myProcessedStates;
+ private final List<DfaMemoryState> myProcessedStates;
protected Instruction() {
myProcessedStates = new ArrayList<DfaMemoryState>();
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java
similarity index 74%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java
index 5f65a86..a46abb6 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java
@@ -36,44 +36,35 @@
public class MethodCallInstruction extends Instruction {
@Nullable private final PsiCallExpression myCall;
- @Nullable private PsiType myType;
+ @Nullable private final PsiType myType;
@NotNull private final PsiExpression[] myArgs;
- private boolean myShouldFlushFields;
+ private final boolean myShouldFlushFields;
@NotNull private final PsiExpression myContext;
private final MethodType myMethodType;
- @Nullable private DfaValue myPrecalculatedReturnValue;
+ @Nullable private final DfaValue myPrecalculatedReturnValue;
public enum MethodType {
BOXING, UNBOXING, REGULAR_METHOD_CALL, CAST
}
- public MethodCallInstruction(@NotNull PsiCallExpression callExpression, @Nullable DfaValue precalculatedReturnValue) {
- this(callExpression, MethodType.REGULAR_METHOD_CALL);
- myPrecalculatedReturnValue = precalculatedReturnValue;
- }
-
public MethodCallInstruction(@NotNull PsiExpression context, MethodType methodType, @Nullable PsiType resultType) {
- this(context, methodType);
- myType = resultType;
- myShouldFlushFields = false;
- }
-
- public MethodCallInstruction(@NotNull PsiExpression context, MethodType methodType) {
myContext = context;
myMethodType = methodType;
- myCall = methodType == MethodType.REGULAR_METHOD_CALL && context instanceof PsiCallExpression ? (PsiCallExpression)context : null;
- final PsiExpressionList argList = myCall == null ? null : myCall.getArgumentList();
- myArgs = argList != null ? argList.getExpressions() : PsiExpression.EMPTY_ARRAY;
-
- myType = myCall == null ? null : myCall.getType();
-
- myShouldFlushFields = true;
- if (myCall instanceof PsiNewExpression && myType != null && myType.getArrayDimensions() > 0) {
- myShouldFlushFields = false;
- }
+ myCall = null;
+ myArgs = PsiExpression.EMPTY_ARRAY;
+ myType = resultType;
+ myShouldFlushFields = false;
+ myPrecalculatedReturnValue = null;
}
- public void setShouldFlushFields(boolean shouldFlushFields) {
- myShouldFlushFields = shouldFlushFields;
+ public MethodCallInstruction(@NotNull PsiCallExpression context, @Nullable DfaValue precalculatedReturnValue) {
+ myContext = context;
+ myMethodType = MethodType.REGULAR_METHOD_CALL;
+ myCall = context;
+ final PsiExpressionList argList = context.getArgumentList();
+ myArgs = argList != null ? argList.getExpressions() : PsiExpression.EMPTY_ARRAY;
+ myType = myCall.getType();
+ myShouldFlushFields = !(myCall instanceof PsiNewExpression && myType != null && myType.getArrayDimensions() > 0);
+ myPrecalculatedReturnValue = precalculatedReturnValue;
}
@Nullable
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/NotInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/NotInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/NotInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/NotInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/PopInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/PopInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/PopInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/PopInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/PushInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/PushInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/PushInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/PushInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnFromSubInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnFromSubInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnFromSubInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnFromSubInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/SwapInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/SwapInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/SwapInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/SwapInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/TypeCastInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/TypeCastInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/TypeCastInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/TypeCastInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaBoxedValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaBoxedValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaBoxedValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaBoxedValue.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaConstValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaConstValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaConstValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaConstValue.java
diff --git a/java/java-impl/src/com/intellij/codeInsight/guess/impl/DfaInstanceofValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaInstanceofValue.java
similarity index 90%
rename from java/java-impl/src/com/intellij/codeInsight/guess/impl/DfaInstanceofValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaInstanceofValue.java
index 574fa5e..833f503 100644
--- a/java/java-impl/src/com/intellij/codeInsight/guess/impl/DfaInstanceofValue.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaInstanceofValue.java
@@ -13,10 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.codeInsight.guess.impl;
+package com.intellij.codeInspection.dataFlow.value;
-import com.intellij.codeInspection.dataFlow.value.DfaValue;
-import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull;
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaNotNullValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaNotNullValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaNotNullValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaNotNullValue.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaUnboxedValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaUnboxedValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaUnboxedValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaUnboxedValue.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaUnknownValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaUnknownValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaUnknownValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaUnknownValue.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
similarity index 89%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
index 758059b..39541bf 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
@@ -24,10 +24,9 @@
*/
package com.intellij.codeInspection.dataFlow.value;
-import com.intellij.codeInspection.dataFlow.DfaUtil;
+import com.intellij.codeInspection.dataFlow.DfaPsiUtil;
import com.intellij.codeInspection.dataFlow.Nullness;
-import com.intellij.psi.PsiType;
-import com.intellij.psi.PsiVariable;
+import com.intellij.psi.*;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
@@ -160,11 +159,11 @@
}
PsiVariable var = getPsiVariable();
- Nullness nullability = DfaUtil.getElementNullability(getVariableType(), var);
+ Nullness nullability = DfaPsiUtil.getElementNullability(getVariableType(), var);
if (nullability == Nullness.UNKNOWN && var != null) {
- if (DfaUtil.isNullableInitialized(var, true)) {
+ if (DfaPsiUtil.isNullableInitialized(var, true)) {
nullability = Nullness.NULLABLE;
- } else if (DfaUtil.isNullableInitialized(var, false)) {
+ } else if (DfaPsiUtil.isNullableInitialized(var, false)) {
nullability = Nullness.NOT_NULL;
}
}
@@ -174,4 +173,14 @@
return nullability;
}
+ public boolean isLocalVariable() {
+ return myVariable instanceof PsiLocalVariable || myVariable instanceof PsiParameter;
+ }
+
+ public boolean isFlushableByCalls() {
+ if (isLocalVariable()) return false;
+ if (!myVariable.hasModifierProperty(PsiModifier.FINAL)) return true;
+ return myQualifier != null && myQualifier.isFlushableByCalls();
+ }
+
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/defUse/DefUseInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/defUse/DefUseInspectionBase.java
new file mode 100644
index 0000000..b21e514
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/defUse/DefUseInspectionBase.java
@@ -0,0 +1,218 @@
+package com.intellij.codeInspection.defUse;
+
+import com.intellij.codeInsight.daemon.GroupNames;
+import com.intellij.codeInspection.*;
+import com.intellij.psi.*;
+import com.intellij.psi.controlFlow.DefUseUtil;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import java.awt.*;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+
+public class DefUseInspectionBase extends BaseJavaBatchLocalInspectionTool {
+ public boolean REPORT_PREFIX_EXPRESSIONS = false;
+ public boolean REPORT_POSTFIX_EXPRESSIONS = true;
+ public boolean REPORT_REDUNDANT_INITIALIZER = true;
+
+ public static final String DISPLAY_NAME = InspectionsBundle.message("inspection.unused.assignment.display.name");
+ @NonNls public static final String SHORT_NAME = "UnusedAssignment";
+
+ @Override
+ @NotNull
+ public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
+ return new JavaElementVisitor() {
+ @Override public void visitMethod(PsiMethod method) {
+ checkCodeBlock(method.getBody(), holder, isOnTheFly);
+ }
+
+ @Override public void visitClassInitializer(PsiClassInitializer initializer) {
+ checkCodeBlock(initializer.getBody(), holder, isOnTheFly);
+ }
+ };
+ }
+
+ private void checkCodeBlock(final PsiCodeBlock body,
+ final ProblemsHolder holder,
+ final boolean isOnTheFly) {
+ if (body == null) return;
+ final Set<PsiVariable> usedVariables = new THashSet<PsiVariable>();
+ List<DefUseUtil.Info> unusedDefs = DefUseUtil.getUnusedDefs(body, usedVariables);
+
+ if (unusedDefs != null && !unusedDefs.isEmpty()) {
+ Collections.sort(unusedDefs, new Comparator<DefUseUtil.Info>() {
+ @Override
+ public int compare(DefUseUtil.Info o1, DefUseUtil.Info o2) {
+ int offset1 = o1.getContext().getTextOffset();
+ int offset2 = o2.getContext().getTextOffset();
+
+ if (offset1 == offset2) return 0;
+ if (offset1 < offset2) return -1;
+
+ return 1;
+ }
+ });
+
+ for (DefUseUtil.Info info : unusedDefs) {
+ PsiElement context = info.getContext();
+ PsiVariable psiVariable = info.getVariable();
+
+ if (context instanceof PsiDeclarationStatement || context instanceof PsiResourceVariable) {
+ if (!info.isRead()) {
+ if (!isOnTheFly) {
+ holder.registerProblem(psiVariable.getNameIdentifier(),
+ InspectionsBundle.message("inspection.unused.assignment.problem.descriptor1", "<code>#ref</code> #loc"),
+ ProblemHighlightType.LIKE_UNUSED_SYMBOL);
+ }
+ }
+ else {
+ if (REPORT_REDUNDANT_INITIALIZER) {
+ holder.registerProblem(psiVariable.getInitializer(),
+ InspectionsBundle.message("inspection.unused.assignment.problem.descriptor2",
+ "<code>" + psiVariable.getName() + "</code>", "<code>#ref</code> #loc"),
+ ProblemHighlightType.LIKE_UNUSED_SYMBOL,
+ createRemoveInitializerFix());
+ }
+ }
+ }
+ else if (context instanceof PsiAssignmentExpression &&
+ ((PsiAssignmentExpression)context).getOperationTokenType() == JavaTokenType.EQ) {
+ final PsiAssignmentExpression assignment = (PsiAssignmentExpression)context;
+ holder.registerProblem(assignment.getLExpression(),
+ InspectionsBundle.message("inspection.unused.assignment.problem.descriptor3",
+ assignment.getRExpression().getText(), "<code>#ref</code>" + " #loc"), ProblemHighlightType.LIKE_UNUSED_SYMBOL);
+ }
+ else {
+ if (context instanceof PsiPrefixExpression && REPORT_PREFIX_EXPRESSIONS ||
+ context instanceof PsiPostfixExpression && REPORT_POSTFIX_EXPRESSIONS) {
+ holder.registerProblem(context,
+ InspectionsBundle.message("inspection.unused.assignment.problem.descriptor4", "<code>#ref</code> #loc"));
+ }
+ }
+ }
+ }
+
+ body.accept(new JavaRecursiveElementWalkingVisitor() {
+ @Override public void visitClass(PsiClass aClass) {
+ }
+
+ @Override public void visitLocalVariable(PsiLocalVariable variable) {
+ if (!usedVariables.contains(variable) && variable.getInitializer() == null && !isOnTheFly) {
+ holder.registerProblem(variable.getNameIdentifier(),
+ InspectionsBundle.message("inspection.unused.assignment.problem.descriptor5", "<code>#ref</code> #loc"),
+ ProblemHighlightType.LIKE_UNUSED_SYMBOL);
+ }
+ }
+
+ @Override public void visitAssignmentExpression(PsiAssignmentExpression expression) {
+ PsiExpression lExpression = expression.getLExpression();
+ PsiExpression rExpression = expression.getRExpression();
+
+ if (lExpression instanceof PsiReferenceExpression && rExpression instanceof PsiReferenceExpression) {
+ PsiReferenceExpression lRef = (PsiReferenceExpression)lExpression;
+ PsiReferenceExpression rRef = (PsiReferenceExpression)rExpression;
+
+ if (lRef.resolve() != rRef.resolve()) return;
+ PsiExpression lQualifier = lRef.getQualifierExpression();
+ PsiExpression rQualifier = rRef.getQualifierExpression();
+
+ if ((lQualifier == null && rQualifier == null ||
+ lQualifier instanceof PsiThisExpression && rQualifier instanceof PsiThisExpression ||
+ lQualifier instanceof PsiThisExpression && rQualifier == null ||
+ lQualifier == null && rQualifier instanceof PsiThisExpression) && !isOnTheFly) {
+ holder.registerProblem(expression,
+ InspectionsBundle.message("inspection.unused.assignment.problem.descriptor6", "<code>#ref</code>"));
+ }
+ }
+ }
+ });
+ }
+
+ protected LocalQuickFix createRemoveInitializerFix() {
+ return null;
+ }
+
+ @Override
+ public JComponent createOptionsPanel() {
+ return new OptionsPanel();
+ }
+
+ private class OptionsPanel extends JPanel {
+ private final JCheckBox myReportPrefix;
+ private final JCheckBox myReportPostfix;
+ private final JCheckBox myReportInitializer;
+
+ private OptionsPanel() {
+ super(new GridBagLayout());
+
+ GridBagConstraints gc = new GridBagConstraints();
+ gc.weighty = 0;
+ gc.weightx = 1;
+ gc.fill = GridBagConstraints.HORIZONTAL;
+ gc.anchor = GridBagConstraints.NORTHWEST;
+
+ myReportInitializer = new JCheckBox(InspectionsBundle.message("inspection.unused.assignment.option2"));
+ myReportInitializer.setSelected(REPORT_REDUNDANT_INITIALIZER);
+ myReportInitializer.getModel().addChangeListener(new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ REPORT_REDUNDANT_INITIALIZER = myReportInitializer.isSelected();
+ }
+ });
+ gc.insets = new Insets(0, 0, 15, 0);
+ gc.gridy = 0;
+ add(myReportInitializer, gc);
+
+ myReportPrefix = new JCheckBox(InspectionsBundle.message("inspection.unused.assignment.option"));
+ myReportPrefix.setSelected(REPORT_PREFIX_EXPRESSIONS);
+ myReportPrefix.getModel().addChangeListener(new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ REPORT_PREFIX_EXPRESSIONS = myReportPrefix.isSelected();
+ }
+ });
+ gc.insets = new Insets(0, 0, 0, 0);
+ gc.gridy++;
+ add(myReportPrefix, gc);
+
+ myReportPostfix = new JCheckBox(InspectionsBundle.message("inspection.unused.assignment.option1"));
+ myReportPostfix.setSelected(REPORT_POSTFIX_EXPRESSIONS);
+ myReportPostfix.getModel().addChangeListener(new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ REPORT_POSTFIX_EXPRESSIONS = myReportPostfix.isSelected();
+ }
+ });
+
+ gc.weighty = 1;
+ gc.gridy++;
+ add(myReportPostfix, gc);
+ }
+ }
+
+
+ @Override
+ @NotNull
+ public String getDisplayName() {
+ return DISPLAY_NAME;
+ }
+
+ @Override
+ @NotNull
+ public String getGroupDisplayName() {
+ return GroupNames.BUGS_GROUP_NAME;
+ }
+
+ @Override
+ @NotNull
+ public String getShortName() {
+ return SHORT_NAME;
+ }
+}
\ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java
similarity index 93%
rename from java/java-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java
index b17f1f5..85b3674 100644
--- a/java/java-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java
@@ -16,18 +16,15 @@
package com.intellij.codeInspection.deprecation;
import com.intellij.codeInsight.daemon.JavaErrorMessages;
-import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightMessageUtil;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
-import com.intellij.codeInspection.ProblemHighlightType;
-import com.intellij.codeInspection.ProblemsHolder;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
+import com.intellij.codeInspection.*;
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.refactoring.util.RefactoringUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,10 +35,10 @@
/**
* @author max
*/
-public class DeprecationInspection extends BaseJavaLocalInspectionTool {
- @NonNls public static final String SHORT_NAME = HighlightInfoType.DEPRECATION_SHORT_NAME;
- @NonNls public static final String ID = HighlightInfoType.DEPRECATION_ID;
- public static final String DISPLAY_NAME = HighlightInfoType.DEPRECATION_DISPLAY_NAME;
+public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool {
+ @NonNls public static final String SHORT_NAME = DeprecationUtil.DEPRECATION_SHORT_NAME;
+ @NonNls public static final String ID = DeprecationUtil.DEPRECATION_ID;
+ public static final String DISPLAY_NAME = DeprecationUtil.DEPRECATION_DISPLAY_NAME;
public boolean IGNORE_INSIDE_DEPRECATED = false;
public boolean IGNORE_ABSTRACT_DEPRECATED_OVERRIDES = true;
@@ -178,7 +175,7 @@
final PsiCodeBlock body = method.getBody();
if (body != null) {
final PsiStatement[] statements = body.getStatements();
- if (statements.length == 0 || !RefactoringUtil.isSuperOrThisCall(statements[0], true, true)) {
+ if (statements.length == 0 || !JavaHighlightUtil.isSuperOrThisCall(statements[0], true, true)) {
registerDefaultConstructorProblem(superClass, method.getNameIdentifier(), false);
}
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/duplicateThrows/DuplicateThrowsInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/duplicateThrows/DuplicateThrowsInspection.java
similarity index 89%
rename from java/java-impl/src/com/intellij/codeInspection/duplicateThrows/DuplicateThrowsInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/duplicateThrows/DuplicateThrowsInspection.java
index b01d105..b95c3c9 100644
--- a/java/java-impl/src/com/intellij/codeInspection/duplicateThrows/DuplicateThrowsInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/duplicateThrows/DuplicateThrowsInspection.java
@@ -16,11 +16,7 @@
package com.intellij.codeInspection.duplicateThrows;
import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInspection.DeleteThrowsFix;
-import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.ProblemHighlightType;
-import com.intellij.codeInspection.ProblemsHolder;
-import com.intellij.codeInspection.ex.BaseLocalInspectionTool;
+import com.intellij.codeInspection.*;
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
@@ -28,8 +24,7 @@
import javax.swing.*;
-public class DuplicateThrowsInspection extends BaseLocalInspectionTool {
-
+public class DuplicateThrowsInspection extends BaseJavaBatchLocalInspectionTool {
@SuppressWarnings("PublicField")
public boolean ignoreSubclassing = false;
@@ -94,4 +89,9 @@
}
};
}
+
+ @Override
+ public boolean isEnabledByDefault() {
+ return true;
+ }
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/ChangeSuperClassFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/ChangeSuperClassFix.java
new file mode 100644
index 0000000..eaab7a3
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/ChangeSuperClassFix.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2000-2013 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.inheritance;
+
+import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInsight.daemon.GroupNames;
+import com.intellij.codeInsight.intention.LowPriorityAction;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.TestOnly;
+
+/**
+ * @author Dmitry Batkovich <dmitry.batkovich@jetbrains.com>
+ */
+public class ChangeSuperClassFix implements LocalQuickFix {
+ @NotNull
+ private final PsiClass myNewSuperClass;
+ @NotNull
+ private final PsiClass myOldSuperClass;
+ private final int myPercent;
+
+ public ChangeSuperClassFix(@NotNull final PsiClass newSuperClass, final int percent, @NotNull final PsiClass oldSuperClass) {
+ myNewSuperClass = newSuperClass;
+ myOldSuperClass = oldSuperClass;
+ myPercent = percent;
+ }
+
+ @NotNull
+ @TestOnly
+ public PsiClass getNewSuperClass() {
+ return myNewSuperClass;
+ }
+
+ @TestOnly
+ public int getPercent() {
+ return myPercent;
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return String.format("Make extends '%s' - %s%%", myNewSuperClass.getQualifiedName(), myPercent);
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return GroupNames.INHERITANCE_GROUP_NAME;
+ }
+
+ @Override
+ public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor problemDescriptor) {
+ changeSuperClass((PsiClass)problemDescriptor.getPsiElement(), myOldSuperClass, myNewSuperClass);
+ }
+
+ /**
+ * myOldSuperClass and myNewSuperClass can be interfaces or classes in any combination
+ * <p/>
+ * 1. not checks that myOldSuperClass is really super of aClass
+ * 2. not checks that myNewSuperClass not exists in currently existed supers
+ */
+ private static void changeSuperClass(@NotNull final PsiClass aClass,
+ @NotNull final PsiClass oldSuperClass,
+ @NotNull final PsiClass newSuperClass) {
+ if (!FileModificationService.getInstance().preparePsiElementForWrite(aClass)) return;
+
+ if (!FileModificationService.getInstance().prepareFileForWrite(aClass.getContainingFile())) return;
+ CommandProcessor.getInstance().executeCommand(newSuperClass.getProject(), new Runnable() {
+ @Override
+ public void run() {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory();
+ if (aClass instanceof PsiAnonymousClass) {
+ ((PsiAnonymousClass)aClass).getBaseClassReference().replace(factory.createClassReferenceElement(newSuperClass));
+ }
+ else if (oldSuperClass.isInterface()) {
+ final PsiReferenceList interfaceList = aClass.getImplementsList();
+ if (interfaceList != null) {
+ for (final PsiJavaCodeReferenceElement interfaceRef : interfaceList.getReferenceElements()) {
+ final PsiElement aInterface = interfaceRef.resolve();
+ if (aInterface != null && aInterface.isEquivalentTo(oldSuperClass)) {
+ interfaceRef.delete();
+ }
+ }
+ }
+
+ final PsiReferenceList extendsList = aClass.getExtendsList();
+ if (extendsList != null) {
+ final PsiJavaCodeReferenceElement newClassReference = factory.createClassReferenceElement(newSuperClass);
+ if (extendsList.getReferenceElements().length == 0) {
+ extendsList.add(newClassReference);
+ }
+ }
+ }
+ else {
+ final PsiReferenceList extendsList = aClass.getExtendsList();
+ if (extendsList != null && extendsList.getReferenceElements().length == 1) {
+ extendsList.getReferenceElements()[0].delete();
+ PsiElement ref = extendsList.add(factory.createClassReferenceElement(newSuperClass));
+ JavaCodeStyleManager.getInstance(aClass.getProject()).shortenClassReferences(ref);
+ }
+ }
+ }
+ });
+ }
+ }, "Changing inheritance", null);
+ }
+
+ public static class LowPriority extends ChangeSuperClassFix implements LowPriorityAction {
+ public LowPriority(@NotNull final PsiClass newSuperClass, final int percent, @NotNull final PsiClass oldSuperClass) {
+ super(newSuperClass, percent, oldSuperClass);
+ }
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInspection/inheritance/SuperClassHasFrequentlyUsedInheritorsInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/SuperClassHasFrequentlyUsedInheritorsInspection.java
similarity index 91%
rename from java/java-impl/src/com/intellij/codeInspection/inheritance/SuperClassHasFrequentlyUsedInheritorsInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/SuperClassHasFrequentlyUsedInheritorsInspection.java
index aa3dd1e..03f5c4d 100644
--- a/java/java-impl/src/com/intellij/codeInspection/inheritance/SuperClassHasFrequentlyUsedInheritorsInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/SuperClassHasFrequentlyUsedInheritorsInspection.java
@@ -16,9 +16,9 @@
/**
* @author Dmitry Batkovich <dmitry.batkovich@jetbrains.com>
*/
-public class SuperClassHasFrequentlyUsedInheritorsInspection extends BaseJavaLocalInspectionTool {
- private final static int MIN_PERCENT_RATIO = 5;
- public final static int MAX_QUICK_FIX_COUNTS = 4;
+public class SuperClassHasFrequentlyUsedInheritorsInspection extends BaseJavaBatchLocalInspectionTool {
+ private static final int MIN_PERCENT_RATIO = 5;
+ public static final int MAX_QUICK_FIX_COUNTS = 4;
@Nls
@NotNull
@@ -36,7 +36,7 @@
@Override
public boolean isEnabledByDefault() {
- return true;
+ return false;
}
@Nullable
@@ -78,13 +78,13 @@
}
}
return new ProblemDescriptor[]{manager
- .createProblemDescriptor(aClass, "Class may extend a commonly used base class instead of implementing interface or extending abstract class", false,
+ .createProblemDescriptor(aClass, getDisplayName(), false,
topInheritorsQuickFix.toArray(new LocalQuickFix[topInheritorsQuickFix.size()]),
ProblemHighlightType.INFORMATION)};
}
@Nullable
- private static PsiClass getSuperIfUnique(final @NotNull PsiClass aClass) {
+ private static PsiClass getSuperIfUnique(@NotNull final PsiClass aClass) {
if (aClass instanceof PsiAnonymousClass) {
return (PsiClass)((PsiAnonymousClass)aClass).getBaseClassReference().resolve();
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsCountData.java b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsCountData.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsCountData.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsCountData.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsStatisticalDataSearch.java b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsStatisticalDataSearch.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsStatisticalDataSearch.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsStatisticalDataSearch.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsStatisticsSearchResult.java b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsStatisticsSearchResult.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsStatisticsSearchResult.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsStatisticsSearchResult.java
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/java15api/Java15APIUsageInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/java15api/Java15APIUsageInspection.java
index fabc58d..f63b2d8 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/java15api/Java15APIUsageInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/java15api/Java15APIUsageInspection.java
@@ -19,7 +19,9 @@
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.codeInspection.*;
+import com.intellij.ide.ui.ListCellRendererWrapper;
import com.intellij.openapi.extensions.ExtensionPoint;
+import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.EffectiveLanguageLevelUtil;
import com.intellij.openapi.module.Module;
@@ -34,7 +36,6 @@
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.reference.SoftReference;
-import com.intellij.ide.ui.ListCellRendererWrapper;
import com.intellij.util.ui.UIUtil;
import gnu.trove.THashSet;
import org.jdom.Element;
@@ -232,10 +233,11 @@
return ourPresentableShortMessage.get(languageLevel);
}
+ public static final ExtensionPointName<FileCheckingInspection> EP_NAME = ExtensionPointName.create(ToolExtensionPoints.JAVA15_INSPECTION_TOOL);
private class MyVisitor extends JavaElementVisitor {
private final ProblemsHolder myHolder;
private final boolean myOnTheFly;
- private final ExtensionPoint<FileCheckingInspection> point = Extensions.getRootArea().getExtensionPoint(ToolExtensionPoints.JAVA15_INSPECTION_TOOL);
+ private final ExtensionPoint<FileCheckingInspection> point = Extensions.getRootArea().getExtensionPoint(EP_NAME);
public MyVisitor(final ProblemsHolder holder, boolean onTheFly) {
myHolder = holder;
diff --git a/java/java-impl/src/com/intellij/codeInspection/nullable/AnnotateOverriddenMethodParameterFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/AnnotateOverriddenMethodParameterFix.java
similarity index 89%
rename from java/java-impl/src/com/intellij/codeInspection/nullable/AnnotateOverriddenMethodParameterFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/nullable/AnnotateOverriddenMethodParameterFix.java
index 56cd621..c1dbdbf 100644
--- a/java/java-impl/src/com/intellij/codeInspection/nullable/AnnotateOverriddenMethodParameterFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/AnnotateOverriddenMethodParameterFix.java
@@ -17,7 +17,7 @@
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.FileModificationService;
-import com.intellij.codeInsight.intention.AddAnnotationFix;
+import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
@@ -25,12 +25,13 @@
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiNameValuePair;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.psi.util.ClassUtil;
import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.util.ArrayUtil;
+import com.intellij.util.ArrayUtilRt;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
@@ -65,7 +66,7 @@
PsiMethod method = PsiTreeUtil.getParentOfType(parameter, PsiMethod.class);
if (method == null) return;
PsiParameter[] parameters = method.getParameterList().getParameters();
- int index = ArrayUtil.find(parameters, parameter);
+ int index = ArrayUtilRt.find(parameters, parameter);
List<PsiParameter> toAnnotate = new ArrayList<PsiParameter>();
@@ -84,7 +85,8 @@
try {
assert psiParam != null : toAnnotate;
if (AnnotationUtil.isAnnotatingApplicable(psiParam, myAnnotation)) {
- new AddAnnotationFix(myAnnotation, psiParam, myAnnosToRemove).invoke(project, null, psiParam.getContainingFile());
+ AddAnnotationPsiFix fix = new AddAnnotationPsiFix(myAnnotation, psiParam, PsiNameValuePair.EMPTY_ARRAY, myAnnosToRemove);
+ fix.invoke(project, psiParam.getContainingFile(), psiParam, psiParam);
}
}
catch (IncorrectOperationException e) {
diff --git a/java/java-impl/src/com/intellij/codeInspection/nullable/ChangeNullableDefaultsFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/ChangeNullableDefaultsFix.java
similarity index 98%
rename from java/java-impl/src/com/intellij/codeInspection/nullable/ChangeNullableDefaultsFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/nullable/ChangeNullableDefaultsFix.java
index 53b439f..aa3f0d0 100644
--- a/java/java-impl/src/com/intellij/codeInspection/nullable/ChangeNullableDefaultsFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/ChangeNullableDefaultsFix.java
@@ -59,7 +59,8 @@
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
if (myNotNullName != null) {
myManager.setDefaultNotNull(myNotNullName);
- } else {
+ }
+ else {
myManager.setDefaultNullable(myNullableName);
}
}
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
new file mode 100644
index 0000000..8014acd
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java
@@ -0,0 +1,469 @@
+/*
+ * Copyright 2000-2011 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.nullable;
+
+import com.intellij.codeInsight.AnnotationUtil;
+import com.intellij.codeInsight.NullableNotNullManager;
+import com.intellij.codeInsight.daemon.GroupNames;
+import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
+import com.intellij.codeInsight.intention.impl.AddNotNullAnnotationFix;
+import com.intellij.codeInspection.*;
+import com.intellij.codeInspection.dataFlow.DfaPsiUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import com.intellij.psi.codeStyle.VariableKind;
+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.*;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.List;
+
+public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionTool {
+ // deprecated fields remain to minimize changes to users inspection profiles (which are often located in version control).
+ @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NULLABLE_METHOD_OVERRIDES_NOTNULL = true;
+ @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL = true;
+ @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE = true;
+ @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL = true;
+ @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_GETTER = true;
+ @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_SETTER_PARAMETER = true;
+ @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = true; // remains for test
+ @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD = true;
+
+ private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.nullable.NullableStuffInspectionBase");
+
+ @Override
+ @NotNull
+ public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
+ return new JavaElementVisitor() {
+ @Override public void visitMethod(PsiMethod method) {
+ if (!PsiUtil.isLanguageLevel5OrHigher(method)) return;
+ checkNullableStuffForMethod(method, holder);
+ }
+
+ @Override public void visitField(PsiField field) {
+ if (!PsiUtil.isLanguageLevel5OrHigher(field)) return;
+ final PsiType type = field.getType();
+ final Annotated annotated = check(field, holder, type);
+ if (TypeConversionUtil.isPrimitiveAndNotNull(type)) {
+ return;
+ }
+ Project project = holder.getProject();
+ final NullableNotNullManager manager = NullableNotNullManager.getInstance(project);
+ if (annotated.isDeclaredNotNull ^ annotated.isDeclaredNullable) {
+ final String anno = annotated.isDeclaredNotNull ? manager.getDefaultNotNull() : manager.getDefaultNullable();
+ final List<String> annoToRemove = annotated.isDeclaredNotNull ? manager.getNullables() : manager.getNotNulls();
+
+ if (!AnnotationUtil.isAnnotatingApplicable(field, anno)) {
+ final PsiAnnotation notNull = AnnotationUtil.findAnnotation(field, manager.getNotNulls());
+ final PsiAnnotation nullable = AnnotationUtil.findAnnotation(field, manager.getNullables());
+ holder.registerProblem(field.getNameIdentifier(), "Nullable/NotNull defaults are not accessible in current context",
+ new ChangeNullableDefaultsFix(notNull, nullable, manager));
+ return;
+ }
+
+ 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 String nullableSimpleName = StringUtil.getShortName(manager.getDefaultNullable());
+ final String notNullSimpleName = StringUtil.getShortName(manager.getDefaultNotNull());
+ final PsiIdentifier nameIdentifier = getter == null ? null : getter.getNameIdentifier();
+ if (nameIdentifier != null && nameIdentifier.isPhysical()) {
+ if (PropertyUtil.isSimpleGetter(getter)) {
+ AnnotateMethodFix getterAnnoFix = new AnnotateMethodFix(anno, ArrayUtil.toStringArray(annoToRemove)) {
+ @Override
+ public int shouldAnnotateBaseMethod(PsiMethod method, PsiMethod superMethod, Project project) {
+ return 1;
+ }
+ };
+ if (REPORT_NOT_ANNOTATED_GETTER) {
+ if (!AnnotationUtil.isAnnotated(getter, manager.getAllAnnotations(), false, false) &&
+ !TypeConversionUtil.isPrimitiveAndNotNull(getter.getReturnType())) {
+ holder.registerProblem(nameIdentifier, InspectionsBundle
+ .message("inspection.nullable.problems.annotated.field.getter.not.annotated", StringUtil.getShortName(anno)),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING, getterAnnoFix);
+ }
+ }
+ if (annotated.isDeclaredNotNull && manager.isNullable(getter, false)) {
+ holder.registerProblem(nameIdentifier, InspectionsBundle.message(
+ "inspection.nullable.problems.annotated.field.getter.conflict", StringUtil.getShortName(anno), nullableSimpleName),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING, getterAnnoFix);
+ } else if (annotated.isDeclaredNullable && manager.isNotNull(getter, false)) {
+ holder.registerProblem(nameIdentifier, InspectionsBundle.message(
+ "inspection.nullable.problems.annotated.field.getter.conflict", StringUtil.getShortName(anno), notNullSimpleName),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING, getterAnnoFix);
+ }
+ }
+ }
+
+ final PsiClass containingClass = field.getContainingClass();
+ final PsiMethod setter = PropertyUtil.findPropertySetter(containingClass, propName, isStatic, false);
+ if (setter != null) {
+ final PsiParameter[] parameters = setter.getParameterList().getParameters();
+ assert parameters.length == 1 : setter.getText();
+ final PsiParameter parameter = parameters[0];
+ LOG.assertTrue(parameter != null, setter.getText());
+ AddAnnotationPsiFix addAnnoFix = new AddAnnotationPsiFix(anno, parameter, PsiNameValuePair.EMPTY_ARRAY, ArrayUtil.toStringArray(annoToRemove));
+ if (REPORT_NOT_ANNOTATED_GETTER && !AnnotationUtil.isAnnotated(parameter, manager.getAllAnnotations(), false, false) && !TypeConversionUtil.isPrimitiveAndNotNull(parameter.getType())) {
+ final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
+ assertValidElement(setter, parameter, nameIdentifier1);
+ holder.registerProblem(nameIdentifier1,
+ InspectionsBundle.message("inspection.nullable.problems.annotated.field.setter.parameter.not.annotated",
+ StringUtil.getShortName(anno)),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+ addAnnoFix);
+ }
+ if (PropertyUtil.isSimpleSetter(setter)) {
+ if (annotated.isDeclaredNotNull && manager.isNullable(parameter, false)) {
+ final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
+ assertValidElement(setter, parameter, nameIdentifier1);
+ holder.registerProblem(nameIdentifier1, InspectionsBundle.message(
+ "inspection.nullable.problems.annotated.field.setter.parameter.conflict",
+ StringUtil.getShortName(anno), nullableSimpleName),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+ addAnnoFix);
+ }
+ else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) {
+ final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
+ assertValidElement(setter, parameter, nameIdentifier1);
+ holder.registerProblem(nameIdentifier1, InspectionsBundle.message(
+ "inspection.nullable.problems.annotated.field.setter.parameter.conflict", StringUtil.getShortName(anno), notNullSimpleName),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+ addAnnoFix);
+ }
+ }
+ }
+
+ for (PsiExpression rhs : DfaPsiUtil.findAllConstructorInitializers(field)) {
+ if (rhs instanceof PsiReferenceExpression) {
+ PsiElement target = ((PsiReferenceExpression)rhs).resolve();
+ if (target instanceof PsiParameter) {
+ PsiParameter parameter = (PsiParameter)target;
+ AddAnnotationPsiFix fix = new AddAnnotationPsiFix(anno, parameter, PsiNameValuePair.EMPTY_ARRAY, ArrayUtil.toStringArray(annoToRemove));
+ if (REPORT_NOT_ANNOTATED_GETTER && !AnnotationUtil.isAnnotated(parameter, manager.getAllAnnotations(), false, false) && !TypeConversionUtil.isPrimitiveAndNotNull(parameter.getType())) {
+ final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier();
+ assert nameIdentifier2 != null : parameter;
+ holder.registerProblem(nameIdentifier2, InspectionsBundle
+ .message("inspection.nullable.problems.annotated.field.constructor.parameter.not.annotated",
+ StringUtil.getShortName(anno)),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING, fix);
+ continue;
+ }
+ if (annotated.isDeclaredNotNull && manager.isNullable(parameter, false)) {
+ final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier();
+ assert nameIdentifier2 != null : parameter;
+ holder.registerProblem(nameIdentifier2, InspectionsBundle.message(
+ "inspection.nullable.problems.annotated.field.constructor.parameter.conflict", StringUtil.getShortName(anno),
+ nullableSimpleName),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+ fix);
+ }
+ else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) {
+ boolean usedAsQualifier = !ReferencesSearch.search(parameter).forEach(new Processor<PsiReference>() {
+ @Override
+ public boolean process(PsiReference reference) {
+ final PsiElement element = reference.getElement();
+ return !(element instanceof PsiReferenceExpression && element.getParent() instanceof PsiReferenceExpression);
+ }
+ });
+ if (!usedAsQualifier) {
+ final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier();
+ assert nameIdentifier2 != null : parameter;
+ holder.registerProblem(nameIdentifier2, InspectionsBundle.message(
+ "inspection.nullable.problems.annotated.field.constructor.parameter.conflict", StringUtil.getShortName(anno),
+ notNullSimpleName),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+ fix);
+ }
+ }
+
+ }
+ }
+ }
+ }
+ }
+
+ private void assertValidElement(PsiMethod setter, PsiParameter parameter, PsiIdentifier nameIdentifier1) {
+ LOG.assertTrue(nameIdentifier1 != null && nameIdentifier1.isPhysical(), setter.getText());
+ LOG.assertTrue(parameter.isPhysical(), setter.getText());
+ }
+
+ @Override public void visitParameter(PsiParameter parameter) {
+ if (!PsiUtil.isLanguageLevel5OrHigher(parameter)) return;
+ check(parameter, holder, parameter.getType());
+ }
+ };
+ }
+
+ private static class Annotated {
+ private final boolean isDeclaredNotNull;
+ private final boolean isDeclaredNullable;
+
+ private Annotated(final boolean isDeclaredNotNull, final boolean isDeclaredNullable) {
+ this.isDeclaredNotNull = isDeclaredNotNull;
+ this.isDeclaredNullable = isDeclaredNullable;
+ }
+ }
+ private static Annotated check(final PsiModifierListOwner parameter, final ProblemsHolder holder, PsiType type) {
+ final NullableNotNullManager manager = NullableNotNullManager.getInstance(holder.getProject());
+ PsiAnnotation isDeclaredNotNull = AnnotationUtil.findAnnotation(parameter, manager.getNotNulls());
+ PsiAnnotation isDeclaredNullable = AnnotationUtil.findAnnotation(parameter, manager.getNullables());
+ if (isDeclaredNullable != null && isDeclaredNotNull != null) {
+ reportNullableNotNullConflict(holder, parameter, isDeclaredNullable, isDeclaredNotNull);
+ }
+ if ((isDeclaredNotNull != null || isDeclaredNullable != null) && type != null && TypeConversionUtil.isPrimitive(type.getCanonicalText())) {
+ PsiAnnotation annotation = isDeclaredNotNull == null ? isDeclaredNullable : isDeclaredNotNull;
+ reportPrimitiveType(holder, annotation, annotation, parameter);
+ }
+ return new Annotated(isDeclaredNotNull != null,isDeclaredNullable != null);
+ }
+
+ private static void reportPrimitiveType(final ProblemsHolder holder, final PsiElement psiElement, final PsiAnnotation annotation,
+ final PsiModifierListOwner listOwner) {
+ holder.registerProblem(psiElement.isPhysical() ? psiElement : listOwner.getNavigationElement(),
+ InspectionsBundle.message("inspection.nullable.problems.primitive.type.annotation"),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new RemoveAnnotationQuickFix(annotation, listOwner));
+ }
+
+ @Override
+ @NotNull
+ public String getDisplayName() {
+ return InspectionsBundle.message("inspection.nullable.problems.display.name");
+ }
+
+ @Override
+ @NotNull
+ public String getGroupDisplayName() {
+ return GroupNames.BUGS_GROUP_NAME;
+ }
+
+ @Override
+ @NotNull
+ public String getShortName() {
+ return "NullableProblems";
+ }
+
+ private void checkNullableStuffForMethod(PsiMethod method, final ProblemsHolder holder) {
+ Annotated annotated = check(method, holder, method.getReturnType());
+
+ PsiParameter[] parameters = method.getParameterList().getParameters();
+
+ List<MethodSignatureBackedByPsiMethod> superMethodSignatures = method.findSuperMethodSignaturesIncludingStatic(true);
+ boolean reported_not_annotated_method_overrides_notnull = false;
+ boolean reported_nullable_method_overrides_notnull = false;
+ boolean[] reported_notnull_parameter_overrides_nullable = new boolean[parameters.length];
+ boolean[] reported_not_annotated_parameter_overrides_notnull = new boolean[parameters.length];
+
+ final NullableNotNullManager nullableManager = NullableNotNullManager.getInstance(holder.getProject());
+ for (MethodSignatureBackedByPsiMethod superMethodSignature : superMethodSignatures) {
+ PsiMethod superMethod = superMethodSignature.getMethod();
+ if (!reported_nullable_method_overrides_notnull
+ && REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE
+ && annotated.isDeclaredNullable
+ && NullableNotNullManager.isNotNull(superMethod)) {
+ reported_nullable_method_overrides_notnull = true;
+ holder.registerProblem(method.getNameIdentifier(),
+ InspectionsBundle.message("inspection.nullable.problems.Nullable.method.overrides.NotNull"),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
+ }
+ if (!reported_not_annotated_method_overrides_notnull
+ && REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL
+ && !annotated.isDeclaredNullable
+ && !annotated.isDeclaredNotNull
+ && NullableNotNullManager.isNotNull(superMethod)) {
+ reported_not_annotated_method_overrides_notnull = true;
+ final String defaultNotNull = nullableManager.getDefaultNotNull();
+ final String[] annotationsToRemove = ArrayUtil.toStringArray(nullableManager.getNullables());
+ final LocalQuickFix fix = AnnotationUtil.isAnnotatingApplicable(method, defaultNotNull)
+ ? createAnnotateMethodFix(defaultNotNull, annotationsToRemove)
+ : createChangeDefaultNotNullFix(nullableManager, superMethod);
+ holder.registerProblem(method.getNameIdentifier(),
+ InspectionsBundle.message("inspection.nullable.problems.method.overrides.NotNull"),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+ wrapFix(fix));
+ }
+ if (REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE || REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL) {
+ PsiParameter[] superParameters = superMethod.getParameterList().getParameters();
+ if (superParameters.length != parameters.length) {
+ continue;
+ }
+ for (int i = 0; i < parameters.length; i++) {
+ PsiParameter parameter = parameters[i];
+ PsiParameter superParameter = superParameters[i];
+ if (!reported_notnull_parameter_overrides_nullable[i] && REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE &&
+ nullableManager.isNotNull(parameter, false) &&
+ nullableManager.isNullable(superParameter, false)) {
+ reported_notnull_parameter_overrides_nullable[i] = true;
+ holder.registerProblem(parameter.getNameIdentifier(),
+ InspectionsBundle.message("inspection.nullable.problems.NotNull.parameter.overrides.Nullable"),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
+ }
+ if (!reported_not_annotated_parameter_overrides_notnull[i] && REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL) {
+ if (!AnnotationUtil.isAnnotated(parameter, nullableManager.getAllAnnotations(), false, false) &&
+ nullableManager.isNotNull(superParameter, false)) {
+ reported_not_annotated_parameter_overrides_notnull[i] = true;
+ final LocalQuickFix fix = AnnotationUtil.isAnnotatingApplicable(parameter, nullableManager.getDefaultNotNull())
+ ? new AddNotNullAnnotationFix(parameter)
+ : createChangeDefaultNotNullFix(nullableManager, superParameter);
+ holder.registerProblem(parameter.getNameIdentifier(),
+ InspectionsBundle.message("inspection.nullable.problems.parameter.overrides.NotNull"),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+ wrapFix(fix));
+ }
+ }
+ }
+ }
+ }
+
+ if (REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS) {
+ boolean[] parameterAnnotated = new boolean[parameters.length];
+ boolean[] parameterQuickFixSuggested = new boolean[parameters.length];
+ boolean hasAnnotatedParameter = false;
+ for (int i = 0; i < parameters.length; i++) {
+ PsiParameter parameter = parameters[i];
+ parameterAnnotated[i] = nullableManager.isNotNull(parameter, false);
+ hasAnnotatedParameter |= parameterAnnotated[i];
+ }
+ if (hasAnnotatedParameter || annotated.isDeclaredNotNull) {
+ PsiManager manager = method.getManager();
+ final String defaultNotNull = nullableManager.getDefaultNotNull();
+ final boolean superMethodApplicable = AnnotationUtil.isAnnotatingApplicable(method, defaultNotNull);
+ PsiMethod[] overridings =
+ OverridingMethodsSearch.search(method, GlobalSearchScope.allScope(manager.getProject()), true).toArray(PsiMethod.EMPTY_ARRAY);
+ boolean methodQuickFixSuggested = false;
+ for (PsiMethod overriding : overridings) {
+ if (!manager.isInProject(overriding)) continue;
+
+ final boolean applicable = AnnotationUtil.isAnnotatingApplicable(overriding, defaultNotNull);
+ if (!methodQuickFixSuggested
+ && annotated.isDeclaredNotNull
+ && !nullableManager.isNotNull(overriding, false)
+ && (nullableManager.isNullable(overriding, false) || !nullableManager.isNullable(overriding, true))) {
+ method.getNameIdentifier(); //load tree
+ PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, nullableManager.getNotNulls());
+ final String[] annotationsToRemove = ArrayUtil.toStringArray(nullableManager.getNullables());
+
+ final LocalQuickFix fix;
+ if (applicable) {
+ fix = new MyAnnotateMethodFix(defaultNotNull, annotationsToRemove);
+ }
+ else {
+ fix = superMethodApplicable ? null : createChangeDefaultNotNullFix(nullableManager, method);
+ }
+
+ PsiElement psiElement = annotation;
+ if (!annotation.isPhysical()) {
+ psiElement = method.getNameIdentifier();
+ if (psiElement == null) continue;
+ }
+ holder.registerProblem(psiElement, InspectionsBundle.message("nullable.stuff.problems.overridden.methods.are.not.annotated"),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+ wrapFix(fix));
+ methodQuickFixSuggested = true;
+ }
+ if (hasAnnotatedParameter) {
+ PsiParameter[] psiParameters = overriding.getParameterList().getParameters();
+ for (int i = 0; i < psiParameters.length; i++) {
+ if (parameterQuickFixSuggested[i]) continue;
+ PsiParameter parameter = psiParameters[i];
+ if (parameterAnnotated[i] && !nullableManager.isNotNull(parameter, false) && !nullableManager.isNullable(parameter, false)) {
+ parameters[i].getNameIdentifier(); //be sure that corresponding tree element available
+ PsiAnnotation annotation = AnnotationUtil.findAnnotation(parameters[i], nullableManager.getNotNulls());
+ PsiElement psiElement = annotation;
+ if (!annotation.isPhysical()) {
+ psiElement = parameters[i].getNameIdentifier();
+ if (psiElement == null) continue;
+ }
+ holder.registerProblem(psiElement,
+ InspectionsBundle.message("nullable.stuff.problems.overridden.method.parameters.are.not.annotated"),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+ wrapFix(!applicable
+ ? createChangeDefaultNotNullFix(nullableManager, parameters[i])
+ : new AnnotateOverriddenMethodParameterFix(defaultNotNull,
+ nullableManager.getDefaultNullable())));
+ parameterQuickFixSuggested[i] = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private static LocalQuickFix[] wrapFix(LocalQuickFix fix) {
+ if (fix == null) return LocalQuickFix.EMPTY_ARRAY;
+ return new LocalQuickFix[]{fix};
+ }
+
+ private static LocalQuickFix createChangeDefaultNotNullFix(NullableNotNullManager nullableManager, PsiModifierListOwner modifierListOwner) {
+ final PsiAnnotation annotation = AnnotationUtil.findAnnotation(modifierListOwner, nullableManager.getNotNulls());
+ if (annotation != null) {
+ final PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement();
+ if (referenceElement != null && referenceElement.resolve() != null) {
+ return new ChangeNullableDefaultsFix(annotation.getQualifiedName(), null, nullableManager);
+ }
+ }
+ return null;
+ }
+
+ protected AnnotateMethodFix createAnnotateMethodFix(final String defaultNotNull, final String[] annotationsToRemove) {
+ return new AnnotateMethodFix(defaultNotNull, annotationsToRemove);
+ }
+
+ private static void reportNullableNotNullConflict(final ProblemsHolder holder, final PsiModifierListOwner listOwner, final PsiAnnotation declaredNullable,
+ final PsiAnnotation declaredNotNull) {
+ holder.registerProblem(declaredNotNull.isPhysical() ? declaredNotNull : listOwner.getNavigationElement(),
+ InspectionsBundle.message("inspection.nullable.problems.Nullable.NotNull.conflict"),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new RemoveAnnotationQuickFix(declaredNotNull, listOwner));
+ holder.registerProblem(declaredNullable.isPhysical() ? declaredNullable : listOwner.getNavigationElement(),
+ InspectionsBundle.message("inspection.nullable.problems.Nullable.NotNull.conflict"),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new RemoveAnnotationQuickFix(declaredNullable, listOwner));
+ }
+
+ @Override
+ public JComponent createOptionsPanel() {
+ throw new RuntimeException("No UI in headless mode");
+ }
+
+ private static class MyAnnotateMethodFix extends AnnotateMethodFix {
+ public MyAnnotateMethodFix(String defaultNotNull, String[] annotationsToRemove) {
+ super(defaultNotNull, annotationsToRemove);
+ }
+
+ @Override
+ protected boolean annotateOverriddenMethods() {
+ return true;
+ }
+
+ @Override
+ public int shouldAnnotateBaseMethod(PsiMethod method, PsiMethod superMethod, Project project) {
+ return 1;
+ }
+
+ @Override
+ @NotNull
+ public String getName() {
+ return InspectionsBundle.message("annotate.overridden.methods.as.notnull", ClassUtil.extractClassName(myAnnotation));
+ }
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInspection/sillyAssignment/SillyAssignmentInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/sillyAssignment/SillyAssignmentInspection.java
similarity index 95%
rename from java/java-impl/src/com/intellij/codeInspection/sillyAssignment/SillyAssignmentInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/sillyAssignment/SillyAssignmentInspection.java
index bc9c679..3135f48 100644
--- a/java/java-impl/src/com/intellij/codeInspection/sillyAssignment/SillyAssignmentInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/sillyAssignment/SillyAssignmentInspection.java
@@ -15,10 +15,7 @@
*/
package com.intellij.codeInspection.sillyAssignment;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
-import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.ProblemHighlightType;
-import com.intellij.codeInspection.ProblemsHolder;
+import com.intellij.codeInspection.*;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
@@ -31,7 +28,7 @@
* User: anna
* Date: 15-Nov-2005
*/
-public class SillyAssignmentInspection extends BaseJavaLocalInspectionTool {
+public class SillyAssignmentInspection extends BaseJavaBatchLocalInspectionTool {
@Override
@NotNull
public String getGroupDisplayName() {
@@ -164,7 +161,8 @@
}
}
return thisQualifier;
- } else if (qualifier != null) {
+ }
+ if (qualifier != null) {
return ((PsiSuperExpression)qualifier).getQualifier();
}
return null;
diff --git a/java/java-impl/src/com/intellij/codeInspection/testOnly/TestOnlyInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/testOnly/TestOnlyInspection.java
similarity index 69%
rename from java/java-impl/src/com/intellij/codeInspection/testOnly/TestOnlyInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/testOnly/TestOnlyInspection.java
index 20f1ea6..9f69dda 100644
--- a/java/java-impl/src/com/intellij/codeInspection/testOnly/TestOnlyInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/testOnly/TestOnlyInspection.java
@@ -17,10 +17,7 @@
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.TestFrameworks;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
-import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.ProblemHighlightType;
-import com.intellij.codeInspection.ProblemsHolder;
+import com.intellij.codeInspection.*;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
@@ -28,7 +25,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public class TestOnlyInspection extends BaseJavaLocalInspectionTool {
+public class TestOnlyInspection extends BaseJavaBatchLocalInspectionTool {
@Override
@NotNull
public String getDisplayName() {
@@ -57,7 +54,7 @@
};
}
- private void validate(PsiCallExpression e, ProblemsHolder h) {
+ private static void validate(PsiCallExpression e, ProblemsHolder h) {
if (!isTestOnlyMethodCalled(e)) return;
if (isInsideTestOnlyMethod(e)) return;
if (isInsideTestClass(e)) return;
@@ -66,28 +63,27 @@
reportProblem(e, h);
}
- private boolean isTestOnlyMethodCalled(PsiCallExpression e) {
+ private static boolean isTestOnlyMethodCalled(PsiCallExpression e) {
return isAnnotatedAsTestOnly(e.resolveMethod());
}
- private boolean isInsideTestOnlyMethod(PsiCallExpression e) {
+ private static boolean isInsideTestOnlyMethod(PsiCallExpression e) {
PsiMethod m = getTopLevelParentOfType(e, PsiMethod.class);
return isAnnotatedAsTestOnly(m);
}
private static boolean isAnnotatedAsTestOnly(@Nullable PsiMethod m) {
- if (m == null) return false;
- return AnnotationUtil.isAnnotated(m, AnnotationUtil.TEST_ONLY, false, false) ||
- AnnotationUtil.isAnnotated(m, "com.google.common.annotations.VisibleForTesting", false, false);
+ return m != null &&
+ (AnnotationUtil.isAnnotated(m, AnnotationUtil.TEST_ONLY, false, false) ||
+ AnnotationUtil.isAnnotated(m, "com.google.common.annotations.VisibleForTesting", false, false));
}
- private boolean isInsideTestClass(PsiCallExpression e) {
+ private static boolean isInsideTestClass(PsiCallExpression e) {
PsiClass c = getTopLevelParentOfType(e, PsiClass.class);
- if (c == null) return false;
- return TestFrameworks.getInstance().isTestClass(c);
+ return c != null && TestFrameworks.getInstance().isTestClass(c);
}
- private <T extends PsiElement> T getTopLevelParentOfType(PsiElement e, Class<T> c) {
+ private static <T extends PsiElement> T getTopLevelParentOfType(PsiElement e, Class<T> c) {
T parent = PsiTreeUtil.getParentOfType(e, c);
if (parent == null) return null;
@@ -99,14 +95,13 @@
while (true);
}
- private boolean isUnderTestSources(PsiCallExpression e) {
+ private static boolean isUnderTestSources(PsiCallExpression e) {
ProjectRootManager rm = ProjectRootManager.getInstance(e.getProject());
VirtualFile f = e.getContainingFile().getVirtualFile();
- if (f == null) return false;
- return rm.getFileIndex().isInTestSourceContent(f);
+ return f != null && rm.getFileIndex().isInTestSourceContent(f);
}
- private void reportProblem(PsiCallExpression e, ProblemsHolder h) {
+ private static void reportProblem(PsiCallExpression e, ProblemsHolder h) {
String message = InspectionsBundle.message("inspection.test.only.problems.test.only.method.call");
h.registerProblem(e, message, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/unneededThrows/RedundantThrowsDeclaration.java b/java/java-analysis-impl/src/com/intellij/codeInspection/unneededThrows/RedundantThrowsDeclaration.java
similarity index 92%
rename from java/java-impl/src/com/intellij/codeInspection/unneededThrows/RedundantThrowsDeclaration.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/unneededThrows/RedundantThrowsDeclaration.java
index 4c56961..61b501c 100644
--- a/java/java-impl/src/com/intellij/codeInspection/unneededThrows/RedundantThrowsDeclaration.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/unneededThrows/RedundantThrowsDeclaration.java
@@ -18,8 +18,7 @@
import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.codeInsight.daemon.JavaErrorMessages;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightMethodUtil;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.codeInspection.*;
import com.intellij.psi.*;
import org.jetbrains.annotations.NonNls;
@@ -34,7 +33,7 @@
* @author anna
* @since 15-Nov-2005
*/
-public class RedundantThrowsDeclaration extends BaseJavaLocalInspectionTool {
+public class RedundantThrowsDeclaration extends BaseJavaBatchLocalInspectionTool {
@Override
@NotNull
public String getGroupDisplayName() {
@@ -118,9 +117,9 @@
}
}
- if (HighlightMethodUtil.isSerializationRelatedMethod(method, containingClass)) return null;
+ if (JavaHighlightUtil.isSerializationRelatedMethod(method, containingClass)) return null;
- String description = JavaErrorMessages.message("exception.is.never.thrown", HighlightUtil.formatType(exceptionType));
+ String description = JavaErrorMessages.message("exception.is.never.thrown", JavaHighlightUtil.formatType(exceptionType));
LocalQuickFix quickFixes = new DeleteThrowsFix(method, exceptionType);
return inspectionManager.createProblemDescriptor(referenceElement, description, quickFixes, ProblemHighlightType.LIKE_UNUSED_SYMBOL, onTheFly);
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/util/ChangeToAppendUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/util/ChangeToAppendUtil.java
new file mode 100644
index 0000000..3b2f747
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/util/ChangeToAppendUtil.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2000-2013 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.util;
+
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+public class ChangeToAppendUtil {
+ @Nullable
+ public static PsiExpression buildAppendExpression(PsiExpression appendable, PsiExpression concatenation) {
+ if (concatenation == null) return null;
+ final PsiType type = appendable.getType();
+ if (type == null) return null;
+ final StringBuilder result =
+ buildAppendExpression(concatenation, type.equalsToText("java.lang.Appendable"), new StringBuilder(appendable.getText()));
+ if (result == null) return null;
+ final PsiElementFactory factory = JavaPsiFacade.getElementFactory(appendable.getProject());
+ return factory.createExpressionFromText(result.toString(), appendable);
+ }
+
+ @Nullable
+ public static StringBuilder buildAppendExpression(PsiExpression concatenation, boolean useStringValueOf, @NonNls StringBuilder out)
+ throws IncorrectOperationException {
+ final PsiType type = concatenation.getType();
+ if (type == null) {
+ return null;
+ }
+ if (concatenation instanceof PsiPolyadicExpression && type.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
+ PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)concatenation;
+ final PsiExpression[] operands = polyadicExpression.getOperands();
+ boolean isConstant = true;
+ boolean isString = false;
+ final StringBuilder builder = new StringBuilder();
+ for (PsiExpression operand : operands) {
+ if (isConstant && PsiUtil.isConstantExpression(operand)) {
+ if (builder.length() != 0) {
+ builder.append('+');
+ }
+ final PsiType operandType = operand.getType();
+ if (operandType != null && operandType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
+ isString = true;
+ }
+ builder.append(operand.getText());
+ }
+ else {
+ isConstant = false;
+ if (builder.length() != 0) {
+ append(builder, useStringValueOf && !isString, out);
+ builder.setLength(0);
+ }
+ buildAppendExpression(operand, useStringValueOf, out);
+ }
+ }
+ if (builder.length() != 0) {
+ append(builder, false, out);
+ }
+ }
+ else if (concatenation instanceof PsiParenthesizedExpression) {
+ final PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression)concatenation;
+ final PsiExpression expression = parenthesizedExpression.getExpression();
+ if (expression != null) {
+ return buildAppendExpression(expression, useStringValueOf, out);
+ }
+ }
+ else {
+ append(concatenation.getText(), useStringValueOf && !type.equalsToText(CommonClassNames.JAVA_LANG_STRING), out);
+ }
+ return out;
+ }
+
+ private static void append(CharSequence text, boolean useStringValueOf, StringBuilder out) {
+ out.append(".append(");
+ if (useStringValueOf) {
+ out.append("String.valueOf(").append(text).append(')');
+ }
+ else {
+ out.append(text);
+ }
+ out.append(')');
+ }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/util/SpecialAnnotationsUtilBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/util/SpecialAnnotationsUtilBase.java
new file mode 100644
index 0000000..ebe8490
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/util/SpecialAnnotationsUtilBase.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2000-2013 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.util;
+
+import com.intellij.codeInsight.AnnotationUtil;
+import com.intellij.codeInspection.InspectionProfile;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.profile.codeInspection.InspectionProfileManager;
+import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
+import com.intellij.psi.PsiAnnotation;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiModifierList;
+import com.intellij.psi.PsiModifierListOwner;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.List;
+
+public class SpecialAnnotationsUtilBase {
+ public static LocalQuickFix createAddToSpecialAnnotationsListQuickFix(@NotNull final String text,
+ @NotNull final String family,
+ @NotNull final List<String> targetList,
+ @NotNull final String qualifiedName,
+ final PsiElement context) {
+ return new LocalQuickFix() {
+ @Override
+ @NotNull
+ public String getName() {
+ return text;
+ }
+
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return family;
+ }
+
+ @Override
+ public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
+ doQuickFixInternal(project, targetList, qualifiedName);
+ }
+ };
+ }
+
+ static void doQuickFixInternal(@NotNull Project project, @NotNull List<String> targetList, @NotNull String qualifiedName) {
+ targetList.add(qualifiedName);
+ Collections.sort(targetList);
+ final InspectionProfile inspectionProfile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
+ //correct save settings
+
+ //TODO lesya
+ InspectionProfileManager.getInstance().fireProfileChanged(inspectionProfile);
+ /*
+ try {
+ inspectionProfile.save();
+ }
+ catch (IOException e) {
+ Messages.showErrorDialog(project, e.getMessage(), CommonBundle.getErrorTitle());
+ }
+
+ */
+ }
+
+ public static void createAddToSpecialAnnotationFixes(@NotNull PsiModifierListOwner owner, @NotNull Processor<String> processor) {
+ final PsiModifierList modifierList = owner.getModifierList();
+ if (modifierList != null) {
+ final PsiAnnotation[] psiAnnotations = modifierList.getAnnotations();
+ for (PsiAnnotation psiAnnotation : psiAnnotations) {
+ @NonNls final String name = psiAnnotation.getQualifiedName();
+ if (name == null) continue;
+ if (name.startsWith("java.") || name.startsWith("javax.") ||
+ name.startsWith("org.jetbrains.") && AnnotationUtil.isJetbrainsAnnotation(StringUtil.getShortName(name))) continue;
+ if (!processor.process(name)) break;
+ }
+ }
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInspection/wrongPackageStatement/AdjustPackageNameFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/wrongPackageStatement/AdjustPackageNameFix.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/wrongPackageStatement/AdjustPackageNameFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/wrongPackageStatement/AdjustPackageNameFix.java
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspectionBase.java
new file mode 100644
index 0000000..8efcc45
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspectionBase.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2000-2009 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.wrongPackageStatement;
+
+import com.intellij.codeHighlighting.HighlightDisplayLevel;
+import com.intellij.codeInsight.daemon.JavaErrorMessages;
+import com.intellij.codeInspection.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiUtilCore;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * User: anna
+ * Date: 14-Nov-2005
+ */
+public class WrongPackageStatementInspectionBase extends BaseJavaBatchLocalInspectionTool {
+ @Override
+ @Nullable
+ public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
+ // does not work in tests since CodeInsightTestCase copies file into temporary location
+ if (ApplicationManager.getApplication().isUnitTestMode()) return null;
+ if (file instanceof PsiJavaFile) {
+ if (isInJsp(file)) return null;
+ PsiJavaFile javaFile = (PsiJavaFile)file;
+
+ PsiDirectory directory = javaFile.getContainingDirectory();
+ if (directory == null) return null;
+ PsiPackage dirPackage = JavaDirectoryService.getInstance().getPackage(directory);
+ if (dirPackage == null) return null;
+ PsiPackageStatement packageStatement = javaFile.getPackageStatement();
+
+ // highlight the first class in the file only
+ PsiClass[] classes = javaFile.getClasses();
+ if (classes.length == 0 && packageStatement == null) return null;
+
+ String packageName = dirPackage.getQualifiedName();
+ if (!Comparing.strEqual(packageName, "", true) && packageStatement == null) {
+ String description = JavaErrorMessages.message("missing.package.statement", packageName);
+
+ return new ProblemDescriptor[]{manager.createProblemDescriptor(classes[0].getNameIdentifier(), description,
+ new AdjustPackageNameFix(packageName),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING, isOnTheFly)};
+ }
+ if (packageStatement != null) {
+ final PsiJavaCodeReferenceElement packageReference = packageStatement.getPackageReference();
+ PsiPackage classPackage = (PsiPackage)packageReference.resolve();
+ List<LocalQuickFix> availableFixes = new ArrayList<LocalQuickFix>();
+ if (classPackage == null || !Comparing.equal(dirPackage.getQualifiedName(), packageReference.getQualifiedName(), true)) {
+ availableFixes.add(new AdjustPackageNameFix(packageName));
+ String packName = classPackage != null ? classPackage.getQualifiedName() : packageReference.getQualifiedName();
+ addMoveToPackageFix(file, packName, availableFixes);
+ }
+ if (!availableFixes.isEmpty()){
+ String description = JavaErrorMessages.message("package.name.file.path.mismatch",
+ packageReference.getQualifiedName(),
+ dirPackage.getQualifiedName());
+ LocalQuickFix[] fixes = availableFixes.toArray(new LocalQuickFix[availableFixes.size()]);
+ ProblemDescriptor descriptor =
+ manager.createProblemDescriptor(packageStatement.getPackageReference(), description, isOnTheFly,
+ fixes, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
+ return new ProblemDescriptor[]{descriptor};
+
+ }
+ }
+ }
+ return null;
+ }
+
+ private static boolean isInJsp(PsiFile file) {
+ return PsiUtilCore.getTemplateLanguageFile(file) instanceof ServerPageFile;
+ }
+
+ protected void addMoveToPackageFix(PsiFile file, String packName, List<LocalQuickFix> availableFixes) {
+ }
+
+ @Override
+ @NotNull
+ public String getGroupDisplayName() {
+ return "";
+ }
+
+ @Override
+ @NotNull
+ public HighlightDisplayLevel getDefaultLevel() {
+ return HighlightDisplayLevel.ERROR;
+ }
+
+ @Override
+ @NotNull
+ public String getDisplayName() {
+ return InspectionsBundle.message("wrong.package.statement");
+ }
+
+ @Override
+ @NotNull
+ @NonNls
+ public String getShortName() {
+ return "WrongPackageStatement";
+ }
+
+ @Override
+ public boolean isEnabledByDefault() {
+ return true;
+ }
+}
diff --git a/java/java-impl/java-impl.iml b/java/java-impl/java-impl.iml
index b305503..b7b5d03 100644
--- a/java/java-impl/java-impl.iml
+++ b/java/java-impl/java-impl.iml
@@ -33,6 +33,7 @@
<orderEntry type="module" module-name="java-indexing-api" />
<orderEntry type="module" module-name="jps-model-impl" />
<orderEntry type="module" module-name="java-analysis-impl" exported="" />
+ <orderEntry type="module" module-name="external-system-api" />
</component>
<component name="copyright">
<Base>
diff --git a/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java b/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java
index 50f48cb..0cb53dd 100644
--- a/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java
@@ -30,7 +30,6 @@
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.PsiDiamondTypeElementImpl;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.tree.IElementType;
@@ -81,7 +80,7 @@
}
public static <T extends PsiElement> T findElementInRange(PsiFile file, int startOffset, int endOffset, Class<T> klass) {
- return CodeInsightUtilBase.findElementInRange(file, startOffset, endOffset, klass, StdLanguages.JAVA);
+ return CodeInsightUtilCore.findElementInRange(file, startOffset, endOffset, klass, StdLanguages.JAVA);
}
@NotNull
@@ -203,7 +202,7 @@
PsiElement[] children = scope.getChildren();
for (PsiElement child : children) {
if (child instanceof PsiExpression) {
- if (areExpressionsEquivalent(RefactoringUtil.unparenthesizeExpression((PsiExpression)child), expr)) {
+ if (JavaPsiEquivalenceUtil.areExpressionsEquivalent(RefactoringUtil.unparenthesizeExpression((PsiExpression)child), expr)) {
array.add((PsiExpression)child);
continue;
}
@@ -233,30 +232,6 @@
}
}
- public static boolean areExpressionsEquivalent(PsiExpression expr1, PsiExpression expr2) {
- return PsiEquivalenceUtil.areElementsEquivalent(expr1, expr2, new Comparator<PsiElement>() {
- @Override
- public int compare(PsiElement o1, PsiElement o2) {
- if (o1 instanceof PsiParameter && o2 instanceof PsiParameter && ((PsiParameter)o1).getDeclarationScope() instanceof PsiMethod) {
- return ((PsiParameter)o1).getName().compareTo(((PsiParameter)o2).getName());
- }
- return 1;
- }
- }, new Comparator<PsiElement>() {
- @Override
- public int compare(PsiElement o1, PsiElement o2) {
- if (!o1.textMatches(o2)) return 1;
-
- if (o1 instanceof PsiDiamondTypeElementImpl && o2 instanceof PsiDiamondTypeElementImpl) {
- final PsiDiamondType.DiamondInferenceResult thisInferenceResult = new PsiDiamondTypeImpl(o1.getManager(), (PsiTypeElement)o1).resolveInferredTypes();
- final PsiDiamondType.DiamondInferenceResult otherInferenceResult = new PsiDiamondTypeImpl(o2.getManager(), (PsiTypeElement)o2).resolveInferredTypes();
- return thisInferenceResult.equals(otherInferenceResult) ? 0 : 1;
- }
- return 0;
- }
- }, null, false);
- }
-
public static Editor positionCursor(final Project project, PsiFile targetFile, PsiElement element) {
TextRange range = element.getTextRange();
int textOffset = range.getStartOffset();
diff --git a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java
index a4306bb..c4c156c 100644
--- a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java
+++ b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java
@@ -18,6 +18,7 @@
import com.intellij.CommonBundle;
import com.intellij.ProjectTopics;
import com.intellij.codeInsight.highlighting.HighlightManager;
+import com.intellij.diagnostic.LogMessageEx;
import com.intellij.icons.AllIcons;
import com.intellij.ide.DataManager;
import com.intellij.ide.highlighter.XmlFileType;
@@ -126,6 +127,7 @@
@NotNull final String annotationFQName,
@NotNull final PsiFile fromFile,
@Nullable final PsiNameValuePair[] value) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
final Project project = myPsiManager.getProject();
final PsiFile containingFile = listOwner.getContainingFile();
if (!(containingFile instanceof PsiJavaFile)) {
@@ -336,6 +338,7 @@
@Override
public boolean deannotate(@NotNull final PsiModifierListOwner listOwner, @NotNull final String annotationFQN) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
return processExistingExternalAnnotations(listOwner, annotationFQN, new Processor<XmlTag>() {
@Override
public boolean process(XmlTag annotationTag) {
@@ -355,6 +358,7 @@
public boolean editExternalAnnotation(@NotNull PsiModifierListOwner listOwner,
@NotNull final String annotationFQN,
@Nullable final PsiNameValuePair[] value) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
return processExistingExternalAnnotations(listOwner, annotationFQN, new Processor<XmlTag>() {
@Override
public boolean process(XmlTag annotationTag) {
@@ -365,7 +369,8 @@
});
}
- private boolean processExistingExternalAnnotations(@NotNull final PsiModifierListOwner listOwner, @NotNull final String annotationFQN,
+ private boolean processExistingExternalAnnotations(@NotNull final PsiModifierListOwner listOwner,
+ @NotNull final String annotationFQN,
@NotNull final Processor<XmlTag> annotationTagProcessor) {
try {
final List<XmlFile> files = findExternalAnnotationsXmlFiles(listOwner);
@@ -428,6 +433,7 @@
@Override
@NotNull
public AnnotationPlace chooseAnnotationsPlace(@NotNull final PsiElement element) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
if (!element.isPhysical()) return AnnotationPlace.IN_CODE; //element just created
if (!element.getManager().isInProject(element)) return AnnotationPlace.EXTERNAL;
final Project project = myPsiManager.getProject();
@@ -634,6 +640,12 @@
return null;
}
+ @Override
+ protected void duplicateError(@NotNull PsiFile file, @NotNull String externalName, @NotNull String text) {
+ String message = text + "; for signature: '" + externalName + "' in the file " + file.getVirtualFile().getPresentableUrl();
+ LogMessageEx.error(LOG, message, file.getText());
+ }
+
private static class MyExternalPromptDialog extends OptionsMessageDialog {
private final Project myProject;
private static final String ADD_IN_CODE = ProjectBundle.message("external.annotations.in.code.option");
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java b/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java
index 6343a29..ac8297d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java
@@ -15,7 +15,7 @@
*/
package com.intellij.codeInsight.completion;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -89,7 +89,7 @@
context.setTailOffset(psiReference.getRangeInElement().getEndOffset() + psiReference.getElement().getTextRange().getStartOffset());
final PsiElement newUnderlying = psiReference.bindToElement(psiClass);
if (newUnderlying != null) {
- final PsiElement psiElement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(newUnderlying);
+ final PsiElement psiElement = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(newUnderlying);
if (psiElement != null) {
for (final PsiReference reference : psiElement.getReferences()) {
if (psiManager.areElementsEquivalent(psiClass, JavaCompletionUtil.resolveReference(reference))) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ClassByNameMerger.java b/java/java-impl/src/com/intellij/codeInsight/completion/ClassByNameMerger.java
deleted file mode 100644
index 5496bb1..0000000
--- a/java/java-impl/src/com/intellij/codeInsight/completion/ClassByNameMerger.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2000-2011 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.codeInsight.completion;
-
-import com.intellij.codeInsight.CodeInsightSettings;
-import com.intellij.codeInsight.lookup.LookupElement;
-import com.intellij.codeInsight.lookup.LookupElementBuilder;
-import com.intellij.util.Consumer;
-
-/**
-* @author peter
-*/
-public class ClassByNameMerger implements Consumer<LookupElement> {
- private int number = 0;
- private LookupElement lastElement;
- private final boolean myShouldMerge;
- private final CompletionResultSet myResult;
-
- public ClassByNameMerger(CompletionParameters parameters, CompletionResultSet result) {
- myShouldMerge = parameters.getInvocationCount() == 0 && CodeInsightSettings.getInstance().SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS;
- myResult = result;
- }
-
- @Override
- public void consume(LookupElement element) {
- if (!myShouldMerge) {
- myResult.addElement(element);
- return;
- }
-
- if (lastElement != null) {
- if (lastElement.getLookupString().equals(element.getLookupString())) {
- number++;
- lastElement = LookupElementBuilder.create(element.getLookupString()).withTailText(" (" + number + " variants...)", true);
- return;
- }
-
- myResult.addElement(lastElement);
- }
- lastElement = element;
- number = 1;
- }
-
- public void finishedClassProcessing() {
- if (lastElement != null) {
- myResult.addElement(lastElement);
- }
- }
-}
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 4480f31..b98ad7a 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
@@ -15,7 +15,6 @@
*/
package com.intellij.codeInsight.completion;
-import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.TailType;
import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor;
import com.intellij.codeInsight.daemon.impl.quickfix.ImportClassFix;
@@ -415,13 +414,7 @@
}
public static boolean mayStartClassName(CompletionResultSet result) {
- String prefix = result.getPrefixMatcher().getPrefix();
- if (StringUtil.isEmpty(prefix)) {
- return false;
- }
-
- return StringUtil.isCapitalized(prefix) ||
- CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE == CodeInsightSettings.NONE;
+ return StringUtil.isNotEmpty(result.getPrefixMatcher().getPrefix());
}
private static void completeAnnotationAttributeName(CompletionResultSet result, PsiElement insertedElement,
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
index e2050a4..163b2c6 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
@@ -677,7 +677,7 @@
documentManager.doPostponedOperationsAndUnblockDocument(document);
documentManager.commitDocument(document);
- newElement = CodeInsightUtilBase.findElementInRange(file, rangeMarker.getStartOffset(), rangeMarker.getEndOffset(),
+ newElement = CodeInsightUtilCore.findElementInRange(file, rangeMarker.getStartOffset(), rangeMarker.getEndOffset(),
PsiJavaCodeReferenceElement.class,
JavaLanguage.INSTANCE);
rangeMarker.dispose();
@@ -764,12 +764,14 @@
context.setAddCompletionChar(false);
}
- final boolean needRightParenth = forceClosingParenthesis || !smart && (CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET || hasTail);
if (hasTail) {
hasParams = false;
}
+ final boolean needRightParenth = forceClosingParenthesis ||
+ !smart && (CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET ||
+ !hasParams && completionChar != '(');
- PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getDocument());
+ context.commitDocument();
final CommonCodeStyleSettings styleSettings = context.getCodeStyleSettings();
final PsiElement elementAt = file.findElementAt(context.getStartOffset());
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java
index 6e95a4c..cbfde63 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java
@@ -16,9 +16,11 @@
package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.ExpectedTypeInfo;
+import com.intellij.codeInsight.completion.impl.BetterPrefixMatcher;
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.filters.ElementFilter;
@@ -39,9 +41,9 @@
public class JavaNoVariantsDelegator extends CompletionContributor {
@Override
- public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
- final boolean empty = containsOnlyPackages(result.runRemainingContributors(parameters, true)) ||
- suggestMetaAnnotations(parameters);
+ public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
+ LinkedHashSet<CompletionResult> plainResults = result.runRemainingContributors(parameters, true);
+ final boolean empty = containsOnlyPackages(plainResults) || suggestMetaAnnotations(parameters);
if (!empty && parameters.getInvocationCount() == 0) {
result.restartCompletionWhenNothingMatches();
@@ -49,6 +51,15 @@
if (empty) {
delegate(parameters, JavaCompletionSorting.addJavaSorting(parameters, result));
+ } else if (Registry.is("ide.completion.show.all.classes") || Registry.is("ide.completion.show.better.matching.classes")) {
+ if (parameters.getInvocationCount() <= 1 &&
+ JavaCompletionContributor.mayStartClassName(result) &&
+ JavaCompletionContributor.isClassNamePossible(parameters)) {
+ if (Registry.is("ide.completion.show.better.matching.classes")) {
+ result = result.withPrefixMatcher(new BetterPrefixMatcher(result.getPrefixMatcher(), BetterPrefixMatcher.getBestMatchingDegree(plainResults)));
+ }
+ suggestNonImportedClasses(parameters, result);
+ }
}
}
@@ -158,9 +169,8 @@
return allClasses;
}
- private static void suggestNonImportedClasses(CompletionParameters parameters, CompletionResultSet result) {
- final ClassByNameMerger merger = new ClassByNameMerger(parameters, result);
-
+ private static void suggestNonImportedClasses(CompletionParameters parameters, final CompletionResultSet _result) {
+ final CompletionResultSet result = JavaCompletionSorting.addJavaSorting(parameters, _result);
JavaClassNameCompletionContributor.addAllClasses(parameters,
true, result.getPrefixMatcher(), new Consumer<LookupElement>() {
@Override
@@ -170,10 +180,8 @@
classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
}
- merger.consume(classElement);
+ result.addElement(element);
}
});
-
- merger.finishedClassProcessing();
}
}
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 79a8b04..6d03085 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java
@@ -15,8 +15,8 @@
*/
package com.intellij.codeInsight.completion;
-import com.intellij.codeInsight.CodeInsightUtil;
import com.intellij.codeInsight.ExpectedTypeInfo;
+import com.intellij.codeInsight.JavaPsiEquivalenceUtil;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementWeigher;
import com.intellij.openapi.util.Comparing;
@@ -79,7 +79,7 @@
if (myCallQualifier != null &&
myPositionQualifier != null &&
myCallQualifier != myPositionQualifier &&
- CodeInsightUtil.areExpressionsEquivalent(myCallQualifier, myPositionQualifier)) {
+ JavaPsiEquivalenceUtil.areExpressionsEquivalent(myCallQualifier, myPositionQualifier)) {
return false;
}
@@ -162,7 +162,7 @@
return Result.normal;
}
- @Nullable
+ @Nullable
private String getSetterPropertyName(@Nullable PsiMethod calledMethod) {
if (PropertyUtil.isSimplePropertySetter(calledMethod)) {
assert calledMethod != null;
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/scope/JavaCompletionProcessor.java b/java/java-impl/src/com/intellij/codeInsight/completion/scope/JavaCompletionProcessor.java
index 5e44202..ae1ae20 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/scope/JavaCompletionProcessor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/scope/JavaCompletionProcessor.java
@@ -226,10 +226,10 @@
if (myOptions.showInstanceInStaticContext && !isQualifiedContext()) {
return true;
}
- if (!(element instanceof PsiClass) && element instanceof PsiModifierListOwner) {
+ if (element instanceof PsiModifierListOwner) {
PsiModifierListOwner modifierListOwner = (PsiModifierListOwner)element;
if (myStatic) {
- if (!modifierListOwner.hasModifierProperty(PsiModifier.STATIC)) {
+ if (!(element instanceof PsiClass) && !modifierListOwner.hasModifierProperty(PsiModifier.STATIC)) {
// we don't need non static method in static context.
return false;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java
index 875d600..b647e7d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java
@@ -31,7 +31,6 @@
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbService;
-import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
@@ -68,15 +67,10 @@
@Nullable
public LineMarkerInfo getLineMarkerInfo(@NotNull final PsiElement element) {
PsiElement parent;
- if (element instanceof PsiIdentifier && (parent = element.getParent()) instanceof PsiMethod) {
+ if (element instanceof PsiIdentifier && (parent = element.getParent()) instanceof PsiMethod &&
+ !DumbService.getInstance(element.getProject()).isDumb()) {
PsiMethod method = (PsiMethod)parent;
- MethodSignatureBackedByPsiMethod superSignature = null;
- try {
- superSignature = SuperMethodsSearch.search(method, null, true, false).findFirst();
- }
- catch (IndexNotReadyException e) {
- //some searchers (EJB) require indices. What shall we do?
- }
+ MethodSignatureBackedByPsiMethod superSignature = SuperMethodsSearch.search(method, null, true, false).findFirst();
if (superSignature != null) {
boolean overrides =
method.hasModifierProperty(PsiModifier.ABSTRACT) == superSignature.getMethod().hasModifierProperty(PsiModifier.ABSTRACT);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java
index 1c21876..a36521f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java
@@ -22,10 +22,7 @@
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.daemon.ImplicitUsageProvider;
import com.intellij.codeInsight.daemon.JavaErrorMessages;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightLevelUtil;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightMessageUtil;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightMethodUtil;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.*;
import com.intellij.codeInsight.daemon.impl.quickfix.*;
import com.intellij.codeInsight.intention.EmptyIntentionAction;
import com.intellij.codeInsight.intention.IntentionAction;
@@ -38,7 +35,7 @@
import com.intellij.codeInspection.unusedImport.UnusedImportLocalInspection;
import com.intellij.codeInspection.unusedParameters.UnusedParametersInspection;
import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection;
-import com.intellij.codeInspection.util.SpecialAnnotationsUtil;
+import com.intellij.codeInspection.util.SpecialAnnotationsUtilBase;
import com.intellij.diagnostic.LogMessageEx;
import com.intellij.diagnostic.errordialog.Attachment;
import com.intellij.find.FindManager;
@@ -442,7 +439,7 @@
QuickFixAction.registerQuickFixAction(info, new CreateGetterOrSetterFix(false, true, field), myUnusedSymbolKey);
QuickFixAction.registerQuickFixAction(info, HighlightMethodUtil.getFixRange(field), new CreateConstructorParameterFromFieldFix(field));
- SpecialAnnotationsUtil.createAddToSpecialAnnotationFixes(field, new Processor<String>() {
+ SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes(field, new Processor<String>() {
@Override
public boolean process(final String annoName) {
QuickFixAction.registerQuickFixAction(info, UnusedSymbolLocalInspection.createQuickFix(annoName, "fields", field.getProject()));
@@ -497,7 +494,7 @@
myUnusedSymbolInspection.REPORT_PARAMETER_FOR_PUBLIC_METHODS &&
!isOverriddenOrOverrides(method)) &&
!method.hasModifierProperty(PsiModifier.NATIVE) &&
- !HighlightMethodUtil.isSerializationRelatedMethod(method, method.getContainingClass()) &&
+ !JavaHighlightUtil.isSerializationRelatedMethod(method, method.getContainingClass()) &&
!PsiClassImplUtil.isMainOrPremainMethod(method)) {
if (UnusedSymbolLocalInspection.isInjected(method)) return null;
HighlightInfo highlightInfo = checkUnusedParameter(parameter, identifier, progress);
@@ -559,10 +556,11 @@
String message = JavaErrorMessages.message(key, symbolName);
final HighlightInfo highlightInfo = createUnusedSymbolInfo(identifier, message, highlightInfoType);
QuickFixAction.registerQuickFixAction(highlightInfo, new SafeDeleteFix(method), highlightDisplayKey);
- SpecialAnnotationsUtil.createAddToSpecialAnnotationFixes(method, new Processor<String>() {
+ SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes(method, new Processor<String>() {
@Override
public boolean process(final String annoName) {
- QuickFixAction.registerQuickFixAction(highlightInfo, UnusedSymbolLocalInspection.createQuickFix(annoName, "methods", method.getProject()));
+ QuickFixAction
+ .registerQuickFixAction(highlightInfo, UnusedSymbolLocalInspection.createQuickFix(annoName, "methods", method.getProject()));
return true;
}
});
@@ -581,7 +579,7 @@
boolean aPrivate = method.hasModifierProperty(PsiModifier.PRIVATE);
PsiClass containingClass = method.getContainingClass();
- if (HighlightMethodUtil.isSerializationRelatedMethod(method, containingClass)) return true;
+ if (JavaHighlightUtil.isSerializationRelatedMethod(method, containingClass)) return true;
if (aPrivate) {
if (isIntentionalPrivateConstructor(method, containingClass)) {
return true;
@@ -727,10 +725,11 @@
String message = JavaErrorMessages.message(pattern, symbolName);
final HighlightInfo highlightInfo = createUnusedSymbolInfo(identifier, message, highlightInfoType);
QuickFixAction.registerQuickFixAction(highlightInfo, new SafeDeleteFix(aClass), highlightDisplayKey);
- SpecialAnnotationsUtil.createAddToSpecialAnnotationFixes((PsiModifierListOwner)aClass, new Processor<String>() {
+ SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes((PsiModifierListOwner)aClass, new Processor<String>() {
@Override
public boolean process(final String annoName) {
- QuickFixAction.registerQuickFixAction(highlightInfo, UnusedSymbolLocalInspection.createQuickFix(annoName, element, aClass.getProject()));
+ QuickFixAction
+ .registerQuickFixAction(highlightInfo, UnusedSymbolLocalInspection.createQuickFix(annoName, element, aClass.getProject()));
return true;
}
});
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java
index 8b66dce..0fd2685 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java
@@ -21,7 +21,7 @@
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
-import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
@@ -36,7 +36,7 @@
/**
* @author Danila Ponomarenko
*/
-public class RecursiveCallLineMarkerProvider implements LineMarkerProvider, DumbAware {
+public class RecursiveCallLineMarkerProvider implements LineMarkerProvider {
@Override
public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
@@ -49,6 +49,7 @@
final Set<PsiStatement> statements = new HashSet<PsiStatement>();
for (PsiElement element : elements) {
+ ProgressManager.checkCanceled();
if (element instanceof PsiMethodCallExpression) {
final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)element;
final PsiStatement statement = PsiTreeUtil.getParentOfType(methodCall, PsiStatement.class, true, PsiMethod.class);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java
index f0ac84d..6fd6ba5 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java
@@ -38,6 +38,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
public class RefCountHolder {
@@ -56,19 +57,26 @@
private static class HolderReference extends SoftReference<RefCountHolder> {
@SuppressWarnings("UnusedDeclaration")
private volatile RefCountHolder myHardRef; // to prevent gc
+ // number of live references to RefCountHolder. Once it reaches zero, hard ref is cleared
+ // the counter is used instead of a flag because multiple passes can be running simultaneously (one actual and several canceled winding down)
+ // and there is a chance they overlap the usage of RCH
+ private final AtomicInteger myRefCount = new AtomicInteger();
public HolderReference(@NotNull RefCountHolder holder) {
super(holder);
myHardRef = holder;
}
-
- private void makeHardReachable(boolean isHard) {
- RefCountHolder holder = get();
- assert !isHard || holder != null : "hard: "+isHard +"; holder="+holder;
- myHardRef = isHard ? holder : null;
+
+ private void changeLivenessBy(int delta) {
+ if (myRefCount.addAndGet(delta) == 0) {
+ myHardRef = null;
+ }
+ else if (myHardRef == null) {
+ myHardRef = get();
+ }
}
}
-
+
private static final Key<HolderReference> REF_COUNT_HOLDER_IN_FILE_KEY = Key.create("REF_COUNT_HOLDER_IN_FILE_KEY");
@NotNull
private static Pair<RefCountHolder, HolderReference> getInstance(@NotNull PsiFile file, boolean create) {
@@ -98,7 +106,7 @@
public static RefCountHolder startUsing(@NotNull PsiFile file) {
Pair<RefCountHolder, HolderReference> pair = getInstance(file, true);
HolderReference reference = pair.second;
- reference.makeHardReachable(true); // make sure RefCountHolder won't be gced during highlighting
+ reference.changeLivenessBy(1); // make sure RefCountHolder won't be gced during highlighting
log("startUsing: " + pair.first.myState+" for "+file);
return pair.first;
}
@@ -107,12 +115,12 @@
public static RefCountHolder endUsing(@NotNull PsiFile file) {
Pair<RefCountHolder, HolderReference> pair = getInstance(file, false);
HolderReference reference = pair.second;
- reference.makeHardReachable(false); // no longer needed, can be cleared
+ reference.changeLivenessBy(-1); // no longer needed, can be cleared
RefCountHolder holder = pair.first;
log("endUsing: " + (holder == null ? null : holder.myState)+" for "+file);
return holder;
}
-
+
private RefCountHolder(@NotNull PsiFile file) {
myFile = file;
log("c: created: " + myState.get()+" for "+file);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java
index 8346db9..6849d74 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java
@@ -133,12 +133,12 @@
}
String description = JavaErrorMessages.message("annotation.incompatible.types",
- formatReference(nameRef), HighlightUtil.formatType(expectedType));
+ formatReference(nameRef), JavaHighlightUtil.formatType(expectedType));
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(value).descriptionAndTooltip(description).create();
}
if (value instanceof PsiArrayInitializerMemberValue) {
if (expectedType instanceof PsiArrayType) return null;
- String description = JavaErrorMessages.message("annotation.illegal.array.initializer", HighlightUtil.formatType(expectedType));
+ String description = JavaErrorMessages.message("annotation.illegal.array.initializer", JavaHighlightUtil.formatType(expectedType));
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(value).descriptionAndTooltip(description).create();
}
if (value instanceof PsiExpression) {
@@ -151,7 +151,7 @@
}
String description = JavaErrorMessages.message("annotation.incompatible.types",
- HighlightUtil.formatType(type), HighlightUtil.formatType(expectedType));
+ JavaHighlightUtil.formatType(type), JavaHighlightUtil.formatType(expectedType));
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(value).descriptionAndTooltip(description).create();
}
@@ -483,7 +483,7 @@
final String qualifiedName = containingClass.getQualifiedName();
if (CommonClassNames.JAVA_LANG_OBJECT.equals(qualifiedName) || CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION.equals(qualifiedName)) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(nameIdentifier).descriptionAndTooltip(
- "@interface member clashes with '" + HighlightUtil.formatMethod(method) + "' in " + HighlightUtil.formatClass(containingClass)).create();
+ "@interface member clashes with '" + JavaHighlightUtil.formatMethod(method) + "' in " + HighlightUtil.formatClass(containingClass)).create();
}
}
}
@@ -599,7 +599,8 @@
if (methods.length == 1) {
PsiType expected = new PsiImmediateClassType((PsiClass)target, PsiSubstitutor.EMPTY).createArrayType();
if (!expected.equals(methods[0].getReturnType())) {
- return JavaErrorMessages.message("annotation.container.bad.type", container.getQualifiedName(), HighlightUtil.formatType(expected));
+ return JavaErrorMessages.message("annotation.container.bad.type", container.getQualifiedName(), JavaHighlightUtil
+ .formatType(expected));
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java
index 000a035..5ee1703 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java
@@ -15,7 +15,6 @@
*/
package com.intellij.codeInsight.daemon.impl.analysis;
-import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.daemon.JavaErrorMessages;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
@@ -41,7 +40,6 @@
import com.intellij.util.containers.HashSet;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -96,8 +94,8 @@
String description = JavaErrorMessages.message(
messageKey,
HighlightUtil.formatClass(typeParameter),
- HighlightUtil.formatType(extendsType),
- HighlightUtil.formatType(substituted)
+ JavaHighlightUtil.formatType(extendsType),
+ JavaHighlightUtil.formatType(substituted)
);
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(call).descriptionAndTooltip(description).create();
@@ -273,7 +271,7 @@
String description = JavaErrorMessages.message(messageKey,
referenceClass != null ? HighlightUtil.formatClass(referenceClass) : type.getPresentableText(),
- HighlightUtil.formatType(bound));
+ JavaHighlightUtil.formatType(bound));
final HighlightInfo highlightInfo =
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement2Highlight).descriptionAndTooltip(description).create();
@@ -363,7 +361,7 @@
return HighlightUtil.formatClass((PsiClass)typeParameterListOwner);
}
else if (typeParameterListOwner instanceof PsiMethod) {
- return HighlightUtil.formatMethod((PsiMethod)typeParameterListOwner);
+ return JavaHighlightUtil.formatMethod((PsiMethod)typeParameterListOwner);
}
else {
LOG.error("Unknown " + typeParameterListOwner);
@@ -447,8 +445,8 @@
if (!Comparing.equal(type1, type2)) {
String description = JavaErrorMessages.message("generics.cannot.be.inherited.with.different.type.arguments",
HighlightUtil.formatClass(superClass),
- HighlightUtil.formatType(type1),
- HighlightUtil.formatType(type2));
+ JavaHighlightUtil.formatType(type1),
+ JavaHighlightUtil.formatType(type2));
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).descriptionAndTooltip(description).create();
}
}
@@ -499,7 +497,7 @@
.isInheritorOrSelf(containingClass, superContainingClass, true)) {
if (superMethod.hasModifierProperty(PsiModifier.DEFAULT)) {
final String inheritUnrelatedDefaultsMessage = HighlightUtil.formatClass(aClass) + " inherits unrelated defaults for " +
- HighlightUtil.formatMethod(method) + " from types " + HighlightUtil.formatClass(containingClass) +
+ JavaHighlightUtil.formatMethod(method) + " from types " + HighlightUtil.formatClass(containingClass) +
" and " + HighlightUtil.formatClass(superContainingClass);
return HighlightInfo
.newHighlightInfo(HighlightInfoType.ERROR).range(classIdentifier).descriptionAndTooltip(inheritUnrelatedDefaultsMessage).create();
@@ -508,7 +506,7 @@
final String message = JavaErrorMessages.message(
aClass instanceof PsiEnumConstantInitializer ? "enum.constant.should.implement.method" : "class.must.be.abstract",
HighlightUtil.formatClass(superContainingClass),
- HighlightUtil.formatMethod(superMethod),
+ JavaHighlightUtil.formatMethod(superMethod),
HighlightUtil.formatClass(superContainingClass, false));
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(classIdentifier).descriptionAndTooltip(message).create();
}
@@ -532,9 +530,9 @@
MethodSignatureBackedByPsiMethod sameErasure = sameErasureMethods.get(signatureToErase);
HighlightInfo info;
if (sameErasure != null) {
- if (aClass instanceof PsiTypeParameter ||
+ if (aClass instanceof PsiTypeParameter ||
MethodSignatureUtil.findMethodBySuperMethod(aClass, sameErasure.getMethod(), false) != null ||
- !(InheritanceUtil.isInheritorOrSelf(sameErasure.getMethod().getContainingClass(), method.getContainingClass(), true) ||
+ !(InheritanceUtil.isInheritorOrSelf(sameErasure.getMethod().getContainingClass(), method.getContainingClass(), true) ||
InheritanceUtil.isInheritorOrSelf(method.getContainingClass(), sameErasure.getMethod().getContainingClass(), true))) {
info = checkSameErasureNotSubSignatureOrSameClass(sameErasure, signature, aClass, method);
if (info != null) return info;
@@ -659,7 +657,7 @@
if (refParent instanceof PsiNewExpression) {
PsiNewExpression newExpression = (PsiNewExpression)refParent;
if (!(newExpression.getType() instanceof PsiArrayType)) {
- String description = JavaErrorMessages.message("wildcard.type.cannot.be.instantiated", HighlightUtil.formatType(type));
+ String description = JavaErrorMessages.message("wildcard.type.cannot.be.instantiated", JavaHighlightUtil.formatType(type));
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(description).create();
}
}
@@ -700,7 +698,7 @@
if (toConvert instanceof PsiPrimitiveType) {
final PsiClassType boxedType = ((PsiPrimitiveType)toConvert).getBoxedType(typeElement);
if (boxedType != null) {
- QuickFixAction.registerQuickFixAction(highlightInfo,
+ QuickFixAction.registerQuickFixAction(highlightInfo,
new ReplacePrimitiveWithBoxedTypeAction(typeElement, toConvert.getPresentableText(), ((PsiPrimitiveType)toConvert).getBoxedTypeName()));
}
}
@@ -710,132 +708,15 @@
return null;
}
- public static boolean isRawToGeneric(PsiType lType, PsiType rType) {
- if (lType instanceof PsiPrimitiveType || rType instanceof PsiPrimitiveType) return false;
- if (lType.equals(rType)) return false;
- if (lType instanceof PsiArrayType && rType instanceof PsiArrayType) {
- return isRawToGeneric(((PsiArrayType)lType).getComponentType(), ((PsiArrayType)rType).getComponentType());
- }
- if (lType instanceof PsiArrayType || rType instanceof PsiArrayType) return false;
-
- if (rType instanceof PsiIntersectionType) {
- for (PsiType type : ((PsiIntersectionType)rType).getConjuncts()) {
- if (isRawToGeneric(lType, type)) return true;
- }
- return false;
- }
- if (lType instanceof PsiIntersectionType) {
- for (PsiType type : ((PsiIntersectionType)lType).getConjuncts()) {
- if (isRawToGeneric(type, rType)) return true;
- }
- return false;
- }
-
- if (!(lType instanceof PsiClassType) || !(rType instanceof PsiClassType)) return false;
-
- PsiClassType.ClassResolveResult lResolveResult = ((PsiClassType)lType).resolveGenerics();
- PsiClassType.ClassResolveResult rResolveResult = ((PsiClassType)rType).resolveGenerics();
- PsiClass lClass = lResolveResult.getElement();
- PsiClass rClass = rResolveResult.getElement();
-
- if (rClass instanceof PsiAnonymousClass) {
- return isRawToGeneric(lType, ((PsiAnonymousClass)rClass).getBaseClassType());
- }
-
- PsiSubstitutor lSubstitutor = lResolveResult.getSubstitutor();
- PsiSubstitutor rSubstitutor = rResolveResult.getSubstitutor();
- if (lClass == null || rClass == null) return false;
- if (lClass instanceof PsiTypeParameter &&
- !InheritanceUtil.isInheritorOrSelf(rClass, lClass, true)) {
- return true;
- }
-
- if (!lClass.getManager().areElementsEquivalent(lClass, rClass)) {
- if (lClass.isInheritor(rClass, true)) {
- lSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(rClass, lClass, lSubstitutor);
- lClass = rClass;
- }
- else if (rClass.isInheritor(lClass, true)) {
- rSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(lClass, rClass, rSubstitutor);
- rClass = lClass;
- }
- else {
- return false;
- }
- }
-
- Iterator<PsiTypeParameter> lIterator = PsiUtil.typeParametersIterator(lClass);
- Iterator<PsiTypeParameter> rIterator = PsiUtil.typeParametersIterator(rClass);
- while (lIterator.hasNext()) {
- if (!rIterator.hasNext()) return false;
- PsiTypeParameter lParameter = lIterator.next();
- PsiTypeParameter rParameter = rIterator.next();
- PsiType lTypeArg = lSubstitutor.substitute(lParameter);
- PsiType rTypeArg = rSubstitutor.substituteWithBoundsPromotion(rParameter);
- if (lTypeArg == null) continue;
- if (rTypeArg == null) {
- if (lTypeArg instanceof PsiWildcardType && ((PsiWildcardType)lTypeArg).getBound() == null) {
- continue;
- }
- else {
- return true;
- }
- }
- if (!TypeConversionUtil.typesAgree(lTypeArg, rTypeArg, true)) return true;
- }
- return false;
- }
-
- public static boolean isUncheckedCast(PsiType castType, PsiType operandType) {
- if (TypeConversionUtil.isAssignable(castType, operandType, false)) return false;
-
- castType = castType.getDeepComponentType();
- if (castType instanceof PsiClassType) {
- final PsiClassType castClassType = (PsiClassType)castType;
- operandType = operandType.getDeepComponentType();
-
- if (!(operandType instanceof PsiClassType)) return false;
- final PsiClassType operandClassType = (PsiClassType)operandType;
- final PsiClassType.ClassResolveResult castResult = castClassType.resolveGenerics();
- final PsiClassType.ClassResolveResult operandResult = operandClassType.resolveGenerics();
- final PsiClass operandClass = operandResult.getElement();
- final PsiClass castClass = castResult.getElement();
-
- if (operandClass == null || castClass == null) return false;
- if (castClass instanceof PsiTypeParameter) return true;
-
- if (castClassType.hasNonTrivialParameters()) {
- if (operandClassType.isRaw()) return true;
- if (castClass.isInheritor(operandClass, true)) {
- PsiSubstitutor castSubstitutor = castResult.getSubstitutor();
- PsiElementFactory factory = JavaPsiFacade.getInstance(castClass.getProject()).getElementFactory();
- for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(castClass)) {
- PsiSubstitutor modifiedSubstitutor = castSubstitutor.put(typeParameter, null);
- PsiClassType otherType = factory.createType(castClass, modifiedSubstitutor);
- if (TypeConversionUtil.isAssignable(operandType, otherType, false)) return true;
- }
- for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(operandClass)) {
- final PsiType operand = operandResult.getSubstitutor().substitute(typeParameter);
- if (operand instanceof PsiCapturedWildcardType) return true;
- }
- return false;
- }
- return true;
- }
- }
-
- return false;
- }
-
@Nullable
public static HighlightInfo checkForeachLoopParameterType(PsiForeachStatement statement) {
final PsiParameter parameter = statement.getIterationParameter();
final PsiExpression expression = statement.getIteratedValue();
if (expression == null || expression.getType() == null) return null;
- final PsiType itemType = getCollectionItemType(expression);
+ final PsiType itemType = JavaGenericsUtil.getCollectionItemType(expression);
if (itemType == null) {
String description = JavaErrorMessages.message("foreach.not.applicable",
- HighlightUtil.formatType(expression.getType()));
+ JavaHighlightUtil.formatType(expression.getType()));
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(description).create();
}
final int start = parameter.getTextRange().getStartOffset();
@@ -848,61 +729,6 @@
return highlightInfo;
}
- @Nullable
- public static PsiType getCollectionItemType(@NotNull PsiExpression expression) {
- final PsiType type = expression.getType();
- if (type == null) return null;
- return getCollectionItemType(type, expression.getResolveScope());
- }
-
- @Nullable
- public static PsiType getCollectionItemType(final PsiType type, final GlobalSearchScope scope) {
- if (type instanceof PsiArrayType) {
- return ((PsiArrayType)type).getComponentType();
- }
- if (type instanceof PsiClassType) {
- final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)type).resolveGenerics();
- PsiClass aClass = resolveResult.getElement();
- if (aClass == null) return null;
- final PsiManager manager = aClass.getManager();
- final String qName = aClass.getQualifiedName();
- PsiSubstitutor substitutor = resolveResult.getSubstitutor();
- JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());
- if (qName != null) {
- PsiClass myClass = facade.findClass(qName, scope);
- if (myClass != null && myClass != aClass) {
- //different JDKs
- PsiTypeParameter thisTypeParameter = getIterableTypeParameter(facade, myClass);
- if (thisTypeParameter == null) return null;
- PsiTypeParameter thatTypeParameter = getIterableTypeParameter(facade, aClass);
- if (thatTypeParameter != null) { //it can be null if we reference collection in JDK1.4 module from JDK5 source
- substitutor = substitutor.put(thisTypeParameter, substitutor.substitute(thatTypeParameter));
- }
- aClass = myClass;
- }
- }
- PsiTypeParameter typeParameter = getIterableTypeParameter(facade, aClass);
- if (typeParameter == null) return null;
- PsiClass owner = (PsiClass)typeParameter.getOwner();
- if (owner == null) return null;
- PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getClassSubstitutor(owner, aClass, PsiSubstitutor.EMPTY);
- if (superClassSubstitutor == null) return null;
- PsiType itemType = superClassSubstitutor.substitute(typeParameter);
- itemType = substitutor.substitute(itemType);
- return itemType == null ? PsiType.getJavaLangObject(manager, aClass.getResolveScope()) : itemType;
- }
- return null;
- }
-
- @Nullable
- private static PsiTypeParameter getIterableTypeParameter(final JavaPsiFacade facade, final PsiClass context) {
- PsiClass iterable = facade.findClass("java.lang.Iterable", context.getResolveScope());
- if (iterable == null) return null;
- PsiTypeParameter[] typeParameters = iterable.getTypeParameters();
- if (typeParameters.length != 1) return null;
- return typeParameters[0];
- }
-
//http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2
@Nullable
public static HighlightInfo checkAccessStaticFieldFromEnumConstructor(PsiReferenceExpression expr, JavaResolveResult result) {
@@ -952,7 +778,7 @@
@Nullable
public static HighlightInfo checkGenericArrayCreation(PsiElement element, PsiType type) {
if (type instanceof PsiArrayType) {
- if (!isReifiableType(((PsiArrayType)type).getComponentType())) {
+ if (!JavaGenericsUtil.isReifiableType(((PsiArrayType)type).getComponentType())) {
String description = JavaErrorMessages.message("generic.array.creation");
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(element).descriptionAndTooltip(description).create();
}
@@ -1058,10 +884,10 @@
if (resolved instanceof PsiClass) {
final PsiClass containingClass = ((PsiClass)resolved).getContainingClass();
- if (containingClass != null &&
- ref.getQualifier() == null &&
- containingClass.getTypeParameters().length > 0 &&
- !((PsiClass)resolved).hasModifierProperty(PsiModifier.STATIC) &&
+ if (containingClass != null &&
+ ref.getQualifier() == null &&
+ containingClass.getTypeParameters().length > 0 &&
+ !((PsiClass)resolved).hasModifierProperty(PsiModifier.STATIC) &&
((PsiClass)resolved).getTypeParameters().length == 0) {
String description = JavaErrorMessages.message("illegal.generic.type.for.instanceof");
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(description).create();
@@ -1180,7 +1006,7 @@
LOG.assertTrue(varParameter.isVarArgs());
final PsiEllipsisType ellipsisType = (PsiEllipsisType)varParameter.getType();
final PsiType componentType = ellipsisType.getComponentType();
- if (isReifiableType(componentType)) {
+ if (JavaGenericsUtil.isReifiableType(componentType)) {
PsiElement element = varParameter.getTypeElement();
return HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING).range(element).descriptionAndTooltip(
"@SafeVarargs is not applicable for reifiable types").create();
@@ -1192,102 +1018,6 @@
}
}
- public static boolean isUncheckedWarning(PsiJavaCodeReferenceElement expression, JavaResolveResult resolveResult) {
- final PsiElement resolve = resolveResult.getElement();
- if (resolve instanceof PsiMethod) {
- final PsiMethod psiMethod = (PsiMethod)resolve;
-
- final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(expression);
-
- if (psiMethod.isVarArgs()) {
- if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_7) || !AnnotationUtil.isAnnotated(psiMethod, "java.lang.SafeVarargs", false)) {
- final int parametersCount = psiMethod.getParameterList().getParametersCount();
- final PsiParameter varargParameter =
- psiMethod.getParameterList().getParameters()[parametersCount - 1];
- final PsiType componentType = ((PsiEllipsisType)varargParameter.getType()).getComponentType();
- if (!isReifiableType(resolveResult.getSubstitutor().substitute(componentType))) {
- final PsiElement parent = expression.getParent();
- if (parent instanceof PsiCall) {
- final PsiExpressionList argumentList = ((PsiCall)parent).getArgumentList();
- if (argumentList != null) {
- final PsiExpression[] args = argumentList.getExpressions();
- if (args.length == parametersCount) {
- final PsiExpression lastArg = args[args.length - 1];
- if (lastArg instanceof PsiReferenceExpression) {
- final PsiElement lastArgsResolve = ((PsiReferenceExpression)lastArg).resolve();
- if (lastArgsResolve instanceof PsiParameter) {
- if (((PsiParameter)lastArgsResolve).getType() instanceof PsiArrayType) {
- return false;
- }
- }
- }
- else if (lastArg instanceof PsiMethodCallExpression) {
- if (lastArg.getType() instanceof PsiArrayType) {
- return false;
- }
- }
- }
- for (int i = parametersCount - 1; i < args.length; i++) {
- if (!isReifiableType(resolveResult.getSubstitutor().substitute(args[i].getType()))) {
- return true;
- }
- }
- return args.length < parametersCount;
- }
- }
- }
- }
- }
- }
- return false;
- }
-
- public static boolean isReifiableType(PsiType type) {
- if (type instanceof PsiArrayType) {
- return isReifiableType(((PsiArrayType)type).getComponentType());
- }
-
- if (type instanceof PsiPrimitiveType) {
- return true;
- }
-
- if (PsiUtil.resolveClassInType(type) instanceof PsiTypeParameter) {
- return false;
- }
-
- if (type instanceof PsiClassType) {
- final PsiClassType classType = (PsiClassType)PsiUtil.convertAnonymousToBaseType(type);
- if (classType.isRaw()) {
- return true;
- }
- PsiType[] parameters = classType.getParameters();
-
- for (PsiType parameter : parameters) {
- if (parameter instanceof PsiWildcardType && ((PsiWildcardType)parameter).getBound() == null) {
- return true;
- }
- }
- final PsiClass resolved = ((PsiClassType)PsiUtil.convertAnonymousToBaseType(classType)).resolve();
- if (resolved instanceof PsiTypeParameter) {
- return false;
- }
- if (parameters.length == 0) {
- if (resolved != null && !resolved.hasModifierProperty(PsiModifier.STATIC)) {
- final PsiClass containingClass = resolved.getContainingClass();
- if (containingClass != null) {
- final PsiTypeParameter[] containingClassTypeParameters = containingClass.getTypeParameters();
- if (containingClassTypeParameters.length > 0) {
- return false;
- }
- }
- }
- return true;
- }
- }
-
- return false;
- }
-
static void checkEnumConstantForConstructorProblems(PsiEnumConstant enumConstant, final HighlightInfoHolder holder) {
PsiClass containingClass = enumConstant.getContainingClass();
if (enumConstant.getInitializingClass() == null) {
@@ -1407,7 +1137,7 @@
if ((parent instanceof PsiCallExpression || parent instanceof PsiMethodReferenceExpression) && PsiUtil.isLanguageLevel7OrHigher(parent)) {
return null;
}
-
+
if (element instanceof PsiMethod) {
if (((PsiMethod)element).findSuperMethods().length > 0) return null;
if (qualifier instanceof PsiReferenceExpression){
@@ -1520,8 +1250,8 @@
if (qualifier instanceof PsiJavaCodeReferenceElement) {
if (((PsiJavaCodeReferenceElement)qualifier).getTypeParameters().length > 0) {
final PsiElement resolve = ((PsiJavaCodeReferenceElement)parent).resolve();
- if (resolve instanceof PsiTypeParameterListOwner
- && ((PsiTypeParameterListOwner)resolve).hasTypeParameters()
+ if (resolve instanceof PsiTypeParameterListOwner
+ && ((PsiTypeParameterListOwner)resolve).hasTypeParameters()
&& !((PsiTypeParameterListOwner)resolve).hasModifierProperty(PsiModifier.STATIC)) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(parent).descriptionAndTooltip(
"Improper formed type; some type parameters are missing").create();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java
index 62a59b0..40e1f57 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java
@@ -98,7 +98,7 @@
return null;
}
String baseClassName = HighlightUtil.formatClass(aClass, false);
- String methodName = HighlightUtil.formatMethod(abstractMethod);
+ String methodName = JavaHighlightUtil.formatMethod(abstractMethod);
String message = JavaErrorMessages.message(aClass instanceof PsiEnumConstantInitializer || implementsFixElement instanceof PsiEnumConstant ? "enum.constant.should.implement.method" : "class.must.be.abstract",
baseClassName,
methodName,
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
index 1f5e33a..80f4b17 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
@@ -23,6 +23,7 @@
import com.intellij.codeInsight.daemon.impl.quickfix.*;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.QuickFixFactory;
+import com.intellij.codeInspection.LocalQuickFixOnPsiElementAsIntentionAdapter;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.util.Comparing;
@@ -60,8 +61,8 @@
public static String createClashMethodMessage(PsiMethod method1, PsiMethod method2, boolean showContainingClasses) {
@NonNls String pattern = showContainingClasses ? "clash.methods.message.show.classes" : "clash.methods.message";
return JavaErrorMessages.message(pattern,
- HighlightUtil.formatMethod(method1),
- HighlightUtil.formatMethod(method2),
+ JavaHighlightUtil.formatMethod(method1),
+ JavaHighlightUtil.formatMethod(method2),
HighlightUtil.formatClass(method1.getContainingClass()),
HighlightUtil.formatClass(method2.getContainingClass()));
}
@@ -212,8 +213,8 @@
// strange things happen when super method is from Object and method from interface
if (superMethod.hasModifierProperty(PsiModifier.FINAL)) {
String description = JavaErrorMessages.message("final.method.override",
- HighlightUtil.formatMethod(method),
- HighlightUtil.formatMethod(superMethod),
+ JavaHighlightUtil.formatMethod(method),
+ JavaHighlightUtil.formatMethod(superMethod),
HighlightUtil.formatClass(superMethod.getContainingClass()));
TextRange textRange = HighlightNamesUtil.getMethodDeclarationTextRange(method);
HighlightInfo errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).descriptionAndTooltip(description).create();
@@ -265,7 +266,7 @@
PsiClassType exception = checkedExceptions.get(index);
String description = JavaErrorMessages.message("overridden.method.does.not.throw",
createClashMethodMessage(method, superMethod, true),
- HighlightUtil.formatType(exception));
+ JavaHighlightUtil.formatType(exception));
TextRange textRange;
if (includeRealPositionInfo) {
PsiElement exceptionContext = exceptionContexts.get(index);
@@ -275,8 +276,8 @@
textRange = TextRange.EMPTY_RANGE;
}
HighlightInfo errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).descriptionAndTooltip(description).create();
- QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createMethodThrowsFix(method, exception, false, false));
- QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createMethodThrowsFix(superMethod, exception, true, true));
+ QuickFixAction.registerQuickFixAction(errorResult, new LocalQuickFixOnPsiElementAsIntentionAdapter(QUICK_FIX_FACTORY.createMethodThrowsFix(method, exception, false, false)));
+ QuickFixAction.registerQuickFixAction(errorResult, new LocalQuickFixOnPsiElementAsIntentionAdapter(QUICK_FIX_FACTORY.createMethodThrowsFix(superMethod, exception, true, true)));
return errorResult;
}
}
@@ -325,6 +326,9 @@
if (resolved instanceof PsiMethod && resolveResult.isValidResult()) {
TextRange fixRange = getFixRange(methodCall);
highlightInfo = HighlightUtil.checkUnhandledExceptions(methodCall, fixRange);
+ if (highlightInfo == null && !LambdaUtil.isValidQualifier4InterfaceStaticMethodCall((PsiMethod)resolved, methodCall.getMethodExpression())) {
+ highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip("Static method may be invoked on containing interface class only").range(fixRange).create();
+ }
}
else {
PsiMethod resolvedMethod = null;
@@ -683,7 +687,7 @@
if (parameter != null) {
PsiType type = substitutor.substitute(parameter.getType());
s += "<font " + (mismatchColor == null ? "" : "color=" + mismatchColor) + ">" +
- esctrim(showShort ? type.getPresentableText() : HighlightUtil.formatType(type))
+ esctrim(showShort ? type.getPresentableText() : JavaHighlightUtil.formatType(type))
+ "</font>"
;
}
@@ -694,7 +698,7 @@
PsiType type = expression.getType();
s += "<font " + (mismatchColor == null ? "" : "color='" + mismatchColor + "'") + ">" +
esctrim(expression.getText()) + " "+
- (mismatchColor == null || type == null || type == PsiType.NULL ? "" : "("+esctrim(HighlightUtil.formatType(type))+")")
+ (mismatchColor == null || type == null || type == PsiType.NULL ? "" : "("+esctrim(JavaHighlightUtil.formatType(type))+")")
+ "</font>"
;
@@ -722,7 +726,7 @@
@NonNls String mismatchColor = showShort ? null : UIUtil.isUnderDarcula() ? "ff6464" : "red";
ms += "<td> " + "<b><nobr>" + (i == 0 ? "(" : "")
+ "<font " + (showShort ? "" : "color=" + mismatchColor) + ">" +
- XmlStringUtil.escapeString(showShort ? type.getPresentableText() : HighlightUtil.formatType(type))
+ XmlStringUtil.escapeString(showShort ? type.getPresentableText() : JavaHighlightUtil.formatType(type))
+ "</font>"
+ (i == expressions.length - 1 ? ")" : ",") + "</nobr></b></td>";
}
@@ -744,7 +748,7 @@
ms += "<td><b><nobr>" + (i == 0 ? "(" : "") +
XmlStringUtil.escapeString(showShortType(i, parameters, expressions, substitutor)
? type.getPresentableText()
- : HighlightUtil.formatType(type))
+ : JavaHighlightUtil.formatType(type))
+ (i == parameters.length - 1 ? ")" : ",") + "</nobr></b></td>";
}
return ms;
@@ -849,7 +853,7 @@
}
if (methodCount > 1) {
String description = JavaErrorMessages.message("duplicate.method",
- HighlightUtil.formatMethod(method),
+ JavaHighlightUtil.formatMethod(method),
HighlightUtil.formatClass(aClass));
TextRange textRange = HighlightNamesUtil.getMethodDeclarationTextRange(method);
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).descriptionAndTooltip(description).create();
@@ -939,7 +943,7 @@
PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expr.getParent().getParent();
PsiMethod method = methodCallExpression.resolveMethod();
if (method != null && method.hasModifierProperty(PsiModifier.ABSTRACT)) {
- String message = JavaErrorMessages.message("direct.abstract.method.access", HighlightUtil.formatMethod(method));
+ String message = JavaErrorMessages.message("direct.abstract.method.access", JavaHighlightUtil.formatMethod(method));
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(methodCallExpression).descriptionAndTooltip(message).create();
}
}
@@ -1028,9 +1032,9 @@
: "instance.method.cannot.override.static.method";
String description = JavaErrorMessages.message(messageKey,
- HighlightUtil.formatMethod(method),
+ JavaHighlightUtil.formatMethod(method),
HighlightUtil.formatClass(aClass),
- HighlightUtil.formatMethod(superMethod),
+ JavaHighlightUtil.formatMethod(superMethod),
HighlightUtil.formatClass(superClass));
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).descriptionAndTooltip(description).create();
@@ -1128,9 +1132,9 @@
PsiMethod superMethod = superSignature.getMethod();
if (!superMethod.hasModifierProperty(PsiModifier.STATIC)) {
description = JavaErrorMessages.message("static.method.cannot.override.instance.method",
- HighlightUtil.formatMethod(method),
+ JavaHighlightUtil.formatMethod(method),
HighlightUtil.formatClass(containingClass),
- HighlightUtil.formatMethod(superMethod),
+ JavaHighlightUtil.formatMethod(superMethod),
HighlightUtil.formatClass(superMethod.getContainingClass()));
break Ultimate;
}
@@ -1177,7 +1181,7 @@
TextRange textRange = HighlightNamesUtil.getMethodDeclarationTextRange(method);
HighlightInfo highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).descriptionAndTooltip(description).create();
for (PsiClassType exception : unhandled) {
- QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createMethodThrowsFix(method, exception, true, false));
+ QuickFixAction.registerQuickFixAction(highlightInfo, new LocalQuickFixOnPsiElementAsIntentionAdapter(QUICK_FIX_FACTORY.createMethodThrowsFix(method, exception, true, false)));
}
return highlightInfo;
}
@@ -1380,43 +1384,6 @@
}
}
- public static boolean isSerializationRelatedMethod(PsiMethod method, PsiClass containingClass) {
- if (containingClass == null || method.isConstructor()) return false;
- if (method.hasModifierProperty(PsiModifier.STATIC)) return false;
- @NonNls String name = method.getName();
- PsiParameter[] parameters = method.getParameterList().getParameters();
- PsiType returnType = method.getReturnType();
- if ("readObjectNoData".equals(name)) {
- return parameters.length == 0 && TypeConversionUtil.isVoidType(returnType) && HighlightUtil.isSerializable(containingClass);
- }
- if ("readObject".equals(name)) {
- return parameters.length == 1
- && parameters[0].getType().equalsToText("java.io.ObjectInputStream")
- && TypeConversionUtil.isVoidType(returnType) && method.hasModifierProperty(PsiModifier.PRIVATE)
- && HighlightUtil.isSerializable(containingClass);
- }
- if ("readResolve".equals(name)) {
- return parameters.length == 0
- && returnType != null
- && returnType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)
- && (containingClass.hasModifierProperty(PsiModifier.ABSTRACT) || HighlightUtil.isSerializable(containingClass));
- }
- if ("writeReplace".equals(name)) {
- return parameters.length == 0
- && returnType != null
- && returnType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)
- && (containingClass.hasModifierProperty(PsiModifier.ABSTRACT) || HighlightUtil.isSerializable(containingClass));
- }
- if ("writeObject".equals(name)) {
- return parameters.length == 1
- && TypeConversionUtil.isVoidType(returnType)
- && parameters[0].getType().equalsToText("java.io.ObjectOutputStream")
- && method.hasModifierProperty(PsiModifier.PRIVATE)
- && HighlightUtil.isSerializable(containingClass);
- }
- return false;
- }
-
private static String buildArgTypesList(PsiExpressionList list) {
StringBuilder builder = new StringBuilder();
builder.append("(");
@@ -1426,7 +1393,7 @@
builder.append(", ");
}
PsiType argType = args[i].getType();
- builder.append(argType != null ? HighlightUtil.formatType(argType) : "?");
+ builder.append(argType != null ? JavaHighlightUtil.formatType(argType) : "?");
}
builder.append(")");
return builder.toString();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
index eb75a70..5354932 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
@@ -26,6 +26,7 @@
import com.intellij.codeInsight.intention.QuickFixFactory;
import com.intellij.codeInsight.quickfix.ChangeVariableTypeQuickFixProvider;
import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider;
+import com.intellij.codeInspection.LocalQuickFixOnPsiElementAsIntentionAdapter;
import com.intellij.lang.findUsages.LanguageFindUsages;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.diagnostic.Logger;
@@ -280,7 +281,8 @@
if (TypeConversionUtil.isPrimitiveAndNotNull(operandType)
|| TypeConversionUtil.isPrimitiveAndNotNull(checkType)
|| !TypeConversionUtil.areTypesConvertible(operandType, checkType)) {
- String message = JavaErrorMessages.message("inconvertible.type.cast", formatType(operandType), formatType(checkType));
+ String message = JavaErrorMessages.message("inconvertible.type.cast", JavaHighlightUtil.formatType(operandType), JavaHighlightUtil
+ .formatType(checkType));
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
}
return null;
@@ -300,7 +302,8 @@
if (operandType != null &&
!TypeConversionUtil.areTypesConvertible(operandType, castType) &&
!RedundantCastUtil.isInPolymorphicCall(expression)) {
- String message = JavaErrorMessages.message("inconvertible.type.cast", formatType(operandType), formatType(castType));
+ String message = JavaErrorMessages.message("inconvertible.type.cast", JavaHighlightUtil.formatType(operandType), JavaHighlightUtil
+ .formatType(castType));
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
}
@@ -347,8 +350,8 @@
PsiType.getJavaLangObject(assignment.getManager(), assignment.getResolveScope()).equals(lType)) {
String operatorText = operationSign.getText().substring(0, operationSign.getText().length() - 1);
String message = JavaErrorMessages.message("binary.operator.not.applicable", operatorText,
- formatType(lType),
- formatType(rType));
+ JavaHighlightUtil.formatType(lType),
+ JavaHighlightUtil.formatType(rType));
errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(assignment).descriptionAndTooltip(message).create();
QuickFixAction.registerQuickFixAction(errorResult, new ChangeToAppendFix(eqOpSign, lType, assignment));
@@ -547,7 +550,7 @@
@NotNull
@Override
public String fun(PsiClassType type) {
- return formatType(type);
+ return JavaHighlightUtil.formatType(type);
}
}, ", ");
}
@@ -630,24 +633,10 @@
}
@NotNull
- public static String formatMethod(@NotNull PsiMethod method) {
- return PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS,
- PsiFormatUtilBase.SHOW_TYPE);
- }
-
- @NotNull
public static String formatField(@NotNull PsiField field) {
return PsiFormatUtil.formatVariable(field, PsiFormatUtilBase.SHOW_CONTAINING_CLASS | PsiFormatUtilBase.SHOW_NAME, PsiSubstitutor.EMPTY);
}
- @NotNull
- public static String formatType(@Nullable PsiType type) {
- if (type == null) return PsiKeyword.NULL;
- String text = type.getInternalCanonicalText();
- return text == null ? PsiKeyword.NULL : text;
- }
-
-
@Nullable
public static HighlightInfo checkUnhandledExceptions(@NotNull final PsiElement element, @Nullable TextRange textRange) {
final List<PsiClassType> unhandledExceptions = ExceptionUtil.getUnhandledExceptions(element);
@@ -1148,7 +1137,7 @@
if (exceptionType.isAssignableFrom(caughtType) || caughtType.isAssignableFrom(exceptionType)) return null;
}
- final String description = JavaErrorMessages.message("exception.never.thrown.try", formatType(caughtType));
+ final String description = JavaErrorMessages.message("exception.never.thrown.try", JavaHighlightUtil.formatType(caughtType));
final HighlightInfo errorResult =
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(parameter).descriptionAndTooltip(description).create();
QuickFixAction.registerQuickFixAction(errorResult, new DeleteCatchFix(parameter));
@@ -1173,7 +1162,7 @@
}
}
if (!used) {
- final String description = JavaErrorMessages.message("exception.never.thrown.try", formatType(catchType));
+ final String description = JavaErrorMessages.message("exception.never.thrown.try", JavaHighlightUtil.formatType(catchType));
final HighlightInfo highlight =
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(description).create();
QuickFixAction.registerQuickFixAction(highlight, new DeleteMultiCatchFix(typeElement));
@@ -1267,7 +1256,8 @@
if (type != null) {
if (!isValidTypeForSwitchSelector(type, PsiUtil.isLanguageLevel7OrHigher(expression))) {
String message =
- JavaErrorMessages.message("incompatible.types", JavaErrorMessages.message("valid.switch.selector.types"), formatType(type));
+ JavaErrorMessages.message("incompatible.types", JavaErrorMessages.message("valid.switch.selector.types"), JavaHighlightUtil
+ .formatType(type));
errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
QuickFixAction.registerQuickFixAction(errorResult, new ConvertSwitchToIfIntention(statement));
if (PsiType.LONG.equals(type) || PsiType.FLOAT.equals(type) || PsiType.DOUBLE.equals(type)) {
@@ -1312,8 +1302,8 @@
if (!TypeConversionUtil.isBinaryOperatorApplicable(operationSign, lType, rType, false)) {
PsiJavaToken token = expression.getTokenBeforeOperand(operand);
String message = JavaErrorMessages.message("binary.operator.not.applicable", token.getText(),
- formatType(lType),
- formatType(rType));
+ JavaHighlightUtil.formatType(lType),
+ JavaHighlightUtil.formatType(rType));
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
}
lType = TypeConversionUtil.calcTypeForBinaryExpression(lType, rType, operationSign, true);
@@ -1328,7 +1318,7 @@
if (token != null && expression != null && !TypeConversionUtil.isUnaryOperatorApplicable(token, expression)) {
PsiType type = expression.getType();
if (type == null) return null;
- String message = JavaErrorMessages.message("unary.operator.not.applicable", token.getText(), formatType(type));
+ String message = JavaErrorMessages.message("unary.operator.not.applicable", token.getText(), JavaHighlightUtil.formatType(type));
PsiElement parentExpr = token.getParent();
HighlightInfo highlightInfo =
@@ -1510,7 +1500,7 @@
final PsiType arrayExpressionType = arrayExpression.getType();
if (arrayExpressionType != null && !(arrayExpressionType instanceof PsiArrayType)) {
- final String description = JavaErrorMessages.message("array.type.expected", formatType(arrayExpressionType));
+ final String description = JavaErrorMessages.message("array.type.expected", JavaHighlightUtil.formatType(arrayExpressionType));
final HighlightInfo info =
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(arrayExpression).descriptionAndTooltip(description).create();
QuickFixAction.registerQuickFixAction(info, new ReplaceWithListAccessFix(arrayAccessExpression));
@@ -1560,12 +1550,12 @@
result.add(info);
if (!arrayTypeFixChecked) {
- final PsiType checkResult = sameType(initializers);
+ final PsiType checkResult = JavaHighlightUtil.sameType(initializers);
fix = checkResult != null ? new VariableArrayTypeFix(arrayInitializer, checkResult) : null;
arrayTypeFixChecked = true;
}
if (fix != null) {
- QuickFixAction.registerQuickFixAction(info, fix);
+ QuickFixAction.registerQuickFixAction(info, new LocalQuickFixOnPsiElementAsIntentionAdapter(fix));
}
}
}
@@ -1573,40 +1563,10 @@
}
@Nullable
- private static PsiType getArrayInitializerType(@NotNull final PsiArrayInitializerExpression element) {
- final PsiType typeCheckResult = sameType(element.getInitializers());
- if (typeCheckResult != null) {
- return typeCheckResult.createArrayType();
- }
- return null;
- }
-
- @Nullable
- public static PsiType sameType(@NotNull PsiExpression[] expressions) {
- PsiType type = null;
- for (PsiExpression expression : expressions) {
- final PsiType currentType;
- if (expression instanceof PsiArrayInitializerExpression) {
- currentType = getArrayInitializerType((PsiArrayInitializerExpression)expression);
- }
- else {
- currentType = expression.getType();
- }
- if (type == null) {
- type = currentType;
- }
- else if (!type.equals(currentType)) {
- return null;
- }
- }
- return type;
- }
-
- @Nullable
private static HighlightInfo checkArrayInitializerCompatibleTypes(@NotNull PsiExpression initializer, final PsiType componentType) {
PsiType initializerType = initializer.getType();
if (initializerType == null) {
- String description = JavaErrorMessages.message("illegal.initializer", formatType(componentType));
+ String description = JavaErrorMessages.message("illegal.initializer", JavaHighlightUtil.formatType(componentType));
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(initializer).descriptionAndTooltip(description).create();
}
PsiExpression expression = initializer instanceof PsiArrayInitializerExpression ? null : initializer;
@@ -2333,7 +2293,8 @@
redIfNotMatch(lRawType, assignable), requiredRow,
redIfNotMatch(rRawType, assignable), foundRow);
- String description = JavaErrorMessages.message("incompatible.types", formatType(lType1), formatType(rType1));
+ String description = JavaErrorMessages.message("incompatible.types", JavaHighlightUtil.formatType(lType1), JavaHighlightUtil
+ .formatType(rType1));
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).description(description).escapedToolTip(toolTip).navigationShift(navigationShift).create();
}
@@ -2503,7 +2464,7 @@
@NotNull
private static String format(@NotNull PsiElement element) {
if (element instanceof PsiClass) return formatClass((PsiClass)element);
- if (element instanceof PsiMethod) return formatMethod((PsiMethod)element);
+ if (element instanceof PsiMethod) return JavaHighlightUtil.formatMethod((PsiMethod)element);
if (element instanceof PsiField) return formatField((PsiField)element);
return ElementDescriptionUtil.getElementDescription(element, HighlightUsagesDescriptionLocation.INSTANCE);
}
@@ -2575,18 +2536,12 @@
}
- public static boolean isSerializable(@NotNull PsiClass aClass) {
- PsiManager manager = aClass.getManager();
- PsiClass serializableClass = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.io.Serializable", aClass.getResolveScope());
- return serializableClass != null && aClass.isInheritor(serializableClass, true);
- }
-
public static boolean isSerializationImplicitlyUsedField(@NotNull PsiField field) {
final String name = field.getName();
if (!SERIAL_VERSION_UID_FIELD_NAME.equals(name) && !SERIAL_PERSISTENT_FIELDS_FIELD_NAME.equals(name)) return false;
if (!field.hasModifierProperty(PsiModifier.STATIC)) return false;
PsiClass aClass = field.getContainingClass();
- return aClass == null || isSerializable(aClass);
+ return aClass == null || JavaHighlightUtil.isSerializable(aClass);
}
@Nullable
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
index 952cb60..1f92c42 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
@@ -26,7 +26,6 @@
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
@@ -54,7 +53,7 @@
import java.util.Map;
import java.util.Set;
-public class HighlightVisitorImpl extends JavaElementVisitor implements HighlightVisitor, DumbAware {
+public class HighlightVisitorImpl extends JavaElementVisitor implements HighlightVisitor {
private final PsiResolveHelper myResolveHelper;
private HighlightInfoHolder myHolder;
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AccessStaticViaInstanceFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AccessStaticViaInstanceFix.java
index d96e461..9841643 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AccessStaticViaInstanceFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AccessStaticViaInstanceFix.java
@@ -21,8 +21,6 @@
import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
import com.intellij.codeInsight.highlighting.HighlightManager;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
-import com.intellij.ide.DataManager;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
@@ -96,7 +94,7 @@
final PsiExpression qualifierExpression = myExpression.getQualifierExpression();
PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
if (qualifierExpression != null) {
- if (!checkSideEffects(project, containingClass, qualifierExpression, factory, myExpression)) return;
+ if (!checkSideEffects(project, containingClass, qualifierExpression, factory, myExpression,editor)) return;
PsiElement newQualifier = qualifierExpression.replace(factory.createReferenceExpression(containingClass));
PsiElement qualifiedWithClassName = myExpression.copy();
newQualifier.delete();
@@ -110,68 +108,71 @@
}
}
- private boolean checkSideEffects(final Project project, PsiClass containingClass, final PsiExpression qualifierExpression,
- PsiElementFactory factory, final PsiElement myExpression) {
+ private boolean checkSideEffects(final Project project,
+ PsiClass containingClass,
+ final PsiExpression qualifierExpression,
+ PsiElementFactory factory,
+ final PsiElement myExpression,
+ Editor editor) {
final List<PsiElement> sideEffects = new ArrayList<PsiElement>();
- boolean hasSideEffects = RemoveUnusedVariableFix.checkSideEffects(qualifierExpression, null, sideEffects);
+ boolean hasSideEffects = RemoveUnusedVariableUtil.checkSideEffects(qualifierExpression, null, sideEffects);
if (hasSideEffects && !myOnTheFly) return false;
- if (hasSideEffects && !ApplicationManager.getApplication().isUnitTestMode()) {
- final TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
- final Editor editor = PlatformDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext());
- if (editor == null)
- return false;
- HighlightManager.getInstance(project).addOccurrenceHighlights(editor, PsiUtilCore.toPsiElementArray(sideEffects), attributes, true,
- null);
- try {
- hasSideEffects = PsiUtil.isStatement(factory.createStatementFromText(qualifierExpression.getText(), qualifierExpression));
- }
- catch (IncorrectOperationException e) {
- hasSideEffects = false;
- }
- final PsiReferenceExpression qualifiedWithClassName = (PsiReferenceExpression)myExpression.copy();
- qualifiedWithClassName.setQualifierExpression(factory.createReferenceExpression(containingClass));
- final boolean canCopeWithSideEffects = hasSideEffects;
- final SideEffectWarningDialog dialog =
- new SideEffectWarningDialog(project, false, null, sideEffects.get(0).getText(), PsiExpressionTrimRenderer.render(qualifierExpression),
- canCopeWithSideEffects){
- @Override
- protected String sideEffectsDescription() {
- if (canCopeWithSideEffects) {
- return "<html><body>" +
- " There are possible side effects found in expression '" +
- qualifierExpression.getText() +
- "'<br>" +
- " You can:<ul><li><b>Remove</b> class reference along with whole expressions involved, or</li>" +
- " <li><b>Transform</b> qualified expression into the statement on its own.<br>" +
- " That is,<br>" +
- " <table border=1><tr><td><code>" +
- myExpression.getText() +
- "</code></td></tr></table><br> becomes: <br>" +
- " <table border=1><tr><td><code>" +
- qualifierExpression.getText() +
- ";<br>" +
- qualifiedWithClassName.getText() +
- " </code></td></tr></table></li>" +
- " </body></html>";
- } else {
- return "<html><body> There are possible side effects found in expression '" + qualifierExpression.getText() + "'<br>" +
- "You can:<ul><li><b>Remove</b> class reference along with whole expressions involved, or</li></body></html>";
- }
+ if (!hasSideEffects || ApplicationManager.getApplication().isUnitTestMode()) {
+ return true;
+ }
+ if (editor == null) {
+ return false;
+ }
+ TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
+ HighlightManager.getInstance(project).addOccurrenceHighlights(editor, PsiUtilCore.toPsiElementArray(sideEffects), attributes, true, null);
+ try {
+ hasSideEffects = PsiUtil.isStatement(factory.createStatementFromText(qualifierExpression.getText(), qualifierExpression));
+ }
+ catch (IncorrectOperationException e) {
+ hasSideEffects = false;
+ }
+ final PsiReferenceExpression qualifiedWithClassName = (PsiReferenceExpression)myExpression.copy();
+ qualifiedWithClassName.setQualifierExpression(factory.createReferenceExpression(containingClass));
+ final boolean canCopeWithSideEffects = hasSideEffects;
+ final SideEffectWarningDialog dialog =
+ new SideEffectWarningDialog(project, false, null, sideEffects.get(0).getText(), PsiExpressionTrimRenderer.render(qualifierExpression),
+ canCopeWithSideEffects){
+ @Override
+ protected String sideEffectsDescription() {
+ if (canCopeWithSideEffects) {
+ return "<html><body>" +
+ " There are possible side effects found in expression '" +
+ qualifierExpression.getText() +
+ "'<br>" +
+ " You can:<ul><li><b>Remove</b> class reference along with whole expressions involved, or</li>" +
+ " <li><b>Transform</b> qualified expression into the statement on its own.<br>" +
+ " That is,<br>" +
+ " <table border=1><tr><td><code>" +
+ myExpression.getText() +
+ "</code></td></tr></table><br> becomes: <br>" +
+ " <table border=1><tr><td><code>" +
+ qualifierExpression.getText() +
+ ";<br>" +
+ qualifiedWithClassName.getText() +
+ " </code></td></tr></table></li>" +
+ " </body></html>";
}
- };
- dialog.show();
- int res = dialog.getExitCode();
- if (res == SideEffectWarningDialog.CANCEL) return false;
- try {
- if (res == SideEffectWarningDialog.MAKE_STATEMENT) {
- final PsiStatement statementFromText = factory.createStatementFromText(qualifierExpression.getText() + ";", null);
- final PsiStatement statement = PsiTreeUtil.getParentOfType(myExpression, PsiStatement.class);
- statement.getParent().addBefore(statementFromText, statement);
+ return "<html><body> There are possible side effects found in expression '" + qualifierExpression.getText() + "'<br>" +
+ "You can:<ul><li><b>Remove</b> class reference along with whole expressions involved, or</li></body></html>";
}
+ };
+ dialog.show();
+ int res = dialog.getExitCode();
+ if (res == RemoveUnusedVariableUtil.CANCEL) return false;
+ try {
+ if (res == RemoveUnusedVariableUtil.MAKE_STATEMENT) {
+ final PsiStatement statementFromText = factory.createStatementFromText(qualifierExpression.getText() + ";", null);
+ final PsiStatement statement = PsiTreeUtil.getParentOfType(myExpression, PsiStatement.class);
+ statement.getParent().addBefore(statementFromText, statement);
}
- catch (IncorrectOperationException e) {
- LOG.error(e);
- }
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
}
return true;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddVariableInitializerFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddVariableInitializerFix.java
index dff7b58..6bb1d53 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddVariableInitializerFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddVariableInitializerFix.java
@@ -16,7 +16,7 @@
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.diagnostic.Logger;
@@ -75,7 +75,7 @@
else {
LOG.error("Unknown variable type: "+myVariable);
}
- PsiVariable var = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(myVariable);
+ PsiVariable var = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(myVariable);
TextRange range = var.getInitializer().getTextRange();
int offset = range.getStartOffset();
editor.getCaretModel().moveToOffset(offset);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CastMethodArgumentFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CastMethodArgumentFix.java
index 554c87c..04a7b58 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CastMethodArgumentFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CastMethodArgumentFix.java
@@ -24,7 +24,7 @@
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.psi.*;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
@@ -38,10 +38,10 @@
@NotNull
public String getText() {
if (myArgList.getExpressions().length == 1) {
- return QuickFixBundle.message("cast.single.parameter.text", HighlightUtil.formatType(myToType));
+ return QuickFixBundle.message("cast.single.parameter.text", JavaHighlightUtil.formatType(myToType));
}
- return QuickFixBundle.message("cast.parameter.text", myIndex + 1, HighlightUtil.formatType(myToType));
+ return QuickFixBundle.message("cast.parameter.text", myIndex + 1, JavaHighlightUtil.formatType(myToType));
}
private static class MyFixerActionFactory extends ArgumentFixerActionFactory {
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java
index ba7171b..1fecce1 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java
@@ -19,7 +19,7 @@
import com.intellij.codeInsight.TargetElementUtil;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.find.FindManager;
import com.intellij.find.findUsages.FindUsagesHandler;
@@ -90,7 +90,7 @@
final String shortText = getShortText();
if (shortText != null) return shortText;
return QuickFixBundle.message("change.method.signature.from.usage.text",
- HighlightUtil.formatMethod(myTargetMethod),
+ JavaHighlightUtil.formatMethod(myTargetMethod),
myTargetMethod.getName(),
formatTypesList(myNewParametersInfo, myContext));
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeToAppendFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeToAppendFix.java
index 8c31230..0683af7 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeToAppendFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeToAppendFix.java
@@ -19,15 +19,13 @@
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.codeInspection.util.ChangeToAppendUtil;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
* @author Bas Leijdekkers
@@ -48,9 +46,10 @@
@Override
public String getText() {
return QuickFixBundle.message("change.to.append.text",
- buildAppendExpression(myAssignmentExpression.getRExpression(),
- myLhsType.equalsToText("java.lang.Appendable"),
- new StringBuilder(myAssignmentExpression.getLExpression().getText())));
+ ChangeToAppendUtil.buildAppendExpression(myAssignmentExpression.getRExpression(),
+ myLhsType.equalsToText("java.lang.Appendable"),
+ new StringBuilder(
+ myAssignmentExpression.getLExpression().getText())));
}
@NotNull
@@ -78,81 +77,8 @@
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;
final PsiExpression appendExpression =
- buildAppendExpression(myAssignmentExpression.getLExpression(), myAssignmentExpression.getRExpression());
+ ChangeToAppendUtil.buildAppendExpression(myAssignmentExpression.getLExpression(), myAssignmentExpression.getRExpression());
if (appendExpression == null) return;
myAssignmentExpression.replace(appendExpression);
}
-
- @Nullable
- public static PsiExpression buildAppendExpression(PsiExpression appendable, PsiExpression concatenation) {
- if (concatenation == null) return null;
- final PsiType type = appendable.getType();
- if (type == null) return null;
- final StringBuilder result =
- buildAppendExpression(concatenation, type.equalsToText("java.lang.Appendable"), new StringBuilder(appendable.getText()));
- if (result == null) return null;
- final PsiElementFactory factory = JavaPsiFacade.getElementFactory(appendable.getProject());
- return factory.createExpressionFromText(result.toString(), appendable);
- }
-
- @Nullable
- private static StringBuilder buildAppendExpression(PsiExpression concatenation, boolean useStringValueOf, @NonNls StringBuilder out)
- throws IncorrectOperationException {
- final PsiType type = concatenation.getType();
- if (type == null) {
- return null;
- }
- if (concatenation instanceof PsiPolyadicExpression && type.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
- PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)concatenation;
- final PsiExpression[] operands = polyadicExpression.getOperands();
- boolean isConstant = true;
- boolean isString = false;
- final StringBuilder builder = new StringBuilder();
- for (PsiExpression operand : operands) {
- if (isConstant && PsiUtil.isConstantExpression(operand)) {
- if (builder.length() != 0) {
- builder.append('+');
- }
- final PsiType operandType = operand.getType();
- if (operandType != null && operandType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
- isString = true;
- }
- builder.append(operand.getText());
- }
- else {
- isConstant = false;
- if (builder.length() != 0) {
- append(builder, useStringValueOf && !isString, out);
- builder.setLength(0);
- }
- buildAppendExpression(operand, useStringValueOf, out);
- }
- }
- if (builder.length() != 0) {
- append(builder, false, out);
- }
- }
- else if (concatenation instanceof PsiParenthesizedExpression) {
- final PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression)concatenation;
- final PsiExpression expression = parenthesizedExpression.getExpression();
- if (expression != null) {
- return buildAppendExpression(expression, useStringValueOf, out);
- }
- }
- else {
- append(concatenation.getText(), useStringValueOf && !type.equalsToText(CommonClassNames.JAVA_LANG_STRING), out);
- }
- return out;
- }
-
- private static void append(CharSequence text, boolean useStringValueOf, StringBuilder out) {
- out.append(".append(");
- if (useStringValueOf) {
- out.append("String.valueOf(").append(text).append(')');
- }
- else {
- out.append(text);
- }
- out.append(')');
- }
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertSwitchToIfIntention.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertSwitchToIfIntention.java
index 9b20330..a996525 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertSwitchToIfIntention.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertSwitchToIfIntention.java
@@ -92,7 +92,7 @@
final boolean hadSideEffects;
final String expressionText;
final Project project = switchStatement.getProject();
- if (RemoveUnusedVariableFix.checkSideEffects(switchExpression, null, new ArrayList<PsiElement>())) {
+ if (RemoveUnusedVariableUtil.checkSideEffects(switchExpression, null, new ArrayList<PsiElement>())) {
hadSideEffects = true;
final JavaCodeStyleManager javaCodeStyleManager =
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateCastExpressionFromInstanceofAction.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateCastExpressionFromInstanceofAction.java
index 35be223..ed56ce5 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateCastExpressionFromInstanceofAction.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateCastExpressionFromInstanceofAction.java
@@ -16,7 +16,7 @@
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
@@ -52,7 +52,7 @@
assert instanceOfExpression.getContainingFile() == file : instanceOfExpression.getContainingFile() + "; file="+file;
PsiElement decl = createAndInsertCast(instanceOfExpression, editor, file);
if (decl == null) return;
- decl = CodeStyleManager.getInstance(project).reformat(CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(decl));
+ decl = CodeStyleManager.getInstance(project).reformat(CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(decl));
editor.getCaretModel().moveToOffset(decl.getTextRange().getEndOffset());
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java
index 43bd4c0..ff1b786 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java
@@ -15,7 +15,7 @@
*/
package com.intellij.codeInsight.daemon.impl.quickfix;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.ExpectedTypesProvider;
import com.intellij.codeInsight.daemon.QuickFixBundle;
@@ -100,7 +100,7 @@
setupSuperCall(aClass, constructor, templateBuilder);
getReferenceElement(newExpression).bindToElement(aClass);
- aClass = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(aClass);
+ aClass = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(aClass);
final Template template = templateBuilder.buildTemplate();
template.setToReformat(true);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromCallFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromCallFix.java
index 7074f27..fa32f9f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromCallFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromCallFix.java
@@ -15,7 +15,7 @@
*/
package com.intellij.codeInsight.daemon.impl.quickfix;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.generation.OverrideImplementUtil;
import com.intellij.codeInsight.template.Template;
@@ -65,7 +65,7 @@
getTargetSubstitutor(myConstructorCall));
final PsiMethod superConstructor = CreateClassFromNewFix.setupSuperCall(targetClass, constructor, templateBuilder);
- constructor = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(constructor);
+ constructor = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(constructor);
Template template = templateBuilder.buildTemplate();
final Editor editor = positionCursor(project, targetClass.getContainingFile(), targetClass);
if (editor == null) return;
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromThisOrSuperFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromThisOrSuperFix.java
index 09fcdeb..f944fc7 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromThisOrSuperFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromThisOrSuperFix.java
@@ -16,7 +16,7 @@
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.CodeInsightUtil;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.template.Template;
import com.intellij.codeInsight.template.TemplateBuilderImpl;
@@ -95,7 +95,7 @@
templateBuilder.setEndVariableAfter(constructor.getBody().getLBrace());
final RangeMarker rangeMarker = psiFile.getViewProvider().getDocument().createRangeMarker(myMethodCall.getTextRange());
- constructor = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(constructor);
+ constructor = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(constructor);
targetClass = constructor.getContainingClass();
myMethodCall = CodeInsightUtil.findElementInRange(psiFile, rangeMarker.getStartOffset(), rangeMarker.getEndOffset(), myMethodCall.getClass());
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateEnumConstantFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateEnumConstantFromUsageFix.java
index 97c8f89..4972ed1 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateEnumConstantFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateEnumConstantFromUsageFix.java
@@ -15,12 +15,11 @@
*/
package com.intellij.codeInsight.daemon.impl.quickfix;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.ExpectedTypeUtil;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.intention.HighPriorityAction;
-import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.template.Template;
import com.intellij.codeInsight.template.TemplateBuilderImpl;
import com.intellij.openapi.diagnostic.Logger;
@@ -29,7 +28,6 @@
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
-import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
@@ -75,7 +73,7 @@
builder.replaceElement(expression, new EmptyExpression());
}
- enumConstant = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(enumConstant);
+ enumConstant = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(enumConstant);
final Template template = builder.buildTemplate();
final Project project = targetClass.getProject();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java
index 41ffc74..24ba71d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java
@@ -15,7 +15,7 @@
*/
package com.intellij.codeInsight.daemon.impl.quickfix;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.intention.impl.TypeExpression;
import com.intellij.codeInsight.template.Template;
@@ -110,7 +110,7 @@
CodeStyleSettingsManager.getSettings(project).GENERATE_FINAL_LOCALS && !CreateFromUsageUtils.isAccessedForWriting(expressions);
PsiUtil.setModifierProperty(var, PsiModifier.FINAL, isFinal);
- var = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(var);
+ var = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(var);
if (var == null) return;
TemplateBuilderImpl builder = new TemplateBuilderImpl(var);
builder.replaceElement(var.getTypeElement(), expression);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalVarFromInstanceofAction.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalVarFromInstanceofAction.java
index e34cbb0..9fc885e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalVarFromInstanceofAction.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalVarFromInstanceofAction.java
@@ -15,7 +15,7 @@
*/
package com.intellij.codeInsight.daemon.impl.quickfix;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.PsiEquivalenceUtil;
import com.intellij.codeInsight.daemon.QuickFixBundle;
@@ -206,7 +206,7 @@
final PsiStatement statementInside = isNegated(instanceOfExpression) ? null : getExpressionStatementInside(file, editor, instanceOfExpression.getOperand());
PsiDeclarationStatement decl = createLocalVariableDeclaration(instanceOfExpression, statementInside);
if (decl == null) return;
- decl = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(decl);
+ decl = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(decl);
PsiLocalVariable localVariable = (PsiLocalVariable)decl.getDeclaredElements()[0];
TemplateBuilderImpl builder = new TemplateBuilderImpl(localVariable);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java
index a7cc465..d3fb2c1 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java
@@ -15,7 +15,7 @@
*/
package com.intellij.codeInsight.daemon.impl.quickfix;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
@@ -214,7 +214,7 @@
ExpectedTypeInfo[] expectedTypes,
@Nullable final PsiElement context) {
- method = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(method);
+ method = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(method);
if (method == null) {
return;
@@ -231,7 +231,7 @@
.setupTypeElement(method.getReturnTypeElement(), expectedTypes, substitutor, builder, context, targetClass);
PsiCodeBlock body = method.getBody();
builder.setEndVariableAfter(shouldBeAbstract || body == null ? method : body.getLBrace());
- method = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(method);
+ method = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(method);
if (method == null) return;
RangeMarker rangeMarker = document.createRangeMarker(method.getTextRange());
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 2626335..c616859 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
@@ -15,7 +15,7 @@
*/
package com.intellij.codeInsight.daemon.impl.quickfix;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.completion.JavaLookupElementBuilder;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.intention.HighPriorityAction;
@@ -100,7 +100,7 @@
if (classes.isEmpty()) return false;
if (!checkTargetClasses(classes, methodName)) return false;
-
+
for (PsiClass aClass : classes) {
if (!aClass.isInterface()) {
setText(getterOrSetter);
@@ -242,13 +242,17 @@
}
accessor.setName(callText);
PsiUtil.setModifierProperty(accessor, PsiModifier.STATIC, isStatic);
+ final String modifier = PsiUtil.getMaximumModifierForMember(targetClass);
+ if (modifier != null) {
+ PsiUtil.setModifierProperty(accessor, modifier, true);
+ }
TemplateBuilderImpl builder = new TemplateBuilderImpl(accessor);
builder.replaceElement(typeReference, TYPE_VARIABLE, new TypeExpression(project, expectedTypes), true);
builder.replaceElement(fieldReference, FIELD_VARIABLE, new FieldExpression(field, targetClass, expectedTypes), true);
builder.setEndVariableAfter(body.getLBrace());
- accessor = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(accessor);
+ accessor = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(accessor);
LOG.assertTrue(accessor != null);
targetClass = accessor.getContainingClass();
LOG.assertTrue(targetClass != null);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteCatchFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteCatchFix.java
index 8ddf826..35d25d8 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteCatchFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteCatchFix.java
@@ -17,7 +17,7 @@
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
@@ -34,7 +34,7 @@
@Override
@NotNull
public String getText() {
- return QuickFixBundle.message("delete.catch.text", HighlightUtil.formatType(myCatchParameter.getType()));
+ return QuickFixBundle.message("delete.catch.text", JavaHighlightUtil.formatType(myCatchParameter.getType()));
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteMultiCatchFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteMultiCatchFix.java
index 69118b9..41e08d6 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteMultiCatchFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteMultiCatchFix.java
@@ -17,7 +17,7 @@
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
@@ -39,7 +39,7 @@
@NotNull
@Override
public String getText() {
- return QuickFixBundle.message("delete.catch.text", HighlightUtil.formatType(myTypeElement.getType()));
+ return QuickFixBundle.message("delete.catch.text", JavaHighlightUtil.formatType(myTypeElement.getType()));
}
@NotNull
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GeneralizeCatchFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GeneralizeCatchFix.java
index 4252711..b0c9790 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GeneralizeCatchFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GeneralizeCatchFix.java
@@ -17,7 +17,7 @@
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
@@ -41,8 +41,8 @@
@NotNull
public String getText() {
return QuickFixBundle.message("generalize.catch.text",
- HighlightUtil.formatType(myCatchParameter == null ? null : myCatchParameter.getType()),
- HighlightUtil.formatType(myUnhandledException));
+ JavaHighlightUtil.formatType(myCatchParameter == null ? null : myCatchParameter.getType()),
+ JavaHighlightUtil.formatType(myUnhandledException));
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java
index ca346d3..a2bebf6 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java
@@ -108,7 +108,7 @@
}
@Override
- protected List<PsiClass> filterByContext(List<PsiClass> candidates, PsiJavaCodeReferenceElement ref) {
+ protected List<PsiClass> filterByContext(@NotNull List<PsiClass> candidates, @NotNull PsiJavaCodeReferenceElement ref) {
PsiElement typeElement = ref.getParent();
if (typeElement instanceof PsiTypeElement) {
PsiElement var = typeElement.getParent();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java
index 1419aca..3e045a3 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java
@@ -58,6 +58,7 @@
* @author peter
*/
public abstract class ImportClassFixBase<T extends PsiElement, R extends PsiReference> implements HintAction, HighPriorityAction {
+ @NotNull
private final T myElement;
private final R myRef;
@@ -88,6 +89,13 @@
@NotNull
public List<PsiClass> getClassesToImport() {
+ if (myRef instanceof PsiJavaReference) {
+ JavaResolveResult result = ((PsiJavaReference)myRef).advancedResolve(true);
+ PsiElement element = result.getElement();
+ // already imported
+ // can happen when e.g. class name happened to be in a method position
+ if (element instanceof PsiClass && result.isValidResult()) return Collections.emptyList();
+ }
PsiShortNamesCache cache = PsiShortNamesCache.getInstance(myElement.getProject());
String name = getReferenceName(myRef);
GlobalSearchScope scope = myElement.getResolveScope();
@@ -149,7 +157,7 @@
return null;
}
- protected List<PsiClass> filterByContext(List<PsiClass> candidates, T ref) {
+ protected List<PsiClass> filterByContext(@NotNull List<PsiClass> candidates, @NotNull T ref) {
return candidates;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/InitializeFinalFieldInConstructorFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/InitializeFinalFieldInConstructorFix.java
index 09053e5..ea5e364 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/InitializeFinalFieldInConstructorFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/InitializeFinalFieldInConstructorFix.java
@@ -15,7 +15,7 @@
*/
package com.intellij.codeInsight.daemon.impl.quickfix;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.generation.PsiMethodMember;
@@ -113,7 +113,7 @@
T highest = null;
int highestTextOffset = Integer.MAX_VALUE;
for (T element : elements) {
- final T forcedElem = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(element);
+ final T forcedElem = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(element);
final int startOffset = forcedElem.getTextOffset();
if (startOffset < highestTextOffset) {
highest = forcedElem;
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JavaCreateFieldFromUsageHelper.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JavaCreateFieldFromUsageHelper.java
index 3fc0555..520f97f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JavaCreateFieldFromUsageHelper.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JavaCreateFieldFromUsageHelper.java
@@ -15,7 +15,7 @@
*/
package com.intellij.codeInsight.daemon.impl.quickfix;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.template.Template;
import com.intellij.codeInsight.template.TemplateBuilderImpl;
@@ -40,7 +40,7 @@
PsiSubstitutor substitutor) {
PsiElementFactory factory = JavaPsiFacade.getElementFactory(field.getProject());
- field = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(field);
+ field = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(field);
TemplateBuilderImpl builder = new TemplateBuilderImpl(field);
if (!(expectedTypes instanceof ExpectedTypeInfo[])) {
expectedTypes = ExpectedTypeInfo.EMPTY_ARRAY;
@@ -53,7 +53,7 @@
builder.replaceElement(field.getInitializer(), new EmptyExpression());
PsiIdentifier identifier = field.getNameIdentifier();
builder.setEndVariableAfter(identifier);
- field = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(field);
+ field = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(field);
}
editor.getCaretModel().moveToOffset(field.getTextRange().getStartOffset());
Template template = builder.buildInlineTemplate();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveCatchUpFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveCatchUpFix.java
index bdd618c..48fae89 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveCatchUpFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveCatchUpFix.java
@@ -17,7 +17,7 @@
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
@@ -44,8 +44,8 @@
@NotNull
public String getText() {
return QuickFixBundle.message("move.catch.up.text",
- HighlightUtil.formatType(myCatchSection.getCatchType()),
- HighlightUtil.formatType(myMoveBeforeSection.getCatchType()));
+ JavaHighlightUtil.formatType(myCatchSection.getCatchType()),
+ JavaHighlightUtil.formatType(myMoveBeforeSection.getCatchType()));
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveRedundantArgumentsFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveRedundantArgumentsFix.java
index 38f2c8a..8ca4195 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveRedundantArgumentsFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveRedundantArgumentsFix.java
@@ -18,7 +18,7 @@
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
@@ -50,7 +50,7 @@
@NotNull
@Override
public String getText() {
- return QuickFixBundle.message("remove.redundant.arguments.text", HighlightUtil.formatMethod(myTargetMethod));
+ return QuickFixBundle.message("remove.redundant.arguments.text", JavaHighlightUtil.formatMethod(myTargetMethod));
}
@NotNull
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableFix.java
index 3c67fa5..d779b1b 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableFix.java
@@ -27,13 +27,8 @@
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
-import com.intellij.psi.util.InheritanceUtil;
-import com.intellij.psi.util.PsiExpressionTrimRenderer;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilCore;
-import com.intellij.refactoring.psi.PropertyUtils;
+import com.intellij.psi.util.*;
import com.intellij.util.IncorrectOperationException;
-import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -75,21 +70,6 @@
removeVariableAndReferencingStatements(editor);
}
- private static void deleteReferences(PsiVariable variable, List<PsiElement> references, int mode) throws IncorrectOperationException {
- for (PsiElement expression : references) {
- processUsage(expression, variable, null, mode);
- }
- }
-
- private static void collectReferences(@NotNull PsiElement context, final PsiVariable variable, final List<PsiElement> references) {
- context.accept(new JavaRecursiveElementWalkingVisitor() {
- @Override public void visitReferenceExpression(PsiReferenceExpression expression) {
- if (expression.resolve() == variable) references.add(expression);
- super.visitReferenceExpression(expression);
- }
- });
- }
-
private void removeVariableAndReferencingStatements(Editor editor) {
final List<PsiElement> references = new ArrayList<PsiElement>();
final List<PsiElement> sideEffects = new ArrayList<PsiElement>();
@@ -97,13 +77,13 @@
try {
PsiElement context = myVariable instanceof PsiField ? ((PsiField)myVariable).getContainingClass() : PsiUtil.getVariableCodeBlock(myVariable, null);
if (context != null) {
- collectReferences(context, myVariable, references);
+ RemoveUnusedVariableUtil.collectReferences(context, myVariable, references);
}
// do not forget to delete variable declaration
references.add(myVariable);
// check for side effects
for (PsiElement element : references) {
- Boolean result = processUsage(element, myVariable, sideEffects, SideEffectWarningDialog.CANCEL);
+ Boolean result = RemoveUnusedVariableUtil.processUsage(element, myVariable, sideEffects, RemoveUnusedVariableUtil.CANCEL);
if (result == null) return;
canCopeWithSideEffects[0] &= result;
}
@@ -118,7 +98,7 @@
@Override
public void run() {
try {
- deleteReferences(myVariable, references, deleteMode);
+ RemoveUnusedVariableUtil.deleteReferences(myVariable, references, deleteMode);
}
catch (IncorrectOperationException e) {
LOG.error(e);
@@ -133,11 +113,11 @@
boolean canCopeWithSideEffects,
@NonNls String beforeText,
@NonNls String afterText) {
- if (sideEffects.isEmpty()) return SideEffectWarningDialog.DELETE_ALL;
+ if (sideEffects.isEmpty()) return RemoveUnusedVariableUtil.DELETE_ALL;
if (ApplicationManager.getApplication().isUnitTestMode()) {
return canCopeWithSideEffects
- ? SideEffectWarningDialog.MAKE_STATEMENT
- : SideEffectWarningDialog.DELETE_ALL;
+ ? RemoveUnusedVariableUtil.MAKE_STATEMENT
+ : RemoveUnusedVariableUtil.DELETE_ALL;
}
Project project = editor.getProject();
HighlightManager highlightManager = HighlightManager.getInstance(project);
@@ -163,235 +143,16 @@
final PsiElement sideEffect = sideEffects.get(0);
if (sideEffect instanceof PsiExpression) {
text = PsiExpressionTrimRenderer.render((PsiExpression)sideEffect);
- } else {
+ }
+ else {
text = sideEffect.getText();
}
}
return showSideEffectsWarning(sideEffects, variable, editor, canCopeWithSideEffects, text, text);
}
- /**
- *
- * @param element
- * @param variable
- * @param sideEffects if null, delete usages, otherwise collect side effects
- * @return true if there are at least one unrecoverable side effect found, false if no side effects,
- * null if read usage found (may happen if interval between fix creation in invoke() call was long enough)
- * @throws IncorrectOperationException
- */
- private static Boolean processUsage(PsiElement element, PsiVariable variable, List<PsiElement> sideEffects, int deleteMode)
- throws IncorrectOperationException {
- if (!element.isValid()) return null;
- PsiElementFactory factory = JavaPsiFacade.getInstance(variable.getProject()).getElementFactory();
- while (element != null) {
- if (element instanceof PsiAssignmentExpression) {
- PsiAssignmentExpression expression = (PsiAssignmentExpression)element;
- PsiExpression lExpression = expression.getLExpression();
- // there should not be read access to the variable, otherwise it is not unused
- if (!(lExpression instanceof PsiReferenceExpression) || variable != ((PsiReferenceExpression)lExpression).resolve()) {
- return null;
- }
- PsiExpression rExpression = expression.getRExpression();
- rExpression = PsiUtil.deparenthesizeExpression(rExpression);
- if (rExpression == null) return true;
- // replace assignment with expression and resimplify
- boolean sideEffectFound = checkSideEffects(rExpression, variable, sideEffects);
- if (!(element.getParent() instanceof PsiExpressionStatement) || PsiUtil.isStatement(rExpression)) {
- if (deleteMode == SideEffectWarningDialog.MAKE_STATEMENT ||
- deleteMode == SideEffectWarningDialog.DELETE_ALL && !(element.getParent() instanceof PsiExpressionStatement)) {
- element = replaceElementWithExpression(rExpression, factory, element);
- while (element.getParent() instanceof PsiParenthesizedExpression) {
- element = element.getParent().replace(element);
- }
- List<PsiElement> references = new ArrayList<PsiElement>();
- collectReferences(element, variable, references);
- deleteReferences(variable, references, deleteMode);
- }
- else if (deleteMode == SideEffectWarningDialog.DELETE_ALL) {
- deleteWholeStatement(element, factory);
- }
- return true;
- }
- else {
- if (deleteMode != SideEffectWarningDialog.CANCEL) {
- deleteWholeStatement(element, factory);
- }
- return !sideEffectFound;
- }
- }
- else if (element instanceof PsiExpressionStatement && deleteMode != SideEffectWarningDialog.CANCEL) {
- element.delete();
- break;
- }
- else if (element instanceof PsiVariable && element == variable) {
- PsiExpression expression = variable.getInitializer();
- if (expression != null) {
- expression = PsiUtil.deparenthesizeExpression(expression);
- }
- boolean sideEffectsFound = checkSideEffects(expression, variable, sideEffects);
- if (expression != null && PsiUtil.isStatement(expression) && variable instanceof PsiLocalVariable
- &&
- !(variable.getParent() instanceof PsiDeclarationStatement &&
- ((PsiDeclarationStatement)variable.getParent()).getDeclaredElements().length > 1)) {
- if (deleteMode == SideEffectWarningDialog.MAKE_STATEMENT) {
- element = element.replace(createStatementIfNeeded(expression, factory, element));
- List<PsiElement> references = new ArrayList<PsiElement>();
- collectReferences(element, variable, references);
- deleteReferences(variable, references, deleteMode);
- }
- else if (deleteMode == SideEffectWarningDialog.DELETE_ALL) {
- element.delete();
- }
- return true;
- }
- else {
- if (deleteMode != SideEffectWarningDialog.CANCEL) {
- if (element instanceof PsiField) {
- ((PsiField)element).normalizeDeclaration();
- }
- element.delete();
- }
- return !sideEffectsFound;
- }
- }
- element = element.getParent();
- }
- return true;
- }
-
- private static void deleteWholeStatement(PsiElement element, PsiElementFactory factory)
- throws IncorrectOperationException {
- // just delete it altogether
- if (element.getParent() instanceof PsiExpressionStatement) {
- PsiExpressionStatement parent = (PsiExpressionStatement)element.getParent();
- if (parent.getParent() instanceof PsiCodeBlock) {
- parent.delete();
- }
- else {
- // replace with empty statement (to handle with 'if (..) i=0;' )
- parent.replace(createStatementIfNeeded(null, factory, element));
- }
- }
- else {
- element.delete();
- }
- }
-
- private static PsiElement createStatementIfNeeded(PsiExpression expression,
- PsiElementFactory factory,
- PsiElement element) throws IncorrectOperationException {
- // if element used in expression, subexpression will do
- if (!(element.getParent() instanceof PsiExpressionStatement) &&
- !(element.getParent() instanceof PsiDeclarationStatement)) {
- return expression;
- }
- return factory.createStatementFromText((expression == null ? "" : expression.getText()) + ";", null);
- }
-
- private static PsiElement replaceElementWithExpression(PsiExpression expression,
- PsiElementFactory factory,
- PsiElement element) throws IncorrectOperationException {
- PsiElement elementToReplace = element;
- PsiElement expressionToReplaceWith = expression;
- if (element.getParent() instanceof PsiExpressionStatement) {
- elementToReplace = element.getParent();
- expressionToReplaceWith =
- factory.createStatementFromText((expression == null ? "" : expression.getText()) + ";", null);
- }
- else if (element.getParent() instanceof PsiDeclarationStatement) {
- expressionToReplaceWith =
- factory.createStatementFromText((expression == null ? "" : expression.getText()) + ";", null);
- }
- return elementToReplace.replace(expressionToReplaceWith);
- }
-
- public static boolean checkSideEffects(PsiElement element, PsiVariable variable, List<PsiElement> sideEffects) {
- if (sideEffects == null || element == null) return false;
- if (element instanceof PsiMethodCallExpression) {
- final PsiMethod psiMethod = ((PsiMethodCallExpression)element).resolveMethod();
- if (psiMethod == null || !PropertyUtils.isSimpleGetter(psiMethod) && !PropertyUtils.isSimpleSetter(psiMethod)) {
- sideEffects.add(element);
- return true;
- }
- }
- if (element instanceof PsiNewExpression) {
- PsiNewExpression newExpression = (PsiNewExpression)element;
- if (newExpression.getArrayDimensions().length == 0
- && newExpression.getArrayInitializer() == null
- && !isSideEffectFreeConstructor(newExpression)) {
- sideEffects.add(element);
- return true;
- }
- }
- if (element instanceof PsiAssignmentExpression
- && !(((PsiAssignmentExpression)element).getLExpression() instanceof PsiReferenceExpression
- && ((PsiReferenceExpression)((PsiAssignmentExpression)element).getLExpression()).resolve() == variable)) {
- sideEffects.add(element);
- return true;
- }
- PsiElement[] children = element.getChildren();
-
- for (PsiElement child : children) {
- checkSideEffects(child, variable, sideEffects);
- }
- return !sideEffects.isEmpty();
- }
-
- private static final Set<String> ourSideEffectFreeClasses = new THashSet<String>();
- static {
- ourSideEffectFreeClasses.add(Object.class.getName());
- ourSideEffectFreeClasses.add(Short.class.getName());
- ourSideEffectFreeClasses.add(Character.class.getName());
- ourSideEffectFreeClasses.add(Byte.class.getName());
- ourSideEffectFreeClasses.add(Integer.class.getName());
- ourSideEffectFreeClasses.add(Long.class.getName());
- ourSideEffectFreeClasses.add(Float.class.getName());
- ourSideEffectFreeClasses.add(Double.class.getName());
- ourSideEffectFreeClasses.add(String.class.getName());
- ourSideEffectFreeClasses.add(StringBuffer.class.getName());
- ourSideEffectFreeClasses.add(Boolean.class.getName());
-
- ourSideEffectFreeClasses.add(ArrayList.class.getName());
- ourSideEffectFreeClasses.add(Date.class.getName());
- ourSideEffectFreeClasses.add(HashMap.class.getName());
- ourSideEffectFreeClasses.add(HashSet.class.getName());
- ourSideEffectFreeClasses.add(Hashtable.class.getName());
- ourSideEffectFreeClasses.add(LinkedHashMap.class.getName());
- ourSideEffectFreeClasses.add(LinkedHashSet.class.getName());
- ourSideEffectFreeClasses.add(LinkedList.class.getName());
- ourSideEffectFreeClasses.add(Stack.class.getName());
- ourSideEffectFreeClasses.add(TreeMap.class.getName());
- ourSideEffectFreeClasses.add(TreeSet.class.getName());
- ourSideEffectFreeClasses.add(Vector.class.getName());
- ourSideEffectFreeClasses.add(WeakHashMap.class.getName());
- }
-
- private static boolean isSideEffectFreeConstructor(PsiNewExpression newExpression) {
- PsiJavaCodeReferenceElement classReference = newExpression.getClassReference();
- PsiClass aClass = classReference == null ? null : (PsiClass)classReference.resolve();
- String qualifiedName = aClass == null ? null : aClass.getQualifiedName();
- if (qualifiedName == null) return false;
- if (ourSideEffectFreeClasses.contains(qualifiedName)) return true;
-
- PsiFile file = aClass.getContainingFile();
- PsiDirectory directory = file.getContainingDirectory();
- PsiPackage classPackage = JavaDirectoryService.getInstance().getPackage(directory);
- String packageName = classPackage == null ? null : classPackage.getQualifiedName();
-
- // all Throwable descendants from java.lang are side effects free
- if ("java.lang".equals(packageName) || "java.io".equals(packageName)) {
- PsiClass throwableClass = JavaPsiFacade.getInstance(aClass.getProject()).findClass("java.lang.Throwable", aClass.getResolveScope());
- if (throwableClass != null && InheritanceUtil.isInheritorOrSelf(aClass, throwableClass, true)) {
- return true;
- }
- }
- return false;
- }
-
@Override
public boolean startInWriteAction() {
return false;
}
-
-
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SideEffectWarningDialog.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SideEffectWarningDialog.java
index 5a15f0f..5f30a43 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SideEffectWarningDialog.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SideEffectWarningDialog.java
@@ -39,9 +39,6 @@
private final boolean myCanCopeWithSideEffects;
private AbstractAction myRemoveAllAction;
private AbstractAction myCancelAllAction;
- public static final int MAKE_STATEMENT = 1;
- public static final int DELETE_ALL = 2;
- public static final int CANCEL = 0;
public SideEffectWarningDialog(Project project, boolean canBeParent, PsiVariable variable, String beforeText, String afterText, boolean canCopeWithSideEffects) {
super(project, canBeParent);
@@ -66,7 +63,7 @@
@Override
public void actionPerformed(ActionEvent e) {
- close(DELETE_ALL);
+ close(RemoveUnusedVariableUtil.DELETE_ALL);
}
};
@@ -79,7 +76,7 @@
@Override
public void actionPerformed(ActionEvent e) {
- close(MAKE_STATEMENT);
+ close(RemoveUnusedVariableUtil.MAKE_STATEMENT);
}
};
actions.add(makeStmtAction);
@@ -113,7 +110,7 @@
@Override
public void doCancelAction() {
- close(CANCEL);
+ close(RemoveUnusedVariableUtil.CANCEL);
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SuperMethodReturnFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SuperMethodReturnFix.java
index 8ff371f..6f48890 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SuperMethodReturnFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SuperMethodReturnFix.java
@@ -17,7 +17,7 @@
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
@@ -52,7 +52,7 @@
);
return QuickFixBundle.message("fix.super.method.return.type.text",
name,
- HighlightUtil.formatType(mySuperMethodType));
+ JavaHighlightUtil.formatType(mySuperMethodType));
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFix.java
index dad6f35..60e07b3 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFix.java
@@ -24,6 +24,7 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.TypeConversionUtil;
@@ -31,6 +32,8 @@
import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor;
import com.intellij.refactoring.changeSignature.JavaChangeSignatureDialog;
import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
+import com.intellij.refactoring.util.RefactoringUIUtil;
+import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -53,6 +56,7 @@
@Override
public String getText() {
return QuickFixBundle.message("fix.variable.type.text",
+ UsageViewUtil.getType(getStartElement()),
myName,
getReturnType().getCanonicalText());
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFromCallFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFromCallFix.java
index 7fd7876..1b43c1b 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFromCallFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFromCallFix.java
@@ -33,6 +33,8 @@
import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
import com.intellij.refactoring.typeMigration.TypeMigrationProcessor;
import com.intellij.refactoring.typeMigration.TypeMigrationRules;
+import com.intellij.usageView.UsageViewUtil;
+import com.intellij.usages.impl.UsageViewImpl;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
@@ -49,6 +51,7 @@
@NotNull
public String getText() {
return QuickFixBundle.message("fix.variable.type.text",
+ UsageViewUtil.getType(myVar),
myVar.getName(),
myExpressionType.getCanonicalText());
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java
index 92b9c8a..85ea365 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 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,7 +35,7 @@
if (!((PsiJavaCodeReferenceElement)element).isQualified()) {
final JavaResolveResult resolveResult = ((PsiJavaCodeReferenceElement)element).advancedResolve(false);
final PsiElement refElement = resolveResult.getElement();
- if (refElement != null && refElement.getContainingFile() != file) {
+ if (refElement != null) {
if (refElement instanceof PsiClass) {
if (refElement.getContainingFile() != element.getContainingFile()) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/DeclarationMover.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/DeclarationMover.java
index 4983733..25a1c5c 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/DeclarationMover.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/DeclarationMover.java
@@ -15,7 +15,7 @@
*/
package com.intellij.codeInsight.editorActions.moveUpDown;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -47,7 +47,7 @@
try {
PsiElement inserted = myEnumToInsertSemicolonAfter.getParent().addAfter(semicolon.getPsi(), myEnumToInsertSemicolonAfter);
- inserted = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(inserted);
+ inserted = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(inserted);
final LogicalPosition position = editor.offsetToLogicalPosition(inserted.getTextRange().getEndOffset());
info.toMove2 = new LineRange(position.line + 1, position.line + 1);
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/StatementMover.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/StatementMover.java
index 3d1983d..6b82868 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/StatementMover.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/StatementMover.java
@@ -16,7 +16,7 @@
package com.intellij.codeInsight.editorActions.moveUpDown;
import com.intellij.codeInsight.CodeInsightUtil;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.lang.StdLanguages;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
@@ -60,7 +60,7 @@
final PsiBlockStatement blockStatement = (PsiBlockStatement)factory.createStatementFromText("{}", statementToSurroundWithCodeBlock);
blockStatement.getCodeBlock().replace(codeBlock);
PsiBlockStatement newStatement = (PsiBlockStatement)statementToSurroundWithCodeBlock.replace(blockStatement);
- newStatement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(newStatement);
+ newStatement = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(newStatement);
info.toMove = new LineRange(document.getLineNumber(lineRangeMarker.getStartOffset()), document.getLineNumber(lineRangeMarker.getEndOffset())+1);
PsiCodeBlock newCodeBlock = newStatement.getCodeBlock();
if (down) {
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 2c91b12..25eec5f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java
@@ -28,7 +28,6 @@
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.*;
import com.intellij.psi.impl.light.LightTypeElement;
-import com.intellij.psi.impl.source.tree.LeafElement;
import com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.util.PsiTreeUtil;
@@ -263,10 +262,10 @@
copyDocComment(sourceMethod, resultMethod);
copyModifiers(sourceMethod.getModifierList(), resultMethod.getModifierList());
final PsiSubstitutor collisionResolvedSubstitutor =
- substituteTypeParameters(factory, target, sourceMethod.getTypeParameterList(), resultMethod.getTypeParameterList(), substitutor);
+ substituteTypeParameters(factory, target, sourceMethod.getTypeParameterList(), resultMethod.getTypeParameterList(), substitutor, sourceMethod);
substituteReturnType(PsiManager.getInstance(project), resultMethod, sourceMethod.getReturnType(), collisionResolvedSubstitutor);
substituteParameters(factory, codeStyleManager, sourceMethod.getParameterList(), resultMethod.getParameterList(), collisionResolvedSubstitutor, target);
- substituteThrows(factory, sourceMethod.getThrowsList(), resultMethod.getThrowsList(), collisionResolvedSubstitutor);
+ substituteThrows(factory, sourceMethod.getThrowsList(), resultMethod.getThrowsList(), collisionResolvedSubstitutor, sourceMethod);
return resultMethod;
}
catch (IncorrectOperationException e) {
@@ -285,14 +284,15 @@
@Nullable PsiElement target,
@Nullable PsiTypeParameterList sourceTypeParameterList,
@Nullable PsiTypeParameterList targetTypeParameterList,
- @NotNull PsiSubstitutor substitutor) {
+ @NotNull PsiSubstitutor substitutor,
+ @NotNull PsiMethod sourceMethod) {
if (sourceTypeParameterList == null || targetTypeParameterList == null) {
return substitutor;
}
final Map<PsiTypeParameter, PsiType> substitutionMap = new HashMap<PsiTypeParameter, PsiType>(substitutor.getSubstitutionMap());
for (PsiTypeParameter typeParam : sourceTypeParameterList.getTypeParameters()) {
- final PsiTypeParameter substitutedTypeParam = substituteTypeParameter(factory, typeParam, substitutor);
+ final PsiTypeParameter substitutedTypeParam = substituteTypeParameter(factory, typeParam, substitutor, sourceMethod);
final PsiTypeParameter resolvedTypeParam = resolveTypeParametersCollision(factory, sourceTypeParameterList, target, substitutedTypeParam, substitutor);
targetTypeParameterList.add(resolvedTypeParam);
@@ -347,7 +347,8 @@
@NotNull
private static PsiTypeParameter substituteTypeParameter(final @NotNull JVMElementFactory factory,
@NotNull PsiTypeParameter typeParameter,
- final @NotNull PsiSubstitutor substitutor) {
+ final @NotNull PsiSubstitutor substitutor,
+ @NotNull final PsiMethod sourceMethod) {
final PsiElement copy = typeParameter.copy();
final Map<PsiElement, PsiElement> replacementMap = new HashMap<PsiElement, PsiElement>();
copy.accept(new JavaRecursiveElementVisitor() {
@@ -357,7 +358,7 @@
final PsiElement resolve = reference.resolve();
if (resolve instanceof PsiTypeParameter) {
final PsiType type = factory.createType((PsiTypeParameter)resolve);
- replacementMap.put(reference, factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, type)));
+ replacementMap.put(reference, factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, type, sourceMethod)));
}
}
});
@@ -374,7 +375,7 @@
for (int i = 0; i < parameters.length; i++) {
PsiParameter parameter = parameters[i];
final PsiType parameterType = parameter.getType();
- final PsiType substituted = substituteType(substitutor, parameterType);
+ final PsiType substituted = substituteType(substitutor, parameterType, (PsiMethod)parameter.getDeclarationScope());
@NonNls String paramName = parameter.getName();
boolean isBaseNameGenerated = true;
final boolean isSubstituted = substituted.equals(parameterType);
@@ -400,17 +401,20 @@
private static void substituteThrows(@NotNull JVMElementFactory factory,
@NotNull PsiReferenceList sourceThrowsList,
@NotNull PsiReferenceList targetThrowsList,
- @NotNull PsiSubstitutor substitutor) {
+ @NotNull PsiSubstitutor substitutor,
+ @NotNull PsiMethod sourceMethod) {
for (PsiClassType thrownType : sourceThrowsList.getReferencedTypes()) {
- targetThrowsList.add(factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, thrownType)));
+ targetThrowsList.add(factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, thrownType, sourceMethod)));
}
}
private static void copyDocComment(PsiMethod source, PsiMethod target) {
final PsiElement navigationElement = source.getNavigationElement();
- final PsiDocComment docComment = ((PsiDocCommentOwner)navigationElement).getDocComment();
- if (docComment != null) {
- target.addAfter(docComment, null);
+ if (navigationElement instanceof PsiDocCommentOwner) {
+ final PsiDocComment docComment = ((PsiDocCommentOwner)navigationElement).getDocComment();
+ if (docComment != null) {
+ target.addAfter(docComment, null);
+ }
}
}
@@ -431,7 +435,7 @@
if (returnTypeElement == null || returnType == null) {
return;
}
- final PsiType substitutedReturnType = substituteType(substitutor, returnType);
+ final PsiType substitutedReturnType = substituteType(substitutor, returnType, method);
returnTypeElement.replace(new LightTypeElement(manager, substitutedReturnType instanceof PsiWildcardType ? TypeConversionUtil.erasure(substitutedReturnType) : substitutedReturnType));
}
@@ -449,7 +453,10 @@
return Arrays.asList(csManager.suggestVariableName(VariableKind.PARAMETER, null, null, parameterType).names).contains(paramName);
}
- private static PsiType substituteType(final PsiSubstitutor substitutor, final PsiType type) {
+ private static PsiType substituteType(final PsiSubstitutor substitutor, final PsiType type, @NotNull PsiTypeParameterListOwner owner) {
+ if (PsiUtil.isRawSubstitutor(owner, substitutor)) {
+ return TypeConversionUtil.erasure(type);
+ }
final PsiType psiType = substitutor.substitute(type);
if (psiType != null) {
final PsiType deepComponentType = psiType.getDeepComponentType();
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/JavaOverrideImplementMemberChooser.java b/java/java-impl/src/com/intellij/codeInsight/generation/JavaOverrideImplementMemberChooser.java
new file mode 100644
index 0000000..3708b5e
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/JavaOverrideImplementMemberChooser.java
@@ -0,0 +1,224 @@
+package com.intellij.codeInsight.generation;
+
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.util.MemberChooser;
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.keymap.KeymapManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.NotNullLazyValue;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.infos.CandidateInfo;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class JavaOverrideImplementMemberChooser extends MemberChooser<PsiMethodMember> {
+ private static final String SORT_METHODS_BY_PERCENT_DESCRIPTION = "Sort by Percent of Classes which Overrides a Method";
+
+ @NonNls public static final String PROP_COMBINED_OVERRIDE_IMPLEMENT = "OverrideImplement.combined";
+ @NonNls public static final String PROP_OVERRIDING_SORTED_OVERRIDE_IMPLEMENT = "OverrideImplement.overriding.sorted";
+
+ private ToggleAction mySortByOverridingAction;
+ private ToggleAction myMergeAction;
+ private final PsiMethodMember[] myAllElements;
+ private final PsiMethodMember[] myOnlyPrimaryElements;
+ private final NotNullLazyValue<PsiMethodWithOverridingPercentMember[]> myLazyElementsWithPercent;
+ private final boolean myToImplement;
+ private Project myProject;
+ private boolean myMerge;
+ private boolean mySortedByOverriding;
+
+ @Nullable
+ public static JavaOverrideImplementMemberChooser create(final PsiElement aClass,
+ final boolean toImplement,
+ final Collection<CandidateInfo> candidates,
+ final Collection<CandidateInfo> secondary) {
+ final Project project = aClass.getProject();
+ if (candidates.isEmpty() && secondary.isEmpty()) return null;
+
+ final PsiMethodMember[] onlyPrimary = convertToMethodMembers(candidates);
+ final PsiMethodMember[] all = ArrayUtil.mergeArrays(onlyPrimary, convertToMethodMembers(secondary));
+ final NotNullLazyValue<PsiMethodWithOverridingPercentMember[]> lazyElementsWithPercent =
+ new NotNullLazyValue<PsiMethodWithOverridingPercentMember[]>() {
+ @NotNull
+ @Override
+ protected PsiMethodWithOverridingPercentMember[] compute() {
+ final PsiMethodWithOverridingPercentMember[] elements =
+ PsiMethodWithOverridingPercentMember.calculateOverridingPercents(candidates);
+ Arrays.sort(elements, PsiMethodWithOverridingPercentMember.COMPARATOR);
+ return elements;
+ }
+ };
+ final boolean merge = PropertiesComponent.getInstance(project).getBoolean(PROP_COMBINED_OVERRIDE_IMPLEMENT, true);
+ final JavaOverrideImplementMemberChooser javaOverrideImplementMemberChooser =
+ new JavaOverrideImplementMemberChooser(all, onlyPrimary, lazyElementsWithPercent, project, PsiUtil.isLanguageLevel5OrHigher(aClass),
+ merge, toImplement, PropertiesComponent.getInstance(project)
+ .getBoolean(PROP_OVERRIDING_SORTED_OVERRIDE_IMPLEMENT, false));
+ javaOverrideImplementMemberChooser.setTitle(getChooserTitle(toImplement, merge));
+
+ javaOverrideImplementMemberChooser.setCopyJavadocVisible(true);
+
+ if (toImplement) {
+ javaOverrideImplementMemberChooser.selectElements(onlyPrimary);
+ }
+
+ if (ApplicationManager.getApplication().isUnitTestMode()) {
+ if (!toImplement || onlyPrimary.length == 0) {
+ javaOverrideImplementMemberChooser.selectElements(all);
+ }
+ javaOverrideImplementMemberChooser.close(DialogWrapper.OK_EXIT_CODE);
+ return javaOverrideImplementMemberChooser;
+ }
+ return javaOverrideImplementMemberChooser;
+ }
+
+ private JavaOverrideImplementMemberChooser(final PsiMethodMember[] allElements,
+ final PsiMethodMember[] onlyPrimaryElements,
+ final NotNullLazyValue<PsiMethodWithOverridingPercentMember[]> lazyElementsWithPercent,
+ final @NotNull Project project,
+ final boolean isInsertOverrideVisible,
+ final boolean merge,
+ final boolean toImplement,
+ final boolean sortedByOverriding) {
+ super(false, true, project, isInsertOverrideVisible, null, null);
+ myAllElements = allElements;
+ myOnlyPrimaryElements = onlyPrimaryElements;
+ myLazyElementsWithPercent = lazyElementsWithPercent;
+ myProject = project;
+ myMerge = merge;
+ myToImplement = toImplement;
+ mySortedByOverriding = sortedByOverriding;
+ resetElements(getInitialElements(allElements, onlyPrimaryElements, lazyElementsWithPercent, merge, toImplement, sortedByOverriding));
+ init();
+ }
+
+ private static PsiMethodMember[] getInitialElements(PsiMethodMember[] allElements,
+ PsiMethodMember[] onlyPrimaryElements,
+ NotNullLazyValue<PsiMethodWithOverridingPercentMember[]> lazyElementsWithPercent,
+ boolean merge,
+ boolean toImplement,
+ boolean sortByOverriding) {
+ final boolean showElementsWithPercents = sortByOverriding && !toImplement;
+ final PsiMethodMember[] defaultElements = toImplement || merge ? allElements : onlyPrimaryElements;
+ return showElementsWithPercents ? lazyElementsWithPercent.getValue() : defaultElements;
+ }
+
+
+ @Override
+ protected void onAlphabeticalSortingEnabled(final AnActionEvent event) {
+ resetElements(myToImplement || myMerge ? myAllElements : myOnlyPrimaryElements, null, true);
+ if (mySortByOverridingAction != null) {
+ mySortByOverridingAction.setSelected(event, false);
+ }
+ }
+
+ @Override
+ protected void doOKAction() {
+ super.doOKAction();
+ PropertiesComponent.getInstance(myProject).setValue(PROP_COMBINED_OVERRIDE_IMPLEMENT, String.valueOf(myMerge));
+ PropertiesComponent.getInstance(myProject).setValue(PROP_OVERRIDING_SORTED_OVERRIDE_IMPLEMENT, String.valueOf(mySortedByOverriding));
+ }
+
+ @Override
+ protected void fillToolbarActions(DefaultActionGroup group) {
+ super.fillToolbarActions(group);
+ if (myToImplement) return;
+
+ mySortByOverridingAction = new MySortByOverridingAction();
+ if (mySortedByOverriding) {
+ changeSortComparator(PsiMethodWithOverridingPercentMember.COMPARATOR);
+ }
+ group.add(mySortByOverridingAction, Constraints.FIRST);
+
+ myMergeAction = new MyMergeAction();
+ group.add(myMergeAction);
+ }
+
+ private static String getChooserTitle(final boolean toImplement, final boolean merge) {
+ return toImplement
+ ? CodeInsightBundle.message("methods.to.implement.chooser.title")
+ : merge
+ ? CodeInsightBundle.message("methods.to.override.implement.chooser.title")
+ : CodeInsightBundle.message("methods.to.override.chooser.title");
+ }
+
+ private static PsiMethodMember[] convertToMethodMembers(Collection<CandidateInfo> candidates) {
+ return ContainerUtil.map2Array(candidates, PsiMethodMember.class, new Function<CandidateInfo, PsiMethodMember>() {
+ @Override
+ public PsiMethodMember fun(final CandidateInfo s) {
+ return new PsiMethodMember(s);
+ }
+ });
+ }
+
+ private class MySortByOverridingAction extends ToggleAction {
+ public MySortByOverridingAction() {
+ super(SORT_METHODS_BY_PERCENT_DESCRIPTION, SORT_METHODS_BY_PERCENT_DESCRIPTION, AllIcons.ObjectBrowser.SortedByUsage);
+ registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.ALT_MASK)), myTree);
+ }
+
+ @Override
+ public boolean isSelected(final AnActionEvent e) {
+ return mySortedByOverriding;
+ }
+
+ @Override
+ public void setSelected(final AnActionEvent e, final boolean state) {
+ mySortedByOverriding = state;
+ if (state) {
+ if (myMerge) {
+ myMergeAction.setSelected(e, false);
+ }
+ disableAlphabeticalSorting(e);
+ final PsiMethodWithOverridingPercentMember[] elementsWithPercent = myLazyElementsWithPercent.getValue();
+ resetElements(elementsWithPercent, PsiMethodWithOverridingPercentMember.COMPARATOR, false);
+ }
+ else {
+ final PsiMethodMember[] elementsToRender = myMerge ? myAllElements : myOnlyPrimaryElements;
+ resetElementsWithDefaultComparator(elementsToRender, true);
+ }
+ }
+ }
+
+ private class MyMergeAction extends ToggleAction {
+ private MyMergeAction() {
+ super("Show methods to implement", "Show methods to implement", AllIcons.General.Show_to_implement);
+ registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_I, InputEvent.ALT_MASK)), myTree);
+ final Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts("OverrideMethods");
+ registerCustomShortcutSet(new CustomShortcutSet(shortcuts), myTree);
+ }
+
+ @Override
+ public boolean isSelected(AnActionEvent e) {
+ return myMerge;
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean state) {
+ myMerge = state;
+ if (state && mySortByOverridingAction.isSelected(e)) {
+ mySortByOverridingAction.setSelected(e, false);
+ }
+ resetElements(state ? myAllElements : myOnlyPrimaryElements, null, true);
+ setTitle(getChooserTitle(false, myMerge));
+ }
+ }
+
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
index 69205b4..68c3684 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 0-2 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,15 +22,14 @@
import com.intellij.codeInsight.intention.AddAnnotationFix;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.featureStatistics.ProductivityFeatureNames;
-import com.intellij.icons.AllIcons;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.ide.fileTemplates.FileTemplateUtil;
import com.intellij.ide.fileTemplates.JavaTemplateUtil;
import com.intellij.ide.util.MemberChooser;
-import com.intellij.ide.util.PropertiesComponent;
import com.intellij.lang.java.JavaLanguage;
-import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.KeyboardShortcut;
+import com.intellij.openapi.actionSystem.Shortcut;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
@@ -49,8 +48,6 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.Ref;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
@@ -61,7 +58,6 @@
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.*;
-import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
@@ -72,15 +68,11 @@
import javax.swing.*;
import java.awt.event.ActionEvent;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
import java.util.*;
public class OverrideImplementUtil extends OverrideImplementExploreUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.generation.OverrideImplementUtil");
- @NonNls private static final String PROP_COMBINED_OVERRIDE_IMPLEMENT = "OverrideImplement.combined";
-
private OverrideImplementUtil() { }
protected static MethodImplementor[] getImplementors() {
@@ -223,7 +215,7 @@
}
annotateOnOverrideImplement(result, aClass, method, insertOverrideIfPossible);
-
+
if (CodeStyleSettingsManager.getSettings(aClass.getProject()).REPEAT_SYNCHRONIZED && method.hasModifierProperty(PsiModifier.SYNCHRONIZED)) {
result.getModifierList().setModifierProperty(PsiModifier.SYNCHRONIZED, true);
}
@@ -379,7 +371,6 @@
final PsiCodeBlock body = result.getBody();
if (body != null) body.delete();
}
-
FileType fileType = FileTypeManager.getInstance().getFileTypeByExtension(template.getExtension());
PsiType returnType = result.getReturnType();
if (returnType == null) {
@@ -474,86 +465,29 @@
public static MemberChooser<PsiMethodMember> showOverrideImplementChooser(Editor editor,
final PsiElement aClass,
final boolean toImplement,
- Collection<CandidateInfo> candidates,
+ final Collection<CandidateInfo> candidates,
Collection<CandidateInfo> secondary) {
+
+ final JavaOverrideImplementMemberChooser chooser =
+ JavaOverrideImplementMemberChooser.create(aClass, toImplement, candidates, secondary);
+ if (chooser == null) {
+ return null;
+ }
Project project = aClass.getProject();
- if (candidates.isEmpty() && secondary.isEmpty()) return null;
-
- final PsiMethodMember[] onlyPrimary = convertToMethodMembers(candidates);
- final PsiMethodMember[] all = ArrayUtil.mergeArrays(onlyPrimary, convertToMethodMembers(secondary));
-
- final Ref<Boolean> merge = Ref.create(PropertiesComponent.getInstance(project).getBoolean(PROP_COMBINED_OVERRIDE_IMPLEMENT, true));
- final MemberChooser<PsiMethodMember> chooser =
- new MemberChooser<PsiMethodMember>(toImplement || merge.get() ? all : onlyPrimary, false, true, project, PsiUtil.isLanguageLevel5OrHigher(aClass)) {
- @Override
- protected void fillToolbarActions(DefaultActionGroup group) {
- super.fillToolbarActions(group);
- if (toImplement) return;
-
- final ToggleAction mergeAction = new ToggleAction("Show methods to implement", "Show methods to implement",
- AllIcons.General.Show_to_implement) {
- @Override
- public boolean isSelected(AnActionEvent e) {
- return merge.get().booleanValue();
- }
-
- @Override
- public void setSelected(AnActionEvent e, boolean state) {
- merge.set(state);
- resetElements(state ? all : onlyPrimary);
- setTitle(getChooserTitle(false, merge));
- }
- };
- mergeAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_I, InputEvent.ALT_MASK)), myTree);
-
- Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts("OverrideMethods");
- mergeAction.registerCustomShortcutSet(new CustomShortcutSet(shortcuts), myTree);
-
- group.add(mergeAction);
- }
- };
- chooser.setTitle(getChooserTitle(toImplement, merge));
registerHandlerForComplementaryAction(project, editor, aClass, toImplement, chooser);
- chooser.setCopyJavadocVisible(true);
-
- if (toImplement) {
- chooser.selectElements(onlyPrimary);
- }
-
if (ApplicationManager.getApplication().isUnitTestMode()) {
- if (!toImplement || onlyPrimary.length == 0) {
- chooser.selectElements(all);
- }
- chooser.close(DialogWrapper.OK_EXIT_CODE);
return chooser;
}
-
chooser.show();
if (chooser.getExitCode() != DialogWrapper.OK_EXIT_CODE) return null;
- PropertiesComponent.getInstance(project).setValue(PROP_COMBINED_OVERRIDE_IMPLEMENT, merge.get().toString());
return chooser;
}
- private static String getChooserTitle(boolean toImplement, Ref<Boolean> merge) {
- return toImplement
- ? CodeInsightBundle.message("methods.to.implement.chooser.title")
- : merge.get().booleanValue()
- ? CodeInsightBundle.message("methods.to.override.implement.chooser.title")
- : CodeInsightBundle.message("methods.to.override.chooser.title");
- }
-
- private static PsiMethodMember[] convertToMethodMembers(Collection<CandidateInfo> candidates) {
- return ContainerUtil.map2Array(candidates, PsiMethodMember.class, new Function<CandidateInfo, PsiMethodMember>() {
- @Override
- public PsiMethodMember fun(final CandidateInfo s) {
- return new PsiMethodMember(s);
- }
- });
- }
-
- private static void registerHandlerForComplementaryAction(final Project project, final Editor editor, final PsiElement aClass,
+ private static void registerHandlerForComplementaryAction(final Project project,
+ final Editor editor,
+ final PsiElement aClass,
final boolean toImplement,
final MemberChooser<PsiMethodMember> chooser) {
final JComponent preferredFocusedComponent = chooser.getPreferredFocusedComponent();
@@ -712,4 +646,4 @@
boolean insert = CodeStyleSettingsManager.getSettings(aClass.getProject()).INSERT_OVERRIDE_ANNOTATION;
return overrideOrImplementMethodCandidates(aClass, candidatesToImplement, copyJavadoc, insert);
}
-}
+}
\ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/PsiMethodWithOverridingPercentMember.java b/java/java-impl/src/com/intellij/codeInsight/generation/PsiMethodWithOverridingPercentMember.java
new file mode 100644
index 0000000..1d57d32
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/PsiMethodWithOverridingPercentMember.java
@@ -0,0 +1,157 @@
+package com.intellij.codeInsight.generation;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.PsiExtensibleClass;
+import com.intellij.psi.infos.CandidateInfo;
+import com.intellij.psi.search.searches.ClassInheritorsSearch;
+import com.intellij.ui.SimpleColoredComponent;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
+
+import javax.swing.*;
+import java.util.*;
+
+/**
+ * @author Dmitry Batkovich <dmitry.batkovich@jetbrains.com>
+ */
+public class PsiMethodWithOverridingPercentMember extends PsiMethodMember {
+
+ private final int myOverridingPercent;
+
+ public PsiMethodWithOverridingPercentMember(final CandidateInfo info, final int overridingPercent) {
+ super(info);
+ myOverridingPercent = overridingPercent;
+ }
+
+ @Override
+ public void renderTreeNode(final SimpleColoredComponent component, final JTree tree) {
+ component.append(myOverridingPercent + "% ", SimpleTextAttributes.GRAY_ATTRIBUTES);
+ super.renderTreeNode(component, tree);
+ }
+
+ @TestOnly
+ public int getOverridingPercent() {
+ return myOverridingPercent;
+ }
+
+ public static final Comparator<PsiMethodMember> COMPARATOR = new Comparator<PsiMethodMember>() {
+ @Override
+ public int compare(PsiMethodMember e1, PsiMethodMember e2) {
+ if (!(e1 instanceof PsiMethodWithOverridingPercentMember)) {
+ if (!(e2 instanceof PsiMethodWithOverridingPercentMember)) {
+ return e1.equals(e2) ? 0 : -1;
+ } else {
+ return -1;
+ }
+ }
+
+
+ if (!(e2 instanceof PsiMethodWithOverridingPercentMember)) {
+ return 1;
+ }
+ int sub =
+ ((PsiMethodWithOverridingPercentMember)e2).myOverridingPercent - ((PsiMethodWithOverridingPercentMember)e1).myOverridingPercent;
+ if (sub != 0) return sub;
+ return String.CASE_INSENSITIVE_ORDER.compare(e1.getText(), e2.getText());
+ }
+ };
+
+ @NotNull
+ public static PsiMethodWithOverridingPercentMember[] calculateOverridingPercents(@NotNull final Collection<CandidateInfo> candidateInfos) {
+ final List<PsiMethodWithOverridingPercentMember> result = new ArrayList<PsiMethodWithOverridingPercentMember>(candidateInfos.size());
+ final Map<String, Collection<PsiClass>> classShortNames2Inheritors = new HashMap<String, Collection<PsiClass>>();
+ for (final CandidateInfo candidateInfo : candidateInfos) {
+ final PsiMethod method = (PsiMethod)candidateInfo.getElement();
+ if (!method.hasModifierProperty(PsiModifier.FINAL) &&
+ !method.isConstructor() &&
+ !method.isDeprecated() &&
+ !EXCLUDED_JAVA_LANG_OBJECT_METHOD_NAMES.contains(method.getName())) {
+ final PsiClass containingClass = method.getContainingClass();
+ if (containingClass == null) {
+ continue;
+ }
+
+ final String classShortName = containingClass.getName();
+
+ Collection<PsiClass> allInheritors = classShortNames2Inheritors.get(classShortName);
+ if (allInheritors == null) {
+ allInheritors = ClassInheritorsSearch.search(containingClass, true).findAll();
+ classShortNames2Inheritors.put(classShortName, allInheritors);
+ }
+
+ final int allInheritorsCount = allInheritors.size() - 1;
+ if (allInheritorsCount > 0) {
+ final int percent = searchForOverridingCount(method, allInheritors) * 100 / allInheritorsCount;
+ if (percent > 1) {
+ result.add(new PsiMethodWithOverridingPercentMember(candidateInfo, percent));
+ }
+ }
+ }
+ }
+ return result.toArray(new PsiMethodWithOverridingPercentMember[result.size()]);
+ }
+
+ private static int searchForOverridingCount(final PsiMethod method, final Collection<PsiClass> containingClassInheritors) {
+ int counter = 0;
+ for (final PsiClass inheritor : containingClassInheritors) {
+ if (inheritor instanceof PsiExtensibleClass) {
+ final List<PsiMethod> ownMethods = ((PsiExtensibleClass)inheritor).getOwnMethods();
+ for (PsiMethod ownMethod : ownMethods) {
+ if (maybeSuper(method, ownMethod)) {
+ counter++;
+ break;
+ }
+ }
+
+ }
+ }
+ return counter;
+ }
+
+ private static boolean maybeSuper(@NotNull final PsiMethod superMethod, @NotNull final PsiMethod method) {
+ if (!superMethod.getName().equals(method.getName())) {
+ return false;
+ }
+ final PsiParameterList superMethodParameterList = superMethod.getParameterList();
+ final PsiParameterList methodParameterList = method.getParameterList();
+ if (superMethodParameterList.getParametersCount() != methodParameterList.getParametersCount()) {
+ return false;
+ }
+ final PsiParameter[] superMethodParameters = superMethodParameterList.getParameters();
+ final PsiParameter[] methodParameters = methodParameterList.getParameters();
+ for (int i = 0; i < methodParameters.length; i++) {
+ if (!StringUtil.equals(getTypeShortName(superMethodParameters[i].getType()), getTypeShortName(methodParameters[i].getType()))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Nullable
+ private static String getTypeShortName(@NotNull final PsiType type) {
+ if (type instanceof PsiPrimitiveType) {
+ return ((PsiPrimitiveType)type).getBoxedTypeName();
+ }
+ if (type instanceof PsiClassType) {
+ return ((PsiClassType)type).getClassName();
+ }
+ if (type instanceof PsiArrayType) {
+ return getTypeShortName(((PsiArrayType)type).getComponentType()) + "[]";
+ }
+ return null;
+ }
+
+ private static final Set<String> EXCLUDED_JAVA_LANG_OBJECT_METHOD_NAMES =
+ ContainerUtil.newHashSet("hashCode", "finalize", "clone", "equals", "toString");
+
+ @Override
+ public String toString() {
+ return "PsiMethodWithOverridingPercentMember{" +
+ "myOverridingPercent=" + myOverridingPercent + ", myElement=" + getElement() +
+ '}';
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateSuperMethodCallHandler.java b/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateSuperMethodCallHandler.java
index baa5638..81a98e9 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateSuperMethodCallHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateSuperMethodCallHandler.java
@@ -21,6 +21,7 @@
import com.intellij.codeInsight.CodeInsightActionHandler;
import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.generation.OverrideImplementUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.editor.Editor;
@@ -53,7 +54,7 @@
else {
toGo = body.addAfter(superCall, body.getLBrace());
}
- toGo = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(toGo);
+ toGo = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(toGo);
editor.getCaretModel().moveToOffset(toGo.getTextOffset());
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithForSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithForSurrounder.java
index 1055c46..e03e6c3 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithForSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithForSurrounder.java
@@ -17,7 +17,7 @@
package com.intellij.codeInsight.generation.surroundWith;
import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
@@ -58,13 +58,13 @@
bodyBlock.addRange(statements[0], statements[statements.length - 1]);
container.deleteChildRange(statements[0], statements[statements.length - 1]);
- forStatement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(forStatement);
+ forStatement = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(forStatement);
PsiStatement initialization = forStatement.getInitialization();
if (initialization == null) {
return null;
}
TextRange range1 = initialization.getTextRange();
-
+
PsiStatement update = forStatement.getUpdate();
if (update == null) {
return null;
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfElseExpressionSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfElseExpressionSurrounder.java
index f789f8ef..a753fc6 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfElseExpressionSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfElseExpressionSurrounder.java
@@ -17,7 +17,7 @@
package com.intellij.codeInsight.generation.surroundWith;
import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
@@ -45,8 +45,8 @@
PsiCodeBlock block = ((PsiBlockStatement)ifStatement.getThenBranch()).getCodeBlock();
- PsiStatement afterStatement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(block.getStatements()[0]);
-
+ PsiStatement afterStatement = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(block.getStatements()[0]);
+
TextRange range = afterStatement.getTextRange();
editor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset());
return new TextRange(range.getStartOffset(), range.getStartOffset());
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfElseSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfElseSurrounder.java
index 7c977e4..4ce38c1 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfElseSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfElseSurrounder.java
@@ -17,7 +17,7 @@
package com.intellij.codeInsight.generation.surroundWith;
import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
@@ -57,7 +57,7 @@
SurroundWithUtil.indentCommentIfNecessary(thenBlock, statements);
thenBlock.addRange(statements[0], statements[statements.length - 1]);
container.deleteChildRange(statements[0], statements[statements.length - 1]);
- ifStatement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(ifStatement);
+ ifStatement = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(ifStatement);
PsiExpression condition = ifStatement.getCondition();
if (condition == null) {
return null;
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfExpressionSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfExpressionSurrounder.java
index a52d0bb..0c492c9 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfExpressionSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfExpressionSurrounder.java
@@ -17,7 +17,7 @@
package com.intellij.codeInsight.generation.surroundWith;
import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
@@ -55,7 +55,7 @@
ifStatement = (PsiIfStatement)statement.replace(ifStatement);
PsiCodeBlock block = ((PsiBlockStatement)ifStatement.getThenBranch()).getCodeBlock();
- block = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(block);
+ block = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(block);
TextRange range = block.getStatements()[0].getTextRange();
editor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset());
return new TextRange(range.getStartOffset(), range.getStartOffset());
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfSurrounder.java
index 8e8454e..01d9840 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfSurrounder.java
@@ -17,7 +17,7 @@
package com.intellij.codeInsight.generation.surroundWith;
import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
@@ -57,7 +57,7 @@
container.deleteChildRange(statements[0], statements[statements.length - 1]);
}
- ifStatement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(ifStatement);
+ ifStatement = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(ifStatement);
if (ifStatement == null) {
return null;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNotInstanceofSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNotInstanceofSurrounder.java
index 8ea3c4d..cec501f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNotInstanceofSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNotInstanceofSurrounder.java
@@ -17,7 +17,7 @@
package com.intellij.codeInsight.generation.surroundWith;
import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
@@ -48,7 +48,7 @@
prefixExpr = (PsiPrefixExpression)expr.replace(prefixExpr);
parenthExpr = (PsiParenthesizedExpression)prefixExpr.getOperand();
instanceofExpr = (PsiInstanceOfExpression)parenthExpr.getExpression();
- instanceofExpr = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(instanceofExpr);
+ instanceofExpr = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(instanceofExpr);
TextRange range = instanceofExpr.getCheckType().getTextRange();
editor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset());
return new TextRange(range.getStartOffset(), range.getStartOffset());
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNullCheckSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNullCheckSurrounder.java
index 612c655..aa258ab 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNullCheckSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNullCheckSurrounder.java
@@ -16,7 +16,7 @@
*/
package com.intellij.codeInsight.generation.surroundWith;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
@@ -56,7 +56,7 @@
String oldText = statement.getText();
ifStatement = (PsiIfStatement)statement.replace(ifStatement);
PsiCodeBlock block = ((PsiBlockStatement)ifStatement.getThenBranch()).getCodeBlock();
- block = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(block);
+ block = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(block);
PsiElement replace = block.getStatements()[0].replace(factory.createStatementFromText(oldText, block));
int offset = replace.getTextRange().getEndOffset();
return new TextRange(offset, offset);
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithSynchronizedSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithSynchronizedSurrounder.java
index 1e2754c..a19980d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithSynchronizedSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithSynchronizedSurrounder.java
@@ -17,7 +17,7 @@
package com.intellij.codeInsight.generation.surroundWith;
import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
@@ -57,7 +57,7 @@
synchronizedBlock.addRange(statements[0], statements[statements.length - 1]);
container.deleteChildRange(statements[0], statements[statements.length - 1]);
- synchronizedStatement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(synchronizedStatement);
+ synchronizedStatement = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(synchronizedStatement);
PsiExpression lockExpression = synchronizedStatement.getLockExpression();
if (lockExpression == null) {
return null;
diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/actions/ShowSiblingsAction.java b/java/java-impl/src/com/intellij/codeInsight/hint/actions/ShowSiblingsAction.java
new file mode 100644
index 0000000..8a8bc91
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/hint/actions/ShowSiblingsAction.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2000-2013 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.codeInsight.hint.actions;
+
+import com.intellij.codeInsight.TargetElementUtilBase;
+import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator;
+import com.intellij.codeInsight.documentation.DocumentationManager;
+import com.intellij.ide.util.MethodCellRenderer;
+import com.intellij.ide.util.PsiClassListCellRenderer;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.TextEditor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.popup.JBPopup;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.FindSuperElementsHelper;
+import com.intellij.psi.presentation.java.SymbolPresentationUtil;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.Consumer;
+import org.jetbrains.annotations.Nullable;
+
+public class ShowSiblingsAction extends ShowImplementationsAction {
+ private static final Logger LOG = Logger.getInstance("#" + ShowSiblingsAction.class.getName());
+
+ public ShowSiblingsAction() {
+ super();
+ }
+
+ @Override
+ public void performForContext(DataContext dataContext, final boolean invokedByShortcut) {
+ final Project project = PlatformDataKeys.PROJECT.getData(dataContext);
+ final PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext);
+
+ if (project == null) return;
+
+ PsiDocumentManager.getInstance(project).commitAllDocuments();
+ final Editor editor = getEditor(dataContext);
+
+ PsiElement element = getElement(project, file, editor, LangDataKeys.PSI_ELEMENT.getData(dataContext));
+
+ if (element == null && file == null) return;
+ PsiFile containingFile = element != null ? element.getContainingFile() : file;
+ if (containingFile == null || !containingFile.getViewProvider().isPhysical()) return;
+
+
+ if (editor != null) {
+ PsiReference ref = TargetElementUtilBase.findReference(editor, editor.getCaretModel().getOffset());
+ if (element == null && ref != null) {
+ element = TargetElementUtilBase.getInstance().adjustReference(ref);
+ }
+ }
+
+ final NavigatablePsiElement[] superElements = (NavigatablePsiElement[])findSuperElements(element);
+ if (superElements == null || superElements.length == 0) return;
+
+ final boolean isMethod = superElements[0] instanceof PsiMethod;
+ final JBPopup popup = PsiElementListNavigator.navigateOrCreatePopup(superElements, "Choose super " + (isMethod ? "method" : "class or interface"), "Super " + (isMethod ? "methods" : "classes/interfaces"),
+ isMethod ? new MethodCellRenderer(false) : new PsiClassListCellRenderer(), null, new Consumer<Object[]>() {
+ @Override
+ public void consume(Object[] objects) {
+ showSiblings(invokedByShortcut, project, editor, file, editor != null, (PsiElement)objects[0]);
+ }
+ });
+ if (popup != null) {
+ if (editor != null) {
+ popup.showInBestPositionFor(editor);
+ } else {
+ popup.showCenteredInCurrentWindow(project);
+ }
+ }
+ }
+
+ private void showSiblings(boolean invokedByShortcut,
+ Project project,
+ Editor editor,
+ PsiFile file,
+ boolean invokedFromEditor,
+ PsiElement element) {
+ final PsiElement[] impls = getSelfAndImplementations(editor, element, createImplementationsSearcher(), false);
+ final String text = SymbolPresentationUtil.getSymbolPresentableText(element);
+ showImplementations(impls, project, text, editor, file, element, invokedFromEditor, invokedByShortcut);
+ }
+
+ @Override
+ protected boolean isIncludeAlwaysSelf() {
+ return false;
+ }
+
+ @Nullable
+ private static PsiElement[] findSuperElements(final PsiElement element) {
+ PsiNameIdentifierOwner parent = PsiTreeUtil.getParentOfType(element, PsiMethod.class, PsiClass.class);
+ if (parent == null) {
+ return null;
+ }
+
+ return FindSuperElementsHelper.findSuperElements(parent);
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConvertAbsolutePathToRelativeIntentionAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConvertAbsolutePathToRelativeIntentionAction.java
index 3cb7547..63df5bf 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConvertAbsolutePathToRelativeIntentionAction.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConvertAbsolutePathToRelativeIntentionAction.java
@@ -24,6 +24,7 @@
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceOwner;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
+import com.intellij.psi.impl.source.resolve.reference.impl.providers.PsiFileReference;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -64,9 +65,9 @@
}
}
else if (original instanceof FileReferenceOwner) {
- final FileReference fileReference = ((FileReferenceOwner)original).getLastFileReference();
- if (fileReference != null) {
- return fileReference;
+ final PsiFileReference fileReference = ((FileReferenceOwner)original).getLastFileReference();
+ if (fileReference instanceof FileReference) {
+ return (FileReference)fileReference;
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SimplifyBooleanExpressionAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SimplifyBooleanExpressionAction.java
index 8b98816..3ae3ddc 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SimplifyBooleanExpressionAction.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SimplifyBooleanExpressionAction.java
@@ -39,7 +39,7 @@
@Override
@NotNull
public String getFamilyName() {
- return new SimplifyBooleanExpressionFix(null,null).getFamilyName();
+ return SimplifyBooleanExpressionFix.FAMILY_NAME;
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java
index 124636c..c55a21b 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java
@@ -21,6 +21,7 @@
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.QuickFixFactory;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
+import com.intellij.codeInspection.LocalQuickFixOnPsiElement;
import com.intellij.psi.*;
import com.intellij.psi.util.PropertyMemberType;
import com.intellij.psi.util.ClassKind;
@@ -77,10 +78,10 @@
}
@Override
- public LocalQuickFixAndIntentionActionOnPsiElement createMethodThrowsFix(@NotNull PsiMethod method,
- @NotNull PsiClassType exceptionClass,
- boolean shouldThrow,
- boolean showContainingClass) {
+ public LocalQuickFixOnPsiElement createMethodThrowsFix(@NotNull PsiMethod method,
+ @NotNull PsiClassType exceptionClass,
+ boolean shouldThrow,
+ boolean showContainingClass) {
return new MethodThrowsFix(method, exceptionClass, shouldThrow, showContainingClass);
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java b/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java
index e93cd0d..9e89d7a 100644
--- a/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java
+++ b/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -225,7 +225,7 @@
if (!psiClass.getManager().areElementsEquivalent(resolved, psiClass) && !PsiUtil.isInnerClass(psiClass)) {
// inner class name should be shown qualified if its not accessible by single name
PsiClass aClass = psiClass.getContainingClass();
- while (aClass != null && !PsiUtil.isInnerClass(aClass)) {
+ while (aClass != null && !PsiUtil.isInnerClass(aClass) && aClass.getName() != null) {
name = aClass.getName() + '.' + name;
allStrings.add(name);
aClass = aClass.getContainingClass();
@@ -275,6 +275,9 @@
presentation.setItemText(((PsiType)object).getCanonicalText());
presentation.setItemTextBold(getAttribute(LookupItem.HIGHLIGHTED_ATTR) != null || object instanceof PsiPrimitiveType);
+ if (isAddArrayInitializer()) {
+ presentation.setTailText("{...}");
+ }
}
if (myBracketsCount > 0) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaArrayInitializerUnwrapper.java b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaArrayInitializerUnwrapper.java
new file mode 100644
index 0000000..59dec48
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaArrayInitializerUnwrapper.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2013 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.codeInsight.unwrap;
+
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.psi.PsiArrayInitializerExpression;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiNewExpression;
+import com.intellij.psi.PsiVariable;
+import com.intellij.util.IncorrectOperationException;
+
+public class JavaArrayInitializerUnwrapper extends JavaUnwrapper {
+
+ public JavaArrayInitializerUnwrapper() {
+ super(CodeInsightBundle.message("unwrap.array.initializer"));
+ }
+
+ @Override
+ public boolean isApplicableTo(PsiElement e) {
+ if (e instanceof PsiArrayInitializerExpression) {
+ final PsiElement gParent = e.getParent();
+ if (gParent instanceof PsiNewExpression && gParent.getParent() instanceof PsiVariable) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException {
+ final PsiArrayInitializerExpression arrayInitializerExpression = (PsiArrayInitializerExpression)element;
+ final PsiElement newExpression = arrayInitializerExpression.getParent();
+ context.extractElement(arrayInitializerExpression, newExpression);
+ context.deleteExactly(newExpression);
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java
index e69505e..deda060 100644
--- a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java
@@ -22,6 +22,7 @@
@Override
protected Unwrapper[] createUnwrappers() {
return new Unwrapper[]{
+ new JavaArrayInitializerUnwrapper(),
new JavaMethodParameterUnwrapper(),
new JavaElseUnwrapper(),
new JavaElseRemover(),
diff --git a/java/java-impl/src/com/intellij/codeInspection/MoveToPackageFix.java b/java/java-impl/src/com/intellij/codeInspection/MoveToPackageFix.java
index 983c4fa..3fd32c3 100644
--- a/java/java-impl/src/com/intellij/codeInspection/MoveToPackageFix.java
+++ b/java/java-impl/src/com/intellij/codeInspection/MoveToPackageFix.java
@@ -99,10 +99,4 @@
LOG.error(e);
}
}
-
- public boolean startInWriteAction() {
- return false;
- }
-
-
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/SurroundWithIfFix.java b/java/java-impl/src/com/intellij/codeInspection/SurroundWithIfFix.java
index 72aaf61..3bdbc7c 100644
--- a/java/java-impl/src/com/intellij/codeInspection/SurroundWithIfFix.java
+++ b/java/java-impl/src/com/intellij/codeInspection/SurroundWithIfFix.java
@@ -60,7 +60,7 @@
if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;
PsiElement[] elements = {anchorStatement};
PsiElement prev = PsiTreeUtil.skipSiblingsBackward(anchorStatement, PsiWhiteSpace.class);
- if (prev instanceof PsiComment && SuppressManager.getInstance().getSuppressedInspectionIdsIn(prev) != null) {
+ if (prev instanceof PsiComment && JavaSuppressionUtil.getSuppressedInspectionIdsIn(prev) != null) {
elements = new PsiElement[]{prev, anchorStatement};
}
try {
diff --git a/java/java-impl/src/com/intellij/codeInspection/accessStaticViaInstance/AccessStaticViaInstance.java b/java/java-impl/src/com/intellij/codeInspection/accessStaticViaInstance/AccessStaticViaInstance.java
index 26afc96..46994c9 100644
--- a/java/java-impl/src/com/intellij/codeInspection/accessStaticViaInstance/AccessStaticViaInstance.java
+++ b/java/java-impl/src/com/intellij/codeInspection/accessStaticViaInstance/AccessStaticViaInstance.java
@@ -15,92 +15,19 @@
*/
package com.intellij.codeInspection.accessStaticViaInstance;
-import com.intellij.codeInsight.daemon.JavaErrorMessages;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightMessageUtil;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
import com.intellij.codeInsight.daemon.impl.quickfix.AccessStaticViaInstanceFix;
-import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableFix;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
-import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.ProblemsHolder;
-import com.intellij.psi.*;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
+import com.intellij.psi.JavaResolveResult;
+import com.intellij.psi.PsiReferenceExpression;
/**
* User: anna
* Date: 15-Nov-2005
*/
-public class AccessStaticViaInstance extends BaseJavaLocalInspectionTool {
-
- public static final String ACCESS_STATIC_VIA_INSTANCE = "AccessStaticViaInstance";
-
+public class AccessStaticViaInstance extends AccessStaticViaInstanceBase {
@Override
- @NotNull
- public String getGroupDisplayName() {
- return "";
- }
-
- @Override
- @NotNull
- public String getDisplayName() {
- return InspectionsBundle.message("access.static.via.instance");
- }
-
- @Override
- @NotNull
- @NonNls
- public String getShortName() {
- return ACCESS_STATIC_VIA_INSTANCE;
- }
-
- @Override
- public String getAlternativeID() {
- return "static-access";
- }
-
- @Override
- public boolean isEnabledByDefault() {
- return true;
- }
-
- @Override
- @NotNull
- public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
- return new JavaElementVisitor() {
- @Override public void visitReferenceExpression(PsiReferenceExpression expression) {
- checkAccessStaticMemberViaInstanceReference(expression, holder, isOnTheFly);
- }
- };
- }
-
- private static void checkAccessStaticMemberViaInstanceReference(PsiReferenceExpression expr, ProblemsHolder holder, boolean onTheFly) {
- JavaResolveResult result = expr.advancedResolve(false);
- PsiElement resolved = result.getElement();
-
- if (!(resolved instanceof PsiMember)) return;
- PsiExpression qualifierExpression = expr.getQualifierExpression();
- if (qualifierExpression == null) return;
-
- if (qualifierExpression instanceof PsiReferenceExpression) {
- final PsiElement qualifierResolved = ((PsiReferenceExpression)qualifierExpression).resolve();
- if (qualifierResolved instanceof PsiClass || qualifierResolved instanceof PsiPackage) {
- return;
- }
- }
- if (!((PsiMember)resolved).hasModifierProperty(PsiModifier.STATIC)) return;
-
- String description = JavaErrorMessages.message("static.member.accessed.via.instance.reference",
- HighlightUtil.formatType(qualifierExpression.getType()),
- HighlightMessageUtil.getSymbolName(resolved, result.getSubstitutor()));
- if (!onTheFly) {
- if (RemoveUnusedVariableFix.checkSideEffects(qualifierExpression, null, new ArrayList<PsiElement>())) {
- holder.registerProblem(expr, description);
- return;
- }
- }
- holder.registerProblem(expr, description, new AccessStaticViaInstanceFix(expr, result, onTheFly));
+ protected AccessStaticViaInstanceFix createAccessStaticViaInstanceFix(PsiReferenceExpression expr,
+ boolean onTheFly,
+ JavaResolveResult result) {
+ return new AccessStaticViaInstanceFix(expr, result, onTheFly);
}
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ConditionCheckDialog.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ConditionCheckDialog.java
index 4e05e24..3363d94 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ConditionCheckDialog.java
+++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ConditionCheckDialog.java
@@ -46,13 +46,13 @@
*/
public class ConditionCheckDialog extends DialogWrapper {
private final Project myProject;
- private final @NotNull Splitter mainSplitter;
- private final @NotNull MethodsPanel myIsNullCheckMethodPanel;
- private final @NotNull MethodsPanel myIsNotNullCheckMethodPanel;
- private final @NotNull MethodsPanel myAssertIsNullMethodPanel;
- private final @NotNull MethodsPanel myAssertIsNotNullMethodPanel;
- private final @NotNull MethodsPanel myAssertTrueMethodPanel;
- private final @NotNull MethodsPanel myAssertFalseMethodPanel;
+ @NotNull private final Splitter mainSplitter;
+ @NotNull private final MethodsPanel myIsNullCheckMethodPanel;
+ @NotNull private final MethodsPanel myIsNotNullCheckMethodPanel;
+ @NotNull private final MethodsPanel myAssertIsNullMethodPanel;
+ @NotNull private final MethodsPanel myAssertIsNotNullMethodPanel;
+ @NotNull private final MethodsPanel myAssertTrueMethodPanel;
+ @NotNull private final MethodsPanel myAssertFalseMethodPanel;
public ConditionCheckDialog(Project project, String mainDialogTitle) {
super(project, true);
@@ -140,12 +140,12 @@
* Is Null, Is Not Null, Assert True and Assert False Method Panel at the top of the main Dialog.
*/
class MethodsPanel {
- private final @NotNull JBList myList;
- private final @NotNull JPanel myPanel;
- private final @NotNull Project myProject;
+ @NotNull private final JBList myList;
+ @NotNull private final JPanel myPanel;
+ @NotNull private final Project myProject;
private Set<MethodsPanel> otherPanels;
- public MethodsPanel(final List<ConditionChecker> checkers, final ConditionChecker.Type type, final @NotNull Project myProject) {
+ public MethodsPanel(final List<ConditionChecker> checkers, final ConditionChecker.Type type, @NotNull final Project myProject) {
this.myProject = myProject;
myList = new JBList(new CollectionListModel<ConditionChecker>(checkers));
myPanel = new JPanel(new BorderLayout());
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java
index c4b90e7..348d3df 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -13,43 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/*
- * Created by IntelliJ IDEA.
- * User: max
- * Date: Dec 24, 2001
- * Time: 2:46:32 PM
- * To change template for new class use
- * Code Style | Class Templates options (Tools | IDE Options).
- */
package com.intellij.codeInspection.dataFlow;
-import com.intellij.codeInsight.AnnotationUtil;
-import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.NullableNotNullDialog;
-import com.intellij.codeInsight.NullableNotNullManager;
-import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInsight.daemon.impl.quickfix.SimplifyBooleanExpressionFix;
-import com.intellij.codeInsight.intention.impl.AddNullableAnnotationFix;
-import com.intellij.codeInspection.*;
-import com.intellij.codeInspection.dataFlow.instructions.*;
-import com.intellij.codeInspection.ex.BaseLocalInspectionTool;
+import com.intellij.codeInspection.InspectionsBundle;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.SurroundWithIfFix;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
-import com.intellij.openapi.util.Pair;
-import com.intellij.pom.java.LanguageLevel;
-import com.intellij.psi.*;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.SmartList;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import com.intellij.psi.PsiExpression;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
@@ -57,497 +31,20 @@
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.util.*;
import java.util.List;
-public class DataFlowInspection extends BaseLocalInspectionTool {
- private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.DataFlowInspection");
- @NonNls private static final String SHORT_NAME = "ConstantConditions";
- public boolean SUGGEST_NULLABLE_ANNOTATIONS = false;
- public boolean DONT_REPORT_TRUE_ASSERT_STATEMENTS = false;
-
+public class DataFlowInspection extends DataFlowInspectionBase {
+ @Override
+ protected void addSurroundWithIfFix(PsiExpression qualifier, List<LocalQuickFix> fixes) {
+ if (SurroundWithIfFix.isAvailable(qualifier)) {
+ fixes.add(new SurroundWithIfFix(qualifier));
+ }
+ }
@Override
public JComponent createOptionsPanel() {
return new OptionsPanel();
}
- @Override
- @NotNull
- public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
- return new JavaElementVisitor() {
- @Override
- public void visitField(PsiField field) {
- analyzeCodeBlock(field, holder);
- }
-
- @Override
- public void visitMethod(PsiMethod method) {
- analyzeCodeBlock(method.getBody(), holder);
- }
-
- @Override
- public void visitClassInitializer(PsiClassInitializer initializer) {
- analyzeCodeBlock(initializer.getBody(), holder);
- }
- };
- }
-
- private void analyzeCodeBlock(@Nullable final PsiElement scope, ProblemsHolder holder) {
- if (scope == null) return;
- final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner(SUGGEST_NULLABLE_ANNOTATIONS);
- final StandardInstructionVisitor visitor = new DataFlowInstructionVisitor(dfaRunner);
- final RunnerResult rc = dfaRunner.analyzeMethod(scope, visitor);
- if (rc == RunnerResult.OK) {
- if (dfaRunner.problemsDetected(visitor)) {
- createDescription(dfaRunner, holder, visitor);
- }
- }
- else if (rc == RunnerResult.TOO_COMPLEX) {
- if (scope.getParent() instanceof PsiMethod) {
- PsiMethod method = (PsiMethod)scope.getParent();
- final PsiIdentifier name = method.getNameIdentifier();
- if (name != null) { // Might be null for synthetic methods like JSP page.
- holder.registerProblem(name, InspectionsBundle.message("dataflow.too.complex"), ProblemHighlightType.WEAK_WARNING);
- }
- }
- }
- }
-
- @Nullable
- private static LocalQuickFix[] createNPEFixes(PsiExpression qualifier, PsiExpression expression) {
- if (qualifier == null || expression == null) return null;
- if (qualifier instanceof PsiMethodCallExpression) return null;
- if (qualifier instanceof PsiLiteralExpression && ((PsiLiteralExpression)qualifier).getValue() == null) return null;
-
- try {
- final List<LocalQuickFix> fixes = new SmartList<LocalQuickFix>();
-
- if (PsiUtil.getLanguageLevel(qualifier).isAtLeast(LanguageLevel.JDK_1_4)) {
- final Project project = qualifier.getProject();
- final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
- final PsiBinaryExpression binary = (PsiBinaryExpression)elementFactory.createExpressionFromText("a != null", null);
- binary.getLOperand().replace(qualifier);
- fixes.add(new AddAssertStatementFix(binary));
- }
-
- if (SurroundWithIfFix.isAvailable(qualifier)) {
- fixes.add(new SurroundWithIfFix(qualifier));
- }
- if (ReplaceWithTernaryOperatorFix.isAvailable(qualifier, expression)) {
- fixes.add(new ReplaceWithTernaryOperatorFix(qualifier));
- }
- return fixes.toArray(new LocalQuickFix[fixes.size()]);
- }
- catch (IncorrectOperationException e) {
- LOG.error(e);
- return null;
- }
- }
-
- private void createDescription(StandardDataFlowRunner runner, ProblemsHolder holder, StandardInstructionVisitor visitor) {
- Pair<Set<Instruction>, Set<Instruction>> constConditions = runner.getConstConditionalExpressions();
- Set<Instruction> trueSet = constConditions.getFirst();
- Set<Instruction> falseSet = constConditions.getSecond();
-
- ArrayList<Instruction> allProblems = new ArrayList<Instruction>();
- allProblems.addAll(trueSet);
- allProblems.addAll(falseSet);
- allProblems.addAll(runner.getNPEInstructions());
- allProblems.addAll(runner.getCCEInstructions());
- allProblems.addAll(StandardDataFlowRunner.getRedundantInstanceofs(runner, visitor));
-
- Collections.sort(allProblems, new Comparator<Instruction>() {
- @Override
- public int compare(Instruction i1, Instruction i2) {
- return i1.getIndex() - i2.getIndex();
- }
- });
-
- HashSet<PsiElement> reportedAnchors = new HashSet<PsiElement>();
-
- for (Instruction instruction : allProblems) {
- if (instruction instanceof MethodCallInstruction) {
- reportCallMayProduceNpe(holder, (MethodCallInstruction)instruction);
- }
- else if (instruction instanceof FieldReferenceInstruction) {
- reportFieldAccessMayProduceNpe(holder, (FieldReferenceInstruction)instruction);
- }
- else if (instruction instanceof TypeCastInstruction) {
- reportCastMayFail(holder, (TypeCastInstruction)instruction);
- }
- else if (instruction instanceof BranchingInstruction) {
- handleBranchingInstruction(holder, visitor, trueSet, falseSet, reportedAnchors, (BranchingInstruction)instruction);
- }
- }
-
- reportNullableArguments(runner, holder);
- reportNullableAssignments(runner, holder);
- reportUnboxedNullables(runner, holder);
- reportNullableReturns(runner, holder);
- reportNullableArgumentsPassedToNonAnnotated(runner, holder);
- }
-
- private static void reportNullableArgumentsPassedToNonAnnotated(StandardDataFlowRunner runner, ProblemsHolder holder) {
- Set<PsiExpression> exprs = runner.getNullableArgumentsPassedToNonAnnotatedParam();
- for (PsiExpression expr : exprs) {
- final String text = isNullLiteralExpression(expr)
- ? "Passing <code>null</code> argument to non annotated parameter"
- : "Argument <code>#ref</code> #loc might be null but passed to non annotated parameter";
- LocalQuickFix[] fixes = createNPEFixes(expr, expr);
- final PsiElement parent = expr.getParent();
- if (parent instanceof PsiExpressionList) {
- final int idx = ArrayUtil.find(((PsiExpressionList)parent).getExpressions(), expr);
- if (idx > -1) {
- final PsiElement gParent = parent.getParent();
- if (gParent instanceof PsiCallExpression) {
- final PsiMethod psiMethod = ((PsiCallExpression)gParent).resolveMethod();
- if (psiMethod != null && psiMethod.getManager().isInProject(psiMethod) && AnnotationUtil.isAnnotatingApplicable(psiMethod)) {
- final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
- if (idx < parameters.length) {
- final AddNullableAnnotationFix addNullableAnnotationFix = new AddNullableAnnotationFix(parameters[idx]);
- fixes = fixes == null ? new LocalQuickFix[]{addNullableAnnotationFix} : ArrayUtil.append(fixes, addNullableAnnotationFix);
- holder.registerProblem(expr, text, fixes);
- }
- }
- }
- }
- }
-
- }
- }
-
- private static void reportCallMayProduceNpe(ProblemsHolder holder, MethodCallInstruction mcInstruction) {
- if (mcInstruction.getCallExpression() instanceof PsiMethodCallExpression) {
- PsiMethodCallExpression callExpression = (PsiMethodCallExpression)mcInstruction.getCallExpression();
- LocalQuickFix[] fix = createNPEFixes(callExpression.getMethodExpression().getQualifierExpression(), callExpression);
-
- holder.registerProblem(callExpression,
- InspectionsBundle.message("dataflow.message.npe.method.invocation"),
- fix);
- }
- }
-
- private static void reportFieldAccessMayProduceNpe(ProblemsHolder holder, FieldReferenceInstruction frInstruction) {
- PsiElement elementToAssert = frInstruction.getElementToAssert();
- PsiExpression expression = frInstruction.getExpression();
- if (expression instanceof PsiArrayAccessExpression) {
- LocalQuickFix[] fix = createNPEFixes((PsiExpression)elementToAssert, expression);
- holder.registerProblem(expression,
- InspectionsBundle.message("dataflow.message.npe.array.access"),
- fix);
- }
- else {
- LocalQuickFix[] fix = createNPEFixes((PsiExpression)elementToAssert, expression);
- holder.registerProblem(elementToAssert,
- InspectionsBundle.message("dataflow.message.npe.field.access"),
- fix);
- }
- }
-
- private static void reportCastMayFail(ProblemsHolder holder, TypeCastInstruction instruction) {
- PsiTypeCastExpression typeCast = instruction.getCastExpression();
- holder.registerProblem(typeCast.getCastType(),
- InspectionsBundle.message("dataflow.message.cce", typeCast.getOperand().getText()));
- }
-
- private void handleBranchingInstruction(ProblemsHolder holder,
- StandardInstructionVisitor visitor,
- Set<Instruction> trueSet,
- Set<Instruction> falseSet, HashSet<PsiElement> reportedAnchors, BranchingInstruction instruction) {
- PsiElement psiAnchor = instruction.getPsiAnchor();
- boolean underBinary = isAtRHSOfBooleanAnd(psiAnchor);
- if (instruction instanceof InstanceofInstruction && visitor.isInstanceofRedundant((InstanceofInstruction)instruction)) {
- if (visitor.canBeNull((BinopInstruction)instruction)) {
- holder.registerProblem(psiAnchor,
- InspectionsBundle.message("dataflow.message.redundant.instanceof"),
- new RedundantInstanceofFix());
- }
- else {
- final LocalQuickFix localQuickFix = createSimplifyBooleanExpressionFix(psiAnchor, true);
- holder.registerProblem(psiAnchor,
- InspectionsBundle.message(underBinary ? "dataflow.message.constant.condition.when.reached" : "dataflow.message.constant.condition", Boolean.toString(true)),
- localQuickFix == null ? null : new LocalQuickFix[]{localQuickFix});
- }
- }
- else if (psiAnchor instanceof PsiSwitchLabelStatement) {
- if (falseSet.contains(instruction)) {
- holder.registerProblem(psiAnchor,
- InspectionsBundle.message("dataflow.message.unreachable.switch.label"));
- }
- }
- else if (psiAnchor != null && !reportedAnchors.contains(psiAnchor) && !isCompileConstantInIfCondition(psiAnchor)) {
- boolean evaluatesToTrue = trueSet.contains(instruction);
- if (onTheLeftSideOfConditionalAssignemnt(psiAnchor)) {
- holder.registerProblem(
- psiAnchor,
- InspectionsBundle.message("dataflow.message.pointless.assignment.expression", Boolean.toString(evaluatesToTrue)),
- createSimplifyToAssignmentFix()
- );
- }
- else if (!skipReportingConstantCondition(visitor, psiAnchor, evaluatesToTrue)) {
- final LocalQuickFix fix = createSimplifyBooleanExpressionFix(psiAnchor, evaluatesToTrue);
- String message = InspectionsBundle.message(underBinary ?
- "dataflow.message.constant.condition.when.reached" :
- "dataflow.message.constant.condition", Boolean.toString(evaluatesToTrue));
- holder.registerProblem(psiAnchor, message, fix == null ? null : new LocalQuickFix[]{fix});
- }
- reportedAnchors.add(psiAnchor);
- }
- }
-
- private boolean skipReportingConstantCondition(StandardInstructionVisitor visitor, PsiElement psiAnchor, boolean evaluatesToTrue) {
- return DONT_REPORT_TRUE_ASSERT_STATEMENTS && isAssertionEffectively(psiAnchor, evaluatesToTrue) ||
- visitor.silenceConstantCondition(psiAnchor);
- }
-
- private static void reportNullableArguments(StandardDataFlowRunner runner, ProblemsHolder holder) {
- Set<PsiExpression> exprs = runner.getNullableArguments();
- for (PsiExpression expr : exprs) {
- final String text = isNullLiteralExpression(expr)
- ? InspectionsBundle.message("dataflow.message.passing.null.argument")
- : InspectionsBundle.message("dataflow.message.passing.nullable.argument");
- LocalQuickFix[] fixes = createNPEFixes(expr, expr);
- holder.registerProblem(expr, text, fixes);
- }
- }
-
- private static void reportNullableAssignments(StandardDataFlowRunner runner, ProblemsHolder holder) {
- for (PsiExpression expr : runner.getNullableAssignments()) {
- final String text = isNullLiteralExpression(expr)
- ? InspectionsBundle.message("dataflow.message.assigning.null")
- : InspectionsBundle.message("dataflow.message.assigning.nullable");
- holder.registerProblem(expr, text);
- }
- }
-
- private static void reportUnboxedNullables(StandardDataFlowRunner runner, ProblemsHolder holder) {
- for (PsiExpression expr : runner.getUnboxedNullables()) {
- holder.registerProblem(expr, InspectionsBundle.message("dataflow.message.unboxing"));
- }
- }
-
- private static void reportNullableReturns(StandardDataFlowRunner runner, ProblemsHolder holder) {
- for (PsiReturnStatement statement : runner.getNullableReturns()) {
- final PsiExpression expr = statement.getReturnValue();
- if (runner.isInNotNullMethod()) {
- final String text = isNullLiteralExpression(expr)
- ? InspectionsBundle.message("dataflow.message.return.null.from.notnull")
- : InspectionsBundle.message("dataflow.message.return.nullable.from.notnull");
- holder.registerProblem(expr, text);
- }
- else if (AnnotationUtil.isAnnotatingApplicable(statement)) {
- final String text = isNullLiteralExpression(expr)
- ? InspectionsBundle.message("dataflow.message.return.null.from.notnullable")
- : InspectionsBundle.message("dataflow.message.return.nullable.from.notnullable");
- final NullableNotNullManager manager = NullableNotNullManager.getInstance(expr.getProject());
- holder.registerProblem(expr, text, new AnnotateMethodFix(manager.getDefaultNullable(), ArrayUtil.toStringArray(manager.getNotNulls())));
- }
- }
- }
-
- private static boolean isAssertionEffectively(PsiElement psiAnchor, boolean evaluatesToTrue) {
- PsiElement parent = psiAnchor.getParent();
- if (parent instanceof PsiAssertStatement) {
- return evaluatesToTrue;
- }
- if (parent instanceof PsiIfStatement && psiAnchor == ((PsiIfStatement)parent).getCondition()) {
- PsiStatement thenBranch = ((PsiIfStatement)parent).getThenBranch();
- if (thenBranch instanceof PsiThrowStatement) {
- return !evaluatesToTrue;
- }
- if (thenBranch instanceof PsiBlockStatement) {
- PsiStatement[] statements = ((PsiBlockStatement)thenBranch).getCodeBlock().getStatements();
- if (statements.length == 1 && statements[0] instanceof PsiThrowStatement) {
- return !evaluatesToTrue;
- }
- }
- }
- return false;
- }
-
- private static boolean isAtRHSOfBooleanAnd(PsiElement expr) {
- PsiElement cur = expr;
-
- while (cur != null && !(cur instanceof PsiMember)) {
- PsiElement parent = cur.getParent();
-
- if (parent instanceof PsiBinaryExpression && cur == ((PsiBinaryExpression)parent).getROperand()) {
- return true;
- }
-
- cur = parent;
- }
-
- return false;
- }
-
- private static boolean isCompileConstantInIfCondition(PsiElement element) {
- if (!(element instanceof PsiReferenceExpression)) return false;
- PsiElement resolved = ((PsiReferenceExpression)element).resolve();
- if (!(resolved instanceof PsiField)) return false;
- PsiField field = (PsiField)resolved;
-
- if (!field.hasModifierProperty(PsiModifier.FINAL)) return false;
- if (!field.hasModifierProperty(PsiModifier.STATIC)) return false;
-
- PsiElement parent = element.getParent();
- if (parent instanceof PsiPrefixExpression && ((PsiPrefixExpression)parent).getOperationTokenType() == JavaTokenType.EXCL) {
- element = parent;
- parent = parent.getParent();
- }
- return parent instanceof PsiIfStatement && ((PsiIfStatement)parent).getCondition() == element;
- }
-
- private static boolean isNullLiteralExpression(PsiExpression expr) {
- if (expr instanceof PsiLiteralExpression) {
- final PsiLiteralExpression literalExpression = (PsiLiteralExpression)expr;
- return PsiType.NULL.equals(literalExpression.getType());
- }
- return false;
- }
-
- private static boolean onTheLeftSideOfConditionalAssignemnt(final PsiElement psiAnchor) {
- final PsiElement parent = psiAnchor.getParent();
- if (parent instanceof PsiAssignmentExpression) {
- final PsiAssignmentExpression expression = (PsiAssignmentExpression)parent;
- if (expression.getLExpression() == psiAnchor) return true;
- }
- return false;
- }
-
- @Nullable
- private static LocalQuickFix createSimplifyBooleanExpressionFix(PsiElement element, final boolean value) {
- SimplifyBooleanExpressionFix fix = createIntention(element, value);
- if (fix == null) return null;
- final String text = fix.getText();
- return new LocalQuickFix() {
- @Override
- @NotNull
- public String getName() {
- return text;
- }
-
- @Override
- public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
- final PsiElement psiElement = descriptor.getPsiElement();
- if (psiElement == null) return;
- final SimplifyBooleanExpressionFix fix = createIntention(psiElement, value);
- if (fix == null) return;
- try {
- LOG.assertTrue(psiElement.isValid());
- fix.invoke(project, null, psiElement.getContainingFile());
- }
- catch (IncorrectOperationException e) {
- LOG.error(e);
- }
- }
-
- @Override
- @NotNull
- public String getFamilyName() {
- return InspectionsBundle.message("inspection.data.flow.simplify.boolean.expression.quickfix");
- }
- };
- }
-
- @NotNull
- private static LocalQuickFix createSimplifyToAssignmentFix() {
- return new LocalQuickFix() {
- @NotNull
- @Override
- public String getName() {
- return InspectionsBundle.message("inspection.data.flow.simplify.to.assignment.quickfix.name");
- }
-
- @NotNull
- @Override
- public String getFamilyName() {
- return InspectionsBundle.message("inspection.data.flow.simplify.boolean.expression.quickfix");
- }
-
- @Override
- public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
- final PsiElement psiElement = descriptor.getPsiElement();
- if (psiElement == null) return;
-
- final PsiAssignmentExpression assignmentExpression = PsiTreeUtil.getParentOfType(psiElement, PsiAssignmentExpression.class);
- if (assignmentExpression == null) {
- return;
- }
-
- final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
- final String lExpressionText = assignmentExpression.getLExpression().getText();
- final PsiExpression rExpression = assignmentExpression.getRExpression();
- final String rExpressionText = rExpression != null ? rExpression.getText() : "";
- assignmentExpression.replace(factory.createExpressionFromText(lExpressionText + " = " + rExpressionText, psiElement));
- }
- };
- }
-
- private static SimplifyBooleanExpressionFix createIntention(PsiElement element, boolean value) {
- if (!(element instanceof PsiExpression)) return null;
- final PsiExpression expression = (PsiExpression)element;
- while (element.getParent() instanceof PsiExpression) {
- element = element.getParent();
- }
- final SimplifyBooleanExpressionFix fix = new SimplifyBooleanExpressionFix(expression, value);
- // simplify intention already active
- if (!fix.isAvailable(element.getProject(), null, element.getContainingFile()) ||
- SimplifyBooleanExpressionFix.canBeSimplified((PsiExpression)element)) {
- return null;
- }
- return fix;
- }
-
- private static class RedundantInstanceofFix implements LocalQuickFix {
- @Override
- @NotNull
- public String getName() {
- return InspectionsBundle.message("inspection.data.flow.redundant.instanceof.quickfix");
- }
-
- @Override
- public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
- if (!FileModificationService.getInstance().preparePsiElementForWrite(descriptor.getPsiElement())) return;
- final PsiElement psiElement = descriptor.getPsiElement();
- if (psiElement instanceof PsiInstanceOfExpression) {
- try {
- final PsiExpression compareToNull = JavaPsiFacade.getInstance(psiElement.getProject()).getElementFactory().
- createExpressionFromText(((PsiInstanceOfExpression)psiElement).getOperand().getText() + " != null", psiElement.getParent());
- psiElement.replace(compareToNull);
- }
- catch (IncorrectOperationException e) {
- LOG.error(e);
- }
- }
- }
-
- @Override
- @NotNull
- public String getFamilyName() {
- return getName();
- }
- }
-
-
- @Override
- @NotNull
- public String getDisplayName() {
- return InspectionsBundle.message("inspection.data.flow.display.name");
- }
-
- @Override
- @NotNull
- public String getGroupDisplayName() {
- return GroupNames.BUGS_GROUP_NAME;
- }
-
- @Override
- @NotNull
- public String getShortName() {
- return SHORT_NAME;
- }
-
private class OptionsPanel extends JPanel {
private final JCheckBox mySuggestNullables;
private final JCheckBox myDontReportTrueAsserts;
@@ -627,47 +124,4 @@
}
}
- private static class DataFlowInstructionVisitor extends StandardInstructionVisitor {
- private final StandardDataFlowRunner myRunner;
-
- private DataFlowInstructionVisitor(StandardDataFlowRunner runner) {
- myRunner = runner;
- }
-
- @Override
- protected void onAssigningToNotNullableVariable(AssignInstruction instruction) {
- myRunner.onAssigningToNotNullableVariable(instruction.getRExpression());
- }
-
- @Override
- protected void onNullableReturn(CheckReturnValueInstruction instruction) {
- myRunner.onNullableReturn(instruction.getReturn());
- }
-
- @Override
- protected void onInstructionProducesCCE(TypeCastInstruction instruction) {
- myRunner.onInstructionProducesCCE(instruction);
- }
-
- @Override
- protected void onInstructionProducesNPE(Instruction instruction) {
- if (instruction instanceof MethodCallInstruction &&
- ((MethodCallInstruction)instruction).getMethodType() == MethodCallInstruction.MethodType.UNBOXING) {
- myRunner.onUnboxingNullable(((MethodCallInstruction)instruction).getContext());
- }
- else {
- myRunner.onInstructionProducesNPE(instruction);
- }
- }
-
- @Override
- protected void onPassingNullParameter(PsiExpression arg) {
- myRunner.onPassingNullParameter(arg);
- }
-
- @Override
- protected void onPassingNullParameterToNonAnnotated(DataFlowRunner runner, PsiExpression arg) {
- myRunner.onPassingNullParameterToNonAnnotated(arg);
- }
- }
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java
deleted file mode 100644
index 9529296..0000000
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Copyright 2000-2009 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.codeInsight.NullableNotNullManager;
-import com.intellij.codeInspection.dataFlow.instructions.AssignInstruction;
-import com.intellij.codeInspection.dataFlow.instructions.Instruction;
-import com.intellij.codeInspection.dataFlow.instructions.PushInstruction;
-import com.intellij.codeInspection.dataFlow.value.DfaValue;
-import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
-import com.intellij.codeInspection.nullable.NullableStuffInspection;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.MultiValuesMap;
-import com.intellij.openapi.util.Ref;
-import com.intellij.psi.*;
-import com.intellij.psi.search.LocalSearchScope;
-import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.util.CachedValue;
-import com.intellij.psi.util.CachedValueProvider;
-import com.intellij.psi.util.CachedValuesManager;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.util.NullableFunction;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.containers.Stack;
-import gnu.trove.THashSet;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.*;
-
-/**
- * @author Gregory.Shrago
- */
-public class DfaUtil {
- private static final Key<CachedValue<MultiValuesMap<PsiVariable, PsiExpression>>> DFA_VARIABLE_INFO_KEY = Key.create("DFA_VARIABLE_INFO_KEY");
-
- private DfaUtil() {
- }
-
- private static final MultiValuesMap<PsiVariable, PsiExpression> TOO_COMPLEX = new MultiValuesMap<PsiVariable, PsiExpression>();
- @Nullable("null means DFA analysis has failed (too complex to analyze)")
- public static Collection<PsiExpression> getCachedVariableValues(@Nullable final PsiVariable variable, @Nullable final PsiElement context) {
- if (variable == null || context == null) return Collections.emptyList();
-
- CachedValue<MultiValuesMap<PsiVariable, PsiExpression>> cachedValue = context.getUserData(DFA_VARIABLE_INFO_KEY);
- if (cachedValue == null) {
- final PsiElement codeBlock = getEnclosingCodeBlock(variable, context);
- cachedValue = CachedValuesManager.getManager(context.getProject()).createCachedValue(new CachedValueProvider<MultiValuesMap<PsiVariable, PsiExpression>>() {
- @Override
- public Result<MultiValuesMap<PsiVariable, PsiExpression>> compute() {
- final MultiValuesMap<PsiVariable, PsiExpression> result;
- if (codeBlock == null) {
- result = null;
- }
- else {
- final ValuableInstructionVisitor visitor = new ValuableInstructionVisitor(context);
- RunnerResult runnerResult = new ValuableDataFlowRunner().analyzeMethod(codeBlock, visitor);
- if (runnerResult == RunnerResult.OK) {
- result = visitor.myValues;
- }
- else {
- result = TOO_COMPLEX;
- }
- }
- return new Result<MultiValuesMap<PsiVariable, PsiExpression>>(result, codeBlock);
- }
- }, false);
- context.putUserData(DFA_VARIABLE_INFO_KEY, cachedValue);
- }
- final MultiValuesMap<PsiVariable, PsiExpression> value = cachedValue.getValue();
- if (value == TOO_COMPLEX) return null;
- final Collection<PsiExpression> expressions = value == null ? null : value.get(variable);
- return expressions == null ? Collections.<PsiExpression>emptyList() : expressions;
- }
-
- @NotNull
- public static Nullness getElementNullability(@Nullable PsiType resultType, @Nullable PsiModifierListOwner owner) {
- if (owner == null) {
- return Nullness.UNKNOWN;
- }
-
- if (NullableNotNullManager.isNullable(owner)) {
- return Nullness.NULLABLE;
- }
- if (NullableNotNullManager.isNotNull(owner)) {
- return Nullness.NOT_NULL;
- }
-
- if (resultType != null) {
- NullableNotNullManager nnn = NullableNotNullManager.getInstance(owner.getProject());
- for (PsiAnnotation annotation : resultType.getAnnotations()) {
- String qualifiedName = annotation.getQualifiedName();
- if (nnn.getNullables().contains(qualifiedName)) {
- return Nullness.NULLABLE;
- }
- if (nnn.getNotNulls().contains(qualifiedName)) {
- return Nullness.NOT_NULL;
- }
- }
- }
-
- return Nullness.UNKNOWN;
- }
-
- public static boolean isNullableInitialized(PsiVariable var, boolean nullable) {
- if (!isFinalField(var)) {
- return false;
- }
-
- List<PsiExpression> initializers = NullableStuffInspection.findAllConstructorInitializers((PsiField)var);
- if (initializers.isEmpty()) {
- return false;
- }
-
- for (PsiExpression expression : initializers) {
- if (!(expression instanceof PsiReferenceExpression)) {
- return false;
- }
- PsiElement target = ((PsiReferenceExpression)expression).resolve();
- if (!(target instanceof PsiParameter)) {
- return false;
- }
- if (nullable && NullableNotNullManager.isNullable((PsiParameter)target)) {
- return true;
- }
- if (!nullable && !NullableNotNullManager.isNotNull((PsiParameter)target)) {
- return false;
- }
- }
- return !nullable;
- }
-
- public static boolean isPlainMutableField(PsiVariable var) {
- return !var.hasModifierProperty(PsiModifier.FINAL) && !var.hasModifierProperty(PsiModifier.TRANSIENT) && !var.hasModifierProperty(PsiModifier.VOLATILE) && var instanceof PsiField;
- }
-
- public static boolean isFinalField(PsiVariable var) {
- return var.hasModifierProperty(PsiModifier.FINAL) && !var.hasModifierProperty(PsiModifier.TRANSIENT) && var instanceof PsiField;
- }
-
- @NotNull
- public static Nullness checkNullness(@Nullable final PsiVariable variable, @Nullable final PsiElement context) {
- if (variable == null || context == null) return Nullness.UNKNOWN;
-
- final PsiElement codeBlock = getEnclosingCodeBlock(variable, context);
- if (codeBlock == null) {
- return Nullness.UNKNOWN;
- }
- final ValuableInstructionVisitor visitor = new ValuableInstructionVisitor(context);
- RunnerResult result = new ValuableDataFlowRunner().analyzeMethod(codeBlock, visitor);
- if (result != RunnerResult.OK) {
- return Nullness.UNKNOWN;
- }
- if (visitor.myNulls.contains(variable) && !visitor.myNotNulls.contains(variable)) return Nullness.NULLABLE;
- if (visitor.myNotNulls.contains(variable) && !visitor.myNulls.contains(variable)) return Nullness.NOT_NULL;
- return Nullness.UNKNOWN;
- }
-
- @Nullable
- public static PsiCodeBlock getTopmostBlockInSameClass(@NotNull PsiElement position) {
- PsiCodeBlock block = PsiTreeUtil.getParentOfType(position, PsiCodeBlock.class, false, PsiMember.class, PsiFile.class);
- if (block == null) {
- return null;
- }
-
- PsiCodeBlock lastBlock = block;
- while (true) {
- block = PsiTreeUtil.getParentOfType(block, PsiCodeBlock.class, true, PsiMember.class, PsiFile.class);
- if (block == null) {
- return lastBlock;
- }
- lastBlock = block;
- }
- }
-
- private static PsiElement getEnclosingCodeBlock(final PsiVariable variable, final PsiElement context) {
- PsiElement codeBlock;
- if (variable instanceof PsiParameter) {
- codeBlock = ((PsiParameter)variable).getDeclarationScope();
- if (codeBlock instanceof PsiMethod) {
- codeBlock = ((PsiMethod)codeBlock).getBody();
- }
- }
- else if (variable instanceof PsiLocalVariable) {
- codeBlock = PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class);
- }
- else {
- codeBlock = PsiTreeUtil.getParentOfType(context, PsiCodeBlock.class);
- }
- while (codeBlock != null) {
- PsiAnonymousClass anon = PsiTreeUtil.getParentOfType(codeBlock, PsiAnonymousClass.class);
- if (anon == null) break;
- codeBlock = PsiTreeUtil.getParentOfType(anon, PsiCodeBlock.class);
- }
- return codeBlock;
- }
-
- @NotNull
- public static Collection<? extends PsiElement> getPossibleInitializationElements(final PsiElement qualifierExpression) {
- if (qualifierExpression instanceof PsiMethodCallExpression) {
- return Collections.singletonList(qualifierExpression);
- }
- if (qualifierExpression instanceof PsiReferenceExpression) {
- final PsiElement targetElement = ((PsiReferenceExpression)qualifierExpression).resolve();
- if (!(targetElement instanceof PsiVariable)) {
- return Collections.emptyList();
- }
- final Collection<? extends PsiElement> variableValues = getCachedVariableValues((PsiVariable)targetElement, qualifierExpression);
- if (variableValues == null || variableValues.isEmpty()) {
- return getVariableAssignmentsInFile((PsiVariable)targetElement, false, qualifierExpression);
- }
- return variableValues;
- }
- if (qualifierExpression instanceof PsiLiteralExpression) {
- return Collections.singletonList(qualifierExpression);
- }
- return Collections.emptyList();
- }
-
- @NotNull
- public static Collection<PsiExpression> getVariableAssignmentsInFile(final PsiVariable psiVariable,
- final boolean literalsOnly,
- final PsiElement place) {
- final Ref<Boolean> modificationRef = Ref.create(Boolean.FALSE);
- final PsiCodeBlock codeBlock = place == null? null : getTopmostBlockInSameClass(place);
- final int placeOffset = codeBlock != null? place.getTextRange().getStartOffset() : 0;
- final List<PsiExpression> list = ContainerUtil.mapNotNull(
- ReferencesSearch.search(psiVariable, new LocalSearchScope(new PsiElement[] {psiVariable.getContainingFile()}, null, true)).findAll(),
- new NullableFunction<PsiReference, PsiExpression>() {
- @Override
- public PsiExpression fun(final PsiReference psiReference) {
- if (modificationRef.get()) return null;
- final PsiElement parent = psiReference.getElement().getParent();
- if (parent instanceof PsiAssignmentExpression) {
- final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)parent;
- final IElementType operation = assignmentExpression.getOperationTokenType();
- if (assignmentExpression.getLExpression() == psiReference) {
- if (JavaTokenType.EQ.equals(operation)) {
- final PsiExpression rValue = assignmentExpression.getRExpression();
- if (!literalsOnly || allOperandsAreLiterals(rValue)) {
- // if there's a codeBlock omit the values assigned later
- if (codeBlock != null && PsiTreeUtil.isAncestor(codeBlock, parent, true)
- && placeOffset < parent.getTextRange().getStartOffset()) {
- return null;
- }
- return rValue;
- }
- else {
- modificationRef.set(Boolean.TRUE);
- }
- }
- else if (JavaTokenType.PLUSEQ.equals(operation)) {
- modificationRef.set(Boolean.TRUE);
- }
- }
- }
- return null;
- }
- });
- if (modificationRef.get()) return Collections.emptyList();
- if (!literalsOnly || allOperandsAreLiterals(psiVariable.getInitializer())) {
- ContainerUtil.addIfNotNull(psiVariable.getInitializer(), list);
- }
- return list;
- }
-
- public static boolean allOperandsAreLiterals(@Nullable final PsiExpression expression) {
- if (expression == null) return false;
- if (expression instanceof PsiLiteralExpression) return true;
- if (expression instanceof PsiPolyadicExpression) {
- Stack<PsiExpression> stack = new Stack<PsiExpression>();
- stack.add(expression);
- while (!stack.isEmpty()) {
- PsiExpression psiExpression = stack.pop();
- if (psiExpression instanceof PsiPolyadicExpression) {
- PsiPolyadicExpression binaryExpression = (PsiPolyadicExpression)psiExpression;
- for (PsiExpression op : binaryExpression.getOperands()) {
- stack.push(op);
- }
- }
- else if (!(psiExpression instanceof PsiLiteralExpression)) {
- return false;
- }
- }
- return true;
- }
- return false;
- }
-
- private static class ValuableInstructionVisitor extends StandardInstructionVisitor {
- final MultiValuesMap<PsiVariable, PsiExpression> myValues = new MultiValuesMap<PsiVariable, PsiExpression>(true);
- final Set<PsiVariable> myNulls = new THashSet<PsiVariable>();
- final Set<PsiVariable> myNotNulls = new THashSet<PsiVariable>();
- private final PsiElement myContext;
-
- public ValuableInstructionVisitor(@NotNull PsiElement context) {
- myContext = context;
- }
-
- @Override
- public DfaInstructionState[] visitPush(PushInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
- if (myContext == instruction.getPlace()) {
- final Map<DfaVariableValue,DfaVariableState> map = ((ValuableDataFlowRunner.MyDfaMemoryState)memState).getVariableStates();
- for (Map.Entry<DfaVariableValue, DfaVariableState> entry : map.entrySet()) {
- ValuableDataFlowRunner.ValuableDfaVariableState state = (ValuableDataFlowRunner.ValuableDfaVariableState)entry.getValue();
- DfaVariableValue variableValue = entry.getKey();
- final PsiExpression psiExpression = state.myExpression;
- if (psiExpression != null && variableValue.getQualifier() == null) {
- myValues.put(variableValue.getPsiVariable(), psiExpression);
- }
- }
- DfaValue value = instruction.getValue();
- if (value instanceof DfaVariableValue && ((DfaVariableValue)value).getQualifier() == null) {
- if (memState.isNotNull((DfaVariableValue)value)) {
- myNotNulls.add(((DfaVariableValue)value).getPsiVariable());
- }
- if (memState.isNull(value)) {
- myNulls.add(((DfaVariableValue)value).getPsiVariable());
- }
- }
- }
- return super.visitPush(instruction, runner, memState);
- }
-
- @Override
- public DfaInstructionState[] visitAssign(AssignInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
- final Instruction nextInstruction = runner.getInstruction(instruction.getIndex() + 1);
-
- final DfaValue dfaSource = memState.pop();
- final DfaValue dfaDest = memState.pop();
-
- if (dfaDest instanceof DfaVariableValue) {
- DfaVariableValue var = (DfaVariableValue)dfaDest;
- final PsiExpression rightValue = instruction.getRExpression();
- final PsiElement parent = rightValue == null ? null : rightValue.getParent();
- final IElementType type = parent instanceof PsiAssignmentExpression
- ? ((PsiAssignmentExpression)parent).getOperationTokenType() : JavaTokenType.EQ;
- // store current value - to use in case of '+='
- final PsiExpression prevValue = ((ValuableDataFlowRunner.ValuableDfaVariableState)((ValuableDataFlowRunner.MyDfaMemoryState)memState).getVariableState(var)).myExpression;
- memState.setVarValue(var, dfaSource);
- // state may have been changed so re-retrieve it
- final ValuableDataFlowRunner.ValuableDfaVariableState curState = (ValuableDataFlowRunner.ValuableDfaVariableState)((ValuableDataFlowRunner.MyDfaMemoryState)memState).getVariableState(var);
- final PsiExpression curValue = curState.myExpression;
- final PsiExpression nextValue;
- if (type == JavaTokenType.PLUSEQ && prevValue != null) {
- PsiExpression tmpExpression;
- try {
- tmpExpression = JavaPsiFacade.getElementFactory(myContext.getProject())
- .createExpressionFromText(prevValue.getText() + "+" + rightValue.getText(), rightValue);
- }
- catch (Exception e) {
- tmpExpression = curValue == null ? rightValue : curValue;
- }
- nextValue = tmpExpression;
- }
- else {
- nextValue = curValue == null ? rightValue : curValue;
- }
- curState.myExpression = nextValue;
- }
- memState.push(dfaDest);
- return new DfaInstructionState[]{new DfaInstructionState(nextInstruction, memState)};
- }
- }
-}
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/MethodCheckerDetailsDialog.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/MethodCheckerDetailsDialog.java
index 154ad18..008ae77 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/MethodCheckerDetailsDialog.java
+++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/MethodCheckerDetailsDialog.java
@@ -39,17 +39,17 @@
* Dialog that appears when the user clicks the Add Button or double clicks a row item in a MethodsPanel. The MethodsPanel is accessed from the ConditionCheckDialog
*/
class MethodCheckerDetailsDialog extends DialogWrapper implements PropertyChangeListener, ItemListener {
- private final @NotNull ConditionChecker.Type myType;
- private final @NotNull Project myProject;
- private final @NotNull ParameterDropDown parameterDropDown;
- private final @NotNull MethodDropDown methodDropDown;
- private final @NotNull ClassField classField;
- private final @NotNull Set<ConditionChecker> myOtherCheckers;
- private final @Nullable ConditionChecker myPreviouslySelectedChecker;
+ @NotNull private final ConditionChecker.Type myType;
+ @NotNull private final Project myProject;
+ @NotNull private final ParameterDropDown parameterDropDown;
+ @NotNull private final MethodDropDown methodDropDown;
+ @NotNull private final ClassField classField;
+ @NotNull private final Set<ConditionChecker> myOtherCheckers;
+ @Nullable private final ConditionChecker myPreviouslySelectedChecker;
/**
* Set by the OK and/or Cancel actions so that the caller can retrieve it via a call to getMethodIsNullIsNotNullChecker
*/
- private @Nullable ConditionChecker mySelectedChecker;
+ @Nullable private ConditionChecker mySelectedChecker;
MethodCheckerDetailsDialog(@Nullable ConditionChecker previouslySelectedChecker,
@NotNull ConditionChecker.Type type,
@@ -263,8 +263,8 @@
*/
static class ClassField extends EditorTextFieldWithBrowseButton implements ActionListener, DocumentListener {
public static final String PROPERTY_PSICLASS = "ClassField.myPsiClass";
- private final @NotNull Project myProject;
- private @Nullable PsiClass myPsiClass;
+ @NotNull private final Project myProject;
+ @Nullable private PsiClass myPsiClass;
public ClassField(@NotNull Project project, @Nullable PsiClass psiClass) {
super(project, true, buildVisibilityChecker());
@@ -341,9 +341,9 @@
* Drop Down for picking Method Name
*/
static class MethodDropDown extends JComboBox implements PropertyChangeListener {
- private final @NotNull ConditionChecker.Type myType;
- private final @NotNull SortedComboBoxModel<MethodWrapper> myModel;
- private @Nullable PsiClass myPsiClass;
+ @NotNull private final ConditionChecker.Type myType;
+ @NotNull private final SortedComboBoxModel<MethodWrapper> myModel;
+ @Nullable private PsiClass myPsiClass;
MethodDropDown(@Nullable PsiClass psiClass,
@Nullable PsiMethod psiMethod,
@@ -478,9 +478,9 @@
* Drop Down for picking Parameter Name
*/
static class ParameterDropDown extends JComboBox implements PropertyChangeListener, ItemListener {
- private final @NotNull SortedComboBoxModel<ParameterWrapper> myModel;
- private final @NotNull ConditionChecker.Type myType;
- private @Nullable PsiMethod myPsiMethod;
+ @NotNull private final SortedComboBoxModel<ParameterWrapper> myModel;
+ @NotNull private final ConditionChecker.Type myType;
+ @Nullable private PsiMethod myPsiMethod;
public ParameterDropDown(@Nullable PsiMethod psiMethod,
@Nullable PsiParameter psiParameter,
@@ -582,8 +582,8 @@
}
class ParameterWrapper implements Comparable<ParameterWrapper> {
- private final @NotNull String id;
- private final @NotNull PsiParameter psiParameter;
+ @NotNull private final String id;
+ @NotNull private final PsiParameter psiParameter;
private final int index;
ParameterWrapper(@NotNull PsiParameter psiParameter, int index) {
@@ -624,8 +624,8 @@
}
static class MethodWrapper implements Comparable<MethodWrapper> {
- private final @NotNull PsiMethod myPsiMethod;
- private final @NotNull String myId;
+ @NotNull private final PsiMethod myPsiMethod;
+ @NotNull private final String myId;
MethodWrapper(@NotNull PsiMethod psiMethod) {
this.myPsiMethod = psiMethod;
diff --git a/java/java-impl/src/com/intellij/codeInspection/defUse/DefUseInspection.java b/java/java-impl/src/com/intellij/codeInspection/defUse/DefUseInspection.java
index db08293..8b19def 100644
--- a/java/java-impl/src/com/intellij/codeInspection/defUse/DefUseInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/defUse/DefUseInspection.java
@@ -25,211 +25,32 @@
package com.intellij.codeInspection.defUse;
import com.intellij.codeInsight.FileModificationService;
-import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableFix;
-import com.intellij.codeInsight.daemon.impl.quickfix.SideEffectWarningDialog;
-import com.intellij.codeInspection.*;
-import com.intellij.codeInspection.ex.BaseLocalInspectionTool;
+import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableUtil;
+import com.intellij.codeInspection.InspectionsBundle;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
-import com.intellij.psi.controlFlow.DefUseUtil;
import com.intellij.psi.util.PsiExpressionTrimRenderer;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
-import gnu.trove.THashSet;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import javax.swing.*;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-import java.awt.*;
-import java.util.*;
+import java.util.ArrayList;
import java.util.List;
-public class DefUseInspection extends BaseLocalInspectionTool {
- public boolean REPORT_PREFIX_EXPRESSIONS = false;
- public boolean REPORT_POSTFIX_EXPRESSIONS = true;
- public boolean REPORT_REDUNDANT_INITIALIZER = true;
-
+public class DefUseInspection extends DefUseInspectionBase {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.defUse.DefUseInspection");
- public static final String DISPLAY_NAME = InspectionsBundle.message("inspection.unused.assignment.display.name");
- @NonNls public static final String SHORT_NAME = "UnusedAssignment";
-
@Override
- @NotNull
- public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
- return new JavaElementVisitor() {
- @Override public void visitMethod(PsiMethod method) {
- checkCodeBlock(method.getBody(), holder, isOnTheFly);
- }
-
- @Override public void visitClassInitializer(PsiClassInitializer initializer) {
- checkCodeBlock(initializer.getBody(), holder, isOnTheFly);
- }
- };
+ protected LocalQuickFix createRemoveInitializerFix() {
+ return new RemoveInitializerFix();
}
- private void checkCodeBlock(final PsiCodeBlock body,
- final ProblemsHolder holder,
- final boolean isOnTheFly) {
- if (body == null) return;
- final Set<PsiVariable> usedVariables = new THashSet<PsiVariable>();
- List<DefUseUtil.Info> unusedDefs = DefUseUtil.getUnusedDefs(body, usedVariables);
-
- if (unusedDefs != null && !unusedDefs.isEmpty()) {
- Collections.sort(unusedDefs, new Comparator<DefUseUtil.Info>() {
- @Override
- public int compare(DefUseUtil.Info o1, DefUseUtil.Info o2) {
- int offset1 = o1.getContext().getTextOffset();
- int offset2 = o2.getContext().getTextOffset();
-
- if (offset1 == offset2) return 0;
- if (offset1 < offset2) return -1;
-
- return 1;
- }
- });
-
- for (DefUseUtil.Info info : unusedDefs) {
- PsiElement context = info.getContext();
- PsiVariable psiVariable = info.getVariable();
-
- if (context instanceof PsiDeclarationStatement || context instanceof PsiResourceVariable) {
- if (!info.isRead()) {
- if (!isOnTheFly) {
- holder.registerProblem(psiVariable.getNameIdentifier(),
- InspectionsBundle.message("inspection.unused.assignment.problem.descriptor1", "<code>#ref</code> #loc"),
- ProblemHighlightType.LIKE_UNUSED_SYMBOL);
- }
- }
- else {
- if (REPORT_REDUNDANT_INITIALIZER) {
- holder.registerProblem(psiVariable.getInitializer(),
- InspectionsBundle.message("inspection.unused.assignment.problem.descriptor2",
- "<code>" + psiVariable.getName() + "</code>", "<code>#ref</code> #loc"),
- ProblemHighlightType.LIKE_UNUSED_SYMBOL,
- new RemoveInitializerFix());
- }
- }
- }
- else if (context instanceof PsiAssignmentExpression &&
- ((PsiAssignmentExpression)context).getOperationTokenType() == JavaTokenType.EQ) {
- final PsiAssignmentExpression assignment = (PsiAssignmentExpression)context;
- holder.registerProblem(assignment.getLExpression(),
- InspectionsBundle.message("inspection.unused.assignment.problem.descriptor3",
- assignment.getRExpression().getText(), "<code>#ref</code>" + " #loc"), ProblemHighlightType.LIKE_UNUSED_SYMBOL);
- }
- else {
- if (context instanceof PsiPrefixExpression && REPORT_PREFIX_EXPRESSIONS ||
- context instanceof PsiPostfixExpression && REPORT_POSTFIX_EXPRESSIONS) {
- holder.registerProblem(context,
- InspectionsBundle.message("inspection.unused.assignment.problem.descriptor4", "<code>#ref</code> #loc"));
- }
- }
- }
- }
-
- body.accept(new JavaRecursiveElementWalkingVisitor() {
- @Override public void visitClass(PsiClass aClass) {
- }
-
- @Override public void visitLocalVariable(PsiLocalVariable variable) {
- if (!usedVariables.contains(variable) && variable.getInitializer() == null && !isOnTheFly) {
- holder.registerProblem(variable.getNameIdentifier(),
- InspectionsBundle.message("inspection.unused.assignment.problem.descriptor5", "<code>#ref</code> #loc"),
- ProblemHighlightType.LIKE_UNUSED_SYMBOL);
- }
- }
-
- @Override public void visitAssignmentExpression(PsiAssignmentExpression expression) {
- PsiExpression lExpression = expression.getLExpression();
- PsiExpression rExpression = expression.getRExpression();
-
- if (lExpression instanceof PsiReferenceExpression && rExpression instanceof PsiReferenceExpression) {
- PsiReferenceExpression lRef = (PsiReferenceExpression)lExpression;
- PsiReferenceExpression rRef = (PsiReferenceExpression)rExpression;
-
- if (lRef.resolve() != rRef.resolve()) return;
- PsiExpression lQualifier = lRef.getQualifierExpression();
- PsiExpression rQualifier = rRef.getQualifierExpression();
-
- if ((lQualifier == null && rQualifier == null ||
- lQualifier instanceof PsiThisExpression && rQualifier instanceof PsiThisExpression ||
- lQualifier instanceof PsiThisExpression && rQualifier == null ||
- lQualifier == null && rQualifier instanceof PsiThisExpression) && !isOnTheFly) {
- holder.registerProblem(expression,
- InspectionsBundle.message("inspection.unused.assignment.problem.descriptor6", "<code>#ref</code>"));
- }
- }
- }
- });
- }
-
- @Override
- public JComponent createOptionsPanel() {
- return new OptionsPanel();
- }
-
- private class OptionsPanel extends JPanel {
- private final JCheckBox myReportPrefix;
- private final JCheckBox myReportPostfix;
- private final JCheckBox myReportInitializer;
-
- private OptionsPanel() {
- super(new GridBagLayout());
-
- GridBagConstraints gc = new GridBagConstraints();
- gc.weighty = 0;
- gc.weightx = 1;
- gc.fill = GridBagConstraints.HORIZONTAL;
- gc.anchor = GridBagConstraints.NORTHWEST;
-
- myReportInitializer = new JCheckBox(InspectionsBundle.message("inspection.unused.assignment.option2"));
- myReportInitializer.setSelected(REPORT_REDUNDANT_INITIALIZER);
- myReportInitializer.getModel().addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- REPORT_REDUNDANT_INITIALIZER = myReportInitializer.isSelected();
- }
- });
- gc.insets = new Insets(0, 0, 15, 0);
- gc.gridy = 0;
- add(myReportInitializer, gc);
-
- myReportPrefix = new JCheckBox(InspectionsBundle.message("inspection.unused.assignment.option"));
- myReportPrefix.setSelected(REPORT_PREFIX_EXPRESSIONS);
- myReportPrefix.getModel().addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- REPORT_PREFIX_EXPRESSIONS = myReportPrefix.isSelected();
- }
- });
- gc.insets = new Insets(0, 0, 0, 0);
- gc.gridy++;
- add(myReportPrefix, gc);
-
- myReportPostfix = new JCheckBox(InspectionsBundle.message("inspection.unused.assignment.option1"));
- myReportPostfix.setSelected(REPORT_POSTFIX_EXPRESSIONS);
- myReportPostfix.getModel().addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- REPORT_POSTFIX_EXPRESSIONS = myReportPostfix.isSelected();
- }
- });
-
- gc.weighty = 1;
- gc.gridy++;
- add(myReportPostfix, gc);
- }
- }
-
-
private static class RemoveInitializerFix implements LocalQuickFix {
-
@Override
@NotNull
public String getName() {
@@ -246,20 +67,21 @@
final PsiVariable variable = (PsiVariable)psiInitializer.getParent();
final PsiDeclarationStatement declaration = (PsiDeclarationStatement)variable.getParent();
final List<PsiElement> sideEffects = new ArrayList<PsiElement>();
- boolean hasSideEffects = RemoveUnusedVariableFix.checkSideEffects(psiInitializer, variable, sideEffects);
- int res = SideEffectWarningDialog.DELETE_ALL;
+ boolean hasSideEffects = RemoveUnusedVariableUtil.checkSideEffects(psiInitializer, variable, sideEffects);
+ int res = RemoveUnusedVariableUtil.DELETE_ALL;
if (hasSideEffects) {
hasSideEffects = PsiUtil.isStatement(psiInitializer);
res = RemoveUnusedVariableFix.showSideEffectsWarning(sideEffects, variable,
FileEditorManager.getInstance(project).getSelectedTextEditor(),
hasSideEffects, sideEffects.get(0).getText(),
- variable.getTypeElement().getText() + " " + variable.getName() + ";<br>" + PsiExpressionTrimRenderer.render((PsiExpression)psiInitializer));
+ variable.getTypeElement().getText() + " " + variable.getName() + ";<br>" + PsiExpressionTrimRenderer
+ .render((PsiExpression)psiInitializer));
}
try {
- if (res == SideEffectWarningDialog.DELETE_ALL) {
+ if (res == RemoveUnusedVariableUtil.DELETE_ALL) {
psiInitializer.delete();
}
- else if (res == SideEffectWarningDialog.MAKE_STATEMENT) {
+ else if (res == RemoveUnusedVariableUtil.MAKE_STATEMENT) {
final PsiElementFactory factory = JavaPsiFacade.getInstance(variable.getProject()).getElementFactory();
final PsiStatement statementFromText = factory.createStatementFromText(psiInitializer.getText() + ";", null);
declaration.getParent().addAfter(statementFromText, declaration);
@@ -277,22 +99,4 @@
return getName();
}
}
-
- @Override
- @NotNull
- public String getDisplayName() {
- return DISPLAY_NAME;
- }
-
- @Override
- @NotNull
- public String getGroupDisplayName() {
- return GroupNames.BUGS_GROUP_NAME;
- }
-
- @Override
- @NotNull
- public String getShortName() {
- return SHORT_NAME;
- }
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/DefaultFileTemplateUsageInspection.java b/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/DefaultFileTemplateUsageInspection.java
index 53f1583..8d7eeaa 100644
--- a/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/DefaultFileTemplateUsageInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/DefaultFileTemplateUsageInspection.java
@@ -17,7 +17,6 @@
import com.intellij.codeInspection.*;
import com.intellij.ide.fileTemplates.FileTemplate;
-import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.ide.fileTemplates.impl.FileTemplateConfigurable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.options.ShowSettingsUtil;
@@ -29,13 +28,19 @@
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import java.util.ArrayList;
-import java.util.Collection;
/**
* @author cdr
*/
public class DefaultFileTemplateUsageInspection extends BaseJavaLocalInspectionTool {
+ // Fields are left for the compatibility
+ @Deprecated @SuppressWarnings("UnusedDeclaration")
+ public boolean CHECK_FILE_HEADER = true;
+ @Deprecated @SuppressWarnings("UnusedDeclaration")
+ public boolean CHECK_TRY_CATCH_SECTION = true;
+ @Deprecated @SuppressWarnings("UnusedDeclaration")
+ public boolean CHECK_METHOD_BODY = true;
+
@Override
@NotNull
public String getGroupDisplayName() {
diff --git a/java/java-impl/src/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java b/java/java-impl/src/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java
index e6a6608..08f1e42 100644
--- a/java/java-impl/src/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java
@@ -23,6 +23,7 @@
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.reference.*;
import com.intellij.codeInspection.util.SpecialAnnotationsUtil;
+import com.intellij.codeInspection.util.SpecialAnnotationsUtilBase;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
@@ -134,10 +135,10 @@
if (message != null) {
final ArrayList<LocalQuickFix> fixes = new ArrayList<LocalQuickFix>();
fixes.add(getFix(processor, needToDeleteHierarchy));
- SpecialAnnotationsUtil.createAddToSpecialAnnotationFixes(refMethod.getElement(), new Processor<String>() {
+ SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes(refMethod.getElement(), new Processor<String>() {
@Override
public boolean process(final String qualifiedName) {
- fixes.add(SpecialAnnotationsUtil.createAddToSpecialAnnotationsListQuickFix(
+ fixes.add(SpecialAnnotationsUtilBase.createAddToSpecialAnnotationsListQuickFix(
QuickFixBundle.message("fix.add.special.annotation.text", qualifiedName),
QuickFixBundle.message("fix.add.special.annotation.family"),
EXCLUDE_ANNOS, qualifiedName, refMethod.getElement()));
diff --git a/java/java-impl/src/com/intellij/codeInspection/inheritance/ChangeSuperClassFix.java b/java/java-impl/src/com/intellij/codeInspection/inheritance/ChangeSuperClassFix.java
deleted file mode 100644
index 22631e2..0000000
--- a/java/java-impl/src/com/intellij/codeInspection/inheritance/ChangeSuperClassFix.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright 2000-2013 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.inheritance;
-
-import com.intellij.codeInsight.FileModificationService;
-import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInsight.intention.LowPriorityAction;
-import com.intellij.codeInspection.LocalQuickFix;
-import com.intellij.codeInspection.ProblemDescriptor;
-import com.intellij.openapi.command.WriteCommandAction;
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.JavaCodeStyleManager;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.TestOnly;
-
-/**
- * @author Dmitry Batkovich <dmitry.batkovich@jetbrains.com>
- */
-public class ChangeSuperClassFix implements LocalQuickFix {
- @NotNull
- private final PsiClass myNewSuperClass;
- @NotNull
- private final PsiClass myOldSuperClass;
- private final int myPercent;
-
- public ChangeSuperClassFix(@NotNull final PsiClass newSuperClass, final int percent, @NotNull final PsiClass oldSuperClass) {
- myNewSuperClass = newSuperClass;
- myOldSuperClass = oldSuperClass;
- myPercent = percent;
- }
-
- @NotNull
- @TestOnly
- public PsiClass getNewSuperClass() {
- return myNewSuperClass;
- }
-
- @TestOnly
- public int getPercent() {
- return myPercent;
- }
-
- @NotNull
- @Override
- public String getName() {
- return String.format("Make extends '%s' - %s%%", myNewSuperClass.getQualifiedName(), myPercent);
- }
-
- @NotNull
- @Override
- public String getFamilyName() {
- return GroupNames.INHERITANCE_GROUP_NAME;
- }
-
- @Override
- public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor problemDescriptor) {
- changeSuperClass((PsiClass)problemDescriptor.getPsiElement(), myOldSuperClass, myNewSuperClass);
- }
-
- /**
- * myOldSuperClass and myNewSuperClass can be interfaces or classes in any combination
- * <p/>
- * 1. not checks that myOldSuperClass is really super of aClass
- * 2. not checks that myNewSuperClass not exists in currently existed supers
- */
- private static void changeSuperClass(@NotNull final PsiClass aClass,
- @NotNull final PsiClass oldSuperClass,
- @NotNull final PsiClass newSuperClass) {
- if (!FileModificationService.getInstance().preparePsiElementForWrite(aClass)) return;
-
- new WriteCommandAction.Simple(newSuperClass.getProject(), aClass.getContainingFile()) {
- @Override
- protected void run() throws Throwable {
- PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory();
- if (aClass instanceof PsiAnonymousClass) {
- ((PsiAnonymousClass)aClass).getBaseClassReference().replace(factory.createClassReferenceElement(newSuperClass));
- }
- else if (oldSuperClass.isInterface()) {
- final PsiReferenceList interfaceList = aClass.getImplementsList();
- if (interfaceList != null) {
- for (final PsiJavaCodeReferenceElement interfaceRef : interfaceList.getReferenceElements()) {
- final PsiElement aInterface = interfaceRef.resolve();
- if (aInterface != null && aInterface.isEquivalentTo(oldSuperClass)) {
- interfaceRef.delete();
- }
- }
- }
-
- final PsiReferenceList extendsList = aClass.getExtendsList();
- if (extendsList != null) {
- final PsiJavaCodeReferenceElement newClassReference = factory.createClassReferenceElement(newSuperClass);
- if (extendsList.getReferenceElements().length == 0) {
- extendsList.add(newClassReference);
- }
- }
- }
- else {
- final PsiReferenceList extendsList = aClass.getExtendsList();
- if (extendsList != null && extendsList.getReferenceElements().length == 1) {
- extendsList.getReferenceElements()[0].delete();
- PsiElement ref = extendsList.add(factory.createClassReferenceElement(newSuperClass));
- JavaCodeStyleManager.getInstance(aClass.getProject()).shortenClassReferences(ref);
- }
- }
- }
- }.execute();
- }
-
- public static class LowPriority extends ChangeSuperClassFix implements LowPriorityAction {
- public LowPriority(@NotNull final PsiClass newSuperClass, final int percent, @NotNull final PsiClass oldSuperClass) {
- super(newSuperClass, percent, oldSuperClass);
- }
- }
-}
diff --git a/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java b/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java
index bc9195d..7e8448e 100644
--- a/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java
@@ -15,474 +15,23 @@
*/
package com.intellij.codeInspection.nullable;
-import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.NullableNotNullDialog;
-import com.intellij.codeInsight.NullableNotNullManager;
-import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInsight.intention.AddAnnotationFix;
-import com.intellij.codeInsight.intention.impl.AddNotNullAnnotationFix;
-import com.intellij.codeInsight.intention.impl.AddNullableAnnotationFix;
-import com.intellij.codeInspection.*;
-import com.intellij.codeInspection.ex.BaseLocalInspectionTool;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.JavaCodeStyleManager;
-import com.intellij.psi.codeStyle.VariableKind;
-import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.LocalSearchScope;
-import com.intellij.psi.search.searches.OverridingMethodsSearch;
-import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.util.*;
-import com.intellij.refactoring.psi.PropertyUtils;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.Processor;
-import com.intellij.util.containers.ContainerUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.util.List;
-public class NullableStuffInspection extends BaseLocalInspectionTool {
- // deprecated fields remain to minimize changes to users inspection profiles (which are often located in version control).
- @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NULLABLE_METHOD_OVERRIDES_NOTNULL = true;
- @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL = true;
- @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE = true;
- @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL = true;
- @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_GETTER = true;
- @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_SETTER_PARAMETER = true;
- @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = true; // remains for test
- @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD = true;
-
- private static final Logger LOG = Logger.getInstance("#" + NullableStuffInspection.class.getName());
-
- @Override
- @NotNull
- public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
- return new JavaElementVisitor() {
- @Override public void visitMethod(PsiMethod method) {
- if (!PsiUtil.isLanguageLevel5OrHigher(method)) return;
- checkNullableStuffForMethod(method, holder);
- }
-
- @Override public void visitField(PsiField field) {
- if (!PsiUtil.isLanguageLevel5OrHigher(field)) return;
- final PsiType type = field.getType();
- final Annotated annotated = check(field, holder, type);
- if (TypeConversionUtil.isPrimitiveAndNotNull(type)) {
- return;
- }
- Project project = holder.getProject();
- final NullableNotNullManager manager = NullableNotNullManager.getInstance(project);
- if (annotated.isDeclaredNotNull ^ annotated.isDeclaredNullable) {
- final String anno = annotated.isDeclaredNotNull ? manager.getDefaultNotNull() : manager.getDefaultNullable();
- final List<String> annoToRemove = annotated.isDeclaredNotNull ? manager.getNullables() : manager.getNotNulls();
-
- if (!AnnotationUtil.isAnnotatingApplicable(field, anno)) {
- final PsiAnnotation notNull = AnnotationUtil.findAnnotation(field, manager.getNotNulls());
- final PsiAnnotation nullable = AnnotationUtil.findAnnotation(field, manager.getNullables());
- holder.registerProblem(field.getNameIdentifier(), "Nullable/NotNull defaults are not accessible in current context",
- new ChangeNullableDefaultsFix(notNull, nullable, manager));
- return;
- }
-
- 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 String nullableSimpleName = StringUtil.getShortName(manager.getDefaultNullable());
- final String notNullSimpleName = StringUtil.getShortName(manager.getDefaultNotNull());
- final PsiIdentifier nameIdentifier = getter == null ? null : getter.getNameIdentifier();
- if (nameIdentifier != null && nameIdentifier.isPhysical()) {
- if (PropertyUtils.isSimpleGetter(getter)) {
- if (REPORT_NOT_ANNOTATED_GETTER) {
- if (!AnnotationUtil.isAnnotated(getter, manager.getAllAnnotations(), false, false) &&
- !TypeConversionUtil.isPrimitiveAndNotNull(getter.getReturnType())) {
- holder.registerProblem(nameIdentifier, InspectionsBundle
- .message("inspection.nullable.problems.annotated.field.getter.not.annotated", StringUtil.getShortName(anno)),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AnnotateMethodFix(anno, ArrayUtil.toStringArray(annoToRemove)));
- }
- }
- if (annotated.isDeclaredNotNull && manager.isNullable(getter, false)) {
- holder.registerProblem(nameIdentifier, InspectionsBundle.message(
- "inspection.nullable.problems.annotated.field.getter.conflict", StringUtil.getShortName(anno), nullableSimpleName),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AnnotateMethodFix(anno, ArrayUtil.toStringArray(annoToRemove)));
- } else if (annotated.isDeclaredNullable && manager.isNotNull(getter, false)) {
- holder.registerProblem(nameIdentifier, InspectionsBundle.message(
- "inspection.nullable.problems.annotated.field.getter.conflict", StringUtil.getShortName(anno), notNullSimpleName),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AnnotateMethodFix(anno, ArrayUtil.toStringArray(annoToRemove)));
- }
- }
- }
-
- final PsiClass containingClass = field.getContainingClass();
- final PsiMethod setter = PropertyUtil.findPropertySetter(containingClass, propName, isStatic, false);
- if (setter != null) {
- final PsiParameter[] parameters = setter.getParameterList().getParameters();
- assert parameters.length == 1 : setter.getText();
- final PsiParameter parameter = parameters[0];
- LOG.assertTrue(parameter != null, setter.getText());
- if (REPORT_NOT_ANNOTATED_GETTER && !AnnotationUtil.isAnnotated(parameter, manager.getAllAnnotations(), false, false) && !TypeConversionUtil.isPrimitiveAndNotNull(parameter.getType())) {
- final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
- assertValidElement(setter, parameter, nameIdentifier1);
- holder.registerProblem(nameIdentifier1,
- InspectionsBundle.message("inspection.nullable.problems.annotated.field.setter.parameter.not.annotated",
- StringUtil.getShortName(anno)),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
- new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove)));
- }
- if (PropertyUtils.isSimpleSetter(setter)) {
- if (annotated.isDeclaredNotNull && manager.isNullable(parameter, false)) {
- final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
- assertValidElement(setter, parameter, nameIdentifier1);
- holder.registerProblem(nameIdentifier1, InspectionsBundle.message(
- "inspection.nullable.problems.annotated.field.setter.parameter.conflict",
- StringUtil.getShortName(anno), nullableSimpleName),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
- new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove)));
- }
- else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) {
- final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
- assertValidElement(setter, parameter, nameIdentifier1);
- holder.registerProblem(nameIdentifier1, InspectionsBundle.message(
- "inspection.nullable.problems.annotated.field.setter.parameter.conflict", StringUtil.getShortName(anno), notNullSimpleName),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
- new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove)));
- }
- }
- }
-
- for (PsiExpression rhs : findAllConstructorInitializers(field)) {
- if (rhs instanceof PsiReferenceExpression) {
- PsiElement target = ((PsiReferenceExpression)rhs).resolve();
- if (target instanceof PsiParameter) {
- PsiParameter parameter = (PsiParameter)target;
- if (REPORT_NOT_ANNOTATED_GETTER && !AnnotationUtil.isAnnotated(parameter, manager.getAllAnnotations(), false, false) && !TypeConversionUtil.isPrimitiveAndNotNull(parameter.getType())) {
- final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier();
- assert nameIdentifier2 != null : parameter;
- holder.registerProblem(nameIdentifier2, InspectionsBundle
- .message("inspection.nullable.problems.annotated.field.constructor.parameter.not.annotated",
- StringUtil.getShortName(anno)),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove)));
- continue;
- }
- if (annotated.isDeclaredNotNull && manager.isNullable(parameter, false)) {
- final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier();
- assert nameIdentifier2 != null : parameter;
- holder.registerProblem(nameIdentifier2, InspectionsBundle.message(
- "inspection.nullable.problems.annotated.field.constructor.parameter.conflict", StringUtil.getShortName(anno),
- nullableSimpleName),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
- new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove)));
- }
- else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) {
- boolean usedAsQualifier = !ReferencesSearch.search(parameter).forEach(new Processor<PsiReference>() {
- @Override
- public boolean process(PsiReference reference) {
- final PsiElement element = reference.getElement();
- if (element instanceof PsiReferenceExpression && element.getParent() instanceof PsiReferenceExpression) {
- return false;
- }
- return true;
- }
- });
- if (!usedAsQualifier) {
- final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier();
- assert nameIdentifier2 != null : parameter;
- holder.registerProblem(nameIdentifier2, InspectionsBundle.message(
- "inspection.nullable.problems.annotated.field.constructor.parameter.conflict", StringUtil.getShortName(anno),
- notNullSimpleName),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
- new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove)));
- }
- }
-
- }
- }
- }
- }
- }
-
- private void assertValidElement(PsiMethod setter, PsiParameter parameter, PsiIdentifier nameIdentifier1) {
- LOG.assertTrue(nameIdentifier1 != null && nameIdentifier1.isPhysical(), setter.getText());
- LOG.assertTrue(parameter.isPhysical(), setter.getText());
- }
-
- @Override public void visitParameter(PsiParameter parameter) {
- if (!PsiUtil.isLanguageLevel5OrHigher(parameter)) return;
- check(parameter, holder, parameter.getType());
- }
- };
- }
-
- private static class Annotated {
- private final boolean isDeclaredNotNull;
- private final boolean isDeclaredNullable;
-
- private Annotated(final boolean isDeclaredNotNull, final boolean isDeclaredNullable) {
- this.isDeclaredNotNull = isDeclaredNotNull;
- this.isDeclaredNullable = isDeclaredNullable;
- }
- }
- private static Annotated check(final PsiModifierListOwner parameter, final ProblemsHolder holder, PsiType type) {
- final NullableNotNullManager manager = NullableNotNullManager.getInstance(holder.getProject());
- PsiAnnotation isDeclaredNotNull = AnnotationUtil.findAnnotation(parameter, manager.getNotNulls());
- PsiAnnotation isDeclaredNullable = AnnotationUtil.findAnnotation(parameter, manager.getNullables());
- if (isDeclaredNullable != null && isDeclaredNotNull != null) {
- reportNullableNotNullConflict(holder, parameter, isDeclaredNullable, isDeclaredNotNull);
- }
- if ((isDeclaredNotNull != null || isDeclaredNullable != null) && type != null && TypeConversionUtil.isPrimitive(type.getCanonicalText())) {
- PsiAnnotation annotation = isDeclaredNotNull == null ? isDeclaredNullable : isDeclaredNotNull;
- reportPrimitiveType(holder, annotation, annotation, parameter);
- }
- return new Annotated(isDeclaredNotNull != null,isDeclaredNullable != null);
- }
-
- private static void reportPrimitiveType(final ProblemsHolder holder, final PsiElement psiElement, final PsiAnnotation annotation,
- final PsiModifierListOwner listOwner) {
- holder.registerProblem(psiElement.isPhysical() ? psiElement : listOwner.getNavigationElement(),
- InspectionsBundle.message("inspection.nullable.problems.primitive.type.annotation"),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new RemoveAnnotationQuickFix(annotation, listOwner));
- }
-
- @Override
- @NotNull
- public String getDisplayName() {
- return InspectionsBundle.message("inspection.nullable.problems.display.name");
- }
-
- @Override
- @NotNull
- public String getGroupDisplayName() {
- return GroupNames.BUGS_GROUP_NAME;
- }
-
- @Override
- @NotNull
- public String getShortName() {
- return "NullableProblems";
- }
-
- private void checkNullableStuffForMethod(PsiMethod method, final ProblemsHolder holder) {
- Annotated annotated = check(method, holder, method.getReturnType());
-
- PsiParameter[] parameters = method.getParameterList().getParameters();
-
- List<MethodSignatureBackedByPsiMethod> superMethodSignatures = method.findSuperMethodSignaturesIncludingStatic(true);
- boolean reported_not_annotated_method_overrides_notnull = false;
- boolean reported_nullable_method_overrides_notnull = false;
- boolean[] reported_notnull_parameter_overrides_nullable = new boolean[parameters.length];
- boolean[] reported_not_annotated_parameter_overrides_notnull = new boolean[parameters.length];
-
- final NullableNotNullManager nullableManager = NullableNotNullManager.getInstance(holder.getProject());
- for (MethodSignatureBackedByPsiMethod superMethodSignature : superMethodSignatures) {
- PsiMethod superMethod = superMethodSignature.getMethod();
- if (!reported_nullable_method_overrides_notnull
- && REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE
- && annotated.isDeclaredNullable
- && NullableNotNullManager.isNotNull(superMethod)) {
- reported_nullable_method_overrides_notnull = true;
- holder.registerProblem(method.getNameIdentifier(),
- InspectionsBundle.message("inspection.nullable.problems.Nullable.method.overrides.NotNull"),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
- }
- if (!reported_not_annotated_method_overrides_notnull
- && REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL
- && !annotated.isDeclaredNullable
- && !annotated.isDeclaredNotNull
- && NullableNotNullManager.isNotNull(superMethod)) {
- reported_not_annotated_method_overrides_notnull = true;
- final String defaultNotNull = nullableManager.getDefaultNotNull();
- final String[] annotationsToRemove = ArrayUtil.toStringArray(nullableManager.getNullables());
- final LocalQuickFix fix = AnnotationUtil.isAnnotatingApplicable(method, defaultNotNull)
- ? createAnnotateMethodFix(defaultNotNull, annotationsToRemove)
- : createChangeDefaultNotNullFix(nullableManager, superMethod);
- holder.registerProblem(method.getNameIdentifier(),
- InspectionsBundle.message("inspection.nullable.problems.method.overrides.NotNull"),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
- wrapFix(fix));
- }
- if (REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE || REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL) {
- PsiParameter[] superParameters = superMethod.getParameterList().getParameters();
- if (superParameters.length != parameters.length) {
- continue;
- }
- for (int i = 0; i < parameters.length; i++) {
- PsiParameter parameter = parameters[i];
- PsiParameter superParameter = superParameters[i];
- if (!reported_notnull_parameter_overrides_nullable[i] && REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE &&
- nullableManager.isNotNull(parameter, false) &&
- nullableManager.isNullable(superParameter, false)) {
- reported_notnull_parameter_overrides_nullable[i] = true;
- holder.registerProblem(parameter.getNameIdentifier(),
- InspectionsBundle.message("inspection.nullable.problems.NotNull.parameter.overrides.Nullable"),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
- }
- if (!reported_not_annotated_parameter_overrides_notnull[i] && REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL) {
- if (!AnnotationUtil.isAnnotated(parameter, nullableManager.getAllAnnotations(), false, false) &&
- nullableManager.isNotNull(superParameter, false)) {
- reported_not_annotated_parameter_overrides_notnull[i] = true;
- final LocalQuickFix fix = AnnotationUtil.isAnnotatingApplicable(parameter, nullableManager.getDefaultNotNull())
- ? new AddNotNullAnnotationFix(parameter)
- : createChangeDefaultNotNullFix(nullableManager, superParameter);
- holder.registerProblem(parameter.getNameIdentifier(),
- InspectionsBundle.message("inspection.nullable.problems.parameter.overrides.NotNull"),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
- wrapFix(fix));
- }
- }
- }
- }
- }
-
- if (REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS) {
- boolean[] parameterAnnotated = new boolean[parameters.length];
- boolean[] parameterQuickFixSuggested = new boolean[parameters.length];
- boolean hasAnnotatedParameter = false;
- for (int i = 0; i < parameters.length; i++) {
- PsiParameter parameter = parameters[i];
- parameterAnnotated[i] = nullableManager.isNotNull(parameter, false);
- hasAnnotatedParameter |= parameterAnnotated[i];
- }
- if (hasAnnotatedParameter || annotated.isDeclaredNotNull) {
- PsiManager manager = method.getManager();
- final String defaultNotNull = nullableManager.getDefaultNotNull();
- final boolean superMethodApplicable = AnnotationUtil.isAnnotatingApplicable(method, defaultNotNull);
- PsiMethod[] overridings =
- OverridingMethodsSearch.search(method, GlobalSearchScope.allScope(manager.getProject()), true).toArray(PsiMethod.EMPTY_ARRAY);
- boolean methodQuickFixSuggested = false;
- for (PsiMethod overriding : overridings) {
- if (!manager.isInProject(overriding)) continue;
-
- final boolean applicable = AnnotationUtil.isAnnotatingApplicable(overriding, defaultNotNull);
- if (!methodQuickFixSuggested
- && annotated.isDeclaredNotNull
- && !nullableManager.isNotNull(overriding, false)
- && (nullableManager.isNullable(overriding, false) || !nullableManager.isNullable(overriding, true))) {
- method.getNameIdentifier(); //load tree
- PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, nullableManager.getNotNulls());
- final String[] annotationsToRemove = ArrayUtil.toStringArray(nullableManager.getNullables());
-
- final LocalQuickFix fix;
- if (applicable) {
- fix = new MyAnnotateMethodFix(defaultNotNull, annotationsToRemove);
- }
- else {
- fix = superMethodApplicable ? null : createChangeDefaultNotNullFix(nullableManager, method);
- }
-
- PsiElement psiElement = annotation;
- if (!annotation.isPhysical()) {
- psiElement = method.getNameIdentifier();
- if (psiElement == null) continue;
- }
- holder.registerProblem(psiElement, InspectionsBundle.message("nullable.stuff.problems.overridden.methods.are.not.annotated"),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
- wrapFix(fix));
- methodQuickFixSuggested = true;
- }
- if (hasAnnotatedParameter) {
- PsiParameter[] psiParameters = overriding.getParameterList().getParameters();
- for (int i = 0; i < psiParameters.length; i++) {
- if (parameterQuickFixSuggested[i]) continue;
- PsiParameter parameter = psiParameters[i];
- if (parameterAnnotated[i] && !nullableManager.isNotNull(parameter, false) && !nullableManager.isNullable(parameter, false)) {
- parameters[i].getNameIdentifier(); //be sure that corresponding tree element available
- PsiAnnotation annotation = AnnotationUtil.findAnnotation(parameters[i], nullableManager.getNotNulls());
- PsiElement psiElement = annotation;
- if (!annotation.isPhysical()) {
- psiElement = parameters[i].getNameIdentifier();
- if (psiElement == null) continue;
- }
- holder.registerProblem(psiElement,
- InspectionsBundle.message("nullable.stuff.problems.overridden.method.parameters.are.not.annotated"),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
- wrapFix(!applicable
- ? createChangeDefaultNotNullFix(nullableManager, parameters[i])
- : new AnnotateOverriddenMethodParameterFix(defaultNotNull,
- nullableManager.getDefaultNullable())));
- parameterQuickFixSuggested[i] = true;
- }
- }
- }
- }
- }
- }
- }
-
- private static LocalQuickFix[] wrapFix(LocalQuickFix fix) {
- if (fix == null) return LocalQuickFix.EMPTY_ARRAY;
- return new LocalQuickFix[]{fix};
- }
-
- private static LocalQuickFix createChangeDefaultNotNullFix(NullableNotNullManager nullableManager, PsiModifierListOwner modifierListOwner) {
- final PsiAnnotation annotation = AnnotationUtil.findAnnotation(modifierListOwner, nullableManager.getNotNulls());
- if (annotation != null) {
- final PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement();
- if (referenceElement != null && referenceElement.resolve() != null) {
- return new ChangeNullableDefaultsFix(annotation.getQualifiedName(), null, nullableManager);
- }
- }
- return null;
- }
-
- protected AnnotateMethodFix createAnnotateMethodFix(final String defaultNotNull, final String[] annotationsToRemove) {
- return new AnnotateMethodFix(defaultNotNull, annotationsToRemove);
- }
-
- private static void reportNullableNotNullConflict(final ProblemsHolder holder, final PsiModifierListOwner listOwner, final PsiAnnotation declaredNullable,
- final PsiAnnotation declaredNotNull) {
- holder.registerProblem(declaredNotNull.isPhysical() ? declaredNotNull : listOwner.getNavigationElement(),
- InspectionsBundle.message("inspection.nullable.problems.Nullable.NotNull.conflict"),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new RemoveAnnotationQuickFix(declaredNotNull, listOwner));
- holder.registerProblem(declaredNullable.isPhysical() ? declaredNullable : listOwner.getNavigationElement(),
- InspectionsBundle.message("inspection.nullable.problems.Nullable.NotNull.conflict"),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new RemoveAnnotationQuickFix(declaredNullable, listOwner));
- }
-
+public class NullableStuffInspection extends NullableStuffInspectionBase {
@Override
public JComponent createOptionsPanel() {
return new OptionsPanel();
}
- private static class MyAddNullableAnnotationFix extends AddNullableAnnotationFix {
- public MyAddNullableAnnotationFix(PsiParameter parameter) {
- super(parameter);
- }
-
- @Override
- public boolean isAvailable(@NotNull Project project,
- @NotNull PsiFile file,
- @NotNull PsiElement startElement,
- @NotNull PsiElement endElement) {
- return true;
- }
- }
-
- private static class MyAnnotateMethodFix extends AnnotateMethodFix {
- public MyAnnotateMethodFix(String defaultNotNull, String[] annotationsToRemove) {
- super(defaultNotNull, annotationsToRemove);
- }
-
- @Override
- protected boolean annotateOverriddenMethods() {
- return true;
- }
-
- @Override
- @NotNull
- public String getName() {
- return InspectionsBundle.message("annotate.overridden.methods.as.notnull", ClassUtil.extractClassName(myAnnotation));
- }
- }
-
private class OptionsPanel extends JPanel {
private JCheckBox myNNParameterOverridesN;
private JCheckBox myNAMethodOverridesNN;
@@ -528,42 +77,4 @@
REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL;
}
}
-
- public static List<PsiExpression> findAllConstructorInitializers(PsiField field) {
- final List<PsiExpression> result = ContainerUtil.createLockFreeCopyOnWriteList();
- ContainerUtil.addIfNotNull(result, field.getInitializer());
-
- PsiClass containingClass = field.getContainingClass();
- if (containingClass != null) {
- LocalSearchScope scope = new LocalSearchScope(containingClass.getConstructors());
- ReferencesSearch.search(field, scope, false).forEach(new Processor<PsiReference>() {
- @Override
- public boolean process(PsiReference reference) {
- final PsiElement element = reference.getElement();
- if (element instanceof PsiReferenceExpression) {
- final PsiAssignmentExpression assignment = getAssignmentExpressionIfOnAssignmentLhs(element);
- final PsiMethod method = PsiTreeUtil.getParentOfType(assignment, PsiMethod.class);
- if (method != null && method.isConstructor() && assignment != null) {
- ContainerUtil.addIfNotNull(result, assignment.getRExpression());
- }
- }
- return true;
- }
- });
- }
- return result;
- }
-
- @Nullable
- private static PsiAssignmentExpression getAssignmentExpressionIfOnAssignmentLhs(PsiElement expression) {
- PsiElement parent = PsiTreeUtil.skipParentsOfType(expression, PsiParenthesizedExpression.class);
- if (!(parent instanceof PsiAssignmentExpression)) {
- return null;
- }
- final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)parent;
- if (!PsiTreeUtil.isAncestor(assignmentExpression.getLExpression(), expression, false)) {
- return null;
- }
- return assignmentExpression;
- }
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java b/java/java-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java
index a5e71fb..b8fea07 100644
--- a/java/java-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java
+++ b/java/java-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java
@@ -15,10 +15,7 @@
*/
package com.intellij.codeInspection.reference;
-import com.intellij.codeInspection.InspectionProfileEntry;
-import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.SuppressManager;
-import com.intellij.codeInspection.SuppressionUtil;
+import com.intellij.codeInspection.*;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
import com.intellij.codeInspection.ex.EntryPointsManager;
import com.intellij.codeInspection.ex.EntryPointsManagerImpl;
@@ -450,7 +447,7 @@
@Override
public void visitAnnotation(PsiAnnotation annotation) {
super.visitAnnotation(annotation);
- if (Comparing.strEqual(annotation.getQualifiedName(), SuppressManager.SUPPRESS_INSPECTIONS_ANNOTATION_NAME)) {
+ if (Comparing.strEqual(annotation.getQualifiedName(), BatchSuppressManager.SUPPRESS_INSPECTIONS_ANNOTATION_NAME)) {
final PsiModifierListOwner listOwner = PsiTreeUtil.getParentOfType(annotation, PsiModifierListOwner.class);
if (listOwner != null) {
final RefElementImpl element = (RefElementImpl)myRefManager.getReference(listOwner);
diff --git a/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java b/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java
index 2d363ec..24cc9d1 100644
--- a/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java
@@ -17,8 +17,8 @@
package com.intellij.codeInspection.uncheckedWarnings;
import com.intellij.codeInsight.daemon.JavaErrorMessages;
-import com.intellij.codeInsight.daemon.impl.analysis.GenericsHighlightUtil;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.codeInsight.daemon.impl.quickfix.GenerifyFileFix;
import com.intellij.codeInsight.daemon.impl.quickfix.VariableArrayTypeFix;
import com.intellij.codeInsight.intention.IntentionAction;
@@ -177,7 +177,7 @@
};
}
- public abstract class UncheckedWarningsVisitor extends JavaElementVisitor {
+ private abstract class UncheckedWarningsVisitor extends JavaElementVisitor {
private final boolean myOnTheFly;
private final LocalQuickFix[] myGenerifyFixes;
@@ -194,7 +194,7 @@
if (IGNORE_UNCHECKED_GENERICS_ARRAY_CREATION) return;
if (!PsiUtil.isLanguageLevel5OrHigher(expression)) return;
final JavaResolveResult result = expression.advancedResolve(false);
- if (GenericsHighlightUtil.isUncheckedWarning(expression, result)) {
+ if (JavaGenericsUtil.isUncheckedWarning(expression, result)) {
registerProblem("Unchecked generics array creation for varargs parameter", expression, LocalQuickFix.EMPTY_ARRAY);
}
}
@@ -205,7 +205,7 @@
if (IGNORE_UNCHECKED_GENERICS_ARRAY_CREATION) return;
if (!PsiUtil.isLanguageLevel5OrHigher(expression)) return;
final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
- if (GenericsHighlightUtil.isUncheckedWarning(classReference, expression.resolveMethodGenerics())) {
+ if (JavaGenericsUtil.isUncheckedWarning(classReference, expression.resolveMethodGenerics())) {
registerProblem("Unchecked generics array creation for varargs parameter", classReference, LocalQuickFix.EMPTY_ARRAY);
}
}
@@ -223,9 +223,10 @@
final PsiType exprType = operand.getType();
if (exprType == null) return;
if (!TypeConversionUtil.areTypesConvertible(exprType, castType)) return;
- if (GenericsHighlightUtil.isUncheckedCast(castType, exprType)) {
+ if (JavaGenericsUtil.isUncheckedCast(castType, exprType)) {
final String description =
- JavaErrorMessages.message("generics.unchecked.cast", HighlightUtil.formatType(exprType), HighlightUtil.formatType(castType));
+ JavaErrorMessages.message("generics.unchecked.cast", JavaHighlightUtil.formatType(exprType), JavaHighlightUtil
+ .formatType(castType));
registerProblem(description, expression, myGenerifyFixes);
}
}
@@ -289,7 +290,7 @@
final PsiType parameterType = parameter.getType();
final PsiExpression iteratedValue = statement.getIteratedValue();
if (iteratedValue == null) return;
- final PsiType itemType = GenericsHighlightUtil.getCollectionItemType(iteratedValue);
+ final PsiType itemType = JavaGenericsUtil.getCollectionItemType(iteratedValue);
if (!PsiUtil.isLanguageLevel5OrHigher(statement)) return;
checkRawToGenericsAssignment(parameter, parameterType, itemType, true, myOnTheFly ? getChangeVariableTypeFixes(parameter, itemType) : LocalQuickFix.EMPTY_ARRAY);
}
@@ -335,12 +336,12 @@
if (itemType == null) continue;
if (!TypeConversionUtil.isAssignable(componentType, itemType)) continue;
- if (GenericsHighlightUtil.isRawToGeneric(componentType, itemType)) {
+ if (JavaGenericsUtil.isRawToGeneric(componentType, itemType)) {
String description = JavaErrorMessages.message("generics.unchecked.assignment",
- HighlightUtil.formatType(itemType),
- HighlightUtil.formatType(componentType));
+ JavaHighlightUtil.formatType(itemType),
+ JavaHighlightUtil.formatType(componentType));
if (!arrayTypeFixChecked) {
- final PsiType checkResult = HighlightUtil.sameType(initializers);
+ final PsiType checkResult = JavaHighlightUtil.sameType(initializers);
fix = checkResult != null ? new VariableArrayTypeFix(arrayInitializer, checkResult) : null;
arrayTypeFixChecked = true;
}
@@ -359,10 +360,10 @@
@NotNull LocalQuickFix[] quickFixes) {
if (parameterType == null || itemType == null) return;
if (checkAssignability && !TypeConversionUtil.isAssignable(parameterType, itemType)) return;
- if (GenericsHighlightUtil.isRawToGeneric(parameterType, itemType)) {
+ if (JavaGenericsUtil.isRawToGeneric(parameterType, itemType)) {
String description = JavaErrorMessages.message("generics.unchecked.assignment",
- HighlightUtil.formatType(itemType),
- HighlightUtil.formatType(parameterType));
+ JavaHighlightUtil.formatType(itemType),
+ JavaHighlightUtil.formatType(parameterType));
registerProblem(description, parameter, quickFixes);
}
}
@@ -384,10 +385,10 @@
final PsiType baseReturnType = substitutor.substitute(baseMethod.getReturnType());
final PsiType overriderReturnType = method.getReturnType();
if (baseReturnType == null || overriderReturnType == null) return;
- if (GenericsHighlightUtil.isRawToGeneric(baseReturnType, overriderReturnType)) {
+ if (JavaGenericsUtil.isRawToGeneric(baseReturnType, overriderReturnType)) {
final String message = JavaErrorMessages.message("unchecked.overriding.incompatible.return.type",
- HighlightUtil.formatType(overriderReturnType),
- HighlightUtil.formatType(baseReturnType));
+ JavaHighlightUtil.formatType(overriderReturnType),
+ JavaHighlightUtil.formatType(baseReturnType));
final PsiTypeElement returnTypeElement = method.getReturnTypeElement();
LOG.assertTrue(returnTypeElement != null);
@@ -470,8 +471,8 @@
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory();
PsiType type = elementFactory.createType(method.getContainingClass(), substitutor);
return JavaErrorMessages.message("generics.unchecked.call.to.member.of.raw.type",
- HighlightUtil.formatMethod(method),
- HighlightUtil.formatType(type));
+ JavaHighlightUtil.formatMethod(method),
+ JavaHighlightUtil.formatType(type));
}
}
return null;
diff --git a/java/java-impl/src/com/intellij/codeInspection/util/SpecialAnnotationsUtil.java b/java/java-impl/src/com/intellij/codeInspection/util/SpecialAnnotationsUtil.java
index 6e90687..1e630d4 100644
--- a/java/java-impl/src/com/intellij/codeInspection/util/SpecialAnnotationsUtil.java
+++ b/java/java-impl/src/com/intellij/codeInspection/util/SpecialAnnotationsUtil.java
@@ -16,12 +16,8 @@
package com.intellij.codeInspection.util;
-import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.intention.IntentionAction;
-import com.intellij.codeInspection.InspectionProfile;
import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.LocalQuickFix;
-import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.ide.DataManager;
import com.intellij.ide.util.ClassFilter;
import com.intellij.ide.util.TreeClassChooser;
@@ -32,24 +28,18 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.profile.codeInspection.InspectionProfileManager;
-import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
import com.intellij.util.IconUtil;
import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.Processor;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import java.awt.*;
-import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@@ -169,7 +159,7 @@
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
- doQuickFixInternal(project, targetList, qualifiedName);
+ SpecialAnnotationsUtilBase.doQuickFixInternal(project, targetList, qualifiedName);
}
@Override
@@ -178,62 +168,4 @@
}
};
}
-
- public static LocalQuickFix createAddToSpecialAnnotationsListQuickFix(final String text,
- final String family,
- final List<String> targetList,
- final String qualifiedName,
- final PsiElement context) {
- return new LocalQuickFix() {
- @Override
- @NotNull
- public String getName() {
- return text;
- }
-
- @Override
- @NotNull
- public String getFamilyName() {
- return family;
- }
-
- @Override
- public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
- doQuickFixInternal(project, targetList, qualifiedName);
- }
- };
- }
-
- private static void doQuickFixInternal(final Project project, final List<String> targetList, final String qualifiedName) {
- targetList.add(qualifiedName);
- Collections.sort(targetList);
- final InspectionProfile inspectionProfile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
- //correct save settings
-
- //TODO lesya
- InspectionProfileManager.getInstance().fireProfileChanged(inspectionProfile);
- /*
- try {
- inspectionProfile.save();
- }
- catch (IOException e) {
- Messages.showErrorDialog(project, e.getMessage(), CommonBundle.getErrorTitle());
- }
-
- */
- }
-
- public static void createAddToSpecialAnnotationFixes(final PsiModifierListOwner owner, final Processor<String> processor) {
- final PsiModifierList modifierList = owner.getModifierList();
- if (modifierList != null) {
- final PsiAnnotation[] psiAnnotations = modifierList.getAnnotations();
- for (PsiAnnotation psiAnnotation : psiAnnotations) {
- @NonNls final String name = psiAnnotation.getQualifiedName();
- if (name == null) continue;
- if (name.startsWith("java.") || name.startsWith("javax.") ||
- (name.startsWith("org.jetbrains.") && AnnotationUtil.isJetbrainsAnnotation(StringUtil.getShortName(name)))) continue;
- if (!processor.process(name)) break;
- }
- }
- }
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/BaseConvertToLocalQuickFix.java b/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/BaseConvertToLocalQuickFix.java
index bbe84bd..6dd3558 100644
--- a/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/BaseConvertToLocalQuickFix.java
+++ b/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/BaseConvertToLocalQuickFix.java
@@ -41,7 +41,7 @@
import java.util.Set;
/**
- * refactored from {@link com.intellij.codeInspection.varScopeCanBeNarrowed.FieldCanBeLocalInspection.MyQuickFix}
+ * refactored from {@link com.intellij.codeInspection.varScopeCanBeNarrowed.FieldCanBeLocalInspection}
*
* @author Danila Ponomarenko
*/
@@ -57,8 +57,8 @@
@Override
public final void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final V variable = getVariable(descriptor);
- final PsiFile myFile = variable.getContainingFile();
if (variable == null || !variable.isValid()) return; //weird. should not get here when field becomes invalid
+ final PsiFile myFile = variable.getContainingFile();
try {
final PsiElement newDeclaration = moveDeclaration(project, variable);
@@ -142,12 +142,12 @@
);
}
- protected PsiElement applyChanges(final @NotNull Project project,
- final @NotNull String localName,
- final @Nullable PsiExpression initializer,
- final @NotNull V variable,
- final @NotNull Collection<PsiReference> references,
- final @NotNull NotNullFunction<PsiDeclarationStatement, PsiElement> action) {
+ protected PsiElement applyChanges(@NotNull final Project project,
+ @NotNull final String localName,
+ @Nullable final PsiExpression initializer,
+ @NotNull final V variable,
+ @NotNull final Collection<PsiReference> references,
+ @NotNull final NotNullFunction<PsiDeclarationStatement, PsiElement> action) {
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
return ApplicationManager.getApplication().runWriteAction(
@@ -202,11 +202,7 @@
final PsiReferenceExpression leftExpression = (PsiReferenceExpression)expression.getLExpression();
- if (!leftExpression.isReferenceTo(variable)) {
- return false;
- }
-
- return true;
+ return leftExpression.isReferenceTo(variable);
}
@NotNull
@@ -273,9 +269,4 @@
}
return result;
}
-
-
- public boolean runForWholeFile() {
- return true;
- }
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspection.java b/java/java-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspection.java
index e6fc026..3f4bd05 100644
--- a/java/java-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspection.java
@@ -15,105 +15,22 @@
*/
package com.intellij.codeInspection.wrongPackageStatement;
-import com.intellij.codeHighlighting.HighlightDisplayLevel;
-import com.intellij.codeInsight.daemon.JavaErrorMessages;
-import com.intellij.codeInspection.*;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.psi.*;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.MoveToPackageFix;
+import com.intellij.psi.PsiFile;
-import java.util.ArrayList;
import java.util.List;
/**
* User: anna
* Date: 14-Nov-2005
*/
-public class WrongPackageStatementInspection extends BaseJavaLocalInspectionTool {
+public class WrongPackageStatementInspection extends WrongPackageStatementInspectionBase {
@Override
- @Nullable
- public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
- // does not work in tests since CodeInsightTestCase copies file into temporary location
- if (ApplicationManager.getApplication().isUnitTestMode()) return null;
- if (file instanceof PsiJavaFile) {
- if (JspPsiUtil.isInJspFile(file)) return null;
- PsiJavaFile javaFile = (PsiJavaFile)file;
-
- PsiDirectory directory = javaFile.getContainingDirectory();
- if (directory == null) return null;
- PsiPackage dirPackage = JavaDirectoryService.getInstance().getPackage(directory);
- if (dirPackage == null) return null;
- PsiPackageStatement packageStatement = javaFile.getPackageStatement();
-
- // highlight the first class in the file only
- PsiClass[] classes = javaFile.getClasses();
- if (classes.length == 0 && packageStatement == null) return null;
-
- String packageName = dirPackage.getQualifiedName();
- if (!Comparing.strEqual(packageName, "", true) && packageStatement == null) {
- String description = JavaErrorMessages.message("missing.package.statement", packageName);
-
- return new ProblemDescriptor[]{manager.createProblemDescriptor(classes[0].getNameIdentifier(), description,
- new AdjustPackageNameFix(packageName),
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING, isOnTheFly)};
- }
- if (packageStatement != null) {
- final PsiJavaCodeReferenceElement packageReference = packageStatement.getPackageReference();
- PsiPackage classPackage = (PsiPackage)packageReference.resolve();
- List<LocalQuickFix> availableFixes = new ArrayList<LocalQuickFix>();
- if (classPackage == null || !Comparing.equal(dirPackage.getQualifiedName(), packageReference.getQualifiedName(), true)) {
- availableFixes.add(new AdjustPackageNameFix(packageName));
- MoveToPackageFix moveToPackageFix = new MoveToPackageFix(classPackage != null ? classPackage.getQualifiedName() : packageReference.getQualifiedName());
- if (moveToPackageFix.isAvailable(file)) {
- availableFixes.add(moveToPackageFix);
- }
- }
- if (!availableFixes.isEmpty()){
- String description = JavaErrorMessages.message("package.name.file.path.mismatch",
- packageReference.getQualifiedName(),
- dirPackage.getQualifiedName());
- LocalQuickFix[] fixes = availableFixes.toArray(new LocalQuickFix[availableFixes.size()]);
- ProblemDescriptor descriptor =
- manager.createProblemDescriptor(packageStatement.getPackageReference(), description, isOnTheFly,
- fixes, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
- return new ProblemDescriptor[]{descriptor};
-
- }
- }
+ protected void addMoveToPackageFix(PsiFile file, String packName, List<LocalQuickFix> availableFixes) {
+ MoveToPackageFix moveToPackageFix = new MoveToPackageFix(packName);
+ if (moveToPackageFix.isAvailable(file)) {
+ availableFixes.add(moveToPackageFix);
}
- return null;
- }
-
- @Override
- @NotNull
- public String getGroupDisplayName() {
- return "";
- }
-
- @Override
- @NotNull
- public HighlightDisplayLevel getDefaultLevel() {
- return HighlightDisplayLevel.ERROR;
- }
-
- @Override
- @NotNull
- public String getDisplayName() {
- return InspectionsBundle.message("wrong.package.statement");
- }
-
- @Override
- @NotNull
- @NonNls
- public String getShortName() {
- return "WrongPackageStatement";
- }
-
- @Override
- public boolean isEnabledByDefault() {
- return true;
}
}
diff --git a/java/java-psi-impl/src/com/intellij/externalSystem/JavaProjectData.java b/java/java-impl/src/com/intellij/externalSystem/JavaProjectData.java
similarity index 98%
rename from java/java-psi-impl/src/com/intellij/externalSystem/JavaProjectData.java
rename to java/java-impl/src/com/intellij/externalSystem/JavaProjectData.java
index d1f5bfa..29f991c 100644
--- a/java/java-psi-impl/src/com/intellij/externalSystem/JavaProjectData.java
+++ b/java/java-impl/src/com/intellij/externalSystem/JavaProjectData.java
@@ -18,7 +18,7 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.Key;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
-import com.intellij.openapi.externalSystem.model.project.AbstractProjectEntityData;
+import com.intellij.openapi.externalSystem.model.project.AbstractExternalEntityData;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.pom.java.LanguageLevel;
@@ -32,7 +32,7 @@
* @author Denis Zhdanov
* @since 4/12/13 12:27 PM
*/
-public class JavaProjectData extends AbstractProjectEntityData {
+public class JavaProjectData extends AbstractExternalEntityData {
@NotNull public static final Key<JavaProjectData> KEY = Key.create(JavaProjectData.class);
diff --git a/java/java-psi-impl/src/com/intellij/externalSystem/JavaProjectDataService.java b/java/java-impl/src/com/intellij/externalSystem/JavaProjectDataService.java
similarity index 95%
rename from java/java-psi-impl/src/com/intellij/externalSystem/JavaProjectDataService.java
rename to java/java-impl/src/com/intellij/externalSystem/JavaProjectDataService.java
index 626763a..47f4b0a 100644
--- a/java/java-psi-impl/src/com/intellij/externalSystem/JavaProjectDataService.java
+++ b/java/java-impl/src/com/intellij/externalSystem/JavaProjectDataService.java
@@ -17,7 +17,6 @@
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.Key;
-import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataService;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.project.Project;
@@ -106,7 +105,7 @@
if (languageLevelExtension.getLanguageLevel().isAtLeast(languageLevel)) {
return;
}
- ExternalSystemApiUtil.executeProjectChangeAction(project, ProjectSystemId.IDE, synchronous, new Runnable() {
+ ExternalSystemApiUtil.executeProjectChangeAction(synchronous, new Runnable() {
@Override
public void run() {
languageLevelExtension.setLanguageLevel(languageLevel);
diff --git a/java/java-impl/src/com/intellij/ide/actions/JavaQualifiedNameProvider.java b/java/java-impl/src/com/intellij/ide/actions/JavaQualifiedNameProvider.java
index 4f49420..de3446e 100644
--- a/java/java-impl/src/com/intellij/ide/actions/JavaQualifiedNameProvider.java
+++ b/java/java-impl/src/com/intellij/ide/actions/JavaQualifiedNameProvider.java
@@ -15,7 +15,7 @@
*/
package com.intellij.ide.actions;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -220,7 +220,7 @@
catch (IncorrectOperationException e) {
// failed to bind
}
- if (referenceExpression.isValid() && !isReferencedTo(referenceExpression, targetElement)) {
+ if (!referenceExpression.isValid() || !isReferencedTo(referenceExpression, targetElement)) {
toInsert = fqn;
}
}
@@ -241,7 +241,7 @@
LOG.error(e);
}
}
- CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(file);
+ CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(file);
try {
CodeStyleManager.getInstance(project).adjustLineIndent(file, offset);
}
diff --git a/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java b/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java
index cec7c4a..c4d1369 100644
--- a/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java
+++ b/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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,7 +18,6 @@
import com.intellij.lexer.JavaHighlightingLexer;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.editor.HighlighterColors;
-import com.intellij.openapi.editor.SyntaxHighlighterColors;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.fileTypes.SyntaxHighlighterBase;
import com.intellij.pom.java.LanguageLevel;
@@ -39,21 +38,11 @@
private static final Map<IElementType, TextAttributesKey> ourMap1;
private static final Map<IElementType, TextAttributesKey> ourMap2;
- private final LanguageLevel myLanguageLevel;
-
- public JavaFileHighlighter() {
- this(LanguageLevel.HIGHEST);
- }
-
- public JavaFileHighlighter(LanguageLevel languageLevel) {
- myLanguageLevel = languageLevel;
- }
-
static {
ourMap1 = new HashMap<IElementType, TextAttributesKey>();
ourMap2 = new HashMap<IElementType, TextAttributesKey>();
- fillMap(ourMap1, ElementType.KEYWORD_BIT_SET, JavaHighlightingColors .KEYWORD);
+ fillMap(ourMap1, ElementType.KEYWORD_BIT_SET, JavaHighlightingColors.KEYWORD);
fillMap(ourMap1, ElementType.LITERAL_BIT_SET, JavaHighlightingColors.KEYWORD);
fillMap(ourMap1, ElementType.OPERATION_BIT_SET, JavaHighlightingColors.OPERATION_SIGN);
@@ -96,25 +85,28 @@
ourMap1.put(JavaDocTokenType.DOC_TAG_NAME, JavaHighlightingColors.DOC_COMMENT);
ourMap2.put(JavaDocTokenType.DOC_TAG_NAME, JavaHighlightingColors.DOC_COMMENT_TAG);
- IElementType[] javaDocMarkup = new IElementType[]{XmlTokenType.XML_START_TAG_START,
- XmlTokenType.XML_END_TAG_START,
- XmlTokenType.XML_TAG_END,
- XmlTokenType.XML_EMPTY_ELEMENT_END,
- XmlTokenType.TAG_WHITE_SPACE,
- XmlTokenType.XML_TAG_NAME,
- XmlTokenType.XML_NAME,
- XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN,
- XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER,
- XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER,
- XmlTokenType.XML_CHAR_ENTITY_REF,
- XmlTokenType.XML_EQ};
-
+ IElementType[] javaDocMarkup = {
+ XmlTokenType.XML_START_TAG_START, XmlTokenType.XML_END_TAG_START, XmlTokenType.XML_TAG_END, XmlTokenType.XML_EMPTY_ELEMENT_END,
+ XmlTokenType.TAG_WHITE_SPACE, XmlTokenType.XML_TAG_NAME, XmlTokenType.XML_NAME, XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN,
+ XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER, XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER, XmlTokenType.XML_CHAR_ENTITY_REF,
+ XmlTokenType.XML_EQ
+ };
for (IElementType idx : javaDocMarkup) {
ourMap1.put(idx, JavaHighlightingColors.DOC_COMMENT);
ourMap2.put(idx, JavaHighlightingColors.DOC_COMMENT_MARKUP);
}
}
+ private final LanguageLevel myLanguageLevel;
+
+ public JavaFileHighlighter() {
+ this(LanguageLevel.HIGHEST);
+ }
+
+ public JavaFileHighlighter(@NotNull LanguageLevel languageLevel) {
+ myLanguageLevel = languageLevel;
+ }
+
@NotNull
public Lexer getHighlightingLexer() {
return new JavaHighlightingLexer(myLanguageLevel);
diff --git a/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java b/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java
index 2aae5d8..e8197bb 100644
--- a/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java
+++ b/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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,10 +21,12 @@
import com.intellij.ide.projectView.impl.nodes.ClassTreeNode;
import com.intellij.ide.projectView.impl.nodes.PsiFileNode;
import com.intellij.ide.util.treeView.AbstractTreeNode;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.jsp.JspFile;
@@ -67,7 +69,12 @@
}
if (fileInRoots(file)) {
- PsiClass[] classes = classOwner.getClasses();
+ PsiClass[] classes = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass[]>() {
+ @Override
+ public PsiClass[] compute() {
+ return classOwner.getClasses();
+ }
+ });
if (classes.length == 1 && !(classes[0] instanceof SyntheticElement) &&
(file == null || file.getNameWithoutExtension().equals(classes[0].getName()))) {
result.add(new ClassTreeNode(myProject, classes[0], settings1));
diff --git a/java/java-impl/src/com/intellij/ide/util/PackageChooserDialog.java b/java/java-impl/src/com/intellij/ide/util/PackageChooserDialog.java
index 245f342..2ad3edc 100644
--- a/java/java-impl/src/com/intellij/ide/util/PackageChooserDialog.java
+++ b/java/java-impl/src/com/intellij/ide/util/PackageChooserDialog.java
@@ -22,6 +22,11 @@
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.event.*;
+import com.intellij.openapi.editor.event.DocumentAdapter;
+import com.intellij.openapi.fileChooser.ex.FileChooserDialogImpl;
+import com.intellij.openapi.fileChooser.ex.TextFieldAction;
+import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ContentIterator;
@@ -35,9 +40,10 @@
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.ui.ScrollPaneFactory;
-import com.intellij.ui.TreeSpeedSearch;
+import com.intellij.ui.*;
+import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.treeStructure.Tree;
+import com.intellij.util.Alarm;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.PlatformIcons;
import com.intellij.util.containers.Convertor;
@@ -66,6 +72,9 @@
private final Project myProject;
private final String myTitle;
private Module myModule;
+ private EditorTextField myPathEditor;
+
+ private Alarm myAlarm = new Alarm(getDisposable());
public PackageChooserDialog(String title, @NotNull Module module) {
super(module.getProject(), true);
@@ -147,19 +156,69 @@
else {
setTitle(myTitle);
}
+ updatePathFromTree();
}
});
panel.add(scrollPane, BorderLayout.CENTER);
DefaultActionGroup group = createActionGroup(myTree);
+ final JPanel northPanel = new JPanel(new BorderLayout());
+ panel.add(northPanel, BorderLayout.NORTH);
ActionToolbar toolBar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true);
- panel.add(toolBar.getComponent(), BorderLayout.NORTH);
- toolBar.getComponent().setAlignmentX(JComponent.LEFT_ALIGNMENT);
-
+ northPanel.add(toolBar.getComponent(), BorderLayout.WEST);
+ setupPathComponent(northPanel);
return panel;
}
+ private void setupPathComponent(final JPanel northPanel) {
+ northPanel.add(new TextFieldAction() {
+ @Override
+ public void linkSelected(LinkLabel aSource, Object aLinkData) {
+ toggleShowPathComponent(northPanel, this);
+ }
+ }, BorderLayout.EAST);
+ myPathEditor = new EditorTextField(JavaReferenceEditorUtil.createDocument("", myProject, false), myProject, StdFileTypes.JAVA);
+ myPathEditor.addDocumentListener(new DocumentAdapter() {
+ @Override
+ public void documentChanged(DocumentEvent e) {
+ myAlarm.cancelAllRequests();
+ myAlarm.addRequest(new Runnable() {
+ @Override
+ public void run() {
+ updateTreeFromPath();
+ }
+ }, 300);
+ }
+ });
+ myPathEditor.setBorder(BorderFactory.createEmptyBorder(0, 0, 2, 0));
+ northPanel.add(myPathEditor, BorderLayout.SOUTH);
+ }
+
+ private void toggleShowPathComponent(JPanel northPanel, TextFieldAction fieldAction) {
+ boolean toShowTextField = !isPathShowing();
+ PropertiesComponent.getInstance().setValue(FileChooserDialogImpl.FILE_CHOOSER_SHOW_PATH_PROPERTY, Boolean.toString(toShowTextField));
+ myPathEditor.setVisible(toShowTextField);
+ fieldAction.update();
+ northPanel.revalidate();
+ northPanel.repaint();
+ updatePathFromTree();
+ }
+
+ private static boolean isPathShowing() {
+ return PropertiesComponent.getInstance().getBoolean(FileChooserDialogImpl.FILE_CHOOSER_SHOW_PATH_PROPERTY, true);
+ }
+
+ private void updatePathFromTree() {
+ if (!isPathShowing()) return;
+ final PsiPackage selection = getTreeSelection();
+ myPathEditor.setText(selection != null ? selection.getQualifiedName() : "");
+ }
+
+ private void updateTreeFromPath() {
+ selectPackage(myPathEditor.getText().trim());
+ }
+
private DefaultActionGroup createActionGroup(JComponent component) {
final DefaultActionGroup group = new DefaultActionGroup();
final DefaultActionGroup temp = new DefaultActionGroup();
diff --git a/java/java-impl/src/com/intellij/ide/util/SuperMethodWarningDialog.java b/java/java-impl/src/com/intellij/ide/util/SuperMethodWarningDialog.java
index 15c17f6..eb09ceb 100644
--- a/java/java-impl/src/com/intellij/ide/util/SuperMethodWarningDialog.java
+++ b/java/java-impl/src/com/intellij/ide/util/SuperMethodWarningDialog.java
@@ -80,12 +80,19 @@
? IdeBundle.message("label.overrides.method.of_class_or_interface.name", methodString, classType, className)
: IdeBundle.message("label.implements.method.of_class_or_interface.name", methodString, classType, className)));
} else {
- labelsPanel.add(new JLabel(IdeBundle.message("label.implements.method.of_interfaces")));
+ final JLabel multLabel = new JLabel(IdeBundle.message("label.implements.method.of_interfaces"));
+ multLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
+ labelsPanel.add(multLabel);
+
for (final String className : myClassNames) {
labelsPanel.add(new JLabel(" " + className));
}
}
- labelsPanel.add(new JLabel(IdeBundle.message("prompt.do.you.want.to.action_verb.the.method.from_class", myActionString, myClassNames.length > 1 ? 2 : 1)));
+
+ final JLabel doYouWantLabel = new JLabel(
+ IdeBundle.message("prompt.do.you.want.to.action_verb.the.method.from_class", myActionString, myClassNames.length > 1 ? 2 : 1));
+ doYouWantLabel.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
+ labelsPanel.add(doYouWantLabel);
panel.add(labelsPanel, BorderLayout.CENTER);
return panel;
}
diff --git a/java/java-impl/src/com/intellij/ide/util/SuperMethodWarningUtil.java b/java/java-impl/src/com/intellij/ide/util/SuperMethodWarningUtil.java
index 5ac29a8..efb05d7 100644
--- a/java/java-impl/src/com/intellij/ide/util/SuperMethodWarningUtil.java
+++ b/java/java-impl/src/com/intellij/ide/util/SuperMethodWarningUtil.java
@@ -15,9 +15,12 @@
*/
package com.intellij.ide.util;
+import com.intellij.codeInspection.InspectionsBundle;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
@@ -27,7 +30,6 @@
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.search.searches.DeepestSuperMethodsSearch;
import com.intellij.ui.components.JBList;
-import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
@@ -68,7 +70,7 @@
}
SuperMethodWarningDialog dialog =
- new SuperMethodWarningDialog(method.getProject(), UsageViewUtil.getDescriptiveName(method), actionString, superAbstract,
+ new SuperMethodWarningDialog(method.getProject(), DescriptiveNameUtil.getDescriptiveName(method), actionString, superAbstract,
parentInterface, aClass.isInterface(), ArrayUtil.toStringArray(superClasses));
dialog.show();
@@ -97,7 +99,7 @@
SuperMethodWarningDialog dialog =
new SuperMethodWarningDialog(
method.getProject(),
- UsageViewUtil.getDescriptiveName(method), actionString, containingClass.isInterface() || superMethod.hasModifierProperty(PsiModifier.ABSTRACT),
+ DescriptiveNameUtil.getDescriptiveName(method), actionString, containingClass.isInterface() || superMethod.hasModifierProperty(PsiModifier.ABSTRACT),
containingClass.isInterface(), aClass.isInterface(), containingClass.getQualifiedName()
);
dialog.show();
@@ -154,4 +156,16 @@
}
}).createPopup().showInBestPositionFor(editor);
}
+
+ public static int askWhetherShouldAnnotateBaseMethod(@NotNull PsiMethod method, @NotNull PsiMethod superMethod) {
+ String implement = !method.hasModifierProperty(PsiModifier.ABSTRACT) && superMethod.hasModifierProperty(PsiModifier.ABSTRACT)
+ ? InspectionsBundle.message("inspection.annotate.quickfix.implements")
+ : InspectionsBundle.message("inspection.annotate.quickfix.overrides");
+ String message = InspectionsBundle.message("inspection.annotate.quickfix.overridden.method.messages",
+ DescriptiveNameUtil.getDescriptiveName(method), implement,
+ DescriptiveNameUtil.getDescriptiveName(superMethod));
+ String title = InspectionsBundle.message("inspection.annotate.quickfix.overridden.method.warning");
+ return Messages.showYesNoCancelDialog(method.getProject(), message, title, Messages.getQuestionIcon());
+
+ }
}
\ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/ide/util/scopeChooser/ClassHierarchyScopeDescriptor.java b/java/java-impl/src/com/intellij/ide/util/scopeChooser/ClassHierarchyScopeDescriptor.java
index 075e091..99826b8 100644
--- a/java/java-impl/src/com/intellij/ide/util/scopeChooser/ClassHierarchyScopeDescriptor.java
+++ b/java/java-impl/src/com/intellij/ide/util/scopeChooser/ClassHierarchyScopeDescriptor.java
@@ -30,7 +30,7 @@
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
-import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.psi.util.PsiUtilCore;
import org.jetbrains.annotations.Nullable;
import java.util.LinkedList;
@@ -64,7 +64,7 @@
classesToSearch.addAll(ClassInheritorsSearch.search(aClass, true).findAll());
- myCachedScope = new LocalSearchScope(PsiUtilBase.toPsiElementArray(classesToSearch),
+ myCachedScope = new LocalSearchScope(PsiUtilCore.toPsiElementArray(classesToSearch),
IdeBundle.message("scope.hierarchy", ClassPresentationUtil.getNameForClass(aClass, true)));
}
diff --git a/java/java-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java b/java/java-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java
index 87d9e78..918b8ff 100644
--- a/java/java-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java
+++ b/java/java-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 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,19 +16,44 @@
package com.intellij.lang.java;
import com.intellij.ide.highlighter.JavaFileHighlighter;
+import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
+import com.intellij.openapi.fileTypes.SyntaxHighlighterProvider;
import com.intellij.openapi.module.LanguageLevelUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.impl.compiled.ClsFileImpl;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-public class JavaSyntaxHighlighterFactory extends SyntaxHighlighterFactory {
+public class JavaSyntaxHighlighterFactory extends SyntaxHighlighterFactory implements SyntaxHighlighterProvider {
+ /**
+ * SyntaxHighlighterFactory implementation (for Java source files).
+ */
@Override
@NotNull
- public SyntaxHighlighter getSyntaxHighlighter(final Project project, final VirtualFile virtualFile) {
- return new JavaFileHighlighter(
- virtualFile != null ? LanguageLevelUtil.getLanguageLevelForFile(virtualFile) : LanguageLevel.HIGHEST);
+ public SyntaxHighlighter getSyntaxHighlighter(@Nullable Project project, @Nullable VirtualFile file) {
+ return new JavaFileHighlighter(LanguageLevelUtil.getLanguageLevelForFile(file));
+ }
+
+ /**
+ * SyntaxHighlighterProvider implementation (for class files).
+ */
+ @Nullable
+ @Override
+ public SyntaxHighlighter create(FileType fileType, @Nullable Project project, @Nullable VirtualFile file) {
+ if (project != null && file != null) {
+ PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
+ if (psiFile instanceof ClsFileImpl) {
+ LanguageLevel sourceLevel = ((ClsFileImpl)psiFile).getSourceLanguageLevel();
+ return new JavaFileHighlighter(sourceLevel);
+ }
+ }
+
+ return new JavaFileHighlighter();
}
}
diff --git a/java/java-impl/src/com/intellij/profile/codeInspection/JavaAwareInspectionProfileManager.java b/java/java-impl/src/com/intellij/profile/codeInspection/JavaAwareInspectionProfileManager.java
index 5404d0a..e1d50a7 100644
--- a/java/java-impl/src/com/intellij/profile/codeInspection/JavaAwareInspectionProfileManager.java
+++ b/java/java-impl/src/com/intellij/profile/codeInspection/JavaAwareInspectionProfileManager.java
@@ -25,7 +25,7 @@
import com.intellij.codeInspection.ex.InspectionToolRegistrar;
import com.intellij.openapi.options.SchemesManagerFactory;
-public class JavaAwareInspectionProfileManager extends InspectionProfileManager{
+public class JavaAwareInspectionProfileManager extends InspectionProfileManagerImpl {
public JavaAwareInspectionProfileManager(InspectionToolRegistrar registrar, SchemesManagerFactory schemesManagerFactory) {
super(registrar, schemesManagerFactory);
}
diff --git a/java/java-impl/src/com/intellij/psi/AbstractQualifiedReference.java b/java/java-impl/src/com/intellij/psi/AbstractQualifiedReference.java
index 5853791..d26892e 100644
--- a/java/java-impl/src/com/intellij/psi/AbstractQualifiedReference.java
+++ b/java/java-impl/src/com/intellij/psi/AbstractQualifiedReference.java
@@ -40,7 +40,8 @@
/**
* @author peter
*/
-public abstract class AbstractQualifiedReference<T extends AbstractQualifiedReference<T>> extends ASTWrapperPsiElement implements PsiPolyVariantReference, PsiQualifiedReference {
+public abstract class AbstractQualifiedReference<T extends AbstractQualifiedReference<T>> extends ASTWrapperPsiElement
+ implements PsiPolyVariantReference, PsiQualifiedReferenceElement {
private static final ResolveCache.PolyVariantResolver<AbstractQualifiedReference> MY_RESOLVER = new ResolveCache.PolyVariantResolver<AbstractQualifiedReference>() {
@NotNull
@Override
diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java
index 89c7d47..001745c 100644
--- a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java
+++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java
@@ -292,7 +292,7 @@
and(matchRules, CLASS, STATIC);
and(matchRules, CLASS);
- return new StdArrangementSettings(groupingRules, matchRules);
+ return new StdRulePriorityAwareSettings(groupingRules, matchRules);
}
@Nullable
diff --git a/java/java-impl/src/com/intellij/psi/impl/light/LightParameter.java b/java/java-impl/src/com/intellij/psi/impl/light/LightParameter.java
index 611992b..6f5b426 100644
--- a/java/java-impl/src/com/intellij/psi/impl/light/LightParameter.java
+++ b/java/java-impl/src/com/intellij/psi/impl/light/LightParameter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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,7 +30,7 @@
private final boolean myVarArgs;
public LightParameter(@NotNull String name, @NotNull PsiType type, PsiElement declarationScope, Language language) {
- this(name, type, declarationScope, language, false);
+ this(name, type, declarationScope, language, type instanceof PsiEllipsisType);
}
public LightParameter(@NotNull String name, @NotNull PsiType type, PsiElement declarationScope, Language language, boolean isVarArgs) {
diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java
index a75bca9..4239f03 100644
--- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java
+++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java
@@ -15,16 +15,11 @@
*/
package com.intellij.psi.impl.smartPointers;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Segment;
-import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.ImplicitVariable;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiIdentifier;
-import com.intellij.psi.util.PsiUtilCore;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,69 +33,25 @@
return null;
}
- private static class ImplicitVariableInfo implements SmartPointerElementInfo {
- private final ImplicitVariable myVar;
- private final Project myProject;
-
+ private static class ImplicitVariableInfo extends HardElementInfo {
public ImplicitVariableInfo(@NotNull ImplicitVariable var, @NotNull Project project) {
- myVar = var;
- myProject = project;
+ super(project, var);
}
@Override
public PsiElement restoreElement() {
+ ImplicitVariable myVar = (ImplicitVariable)super.restoreElement();
PsiIdentifier psiIdentifier = myVar.getNameIdentifier();
if (psiIdentifier == null || psiIdentifier.isValid()) return myVar;
return null;
}
@Override
- @Nullable
- public Document getDocumentToSynchronize() {
- return null;
- }
-
- @Override
- public void documentAndPsiInSync() {
- }
-
- @Override
- public void fastenBelt(int offset, RangeMarker[] cachedRangeMarker) {
- }
-
- @Override
- public void unfastenBelt(int offset) {
- }
-
- @Override
- public int elementHashCode() {
- return myVar.hashCode();
- }
-
- @Override
- public boolean pointsToTheSameElementAs(@NotNull SmartPointerElementInfo other) {
- if (other instanceof ImplicitVariableInfo) {
- return myVar == ((ImplicitVariableInfo)other).myVar;
- }
- return Comparing.equal(restoreElement(), other.restoreElement());
- }
-
- @Override
- public VirtualFile getVirtualFile() {
- return PsiUtilCore.getVirtualFile(myVar);
- }
-
- @Override
public Segment getRange() {
+ ImplicitVariable myVar = (ImplicitVariable)super.restoreElement();
PsiIdentifier psiIdentifier = myVar.getNameIdentifier();
if (psiIdentifier == null || !psiIdentifier.isValid()) return null;
return psiIdentifier.getTextRange();
}
-
- @NotNull
- @Override
- public Project getProject() {
- return myProject;
- }
}
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ReferenceAdjuster.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ReferenceAdjuster.java
index a25476a..0f9e286 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ReferenceAdjuster.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ReferenceAdjuster.java
@@ -207,15 +207,15 @@
private static ASTNode makeShortReference(@NotNull CompositeElement reference, @NotNull PsiClass refClass, boolean addImports) {
@NotNull final PsiJavaCodeReferenceElement psiReference = (PsiJavaCodeReferenceElement)reference.getPsi();
- final PsiQualifiedReference reference1 = getClassReferenceToShorten(refClass, addImports, psiReference);
+ final PsiQualifiedReferenceElement reference1 = getClassReferenceToShorten(refClass, addImports, psiReference);
if (reference1 != null) replaceReferenceWithShort(reference1);
return reference;
}
@Nullable
- public static PsiQualifiedReference getClassReferenceToShorten(@NotNull final PsiClass refClass,
+ public static PsiQualifiedReferenceElement getClassReferenceToShorten(@NotNull final PsiClass refClass,
final boolean addImports,
- @NotNull final PsiQualifiedReference reference) {
+ @NotNull final PsiQualifiedReferenceElement reference) {
PsiClass parentClass = refClass.getContainingClass();
if (parentClass != null) {
JavaPsiFacade facade = JavaPsiFacade.getInstance(parentClass.getProject());
@@ -227,7 +227,7 @@
if (!CodeStyleSettingsManager.getSettings(reference.getProject()).INSERT_INNER_CLASS_IMPORTS) {
final PsiElement qualifier = reference.getQualifier();
if (qualifier instanceof PsiQualifiedReference) {
- return getClassReferenceToShorten(parentClass, addImports, (PsiQualifiedReference)qualifier);
+ return getClassReferenceToShorten(parentClass, addImports, (PsiQualifiedReferenceElement)qualifier);
}
return null;
}
@@ -255,7 +255,7 @@
}
@NotNull
- private static ASTNode replaceReferenceWithShort(PsiQualifiedReference reference) {
+ private static ASTNode replaceReferenceWithShort(PsiQualifiedReferenceElement reference) {
ASTNode node = reference.getNode();
assert node != null;
deQualifyImpl((CompositeElement)node);
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java
index 6e34ca2..f6ba9fd 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java
@@ -114,10 +114,10 @@
if (original instanceof PsiCompiledElement) {
PsiElement sourceVersion = original.getNavigationElement();
if (sourceVersion != original) {
- return ChangeUtil.generateTreeElement(sourceVersion, table,manager);
+ return ChangeUtil.generateTreeElement(sourceVersion, table, manager);
}
- ASTNode mirror = SourceTreeToPsiMap.psiElementToTree(((PsiCompiledElement)original).getMirror());
- return ChangeUtil.generateTreeElement(SourceTreeToPsiMap.treeElementToPsi(mirror), table,manager);
+ PsiElement mirror = ((PsiCompiledElement)original).getMirror();
+ return ChangeUtil.generateTreeElement(mirror, table, manager);
}
if (original instanceof PsiTypeElement) {
diff --git a/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java b/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java
index 3f6d158..7bca3c0 100644
--- a/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java
@@ -30,6 +30,7 @@
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.refactoring.util.ParameterTablePanel;
import com.intellij.refactoring.util.RefactoringMessageUtil;
+import com.intellij.refactoring.util.VariableData;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.NonFocusableCheckBox;
import com.intellij.util.Function;
@@ -49,7 +50,7 @@
private final boolean myShowCanBeStatic;
private NameSuggestionsField myNameField;
- private final ParameterTablePanel.VariableData[] myVariableData;
+ private final VariableData[] myVariableData;
private final Map<PsiVariable,VariableInfo> myVariableToInfoMap = new HashMap<PsiVariable, VariableInfo>();
private JCheckBox myCbMakeStatic;
@@ -65,7 +66,7 @@
for (VariableInfo info : variableInfos) {
myVariableToInfoMap.put(info.variable, info);
}
- myVariableData = new ParameterTablePanel.VariableData[variableInfos.length];
+ myVariableData = new VariableData[variableInfos.length];
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(myProject);
for(int idx = 0; idx < variableInfos.length; idx++){
@@ -74,7 +75,7 @@
VariableKind kind = codeStyleManager.getVariableKind(info.variable);
name = codeStyleManager.variableNameToPropertyName(name, kind);
name = codeStyleManager.propertyNameToVariableName(name, VariableKind.PARAMETER);
- ParameterTablePanel.VariableData data = new ParameterTablePanel.VariableData(info.variable);
+ VariableData data = new VariableData(info.variable);
data.name = name;
data.passAsParameter = true;
myVariableData[idx] = data;
@@ -127,7 +128,7 @@
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(myProject);
VariableInfo[] infos = new VariableInfo[myVariableData.length];
for (int idx = 0; idx < myVariableData.length; idx++) {
- ParameterTablePanel.VariableData data = myVariableData[idx];
+ VariableData data = myVariableData[idx];
VariableInfo info = myVariableToInfoMap.get(data.variable);
info.passAsParameter = data.passAsParameter;
diff --git a/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java b/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java
index f8ff36b..f8e27c4 100644
--- a/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java
@@ -15,6 +15,7 @@
*/
package com.intellij.refactoring.changeClassSignature;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -27,7 +28,6 @@
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.ui.*;
import com.intellij.ui.table.JBTable;
-import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.EditableModel;
import org.jetbrains.annotations.NotNull;
@@ -116,7 +116,7 @@
}
protected JComponent createNorthPanel() {
- return new JLabel(RefactoringBundle.message("changeClassSignature.class.label.text", UsageViewUtil.getDescriptiveName(myClass)));
+ return new JLabel(RefactoringBundle.message("changeClassSignature.class.label.text", DescriptiveNameUtil.getDescriptiveName(myClass)));
}
@Override
diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/DetectedJavaChangeInfo.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/DetectedJavaChangeInfo.java
index e1ad62f..250efce 100644
--- a/java/java-impl/src/com/intellij/refactoring/changeSignature/DetectedJavaChangeInfo.java
+++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/DetectedJavaChangeInfo.java
@@ -15,6 +15,7 @@
*/
package com.intellij.refactoring.changeSignature;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Document;
@@ -25,7 +26,6 @@
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.util.CanonicalTypes;
import com.intellij.usageView.UsageInfo;
-import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.VisibilityUtil;
import org.jetbrains.annotations.NotNull;
@@ -288,7 +288,7 @@
temporallyRevertChanges(method, oldText);
doRefactor(processor);
}
- }, RefactoringBundle.message("changing.signature.of.0", UsageViewUtil.getDescriptiveName(currentMethod)), null);
+ }, RefactoringBundle.message("changing.signature.of.0", DescriptiveNameUtil.getDescriptiveName(currentMethod)), null);
}
private void doRefactor(BaseRefactoringProcessor processor) {
diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java
index e480912..cc4d0cd 100644
--- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java
@@ -16,6 +16,7 @@
package com.intellij.refactoring.changeSignature;
import com.intellij.codeInsight.ExceptionUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.lang.StdLanguages;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -245,7 +246,7 @@
if (toCatchExceptions) {
if (!(ref instanceof PsiReferenceExpression &&
- RefactoringUtil.isSuperOrThisCall(PsiTreeUtil.getParentOfType(ref, PsiStatement.class), true, false))) {
+ JavaHighlightUtil.isSuperOrThisCall(PsiTreeUtil.getParentOfType(ref, PsiStatement.class), true, false))) {
if (needToCatchExceptions(changeInfo, caller)) {
PsiClassType[] newExceptions =
callee != null ? getCalleeChangedExceptionInfo(callee) : getPrimaryChangedExceptionInfo(changeInfo);
diff --git a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java
index c3b911b..180e28d 100644
--- a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java
@@ -16,6 +16,7 @@
*/
package com.intellij.refactoring.encapsulateFields;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
@@ -75,7 +76,7 @@
}
protected String getCommandName() {
- return RefactoringBundle.message("encapsulate.fields.command.name", UsageViewUtil.getDescriptiveName(myClass));
+ return RefactoringBundle.message("encapsulate.fields.command.name", DescriptiveNameUtil.getDescriptiveName(myClass));
}
protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
diff --git a/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceHandler.java b/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceHandler.java
index 1e2448e..061d04e 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceHandler.java
@@ -17,6 +17,7 @@
import com.intellij.history.LocalHistory;
import com.intellij.history.LocalHistoryAction;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
@@ -34,7 +35,6 @@
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.refactoring.util.DocCommentPolicy;
import com.intellij.refactoring.util.classMembers.MemberInfo;
-import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.MultiMap;
@@ -150,7 +150,7 @@
}
private String getCommandName() {
- return RefactoringBundle.message("extract.interface.command.name", myInterfaceName, UsageViewUtil.getDescriptiveName(myClass));
+ return RefactoringBundle.message("extract.interface.command.name", myInterfaceName, DescriptiveNameUtil.getDescriptiveName(myClass));
}
public boolean isEnabledOnElements(PsiElement[] elements) {
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractDialog.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractDialog.java
index 2e4531c..7e49181 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractDialog.java
@@ -23,7 +23,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.psi.PsiModifier;
-import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
public abstract class AbstractExtractDialog extends DialogWrapper {
protected AbstractExtractDialog(Project project) {
@@ -33,7 +33,7 @@
public abstract String getChosenMethodName();
- public abstract ParameterTablePanel.VariableData[] getChosenParameters();
+ public abstract VariableData[] getChosenParameters();
@PsiModifier.ModifierConstant
public abstract String getVisibility();
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java
index 5e64113..0f31912 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java
@@ -32,6 +32,7 @@
import com.intellij.refactoring.ui.MethodSignatureComponent;
import com.intellij.refactoring.util.ConflictsUtil;
import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
import com.intellij.ui.EditorTextField;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.NonFocusableCheckBox;
@@ -81,7 +82,7 @@
private final JCheckBox myFoldParameters = new NonFocusableCheckBox(RefactoringBundle.message("declare.folded.parameters"));
public JPanel myCenterPanel;
public JPanel myParamTable;
- private ParameterTablePanel.VariableData[] myInputVariables;
+ private VariableData[] myInputVariables;
public ExtractMethodDialog(Project project,
PsiClass targetClass, final InputVariables inputVariables, PsiType returnType,
@@ -156,7 +157,7 @@
return myNameField.getText();
}
- public ParameterTablePanel.VariableData[] getChosenParameters() {
+ public VariableData[] getChosenParameters() {
return myInputVariables;
}
@@ -182,7 +183,7 @@
}
if (myMakeVarargs != null && myMakeVarargs.isSelected()) {
- final ParameterTablePanel.VariableData data = myInputVariables[myInputVariables.length - 1];
+ final VariableData data = myInputVariables[myInputVariables.length - 1];
if (data.type instanceof PsiArrayType) {
data.type = new PsiEllipsisType(((PsiArrayType)data.type).getComponentType());
}
@@ -243,12 +244,12 @@
myFoldParameters.setSelected(myVariableData.isFoldingSelectedByDefault());
myFoldParameters.setVisible(myVariableData.isFoldable());
myVariableData.setFoldingAvailable(myFoldParameters.isSelected());
- myInputVariables = myVariableData.getInputVariables().toArray(new ParameterTablePanel.VariableData[myVariableData.getInputVariables().size()]);
+ myInputVariables = myVariableData.getInputVariables().toArray(new VariableData[myVariableData.getInputVariables().size()]);
myFoldParameters.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
myVariableData.setFoldingAvailable(myFoldParameters.isSelected());
myInputVariables =
- myVariableData.getInputVariables().toArray(new ParameterTablePanel.VariableData[myVariableData.getInputVariables().size()]);
+ myVariableData.getInputVariables().toArray(new VariableData[myVariableData.getInputVariables().size()]);
updateVarargsEnabled();
createParametersPanel();
updateSignature();
@@ -258,7 +259,7 @@
myFoldParameters.setBorder(emptyBorder);
boolean canBeVarargs = false;
- for (ParameterTablePanel.VariableData data : myInputVariables) {
+ for (VariableData data : myInputVariables) {
canBeVarargs |= data.type instanceof PsiArrayType;
}
if (myVariableData.isFoldable()) {
@@ -453,10 +454,10 @@
final String INDENT = StringUtil.repeatSymbol(' ', buffer.length());
- final ParameterTablePanel.VariableData[] datas = myInputVariables;
+ final VariableData[] datas = myInputVariables;
int count = 0;
for (int i = 0; i < datas.length;i++) {
- ParameterTablePanel.VariableData data = datas[i];
+ VariableData data = datas[i];
if (data.passAsParameter) {
//String typeAndModifiers = PsiFormatUtil.formatVariable(data.variable,
// PsiFormatUtil.SHOW_MODIFIERS | PsiFormatUtil.SHOW_TYPE);
@@ -500,7 +501,7 @@
PsiElementFactory factory = JavaPsiFacade.getInstance(myProject).getElementFactory();
prototype = factory.createMethod(myNameField.getText().trim(), myReturnType);
if (myTypeParameterList != null) prototype.getTypeParameterList().replace(myTypeParameterList);
- for (ParameterTablePanel.VariableData data : myInputVariables) {
+ for (VariableData data : myInputVariables) {
if (data.passAsParameter) {
prototype.getParameterList().add(factory.createParameter(data.name, data.type));
}
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java
index 70d031b..21de8fc 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java
@@ -16,6 +16,7 @@
package com.intellij.refactoring.extractMethod;
import com.intellij.codeInsight.CodeInsightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.codeInsight.highlighting.HighlightManager;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
@@ -80,8 +81,7 @@
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
if (!editor.getSelectionModel().hasSelection()) {
final int offset = editor.getCaretModel().getOffset();
- final PsiElement[] statementsInRange = IntroduceVariableBase.findStatementsAtOffset(editor, file, offset);
- final List<PsiExpression> expressions = IntroduceVariableBase.collectExpressions(file, editor, offset, statementsInRange);
+ final List<PsiExpression> expressions = IntroduceVariableBase.collectExpressions(file, editor, offset, true);
if (expressions.isEmpty()) {
editor.getSelectionModel().selectLineAtCaret();
}
@@ -166,7 +166,7 @@
final Project project,
final PsiFile file,
final Editor editor,
- final boolean showErrorMessages,
+ final boolean showErrorMessages,
final @Nullable Pass<ExtractMethodProcessor> pass) {
if (elements == null || elements.length == 0) {
if (showErrorMessages) {
@@ -178,7 +178,7 @@
}
for (PsiElement element : elements) {
- if (element instanceof PsiStatement && RefactoringUtil.isSuperOrThisCall((PsiStatement)element, true, true)) {
+ if (element instanceof PsiStatement && JavaHighlightUtil.isSuperOrThisCall((PsiStatement)element, true, true)) {
if (showErrorMessages) {
String message = RefactoringBundle
.getCannotRefactorMessage(RefactoringBundle.message("selected.block.contains.invocation.of.another.class.constructor"));
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
index 14535e0..7279f90 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
@@ -18,6 +18,7 @@
import com.intellij.codeInsight.ChangeContextUtil;
import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.codeInsight.NullableNotNullManager;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.codeInsight.highlighting.HighlightManager;
import com.intellij.codeInsight.intention.impl.AddNullableAnnotationFix;
import com.intellij.codeInsight.navigation.NavigationUtil;
@@ -66,10 +67,7 @@
import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
import com.intellij.refactoring.util.*;
import com.intellij.refactoring.util.classMembers.ElementNeedsThis;
-import com.intellij.refactoring.util.duplicates.DuplicatesFinder;
-import com.intellij.refactoring.util.duplicates.Match;
-import com.intellij.refactoring.util.duplicates.MatchProvider;
-import com.intellij.refactoring.util.duplicates.VariableReturnValue;
+import com.intellij.refactoring.util.duplicates.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Processor;
@@ -104,7 +102,7 @@
protected String myMethodName; // name for extracted method
protected PsiType myReturnType; // return type for extracted method
protected PsiTypeParameterList myTypeParameterList; //type parameter list of extracted method
- private ParameterTablePanel.VariableData[] myVariableDatum; // parameter data for extracted method
+ private VariableData[] myVariableDatum; // parameter data for extracted method
protected PsiClassType[] myThrownExceptions; // exception to declare as thrown by extracted method
protected boolean myStatic; // whether to declare extracted method static
@@ -446,7 +444,7 @@
private boolean shouldBeStatic() {
for(PsiElement element: myElements) {
final PsiExpressionStatement statement = PsiTreeUtil.getParentOfType(element, PsiExpressionStatement.class);
- if (statement != null && RefactoringUtil.isSuperOrThisCall(statement, true, true)) {
+ if (statement != null && JavaHighlightUtil.isSuperOrThisCall(statement, true, true)) {
return true;
}
}
@@ -546,7 +544,7 @@
public void testPrepare() {
myInputVariables.setFoldingAvailable(myInputVariables.isFoldingSelectedByDefault());
myMethodName = myInitialMethodName;
- myVariableDatum = new ParameterTablePanel.VariableData[myInputVariables.getInputVariables().size()];
+ myVariableDatum = new VariableData[myInputVariables.getInputVariables().size()];
for (int i = 0; i < myInputVariables.getInputVariables().size(); i++) {
myVariableDatum[i] = myInputVariables.getInputVariables().get(i);
}
@@ -805,7 +803,7 @@
adjustFinalParameters(newMethod);
int i = 0;
- for (ParameterTablePanel.VariableData data : myVariableDatum) {
+ for (VariableData data : myVariableDatum) {
if (!data.passAsParameter) continue;
final PsiVariable variable = data.variable;
final PsiParameter psiParameter = newMethod.getParameterList().getParameters()[i++];
@@ -926,20 +924,20 @@
}
public PsiElement processMatch(Match match) throws IncorrectOperationException {
- match.changeSignature(myExtractedMethod);
+ MatchUtil.changeSignature(match, myExtractedMethod);
if (RefactoringUtil.isInStaticContext(match.getMatchStart(), myExtractedMethod.getContainingClass())) {
PsiUtil.setModifierProperty(myExtractedMethod, PsiModifier.STATIC, true);
}
final PsiMethodCallExpression methodCallExpression = generateMethodCall(match.getInstanceExpression(), false);
- ArrayList<ParameterTablePanel.VariableData> datas = new ArrayList<ParameterTablePanel.VariableData>();
- for (final ParameterTablePanel.VariableData variableData : myVariableDatum) {
+ ArrayList<VariableData> datas = new ArrayList<VariableData>();
+ for (final VariableData variableData : myVariableDatum) {
if (variableData.passAsParameter) {
datas.add(variableData);
}
}
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
- for (ParameterTablePanel.VariableData data : datas) {
+ for (VariableData data : datas) {
final List<PsiElement> parameterValue = match.getParameterValues(data.variable);
if (parameterValue != null) {
for (PsiElement val : parameterValue) {
@@ -983,7 +981,7 @@
}
private void renameInputVariables() throws IncorrectOperationException {
- for (ParameterTablePanel.VariableData data : myVariableDatum) {
+ for (VariableData data : myVariableDatum) {
PsiVariable variable = data.variable;
if (!data.name.equals(variable.getName())) {
for (PsiElement element : myElements) {
@@ -1015,7 +1013,7 @@
boolean isFinal = CodeStyleSettingsManager.getSettings(myProject).GENERATE_FINAL_PARAMETERS;
PsiParameterList list = newMethod.getParameterList();
- for (ParameterTablePanel.VariableData data : myVariableDatum) {
+ for (VariableData data : myVariableDatum) {
if (data.passAsParameter) {
PsiParameter parm = myElementFactory.createParameter(data.name, data.type);
if (isFinal) {
@@ -1053,7 +1051,7 @@
final PsiClass nullableAnnotationClass =
JavaPsiFacade.getInstance(myProject).findClass(manager.getDefaultNullable(), GlobalSearchScope.allScope(myProject));
if (nullableAnnotationClass != null) {
- new AddNullableAnnotationFix(newMethod).invoke(myProject, myEditor, myTargetClass.getContainingFile());
+ new AddNullableAnnotationFix(newMethod).invoke(myProject, myTargetClass.getContainingFile(), newMethod, newMethod);
}
}
}
@@ -1104,7 +1102,7 @@
buffer.append("(");
if (generateArgs) {
int count = 0;
- for (ParameterTablePanel.VariableData data : myVariableDatum) {
+ for (VariableData data : myVariableDatum) {
if (data.passAsParameter) {
if (count > 0) {
buffer.append(",");
@@ -1252,7 +1250,7 @@
}
private String getNewVariableName(PsiVariable variable) {
- for (ParameterTablePanel.VariableData data : myVariableDatum) {
+ for (VariableData data : myVariableDatum) {
if (data.variable.equals(variable)) {
return data.name;
}
@@ -1373,7 +1371,8 @@
@Nullable
public String getConfirmDuplicatePrompt(Match match) {
final boolean needToBeStatic = RefactoringUtil.isInStaticContext(match.getMatchStart(), myExtractedMethod.getContainingClass());
- final String changedSignature = match.getChangedSignature(myExtractedMethod, needToBeStatic, VisibilityUtil.getVisibilityStringToDisplay(myExtractedMethod));
+ final String changedSignature = MatchUtil
+ .getChangedSignature(match, myExtractedMethod, needToBeStatic, VisibilityUtil.getVisibilityStringToDisplay(myExtractedMethod));
if (changedSignature != null) {
return RefactoringBundle.message("replace.this.code.fragment.and.change.signature", changedSignature);
}
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java
index b5a9099..2a41db9 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java
@@ -27,6 +27,7 @@
import com.intellij.refactoring.extractMethod.InputVariables;
import com.intellij.refactoring.ui.ConflictsDialog;
import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
import com.intellij.ui.EditorTextField;
import com.intellij.util.Function;
import com.intellij.util.VisibilityUtil;
@@ -78,7 +79,7 @@
private JPanel myAnonymousClassPanel;
private JCheckBox myFoldCb;
private ButtonGroup myVisibilityGroup;
- private ParameterTablePanel.VariableData[] myInputVariables;
+ private VariableData[] myInputVariables;
public ExtractMethodObjectDialog(Project project, PsiClass targetClass, final InputVariables inputVariables, PsiType returnType,
@@ -96,7 +97,7 @@
myMultipleExitPoints = multipleExitPoints;
boolean canBeVarargs = false;
- for (ParameterTablePanel.VariableData data : inputVariables.getInputVariables()) {
+ for (VariableData data : inputVariables.getInputVariables()) {
canBeVarargs |= data.type instanceof PsiArrayType;
}
canBeVarargs |= inputVariables.isFoldable() && inputVariables.isFoldingSelectedByDefault();
@@ -136,7 +137,7 @@
return myCreateInnerClassRb.isSelected() ? myInnerClassName.getText() : myMethodName.getText();
}
- public ParameterTablePanel.VariableData[] getChosenParameters() {
+ public VariableData[] getChosenParameters() {
return myInputVariables;
}
@@ -167,7 +168,7 @@
final JCheckBox makeVarargsCb = myCreateInnerClassRb.isSelected() ? myCbMakeVarargs : myCbMakeVarargsAnonymous;
if (makeVarargsCb != null && makeVarargsCb.isSelected()) {
- final ParameterTablePanel.VariableData data = myInputVariables[myInputVariables.length - 1];
+ final VariableData data = myInputVariables[myInputVariables.length - 1];
if (data.type instanceof PsiArrayType) {
data.type = new PsiEllipsisType(((PsiArrayType)data.type).getComponentType());
}
@@ -212,7 +213,7 @@
protected JComponent createCenterPanel() {
mySignatureArea.setEditable(false);
myCreateInnerClassRb.setSelected(true);
-
+
final ActionListener enableDisableListener = new ActionListener() {
public void actionPerformed(final ActionEvent e) {
enable(myCreateInnerClassRb.isSelected());
@@ -225,11 +226,11 @@
myFoldCb.setSelected(myVariableData.isFoldingSelectedByDefault());
myFoldCb.setVisible(myVariableData.isFoldable());
myVariableData.setFoldingAvailable(myFoldCb.isSelected());
- myInputVariables = myVariableData.getInputVariables().toArray(new ParameterTablePanel.VariableData[myVariableData.getInputVariables().size()]);
+ myInputVariables = myVariableData.getInputVariables().toArray(new VariableData[myVariableData.getInputVariables().size()]);
myFoldCb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
myVariableData.setFoldingAvailable(myFoldCb.isSelected());
- myInputVariables = myVariableData.getInputVariables().toArray(new ParameterTablePanel.VariableData[myVariableData.getInputVariables().size()]);
+ myInputVariables = myVariableData.getInputVariables().toArray(new VariableData[myVariableData.getInputVariables().size()]);
myParametersTableContainer.removeAll();
myParametersTableContainer.add(createParametersPanel(), BorderLayout.CENTER);
updateSignature();
@@ -359,8 +360,8 @@
buffer.append("\n}.");
buffer.append(myMethodName.getText());
buffer.append("(");
- buffer.append(StringUtil.join(myInputVariables, new Function<ParameterTablePanel.VariableData, String>() {
- public String fun(final ParameterTablePanel.VariableData variableData) {
+ buffer.append(StringUtil.join(myInputVariables, new Function<VariableData, String>() {
+ public String fun(final VariableData variableData) {
return variableData.name;
}
}, ", "));
@@ -375,7 +376,7 @@
int count = 0;
final String indent = " ";
for (int i = 0; i < myInputVariables.length; i++) {
- ParameterTablePanel.VariableData data = myInputVariables[i];
+ VariableData data = myInputVariables[i];
if (data.passAsParameter) {
//String typeAndModifiers = PsiFormatUtil.formatVariable(data.variable,
// PsiFormatUtil.SHOW_MODIFIERS | PsiFormatUtil.SHOW_TYPE);
diff --git a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperClassUtil.java b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperClassUtil.java
index b2509d9..96019d4 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperClassUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperClassUtil.java
@@ -27,10 +27,7 @@
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.util.MethodSignature;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilBase;
-import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.psi.util.*;
import com.intellij.refactoring.memberPullUp.PullUpHelper;
import com.intellij.refactoring.ui.ConflictsDialog;
import com.intellij.refactoring.util.DocCommentPolicy;
@@ -76,7 +73,7 @@
clearPsiReferenceList(subclass.getExtendsList());
// make original class extend extracted superclass
- PsiJavaCodeReferenceElement ref = createExtendingReference(superclass, subclass, selectedMemberInfos);
+ PsiJavaCodeReferenceElement ref = createExtendingReference(superclass, subclass, selectedMemberInfos);
subclass.getExtendsList().add(ref);
PullUpHelper pullUpHelper = new PullUpHelper(subclass, superclass, selectedMemberInfos,
@@ -185,7 +182,7 @@
.getName()) !=
null;
}
- }, PsiUtilBase
+ }, PsiUtilCore
.toPsiElementArray(movedElements));
final PsiTypeParameterList originalTypeParameterList = superClass.getTypeParameterList();
assert originalTypeParameterList != null;
diff --git a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperclassHandler.java b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperclassHandler.java
index 4352e96..4a4e8d8 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperclassHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperclassHandler.java
@@ -22,6 +22,7 @@
import com.intellij.history.LocalHistory;
import com.intellij.history.LocalHistoryAction;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
@@ -41,7 +42,6 @@
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.refactoring.util.DocCommentPolicy;
import com.intellij.refactoring.util.classMembers.MemberInfo;
-import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.MultiMap;
@@ -182,7 +182,7 @@
}
private String getCommandName(final PsiClass subclass, String newName) {
- return RefactoringBundle.message("extract.superclass.command.name", newName, UsageViewUtil.getDescriptiveName(subclass));
+ return RefactoringBundle.message("extract.superclass.command.name", newName, DescriptiveNameUtil.getDescriptiveName(subclass));
}
public boolean isEnabledOnElements(PsiElement[] elements) {
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 8aaf941..d096db5 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java
@@ -53,6 +53,7 @@
import com.intellij.refactoring.util.classMembers.MemberInfo;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
+import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.VisibilityUtil;
import com.intellij.util.containers.ContainerUtil;
@@ -320,7 +321,7 @@
super.performRefactoring(usageInfos);
if (myNewVisibility == null) return;
for (PsiMember member : members) {
- VisibilityUtil.fixVisibility(usageInfos, member, myNewVisibility);
+ VisibilityUtil.fixVisibility(UsageViewUtil.toElements(usageInfos), member, myNewVisibility);
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationProcessor.java b/java/java-impl/src/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationProcessor.java
index 6d9cc0a..28650c7 100644
--- a/java/java-impl/src/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationProcessor.java
@@ -16,9 +16,11 @@
package com.intellij.refactoring.inheritanceToDelegation;
import com.intellij.codeInsight.NullableNotNullManager;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.codeInsight.generation.GenerateMembersUtil;
import com.intellij.codeInsight.generation.OverrideImplementUtil;
import com.intellij.find.findUsages.PsiElement2UsageTargetAdapter;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
@@ -37,14 +39,12 @@
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.refactoring.util.ConflictsUtil;
import com.intellij.refactoring.util.RefactoringUIUtil;
-import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.refactoring.util.classMembers.ClassMemberReferencesVisitor;
import com.intellij.refactoring.util.classRefs.ClassInstanceScanner;
import com.intellij.refactoring.util.classRefs.ClassReferenceScanner;
import com.intellij.refactoring.util.classRefs.ClassReferenceSearchingScanner;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
-import com.intellij.usageView.UsageViewUtil;
import com.intellij.usages.UsageInfoToUsageConverter;
import com.intellij.usages.UsageTarget;
import com.intellij.usages.UsageViewManager;
@@ -682,7 +682,7 @@
}
}
final @NonNls String assignmentText = fieldQualifier + myFieldName + "= new " + defaultClassFieldType() + "()";
- if (statements.length < 1 || !RefactoringUtil.isSuperOrThisCall(statements[0], true, true) || myBaseClass.isInterface()) {
+ if (statements.length < 1 || !JavaHighlightUtil.isSuperOrThisCall(statements[0], true, true) || myBaseClass.isInterface()) {
PsiExpressionStatement assignmentStatement =
(PsiExpressionStatement)myFactory.createStatementFromText(
assignmentText, body
@@ -698,7 +698,7 @@
assignmentStatement = (PsiExpressionStatement)CodeStyleManager.getInstance(myProject).reformat(assignmentStatement);
if (statements.length > 0) {
- if (!RefactoringUtil.isSuperOrThisCall(statements[0], true, false)) {
+ if (!JavaHighlightUtil.isSuperOrThisCall(statements[0], true, false)) {
body.addBefore(assignmentStatement, statements[0]);
}
else {
@@ -711,7 +711,7 @@
}
else {
final PsiExpressionStatement callStatement = ((PsiExpressionStatement)statements[0]);
- if (!RefactoringUtil.isSuperOrThisCall(callStatement, false, true)) {
+ if (!JavaHighlightUtil.isSuperOrThisCall(callStatement, false, true)) {
final PsiMethodCallExpression superConstructorCall =
(PsiMethodCallExpression)callStatement.getExpression();
PsiAssignmentExpression assignmentExpression =
@@ -736,7 +736,7 @@
PsiMethod[] constructors = myClass.getConstructors();
for (PsiMethod constructor : constructors) {
final PsiStatement[] statements = constructor.getBody().getStatements();
- if (statements.length > 0 && RefactoringUtil.isSuperOrThisCall(statements[0], true, false)) return false;
+ if (statements.length > 0 && JavaHighlightUtil.isSuperOrThisCall(statements[0], true, false)) return false;
}
return true;
}
@@ -749,7 +749,7 @@
PsiMethod[] constructors = myClass.getConstructors();
for (PsiMethod constructor : constructors) {
final PsiStatement[] statements = constructor.getBody().getStatements();
- if (statements.length > 0 && RefactoringUtil.isSuperOrThisCall(statements[0], true, false)) {
+ if (statements.length > 0 && JavaHighlightUtil.isSuperOrThisCall(statements[0], true, false)) {
final PsiMethodCallExpression superConstructorCall =
(PsiMethodCallExpression)((PsiExpressionStatement)statements[0]).getExpression();
PsiElement superConstructor = superConstructorCall.getMethodExpression().resolve();
@@ -906,7 +906,7 @@
protected String getCommandName() {
- return RefactoringBundle.message("replace.inheritance.with.delegation.command", UsageViewUtil.getDescriptiveName(myClass));
+ return RefactoringBundle.message("replace.inheritance.with.delegation.command", DescriptiveNameUtil.getDescriptiveName(myClass));
}
private Set<PsiMember> getAllBaseClassMembers() {
diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java
index bcf0b35..edb86b4 100644
--- a/java/java-impl/src/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java
@@ -15,6 +15,7 @@
*/
package com.intellij.refactoring.inline;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
@@ -30,7 +31,6 @@
import com.intellij.refactoring.util.*;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
-import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
@@ -179,8 +179,8 @@
} else if (initializer1 instanceof PsiMethodCallExpression) {
referenceExpression = ((PsiMethodCallExpression)initializer1).getMethodExpression();
}
- if (referenceExpression != null &&
- referenceExpression.getQualifierExpression() == null &&
+ if (referenceExpression != null &&
+ referenceExpression.getQualifierExpression() == null &&
!(referenceExpression.advancedResolve(false).getCurrentFileResolveScope() instanceof PsiImportStaticStatement)) {
referenceExpression.setQualifierExpression(qExpression);
}
@@ -212,7 +212,7 @@
}
protected String getCommandName() {
- return RefactoringBundle.message("inline.field.command", UsageViewUtil.getDescriptiveName(myField));
+ return RefactoringBundle.message("inline.field.command", DescriptiveNameUtil.getDescriptiveName(myField));
}
protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java
index 344a5f0..3171175 100644
--- a/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java
@@ -36,7 +36,7 @@
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.util.CommonRefactoringUtil;
@@ -104,7 +104,7 @@
}
innerClass = parentPsiClass;
continue;
- }
+ }
innerClassesWithUsages.add(innerClass);
innerClassUsages.add(element);
}
@@ -143,7 +143,7 @@
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.INLINE_VARIABLE);
return;
}
- final PsiElement[] refsToInline = PsiUtilBase.toPsiElementArray(refsToInlineList);
+ final PsiElement[] refsToInline = PsiUtilCore.toPsiElementArray(refsToInlineList);
EditorColorsManager manager = EditorColorsManager.getInstance();
final TextAttributes attributes = manager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java
index 7c55aae..1659cac 100644
--- a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java
@@ -19,6 +19,7 @@
import com.intellij.history.LocalHistory;
import com.intellij.history.LocalHistoryAction;
import com.intellij.lang.Language;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.lang.refactoring.InlineHandler;
import com.intellij.openapi.diagnostic.Logger;
@@ -51,7 +52,6 @@
import com.intellij.refactoring.util.*;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
-import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashMap;
@@ -110,7 +110,7 @@
myFactory = JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory();
myCodeStyleManager = CodeStyleManager.getInstance(myProject);
myJavaCodeStyle = JavaCodeStyleManager.getInstance(myProject);
- myDescriptiveName = UsageViewUtil.getDescriptiveName(myMethod);
+ myDescriptiveName = DescriptiveNameUtil.getDescriptiveName(myMethod);
}
protected String getCommandName() {
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java
index 0d1aacf..d186ef9 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java
@@ -54,7 +54,7 @@
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.refactoring.IntroduceHandlerBase;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.introduce.inplace.AbstractInplaceIntroducer;
@@ -819,7 +819,7 @@
if (myEditor != null) {
if (!ApplicationManager.getApplication().isUnitTestMode()) {
- PsiElement[] exprsToHighlight = PsiUtilBase.toPsiElementArray(array);
+ PsiElement[] exprsToHighlight = PsiUtilCore.toPsiElementArray(array);
HighlightManager highlightManager = HighlightManager.getInstance(myProject);
highlightManager.addOccurrenceHighlights(myEditor, exprsToHighlight, highlightAttributes(), true, null);
WindowManager
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/ElementToWorkOn.java b/java/java-impl/src/com/intellij/refactoring/introduceField/ElementToWorkOn.java
index 93e19e3..9e4f79c 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceField/ElementToWorkOn.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceField/ElementToWorkOn.java
@@ -99,7 +99,7 @@
}
if (!editor.getSelectionModel().hasSelection()){
- final List<PsiExpression> expressions = IntroduceVariableBase.collectExpressions(file, editor, offset, statementsInRange);
+ final List<PsiExpression> expressions = IntroduceVariableBase.collectExpressions(file, editor, offset);
for (Iterator<PsiExpression> iterator = expressions.iterator(); iterator.hasNext(); ) {
PsiExpression expression = iterator.next();
if (!processor.accept(new ElementToWorkOn(null, expression))) {
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java
index 189fe82..8f0f5fb 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java
@@ -25,6 +25,7 @@
package com.intellij.refactoring.introduceParameter;
import com.intellij.codeInsight.ChangeContextUtil;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
@@ -535,7 +536,7 @@
}
protected String getCommandName() {
- return RefactoringBundle.message("introduce.parameter.command", UsageViewUtil.getDescriptiveName(myMethodToReplaceIn));
+ return RefactoringBundle.message("introduce.parameter.command", DescriptiveNameUtil.getDescriptiveName(myMethodToReplaceIn));
}
@Nullable
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java
index 3e18ae1..740c2cc 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java
@@ -125,7 +125,7 @@
}
if (!selectionModel.hasSelection()) {
- final List<PsiExpression> expressions = collectExpressions(file, editor, offset, statementsInRange);
+ final List<PsiExpression> expressions = collectExpressions(file, editor, offset);
if (expressions.isEmpty()) {
selectionModel.selectLineAtCaret();
} else if (expressions.size() == 1) {
@@ -162,7 +162,16 @@
return Boolean.valueOf(PropertiesComponent.getInstance().getOrInit(PREFER_STATEMENTS_OPTION, "false")).booleanValue() || Registry.is(PREFER_STATEMENTS_OPTION, false);
}
- public static List<PsiExpression> collectExpressions(final PsiFile file, final Editor editor, final int offset, final PsiElement... statementsInRange) {
+ public static List<PsiExpression> collectExpressions(final PsiFile file,
+ final Editor editor,
+ final int offset) {
+ return collectExpressions(file, editor, offset, false);
+ }
+
+ public static List<PsiExpression> collectExpressions(final PsiFile file,
+ final Editor editor,
+ final int offset,
+ boolean acceptVoid) {
Document document = editor.getDocument();
CharSequence text = document.getCharsSequence();
int correctedOffset = offset;
@@ -196,7 +205,8 @@
}*/
PsiExpression expression = PsiTreeUtil.getParentOfType(elementAtCaret, PsiExpression.class);
while (expression != null) {
- if (!expressions.contains(expression) && !(expression instanceof PsiParenthesizedExpression) && !(expression instanceof PsiSuperExpression) && expression.getType() != PsiType.VOID) {
+ if (!expressions.contains(expression) && !(expression instanceof PsiParenthesizedExpression) && !(expression instanceof PsiSuperExpression) &&
+ (acceptVoid || expression.getType() != PsiType.VOID)) {
if (expression instanceof PsiMethodReferenceExpression) {
expressions.add(expression);
}
@@ -592,14 +602,14 @@
final boolean allOccurences = choice != OccurrencesChooser.ReplaceChoice.NO;
final PsiElement chosenAnchor = allOccurences ? anchorStatementIfAll : anchorStatement;
final Ref<SmartPsiElementPointer<PsiVariable>> variable = new Ref<SmartPsiElementPointer<PsiVariable>>();
-
+
final Editor topLevelEditor;
if (!InjectedLanguageManager.getInstance(project).isInjectedFragment(anchorStatement.getContainingFile())) {
topLevelEditor = InjectedLanguageUtil.getTopLevelEditor(editor);
} else {
topLevelEditor = editor;
}
-
+
final IntroduceVariableSettings settings =
getSettings(project, topLevelEditor, expr, occurrences, typeSelectorManager, inFinalContext, hasWriteAccess, validator, chosenAnchor, choice);
if (!settings.isOK()) {
@@ -840,9 +850,9 @@
if (!deleteSelf && replaceSelf && expr1 instanceof PsiPolyadicExpression && expr1.isValid() && !expr1.isPhysical() ) {
array.add(replace(expr1, ref, project));
}
-
+
if (editor != null) {
- final PsiElement[] replacedOccurences = PsiUtilBase.toPsiElementArray(array);
+ final PsiElement[] replacedOccurences = PsiUtilCore.toPsiElementArray(array);
highlightReplacedOccurences(project, editor, replacedOccurences);
}
} else {
@@ -900,7 +910,7 @@
}
return false;
}
-
+
public static PsiExpression replaceExplicitWithDiamondWhenApplicable(final PsiExpression initializer,
final PsiType expectedType) {
if (initializer instanceof PsiNewExpression) {
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java
index 4260c05..7ca675c 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java
@@ -32,6 +32,7 @@
import com.intellij.refactoring.ui.PackageNameReferenceEditorCombo;
import com.intellij.refactoring.ui.RefactoringDialog;
import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
import com.intellij.ui.ComboboxWithBrowseButton;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.RecentsManager;
@@ -53,7 +54,7 @@
public class IntroduceParameterObjectDialog extends RefactoringDialog {
private final PsiMethod sourceMethod;
- private final ParameterTablePanel.VariableData[] parameterInfo;
+ private final VariableData[] parameterInfo;
private JTextField sourceMethodTextField;
private JRadioButton useExistingClassButton;
@@ -94,9 +95,9 @@
myInnerClassNameTextField.getDocument().addDocumentListener(docListener);
final PsiParameterList parameterList = sourceMethod.getParameterList();
final PsiParameter[] parameters = parameterList.getParameters();
- parameterInfo = new ParameterTablePanel.VariableData[parameters.length];
+ parameterInfo = new VariableData[parameters.length];
for (int i = 0; i < parameterInfo.length; i++) {
- parameterInfo[i] = new ParameterTablePanel.VariableData(parameters[i]);
+ parameterInfo[i] = new VariableData(parameters[i]);
parameterInfo[i].name = parameters[i].getName();
parameterInfo[i].passAsParameter = true;
}
@@ -164,8 +165,8 @@
packageName = getPackageName();
className = getClassName();
}
- List<ParameterTablePanel.VariableData> parameters = new ArrayList<ParameterTablePanel.VariableData>();
- for (ParameterTablePanel.VariableData data : parameterInfo) {
+ List<VariableData> parameters = new ArrayList<VariableData>();
+ for (VariableData data : parameterInfo) {
if (data.passAsParameter) {
parameters.add(data);
}
@@ -175,7 +176,7 @@
final MoveDestination moveDestination = ((DestinationFolderComboBox)myDestinationCb)
.selectDirectory(new PackageWrapper(PsiManager.getInstance(myProject), packageName), false);
invokeRefactoring(new IntroduceParameterObjectProcessor(className, packageName, moveDestination, sourceMethod,
- parameters.toArray(new ParameterTablePanel.VariableData[parameters.size()]),
+ parameters.toArray(new VariableData[parameters.size()]),
keepMethod, useExistingClass,
createInnerClass, newVisibility, myGenerateAccessorsCheckBox.isSelected()));
}
@@ -238,7 +239,7 @@
@NotNull
public List<PsiParameter> getParametersToExtract() {
final List<PsiParameter> out = new ArrayList<PsiParameter>();
- for (ParameterTablePanel.VariableData info : parameterInfo) {
+ for (VariableData info : parameterInfo) {
if (info.passAsParameter) {
out.add((PsiParameter)info.variable);
}
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java
index bcd84bd..5fdf3f7 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java
@@ -26,6 +26,7 @@
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
+import com.intellij.psi.impl.source.javadoc.PsiDocParamRef;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.search.GlobalSearchScope;
@@ -37,13 +38,10 @@
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.RefactorJBundle;
import com.intellij.refactoring.introduceparameterobject.usageInfo.*;
-import com.intellij.refactoring.psi.PropertyUtils;
-import com.intellij.refactoring.util.FixableUsageInfo;
-import com.intellij.refactoring.util.FixableUsagesRefactoringProcessor;
-import com.intellij.refactoring.util.ParameterTablePanel;
-import com.intellij.refactoring.util.RefactoringUtil;
+import com.intellij.refactoring.util.*;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
+import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.VisibilityUtil;
import com.intellij.util.containers.MultiMap;
@@ -77,7 +75,7 @@
String packageName,
MoveDestination moveDestination,
PsiMethod method,
- ParameterTablePanel.VariableData[] parameters, boolean keepMethodAsDelegate, final boolean useExistingClass,
+ VariableData[] parameters, boolean keepMethodAsDelegate, final boolean useExistingClass,
final boolean createInnerClass,
String newVisibility,
boolean generateAccessors) {
@@ -92,14 +90,14 @@
myNewVisibility = newVisibility;
myGenerateAccessors = generateAccessors;
this.parameters = new ArrayList<ParameterChunk>();
- for (ParameterTablePanel.VariableData parameter : parameters) {
+ for (VariableData parameter : parameters) {
this.parameters.add(new ParameterChunk(parameter));
}
final PsiParameterList parameterList = method.getParameterList();
final PsiParameter[] methodParams = parameterList.getParameters();
paramsToMerge = new int[parameters.length];
for (int p = 0; p < parameters.length; p++) {
- ParameterTablePanel.VariableData parameter = parameters[p];
+ VariableData parameter = parameters[p];
for (int i = 0; i < methodParams.length; i++) {
final PsiParameter methodParam = methodParams[i];
if (parameter.variable.equals(methodParam)) {
@@ -119,7 +117,7 @@
return super.visitClassType(classType);
}
};
- for (ParameterTablePanel.VariableData parameter : parameters) {
+ for (VariableData parameter : parameters) {
parameter.type.accept(typeParametersVisitor);
}
typeParams = new ArrayList<PsiTypeParameter>(typeParamSet);
@@ -266,7 +264,7 @@
beanClassBuilder.setClassName(className);
beanClassBuilder.setPackageName(packageName);
for (ParameterChunk parameterChunk : parameters) {
- final ParameterTablePanel.VariableData parameter = parameterChunk.parameter;
+ final VariableData parameter = parameterChunk.parameter;
final boolean setterRequired = paramsNeedingSetters.contains(parameter.variable);
beanClassBuilder.addField((PsiParameter)parameter.variable, parameter.name, parameter.type, setterRequired);
}
@@ -316,6 +314,16 @@
for (PsiDocTag paramTag : paramTags) {
final PsiElement[] dataElements = paramTag.getDataElements();
if (dataElements.length > 0) {
+ if (dataElements[0] instanceof PsiDocParamRef) {
+ final PsiReference reference = dataElements[0].getReference();
+ if (reference != null) {
+ final PsiElement resolve = reference.resolve();
+ if (resolve instanceof PsiParameter) {
+ final int parameterIndex = method.getParameterList().getParameterIndex((PsiParameter)resolve);
+ if (ArrayUtil.find(paramsToMerge, parameterIndex) < 0) continue;
+ }
+ }
+ }
mergedTags.add((PsiDocTag)paramTag.copy());
}
}
@@ -411,12 +419,12 @@
parameterChunk.setField(field);
- final PsiMethod getterForField = PropertyUtils.findGetterForField(field);
+ final PsiMethod getterForField = PropertyUtil.findGetterForField(field);
if (getterForField != null) {
parameterChunk.setGetter(getterForField.getName());
}
- final PsiMethod setterForField = PropertyUtils.findSetterForField(field);
+ final PsiMethod setterForField = PropertyUtil.findSetterForField(field);
if (setterForField != null) {
parameterChunk.setSetter(setterForField.getName());
}
@@ -439,12 +447,12 @@
}
public static class ParameterChunk {
- private final ParameterTablePanel.VariableData parameter;
+ private final VariableData parameter;
private PsiField field;
private String getter;
private String setter;
- public ParameterChunk(ParameterTablePanel.VariableData parameter) {
+ public ParameterChunk(VariableData parameter) {
this.parameter = parameter;
}
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/usageInfo/BeanClassVisibilityUsageInfo.java b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/usageInfo/BeanClassVisibilityUsageInfo.java
index 3161380..fab0644 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/usageInfo/BeanClassVisibilityUsageInfo.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/usageInfo/BeanClassVisibilityUsageInfo.java
@@ -24,6 +24,7 @@
import com.intellij.psi.PsiMethod;
import com.intellij.refactoring.util.FixableUsageInfo;
import com.intellij.usageView.UsageInfo;
+import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.VisibilityUtil;
@@ -46,9 +47,9 @@
@Override
public void fixUsage() throws IncorrectOperationException {
- VisibilityUtil.fixVisibility(usages, existingClass, myNewVisibility);
+ VisibilityUtil.fixVisibility(UsageViewUtil.toElements(usages), existingClass, myNewVisibility);
if (myExistingClassCompatibleConstructor != null) {
- VisibilityUtil.fixVisibility(usages, myExistingClassCompatibleConstructor, myNewVisibility);
+ VisibilityUtil.fixVisibility(UsageViewUtil.toElements(usages), myExistingClassCompatibleConstructor, myNewVisibility);
}
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanDialog.java b/java/java-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanDialog.java
index c230a87..4870241 100644
--- a/java/java-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanDialog.java
@@ -15,6 +15,7 @@
*/
package com.intellij.refactoring.invertBoolean;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.help.HelpManager;
import com.intellij.psi.PsiNamedElement;
@@ -47,7 +48,7 @@
myLabel.setText(RefactoringBundle.message("invert.boolean.name.of.inverted.element", typeString));
myCaptionLabel.setText(RefactoringBundle.message("invert.0.1",
typeString,
- UsageViewUtil.getDescriptiveName(myElement)));
+ DescriptiveNameUtil.getDescriptiveName(myElement)));
setTitle(InvertBooleanHandler.REFACTORING_NAME);
init();
diff --git a/java/java-impl/src/com/intellij/refactoring/makeStatic/AbstractMakeStaticDialog.java b/java/java-impl/src/com/intellij/refactoring/makeStatic/AbstractMakeStaticDialog.java
index e76ad57..a990681 100644
--- a/java/java-impl/src/com/intellij/refactoring/makeStatic/AbstractMakeStaticDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/makeStatic/AbstractMakeStaticDialog.java
@@ -19,7 +19,7 @@
* User: dsl
* Date: 04.07.2002
* Time: 13:14:49
- * To change template for new class use
+ * To change template for new class use
* Code Style | Class Templates options (Tools | IDE Options).
*/
package com.intellij.refactoring.makeStatic;
@@ -30,7 +30,7 @@
import com.intellij.psi.PsiTypeParameterListOwner;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.ui.RefactoringDialog;
-import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
import com.intellij.usageView.UsageViewUtil;
import javax.swing.*;
@@ -68,7 +68,7 @@
public abstract String getClassParameterName();
- public abstract ParameterTablePanel.VariableData[] getVariableData();
+ public abstract VariableData[] getVariableData();
public abstract boolean isReplaceUsages();
diff --git a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeMethodOrClassStaticProcessor.java b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeMethodOrClassStaticProcessor.java
index ac618d8..2e6467b 100644
--- a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeMethodOrClassStaticProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeMethodOrClassStaticProcessor.java
@@ -24,6 +24,7 @@
*/
package com.intellij.refactoring.makeStatic;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
@@ -274,7 +275,7 @@
}
protected String getCommandName() {
- return RefactoringBundle.message("make.static.command", UsageViewUtil.getDescriptiveName(myMember));
+ return RefactoringBundle.message("make.static.command", DescriptiveNameUtil.getDescriptiveName(myMember));
}
public T getMember() {
diff --git a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeParameterizedStaticDialog.java b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeParameterizedStaticDialog.java
index c737e10..40e1d5e 100644
--- a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeParameterizedStaticDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeParameterizedStaticDialog.java
@@ -24,6 +24,7 @@
*/
package com.intellij.refactoring.makeStatic;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
@@ -33,8 +34,8 @@
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
import com.intellij.ui.DocumentAdapter;
-import com.intellij.ui.IdeBorderFactory;
import com.intellij.usageView.UsageViewUtil;
import javax.swing.*;
@@ -52,7 +53,7 @@
private final JCheckBox myMakeFieldParameters = new JCheckBox();
private ParameterTablePanel myParameterPanel;
- private ParameterTablePanel.VariableData[] myVariableData;
+ private VariableData[] myVariableData;
private final boolean myAnyNonFieldMembersUsed;
@@ -71,10 +72,10 @@
}
private boolean buildVariableData(InternalUsageInfo[] internalUsages) {
- ArrayList<ParameterTablePanel.VariableData> variableDatum = new ArrayList<ParameterTablePanel.VariableData>();
+ ArrayList<VariableData> variableDatum = new ArrayList<VariableData>();
boolean nonFieldUsages = MakeStaticUtil.collectVariableData(myMember, internalUsages, variableDatum);
- myVariableData = variableDatum.toArray(new ParameterTablePanel.VariableData[0]);
+ myVariableData = variableDatum.toArray(new VariableData[0]);
return nonFieldUsages;
}
@@ -109,7 +110,7 @@
*
* @return null if field parameters are not selected
*/
- public ParameterTablePanel.VariableData[] getVariableData() {
+ public VariableData[] getVariableData() {
if(myMakeFieldParameters != null && myMakeFieldParameters.isSelected()) {
return myVariableData;
}
@@ -222,7 +223,8 @@
if (isMakeClassParameter()) {
final PsiMethod methodWithParameter = checkParameterDoesNotExist();
if (methodWithParameter != null) {
- String who = methodWithParameter == myMember ? RefactoringBundle.message("this.method") : UsageViewUtil.getDescriptiveName(methodWithParameter);
+ String who = methodWithParameter == myMember ? RefactoringBundle.message("this.method") : DescriptiveNameUtil
+ .getDescriptiveName(methodWithParameter);
String message = RefactoringBundle.message("0.already.has.parameter.named.1.use.this.name.anyway", who, getClassParameterName());
ret = Messages.showYesNoDialog(myProject, message, RefactoringBundle.message("warning.title"), Messages.getWarningIcon());
myClassParameterNameInputField.requestFocusInWindow();
diff --git a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeStaticUtil.java b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeStaticUtil.java
index c1e2269..e5c966f 100644
--- a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeStaticUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeStaticUtil.java
@@ -29,8 +29,8 @@
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.refactoring.util.ParameterTablePanel;
import com.intellij.refactoring.util.RefactoringUtil;
+import com.intellij.refactoring.util.VariableData;
import java.util.ArrayList;
import java.util.Collections;
@@ -132,13 +132,13 @@
return false;
}
- public static boolean buildVariableData(PsiTypeParameterListOwner member, ArrayList<ParameterTablePanel.VariableData> result) {
+ public static boolean buildVariableData(PsiTypeParameterListOwner member, ArrayList<VariableData> result) {
final InternalUsageInfo[] classRefsInMethod = findClassRefsInMember(member, false);
return collectVariableData(member, classRefsInMethod, result);
}
public static boolean collectVariableData(PsiMember member, InternalUsageInfo[] internalUsages,
- ArrayList<ParameterTablePanel.VariableData> variableDatum) {
+ ArrayList<VariableData> variableDatum) {
HashSet<PsiField> reported = new HashSet<PsiField>();
HashSet<PsiField> accessedForWriting = new HashSet<PsiField>();
boolean needClassParameter = false;
@@ -165,7 +165,7 @@
});
for (final PsiField field : psiFields) {
if (accessedForWriting.contains(field)) continue;
- ParameterTablePanel.VariableData data = new ParameterTablePanel.VariableData(field);
+ VariableData data = new VariableData(field);
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(member.getProject());
String name = field.getName();
name = codeStyleManager.variableNameToPropertyName(name, VariableKind.FIELD);
diff --git a/java/java-impl/src/com/intellij/refactoring/makeStatic/Settings.java b/java/java-impl/src/com/intellij/refactoring/makeStatic/Settings.java
index e3bdccf..cd76eb9 100644
--- a/java/java-impl/src/com/intellij/refactoring/makeStatic/Settings.java
+++ b/java/java-impl/src/com/intellij/refactoring/makeStatic/Settings.java
@@ -19,14 +19,14 @@
* User: dsl
* Date: 01.07.2002
* Time: 15:48:33
- * To change template for new class use
+ * To change template for new class use
* Code Style | Class Templates options (Tools | IDE Options).
*/
package com.intellij.refactoring.makeStatic;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiType;
-import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.Nullable;
@@ -56,7 +56,7 @@
public Settings(boolean replaceUsages, String classParameterName,
- ParameterTablePanel.VariableData[] variableDatum) {
+ VariableData[] variableDatum) {
myReplaceUsages = replaceUsages;
myMakeClassParameter = classParameterName != null;
myClassParameterName = classParameterName;
@@ -64,7 +64,7 @@
myFieldToNameList = new ArrayList<FieldParameter>();
if(myMakeFieldParameters) {
myFieldToNameMapping = new com.intellij.util.containers.HashMap<PsiField, String>();
- for (ParameterTablePanel.VariableData data : variableDatum) {
+ for (VariableData data : variableDatum) {
if (data.passAsParameter) {
myFieldToNameMapping.put((PsiField)data.variable, data.name);
myFieldToNameList.add(new FieldParameter((PsiField)data.variable, data.name, data.type));
@@ -76,7 +76,7 @@
}
}
- public Settings(boolean replaceUsages, String classParameterName,
+ public Settings(boolean replaceUsages, String classParameterName,
PsiField[] fields, String[] names) {
myReplaceUsages = replaceUsages;
myMakeClassParameter = classParameterName != null;
@@ -96,7 +96,7 @@
myFieldToNameMapping = null;
}
}
-
+
public boolean isReplaceUsages() {
return myReplaceUsages;
}
diff --git a/java/java-impl/src/com/intellij/refactoring/makeStatic/SimpleMakeStaticDialog.java b/java/java-impl/src/com/intellij/refactoring/makeStatic/SimpleMakeStaticDialog.java
index 995255a..3bbc129 100644
--- a/java/java-impl/src/com/intellij/refactoring/makeStatic/SimpleMakeStaticDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/makeStatic/SimpleMakeStaticDialog.java
@@ -19,7 +19,7 @@
* User: dsl
* Date: 04.07.2002
* Time: 13:54:39
- * To change template for new class use
+ * To change template for new class use
* Code Style | Class Templates options (Tools | IDE Options).
*/
package com.intellij.refactoring.makeStatic;
@@ -30,8 +30,7 @@
import com.intellij.psi.PsiTypeParameterListOwner;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.RefactoringBundle;
-import com.intellij.refactoring.util.ParameterTablePanel;
-import com.intellij.ui.IdeBorderFactory;
+import com.intellij.refactoring.util.VariableData;
import com.intellij.usageView.UsageViewUtil;
import javax.swing.*;
@@ -59,7 +58,7 @@
return null;
}
- public ParameterTablePanel.VariableData[] getVariableData() {
+ public VariableData[] getVariableData() {
return null;
}
diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java
index 0f7b115..95c826f 100644
--- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java
+++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java
@@ -29,6 +29,7 @@
import com.intellij.codeInsight.ChangeContextUtil;
import com.intellij.codeInsight.PsiEquivalenceUtil;
import com.intellij.codeInsight.intention.AddAnnotationFix;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
@@ -54,7 +55,6 @@
import com.intellij.refactoring.util.duplicates.MethodDuplicatesHandler;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
-import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Query;
import com.intellij.util.VisibilityUtil;
@@ -154,7 +154,7 @@
}
protected String getCommandName() {
- return RefactoringBundle.message("pullUp.command", UsageViewUtil.getDescriptiveName(mySourceClass));
+ return RefactoringBundle.message("pullUp.command", DescriptiveNameUtil.getDescriptiveName(mySourceClass));
}
public void moveMembersToBase() throws IncorrectOperationException {
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassToInnerProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassToInnerProcessor.java
index ca3ecc3..48ab4c4 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassToInnerProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassToInnerProcessor.java
@@ -24,10 +24,7 @@
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.util.PsiElementFilter;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.psi.util.*;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.PackageWrapper;
import com.intellij.refactoring.RefactoringBundle;
@@ -186,7 +183,7 @@
elementsToMakeWritable.add(element);
}
}
- if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, PsiUtilBase.toPsiElementArray(elementsToMakeWritable))) {
+ if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, PsiUtilCore.toPsiElementArray(elementsToMakeWritable))) {
return false;
}
return true;
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java
index 83851b3..e94e32e 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java
@@ -25,6 +25,7 @@
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Pass;
@@ -32,6 +33,8 @@
import com.intellij.psi.*;
import com.intellij.psi.search.ProjectScope;
import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.refactoring.*;
import com.intellij.refactoring.move.MoveCallback;
import com.intellij.refactoring.move.MoveClassesOrPackagesCallback;
@@ -47,6 +50,7 @@
import com.intellij.ui.ReferenceEditorWithBrowseButton;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.hash.HashSet;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -56,6 +60,7 @@
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.util.Set;
public class MoveClassesOrPackagesDialog extends RefactoringDialog {
@NonNls private static final String RECENTS_KEY = "MoveClassesOrPackagesDialog.RECENTS_KEY";
@@ -270,7 +275,12 @@
if (initialTargetDirectory != null &&
JavaMoveClassesOrPackagesHandler.packageHasMultipleDirectoriesInModule(myProject, initialTargetDirectory)) {
- initialTargetDirectory = null;
+ final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
+ final Set<VirtualFile> initialRoots = new HashSet<VirtualFile>();
+ collectSourceRoots(psiElements, fileIndex, initialRoots);
+ if (initialRoots.size() > 1) {
+ initialTargetDirectory = null;
+ }
}
((DestinationFolderComboBox)myDestinationFolderCB).setData(myProject, initialTargetDirectory,
new Pass<String>() {
@@ -284,6 +294,20 @@
myHelpID = helpID;
}
+ private static void collectSourceRoots(PsiElement[] psiElements, ProjectFileIndex fileIndex, Set<VirtualFile> initialRoots) {
+ for (PsiElement element : psiElements) {
+ final VirtualFile file = PsiUtilCore.getVirtualFile(element);
+ if (file != null) {
+ final VirtualFile sourceRootForFile = fileIndex.getSourceRootForFile(file);
+ if (sourceRootForFile != null) {
+ initialRoots.add(sourceRootForFile);
+ }
+ } else if (element instanceof PsiDirectoryContainer) {
+ collectSourceRoots(((PsiDirectoryContainer)element).getDirectories(), fileIndex, initialRoots);
+ }
+ }
+ }
+
protected void doHelpAction() {
HelpManager.getInstance().invokeHelp(myHelpID);
}
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java
index f487e94..2982483 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java
@@ -275,14 +275,15 @@
PsiDirectory[] directories = aPackage != null ? aPackage.getDirectories() : null;
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
- final boolean filterOutSources = baseDir != null && fileIndex.isInTestSourceContent(baseDir.getVirtualFile());
- if (directories != null && directories.length == 1 && !(filterOutSources &&
- !fileIndex.isInTestSourceContent(directories[0].getVirtualFile()))) {
+ final VirtualFile baseDirVirtualFile = baseDir != null ? baseDir.getVirtualFile() : null;
+ final boolean isBaseDirInTestSources = baseDirVirtualFile != null && fileIndex.isInTestSourceContent(baseDirVirtualFile);
+ if (directories != null && directories.length == 1 && (baseDirVirtualFile == null ||
+ fileIndex.isInTestSourceContent(directories[0].getVirtualFile()) == isBaseDirInTestSources)) {
directory = directories[0];
}
else {
final VirtualFile[] contentSourceRoots = ProjectRootManager.getInstance(project).getContentSourceRoots();
- if (contentSourceRoots.length == 1 && !(filterOutSources && !fileIndex.isInTestSourceContent(contentSourceRoots[0]))) {
+ if (contentSourceRoots.length == 1 && (baseDirVirtualFile == null || fileIndex.isInTestSourceContent(contentSourceRoots[0]) == isBaseDirInTestSources)) {
directory = ApplicationManager.getApplication().runWriteAction(new Computable<PsiDirectory>() {
@Override
public PsiDirectory compute() {
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/JavaMoveFilesOrDirectoriesHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/JavaMoveFilesOrDirectoriesHandler.java
index c67b7b7..0f64675 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/JavaMoveFilesOrDirectoriesHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/JavaMoveFilesOrDirectoriesHandler.java
@@ -25,7 +25,7 @@
import com.intellij.psi.impl.file.JavaDirectoryServiceImpl;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.refactoring.move.MoveCallback;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
@@ -63,7 +63,7 @@
for (PsiElement sourceElement : sourceElements) {
result.add(sourceElement instanceof PsiClass ? sourceElement.getContainingFile() : sourceElement);
}
- return PsiUtilBase.toPsiElementArray(result);
+ return PsiUtilCore.toPsiElementArray(result);
}
@Override
@@ -91,7 +91,7 @@
adjustedElements.add(element);
}
}
- result.setResult(PsiUtilBase.toPsiElementArray(adjustedElements));
+ result.setResult(PsiUtilCore.toPsiElementArray(adjustedElements));
}
}.execute().getResultObject();
}
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java
index 57936c6..35ca3e2 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java
@@ -16,7 +16,8 @@
package com.intellij.refactoring.move.moveInner;
import com.intellij.codeInsight.ChangeContextUtil;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
@@ -39,7 +40,6 @@
import com.intellij.refactoring.util.*;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
-import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.VisibilityUtil;
@@ -171,7 +171,7 @@
ChangeContextUtil.encodeContextInfo(myInnerClass, false);
- myInnerClass = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(myInnerClass);
+ myInnerClass = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(myInnerClass);
final MoveInnerOptions moveInnerOptions = new MoveInnerOptions(myInnerClass, myOuterClass, myTargetContainer, myNewClassName);
final MoveInnerHandler handler = MoveInnerHandler.EP_NAME.forLanguage(myInnerClass.getLanguage());
@@ -407,7 +407,7 @@
@NotNull final PsiElement targetContainer) {
myNewClassName = className;
myInnerClass = innerClass;
- myDescriptiveName = UsageViewUtil.getDescriptiveName(myInnerClass);
+ myDescriptiveName = DescriptiveNameUtil.getDescriptiveName(myInnerClass);
myOuterClass = myInnerClass.getContainingClass();
myTargetContainer = targetContainer;
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(myProject);
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodDialogBase.java b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodDialogBase.java
index 67a1c98..1196d73 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodDialogBase.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodDialogBase.java
@@ -15,6 +15,7 @@
*/
package com.intellij.refactoring.move.moveInstanceMethod;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiClass;
@@ -28,7 +29,6 @@
import com.intellij.refactoring.ui.RefactoringDialog;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.components.JBList;
-import com.intellij.usageView.UsageViewUtil;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
@@ -109,14 +109,15 @@
if (targetClass.isInterface()) {
final Project project = getProject();
if (ClassInheritorsSearch.search(targetClass, false).findFirst() == null) {
- final String message = RefactoringBundle.message("0.is.an.interface.that.has.no.implementing.classes", UsageViewUtil.getDescriptiveName(targetClass));
+ final String message = RefactoringBundle.message("0.is.an.interface.that.has.no.implementing.classes", DescriptiveNameUtil
+ .getDescriptiveName(targetClass));
Messages.showErrorDialog(project, message, myRefactoringName);
return false;
}
final String message = RefactoringBundle.message("0.is.an.interface.method.implementation.will.be.added.to.all.directly.implementing.classes",
- UsageViewUtil.getDescriptiveName(targetClass));
+ DescriptiveNameUtil.getDescriptiveName(targetClass));
final int result = Messages.showYesNoDialog(project, message, myRefactoringName,
Messages.getQuestionIcon());
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java
index 5784665..ca844f0 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java
@@ -34,6 +34,7 @@
import com.intellij.refactoring.util.*;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
+import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.VisibilityUtil;
import com.intellij.util.containers.HashSet;
@@ -245,7 +246,7 @@
for (PsiReference reference : docRefs) {
reference.bindToElement(method);
}
- VisibilityUtil.fixVisibility(usages, method, myNewVisibility);
+ VisibilityUtil.fixVisibility(UsageViewUtil.toElements(usages), method, myNewVisibility);
}
catch (IncorrectOperationException e) {
LOG.error(e);
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java
index 4efd85f..3f4f59a 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java
@@ -22,7 +22,7 @@
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.RefactoringBundle;
@@ -105,7 +105,7 @@
@NotNull
protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) {
- return new MoveMemberViewDescriptor(PsiUtilBase.toPsiElementArray(myMembersToMove));
+ return new MoveMemberViewDescriptor(PsiUtilCore.toPsiElementArray(myMembersToMove));
}
@NotNull
@@ -203,7 +203,7 @@
final PsiElement anchor;
if (anchorsInSourceClass.containsKey(member)) {
final PsiMember memberInSourceClass = anchorsInSourceClass.get(member);
- //anchor should be already moved as myMembersToMove contains members in order they appear in source class
+ //anchor should be already moved as myMembersToMove contains members in order they appear in source class
anchor = memberInSourceClass != null ? movedMembers.get(memberInSourceClass) : null;
}
else {
@@ -258,7 +258,8 @@
filtered.add(usage);
}
}
- VisibilityUtil.fixVisibility(filtered.toArray(new UsageInfo[filtered.size()]), newMember, myNewVisibility);
+ UsageInfo[] infos = filtered.toArray(new UsageInfo[filtered.size()]);
+ VisibilityUtil.fixVisibility(UsageViewUtil.toElements(infos), newMember, myNewVisibility);
}
protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
diff --git a/java/java-impl/src/com/intellij/refactoring/psi/PropertyUtils.java b/java/java-impl/src/com/intellij/refactoring/psi/PropertyUtils.java
deleted file mode 100644
index 9d188b7..0000000
--- a/java/java-impl/src/com/intellij/refactoring/psi/PropertyUtils.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright 2000-2011 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.refactoring.psi;
-
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.*;
-import com.intellij.psi.util.InheritanceUtil;
-import com.intellij.psi.util.PropertyUtil;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class PropertyUtils {
- private PropertyUtils() {
- }
-
- public static PsiMethod findSetterForField(PsiField field) {
- final PsiClass containingClass = field.getContainingClass();
- final Project project = field.getProject();
- final String propertyName = PropertyUtil.suggestPropertyName(project, field);
- final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
- return PropertyUtil.findPropertySetter(containingClass, propertyName, isStatic, true);
- }
-
- public static PsiMethod findGetterForField(PsiField field) {
- final PsiClass containingClass = field.getContainingClass();
- final Project project = field.getProject();
- final String propertyName = PropertyUtil.suggestPropertyName(project, field);
- final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
- return PropertyUtil.findPropertyGetter(containingClass, propertyName, isStatic, true);
- }
-
- /**
- * If the name of the method looks like a getter and the body consists of a single return statement,
- * returns the returned expression. Otherwise, returns null.
- *
- * @param method the method to check
- * @return the return value, or null if it doesn't match the condotions.
- */
- @Nullable
- public static PsiExpression getGetterReturnExpression(PsiMethod method) {
- return method != null && hasGetterSignature(method) ? getSingleReturnValue(method) : null;
- }
-
- private static boolean hasGetterSignature(@NotNull PsiMethod method) {
- return PropertyUtil.isSimplePropertyGetter(method) && !method.hasModifierProperty(PsiModifier.SYNCHRONIZED);
- }
-
- @Nullable
- public static PsiExpression getSingleReturnValue(@NotNull PsiMethod method) {
- final PsiCodeBlock body = method.getBody();
- if (body == null) {
- return null;
- }
- final PsiStatement[] statements = body.getStatements();
- final PsiStatement statement = statements.length != 1 ? null : statements[0];
- return statement instanceof PsiReturnStatement ? ((PsiReturnStatement)statement).getReturnValue() : null;
- }
-
- @Nullable
- public static PsiField getFieldOfGetter(PsiMethod method) {
- PsiField field = getSimplyReturnedField(method, getGetterReturnExpression(method));
- if (field != null) {
- final PsiType returnType = method.getReturnType();
- if (returnType != null && field.getType().equalsToText(returnType.getCanonicalText())) {
- return field;
- }
- }
- return null;
- }
-
- @Nullable
- public static PsiField getSimplyReturnedField(PsiMethod method, @Nullable PsiExpression value) {
- if (!(value instanceof PsiReferenceExpression)) {
- return null;
- }
-
- final PsiReferenceExpression reference = (PsiReferenceExpression)value;
- if (hasSubstantialQualifier(reference)) {
- return null;
- }
-
- final PsiElement referent = reference.resolve();
- if (!(referent instanceof PsiField)) {
- return null;
- }
-
- final PsiField field = (PsiField)referent;
- return InheritanceUtil.isInheritorOrSelf(method.getContainingClass(), field.getContainingClass(), true) ? field : null;
- }
-
- private static boolean hasSubstantialQualifier(PsiReferenceExpression reference) {
- final PsiExpression qualifier = reference.getQualifierExpression();
- if (qualifier == null) return false;
-
- if (qualifier instanceof PsiThisExpression || qualifier instanceof PsiSuperExpression) {
- return false;
- }
-
- if (qualifier instanceof PsiReferenceExpression) {
- return !(((PsiReferenceExpression)qualifier).resolve() instanceof PsiClass);
- }
- return true;
- }
-
- public static boolean isSimpleGetter(PsiMethod method) {
- return getFieldOfGetter(method) != null;
- }
-
- @Nullable
- public static PsiField getFieldOfSetter(PsiMethod method) {
- if (method == null) {
- return null;
- }
- final PsiParameterList parameterList = method.getParameterList();
- if (parameterList.getParametersCount() != 1) {
- return null;
- }
- @NonNls final String name = method.getName();
- if (!name.startsWith("set")) {
- return null;
- }
- if (method.hasModifierProperty(PsiModifier.SYNCHRONIZED)) {
- return null;
- }
- final PsiCodeBlock body = method.getBody();
- if (body == null) {
- return null;
- }
- final PsiStatement[] statements = body.getStatements();
- if (statements.length != 1) {
- return null;
- }
- final PsiStatement statement = statements[0];
- if (!(statement instanceof PsiExpressionStatement)) {
- return null;
- }
- final PsiExpressionStatement possibleAssignmentStatement = (PsiExpressionStatement)statement;
- final PsiExpression possibleAssignment = possibleAssignmentStatement.getExpression();
- if (!(possibleAssignment instanceof PsiAssignmentExpression)) {
- return null;
- }
- final PsiAssignmentExpression assignment = (PsiAssignmentExpression)possibleAssignment;
- if (!JavaTokenType.EQ.equals(assignment.getOperationTokenType())) {
- return null;
- }
- final PsiExpression lhs = assignment.getLExpression();
- if (!(lhs instanceof PsiReferenceExpression)) {
- return null;
- }
- final PsiReferenceExpression reference = (PsiReferenceExpression)lhs;
- final PsiExpression qualifier = reference.getQualifierExpression();
- if (qualifier instanceof PsiReferenceExpression) {
- final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)qualifier;
- final PsiElement target = referenceExpression.resolve();
- if (!(target instanceof PsiClass)) {
- return null;
- }
- }
- else if (qualifier != null && !(qualifier instanceof PsiThisExpression) && !(qualifier instanceof PsiSuperExpression)) {
- return null;
- }
- final PsiElement referent = reference.resolve();
- if (referent == null) {
- return null;
- }
- if (!(referent instanceof PsiField)) {
- return null;
- }
- final PsiField field = (PsiField)referent;
- final PsiClass fieldContainingClass = field.getContainingClass();
- final PsiClass methodContainingClass = method.getContainingClass();
- if (!InheritanceUtil.isInheritorOrSelf(methodContainingClass, fieldContainingClass, true)) {
- return null;
- }
- final PsiExpression rhs = assignment.getRExpression();
- if (!(rhs instanceof PsiReferenceExpression)) {
- return null;
- }
- final PsiReferenceExpression rReference = (PsiReferenceExpression)rhs;
- final PsiExpression rQualifier = rReference.getQualifierExpression();
- if (rQualifier != null) {
- return null;
- }
- final PsiElement rReferent = rReference.resolve();
- if (rReferent == null) {
- return null;
- }
- if (!(rReferent instanceof PsiParameter)) {
- return null;
- }
- final PsiType fieldType = field.getType();
- final PsiType parameterType = ((PsiVariable)rReferent).getType();
- if (fieldType.equalsToText(parameterType.getCanonicalText())) {
- return field;
- }
- else {
- return null;
- }
- }
-
- public static boolean isSimpleSetter(PsiMethod method) {
- return getFieldOfSetter(method) != null;
- }
-
- @Nullable
- public static PsiMethod getReversePropertyMethod(PsiMethod propertyMethod) {
- if (propertyMethod == null) {
- return null;
- }
- final PsiClass aClass = propertyMethod.getContainingClass();
- if (aClass == null) {
- return null;
- }
- final String methodName = propertyMethod.getName();
- final String prefix;
- if (methodName.startsWith("get")) {
- prefix = "get";
- }
- else if (methodName.startsWith("is")) {
- prefix = "is";
- }
- else if (methodName.startsWith("set")) {
- prefix = "set";
- }
- else {
- return null;
- }
- final String name = methodName.substring(prefix.length());
- final PsiField field;
- if (prefix.equals("set")) {
- field = getFieldOfSetter(propertyMethod);
- }
- else {
- field = getFieldOfGetter(propertyMethod);
- }
- if (field == null) {
- return null;
- }
- if (prefix.equals("set")) {
- final PsiMethod result = findPropertyMethod(aClass, "get", name, field);
- if (result != null) {
- return result;
- }
- return findPropertyMethod(aClass, "is", name, field);
- }
- else {
- return findPropertyMethod(aClass, "set", name, field);
- }
- }
-
- private static PsiMethod findPropertyMethod(@NotNull PsiClass aClass, @NotNull String prefix, @NotNull String propertyName, @NotNull PsiField field1) {
- final PsiMethod[] methods = aClass.findMethodsByName(prefix + propertyName, true);
- for (PsiMethod method : methods) {
- final PsiField field2;
- if (prefix.equals("set")) {
- field2 = getFieldOfSetter(method);
- }
- else {
- field2 = getFieldOfGetter(method);
- }
- if (field1.equals(field2)) {
- return method;
- }
- }
- return null;
- }
-}
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 785c5da..4f3bf58 100644
--- a/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java
@@ -23,6 +23,9 @@
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiParameter;
+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.refactoring.RenameRefactoring;
@@ -65,6 +68,15 @@
if (setter != null) {
final String setterName = PropertyUtil.suggestSetterName(newName);
rename.addElement(setter, setterName);
+
+ final PsiParameter[] setterParameters = setter.getParameterList().getParameters();
+ if (setterParameters.length == 1) {
+ final JavaCodeStyleManager manager = JavaCodeStyleManager.getInstance(psiElement.getProject());
+ final String suggestedParameterName = manager.propertyNameToVariableName(property.getName(), VariableKind.PARAMETER);
+ if (suggestedParameterName.equals(setterParameters[0].getName())) {
+ rename.addElement(setterParameters[0], manager.propertyNameToVariableName(newName, VariableKind.PARAMETER));
+ }
+ }
}
final PsiMethod getter = property.getGetter();
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 1573362..7e485dc 100644
--- a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java
@@ -260,6 +260,16 @@
}
@Override
+ public void findExistingNameConflicts(PsiElement element,
+ String newName,
+ MultiMap<PsiElement, String> conflicts,
+ Map<PsiElement, String> allRenames) {
+ for (PsiElement psiElement : allRenames.keySet()) {
+ RenamePsiElementProcessor.forElement(psiElement).findExistingNameConflicts(psiElement, allRenames.get(psiElement), conflicts);
+ }
+ }
+
+ @Override
public void findExistingNameConflicts(PsiElement element, String newName, MultiMap<PsiElement, String> conflicts) {
if (element instanceof PsiCompiledElement) return;
if (element instanceof PsiField) {
diff --git a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryProcessor.java b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryProcessor.java
index 2f7af47..202a990 100644
--- a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryProcessor.java
@@ -15,6 +15,7 @@
*/
package com.intellij.refactoring.replaceConstructorWithFactory;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
@@ -30,7 +31,6 @@
import com.intellij.refactoring.util.RefactoringUIUtil;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
-import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.VisibilityUtil;
import com.intellij.util.containers.MultiMap;
@@ -300,11 +300,11 @@
protected String getCommandName() {
if (myConstructor != null) {
return RefactoringBundle.message("replace.constructor.0.with.a.factory.method",
- UsageViewUtil.getDescriptiveName(myConstructor));
+ DescriptiveNameUtil.getDescriptiveName(myConstructor));
}
else {
return RefactoringBundle.message("replace.default.constructor.of.0.with.a.factory.method",
- UsageViewUtil.getDescriptiveName(myOriginalClass));
+ DescriptiveNameUtil.getDescriptiveName(myOriginalClass));
}
}
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 871c964..ccdeb37 100644
--- a/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java
@@ -15,7 +15,7 @@
*/
package com.intellij.refactoring.safeDelete;
-import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableFix;
+import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableUtil;
import com.intellij.find.findUsages.PsiElement2UsageTargetAdapter;
import com.intellij.ide.util.SuperMethodWarningUtil;
import com.intellij.openapi.application.ApplicationManager;
@@ -88,7 +88,9 @@
boolean hasSideEffects = false;
if (PsiUtil.isOnAssignmentLeftHand(referencedElement)) {
hasSideEffects =
- RemoveUnusedVariableFix.checkSideEffects(((PsiAssignmentExpression)referencedElement.getParent()).getRExpression(), ((PsiLocalVariable)element), new ArrayList<PsiElement>());
+ RemoveUnusedVariableUtil
+ .checkSideEffects(((PsiAssignmentExpression)referencedElement.getParent()).getRExpression(), ((PsiLocalVariable)element),
+ new ArrayList<PsiElement>());
}
usages.add(new SafeDeleteReferenceJavaDeleteUsageInfo(statement, element, isSafeToDelete && !hasSideEffects));
}
diff --git a/java/java-impl/src/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteExtendsClassUsageInfo.java b/java/java-impl/src/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteExtendsClassUsageInfo.java
index 6d7f6c5..4b586aa 100644
--- a/java/java-impl/src/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteExtendsClassUsageInfo.java
+++ b/java/java-impl/src/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteExtendsClassUsageInfo.java
@@ -50,7 +50,7 @@
final PsiReferenceList extendingImplementsList = myExtendingClass.getImplementsList();
if (extendsList != null) {
final PsiClassType[] referenceTypes = extendsList.getReferencedTypes();
- final PsiReferenceList listToAddExtends = refClass.isInterface() == myExtendingClass.isInterface() ? myExtendingClass.getExtendsList() : extendingImplementsList;
+ final PsiReferenceList listToAddExtends = refClass.isInterface() == myExtendingClass.isInterface() || myExtendingClass instanceof PsiTypeParameter ? myExtendingClass.getExtendsList() : extendingImplementsList;
final PsiClassType[] existingRefTypes = listToAddExtends.getReferencedTypes();
for (PsiClassType referenceType : referenceTypes) {
if (ArrayUtilRt.find(existingRefTypes, referenceType) > -1) continue;
diff --git a/java/java-impl/src/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessor.java b/java/java-impl/src/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessor.java
index 90372d7..210b8d3 100644
--- a/java/java-impl/src/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessor.java
@@ -15,6 +15,7 @@
*/
package com.intellij.refactoring.turnRefsToSuper;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
@@ -52,7 +53,7 @@
protected String getCommandName() {
return RefactoringBundle.message("turn.refs.to.super.command",
- UsageViewUtil.getDescriptiveName(myClass), UsageViewUtil.getDescriptiveName(mySuper));
+ DescriptiveNameUtil.getDescriptiveName(myClass), DescriptiveNameUtil.getDescriptiveName(mySuper));
}
@NotNull
diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/TypeCookDialog.java b/java/java-impl/src/com/intellij/refactoring/typeCook/TypeCookDialog.java
index c176555..9c723f4 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeCook/TypeCookDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeCook/TypeCookDialog.java
@@ -15,6 +15,7 @@
*/
package com.intellij.refactoring.typeCook;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
@@ -63,7 +64,7 @@
PsiElement element = elements[i];
name.append(StringUtil.capitalize(UsageViewUtil.getType(element)));
name.append(" ");
- name.append(UsageViewUtil.getDescriptiveName(element));
+ name.append(DescriptiveNameUtil.getDescriptiveName(element));
if (i < elements.length - 1) {
name.append("<br>");
}
diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeEvaluator.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeEvaluator.java
index 67e6438..105c383 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeEvaluator.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeEvaluator.java
@@ -415,24 +415,25 @@
public static PsiType substituteType(final PsiType migrationTtype, final PsiType originalType, final boolean isContraVariantPosition) {
if ( originalType instanceof PsiClassType && migrationTtype instanceof PsiClassType) {
final PsiClass originalClass = ((PsiClassType)originalType).resolve();
- if (isContraVariantPosition && TypeConversionUtil.erasure(originalType).isAssignableFrom(TypeConversionUtil.erasure(migrationTtype))) {
- final PsiClass psiClass = ((PsiClassType)migrationTtype).resolve();
- final PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(originalClass, psiClass, PsiSubstitutor.EMPTY);
- if (substitutor != null) {
- final PsiType psiType =
- substituteType(migrationTtype, originalType, false, psiClass, JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(originalClass, substitutor));
+ if (originalClass != null) {
+ if (isContraVariantPosition && TypeConversionUtil.erasure(originalType).isAssignableFrom(TypeConversionUtil.erasure(migrationTtype))) {
+ final PsiClass psiClass = ((PsiClassType)migrationTtype).resolve();
+ final PsiSubstitutor substitutor = psiClass != null ? TypeConversionUtil.getClassSubstitutor(originalClass, psiClass, PsiSubstitutor.EMPTY) : null;
+ if (substitutor != null) {
+ final PsiType psiType =
+ substituteType(migrationTtype, originalType, false, psiClass, JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(originalClass, substitutor));
+ if (psiType != null) {
+ return psiType;
+ }
+ }
+ }
+ else if (!isContraVariantPosition && TypeConversionUtil.erasure(migrationTtype).isAssignableFrom(TypeConversionUtil.erasure(originalType))) {
+ final PsiType psiType = substituteType(migrationTtype, originalType, false, originalClass, JavaPsiFacade.getElementFactory(originalClass.getProject()).createType(originalClass, PsiSubstitutor.EMPTY));
if (psiType != null) {
return psiType;
}
}
}
- else if (!isContraVariantPosition && TypeConversionUtil.erasure(migrationTtype).isAssignableFrom(TypeConversionUtil.erasure(
- originalType))) {
- final PsiType psiType = substituteType(migrationTtype, originalType, false, originalClass, JavaPsiFacade.getElementFactory(originalClass.getProject()).createType(originalClass, PsiSubstitutor.EMPTY));
- if (psiType != null) {
- return psiType;
- }
- }
}
return migrationTtype;
}
diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationProcessor.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationProcessor.java
index 7a0bdb6..2f85e7a 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationProcessor.java
@@ -26,7 +26,7 @@
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.tree.JavaElementType;
-import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.typeMigration.ui.FailedConversionsDialog;
import com.intellij.refactoring.typeMigration.ui.MigrationPanel;
@@ -76,7 +76,7 @@
}
return new PsiElement[]{root};
}
-
+
public TypeMigrationProcessor(final Project project, final PsiElement[] roots, final TypeMigrationRules rules) {
super(project);
myRoot = roots;
@@ -106,7 +106,7 @@
result.add(element);
}
}
- if (editor != null) RefactoringUtil.highlightAllOccurrences(project, PsiUtilBase.toPsiElementArray(result), editor);
+ if (editor != null) RefactoringUtil.highlightAllOccurrences(project, PsiUtilCore.toPsiElementArray(result), editor);
}
});
}
diff --git a/java/java-impl/src/com/intellij/refactoring/util/ConflictsUtil.java b/java/java-impl/src/com/intellij/refactoring/util/ConflictsUtil.java
index f21c11a..7f13923 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/ConflictsUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/ConflictsUtil.java
@@ -20,13 +20,13 @@
*/
package com.intellij.refactoring.util;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.FileContextUtil;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.RefactoringBundle;
-import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.Processor;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
@@ -74,7 +74,7 @@
}
else { // method somewhere in base class
if (JavaPsiFacade.getInstance(method.getProject()).getResolveHelper().isAccessible(method, aClass, null)) {
- String className = CommonRefactoringUtil.htmlEmphasize(UsageViewUtil.getDescriptiveName(method.getContainingClass()));
+ String className = CommonRefactoringUtil.htmlEmphasize(DescriptiveNameUtil.getDescriptiveName(method.getContainingClass()));
if (PsiUtil.getAccessLevel(prototype.getModifierList()) >= PsiUtil.getAccessLevel(method.getModifierList()) ) {
boolean isMethodAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);
boolean isMyMethodAbstract = refactoredMethod != null && refactoredMethod.hasModifierProperty(PsiModifier.ABSTRACT);
diff --git a/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java b/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java
index c02644f..527c030 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java
@@ -16,7 +16,7 @@
package com.intellij.refactoring.util;
import com.intellij.codeInsight.ChangeContextUtil;
-import com.intellij.codeInsight.daemon.impl.analysis.GenericsHighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Comparing;
@@ -58,7 +58,7 @@
PsiType exprType = expr.getType();
if (exprType != null && (!varType.equals(exprType) && (varType instanceof PsiPrimitiveType || exprType instanceof PsiPrimitiveType)
|| !TypeConversionUtil.isAssignable(varType, exprType)
- || insertCastWhenUnchecked && GenericsHighlightUtil.isRawToGeneric(varType, exprType))) {
+ || insertCastWhenUnchecked && JavaGenericsUtil.isRawToGeneric(varType, exprType))) {
boolean matchedTypes = false;
//try explicit type arguments
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
diff --git a/java/java-impl/src/com/intellij/refactoring/util/JavaRefactoringElementDescriptionProvider.java b/java/java-impl/src/com/intellij/refactoring/util/JavaRefactoringElementDescriptionProvider.java
index 8e691a6..2b0163c 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/JavaRefactoringElementDescriptionProvider.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/JavaRefactoringElementDescriptionProvider.java
@@ -15,10 +15,10 @@
*/
package com.intellij.refactoring.util;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.refactoring.RefactoringBundle;
-import com.intellij.usageView.UsageViewUtil;
import org.jetbrains.annotations.NotNull;
public class JavaRefactoringElementDescriptionProvider implements ElementDescriptionProvider {
@@ -71,7 +71,8 @@
if ((element instanceof PsiClass)) {
//TODO : local & anonymous
PsiClass psiClass = (PsiClass) element;
- return RefactoringBundle.message("class.description", CommonRefactoringUtil.htmlEmphasize(UsageViewUtil.getDescriptiveName(psiClass)));
+ return RefactoringBundle.message("class.description", CommonRefactoringUtil.htmlEmphasize(
+ DescriptiveNameUtil.getDescriptiveName(psiClass)));
}
return null;
}
diff --git a/java/java-impl/src/com/intellij/refactoring/util/ParameterTablePanel.java b/java/java-impl/src/com/intellij/refactoring/util/ParameterTablePanel.java
index 218607a..256c3a9 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/ParameterTablePanel.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/ParameterTablePanel.java
@@ -59,23 +59,6 @@
return myVariableData;
}
- public static class VariableData {
- public final PsiVariable variable;
- public PsiType type;
- public String name;
- public boolean passAsParameter;
-
- public VariableData(PsiVariable var) {
- variable = var;
- type = var.getType();
- }
-
- public VariableData(PsiVariable var, PsiType type) {
- variable = var;
- this.type = SmartTypePointerManager.getInstance(var.getProject()).createSmartTypePointer(type).getType();
- }
- }
-
protected abstract void updateSignature();
protected abstract void doEnterAction();
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 b30b63c..80a4a91 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java
@@ -18,6 +18,7 @@
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.ExpectedTypesProvider;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.codeInsight.highlighting.HighlightManager;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.diagnostic.Logger;
@@ -822,21 +823,6 @@
return buffer.toString();
}
- public static boolean isSuperOrThisCall(PsiStatement statement, boolean testForSuper, boolean testForThis) {
- if (!(statement instanceof PsiExpressionStatement)) return false;
- PsiExpression expression = ((PsiExpressionStatement)statement).getExpression();
- if (!(expression instanceof PsiMethodCallExpression)) return false;
- final PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)expression).getMethodExpression();
- if (testForSuper) {
- if ("super".equals(methodExpression.getText())) return true;
- }
- if (testForThis) {
- if ("this".equals(methodExpression.getText())) return true;
- }
-
- return false;
- }
-
public static void visitImplicitSuperConstructorUsages(PsiClass subClass,
final ImplicitConstructorUsageVisitor implicitConstructorUsageVistor,
PsiClass superClass) {
@@ -845,7 +831,7 @@
if (constructors.length > 0) {
for (PsiMethod constructor : constructors) {
final PsiStatement[] statements = constructor.getBody().getStatements();
- if (statements.length < 1 || !isSuperOrThisCall(statements[0], true, true)) {
+ if (statements.length < 1 || !JavaHighlightUtil.isSuperOrThisCall(statements[0], true, true)) {
implicitConstructorUsageVistor.visitConstructor(constructor, baseDefaultConstructor);
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/MatchUtil.java b/java/java-impl/src/com/intellij/refactoring/util/duplicates/MatchUtil.java
new file mode 100644
index 0000000..7c88fc1
--- /dev/null
+++ b/java/java-impl/src/com/intellij/refactoring/util/duplicates/MatchUtil.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2000-2013 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.refactoring.util.duplicates;
+
+import com.intellij.codeInsight.PsiEquivalenceUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiFormatUtil;
+import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor;
+import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class MatchUtil {
+ @Nullable
+ public static String getChangedSignature(Match match, final PsiMethod method, final boolean shouldBeStatic, String visibility) {
+ final PsiType returnType = match.getChangedReturnType(method);
+ if (!match.myChangedParams.isEmpty() || returnType != null) {
+ @NonNls StringBuilder buffer = new StringBuilder();
+ buffer.append(visibility);
+ if (buffer.length() > 0) {
+ buffer.append(" ");
+ }
+ if (shouldBeStatic) {
+ buffer.append("static ");
+ }
+ final PsiTypeParameterList typeParameterList = method.getTypeParameterList();
+ if (typeParameterList != null) {
+ buffer.append(typeParameterList.getText());
+ buffer.append(" ");
+ }
+
+ buffer.append(PsiFormatUtil.formatType(returnType != null ? returnType : method.getReturnType(), 0, PsiSubstitutor.EMPTY));
+ buffer.append(" ");
+ buffer.append(method.getName());
+ buffer.append("(");
+ int count = 0;
+ final String INDENT = " ";
+ final List<ParameterInfoImpl> params = patchParams(match.myChangedParams, method);
+ for (ParameterInfoImpl param : params) {
+ String typeText = param.getTypeText();
+ if (count > 0) {
+ buffer.append(",");
+ }
+ buffer.append("\n");
+ buffer.append(INDENT);
+ buffer.append(typeText);
+ buffer.append(" ");
+ buffer.append(param.getName());
+ count++;
+ }
+
+ if (count > 0) {
+ buffer.append("\n");
+ }
+ buffer.append(")");
+ final PsiClassType[] exceptions = method.getThrowsList().getReferencedTypes();
+ if (exceptions.length > 0) {
+ buffer.append("\n");
+ buffer.append("throws\n");
+ for (PsiType exception : exceptions) {
+ buffer.append(INDENT);
+ buffer.append(PsiFormatUtil.formatType(exception, 0, PsiSubstitutor.EMPTY));
+ buffer.append("\n");
+ }
+ }
+ return buffer.toString();
+ }
+ return null;
+ }
+
+ public static void changeSignature(@NotNull Match match, @NotNull PsiMethod psiMethod) {
+ final PsiType expressionType = match.getChangedReturnType(psiMethod);
+ if (expressionType == null && match.myChangedParams.isEmpty()) return;
+ final List<ParameterInfoImpl> newParameters = patchParams(match.myChangedParams, psiMethod);
+ final ChangeSignatureProcessor csp = new ChangeSignatureProcessor(psiMethod.getProject(), psiMethod, false, null, psiMethod.getName(),
+ expressionType != null ? expressionType : psiMethod.getReturnType(),
+ newParameters.toArray(new ParameterInfoImpl[newParameters.size()]));
+
+ csp.run();
+ }
+
+ public static List<ParameterInfoImpl> patchParams(Map<PsiVariable, PsiType> changedParams, final PsiMethod psiMethod) {
+ final ArrayList<ParameterInfoImpl> newParameters = new ArrayList<ParameterInfoImpl>();
+ final PsiParameter[] oldParameters = psiMethod.getParameterList().getParameters();
+ for (int i = 0; i < oldParameters.length; i++) {
+ final PsiParameter oldParameter = oldParameters[i];
+ PsiType type = oldParameter.getType();
+ for (PsiVariable variable : changedParams.keySet()) {
+ if (PsiEquivalenceUtil.areElementsEquivalent(variable, oldParameter)) {
+ type = changedParams.get(variable);
+ break;
+ }
+ }
+ newParameters.add(new ParameterInfoImpl(i, oldParameter.getName(), type));
+ }
+ return newParameters;
+ }
+}
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/MethodDuplicatesMatchProvider.java b/java/java-impl/src/com/intellij/refactoring/util/duplicates/MethodDuplicatesMatchProvider.java
index 6476aa4..7686126 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/duplicates/MethodDuplicatesMatchProvider.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/duplicates/MethodDuplicatesMatchProvider.java
@@ -48,7 +48,7 @@
@Override
public PsiElement processMatch(Match match) throws IncorrectOperationException {
- match.changeSignature(myMethod);
+ MatchUtil.changeSignature(match, myMethod);
final PsiClass containingClass = myMethod.getContainingClass();
if (isEssentialStaticContextAbsent(match)) {
PsiUtil.setModifierProperty(myMethod, PsiModifier.STATIC, true);
@@ -159,7 +159,8 @@
final PsiElement matchStart = match.getMatchStart();
String visibility = VisibilityUtil.getPossibleVisibility(myMethod, matchStart);
final boolean shouldBeStatic = isEssentialStaticContextAbsent(match);
- final String signature = match.getChangedSignature(myMethod, myMethod.hasModifierProperty(PsiModifier.STATIC) || shouldBeStatic, visibility);
+ final String signature = MatchUtil
+ .getChangedSignature(match, myMethod, myMethod.hasModifierProperty(PsiModifier.STATIC) || shouldBeStatic, visibility);
if (signature != null) {
return RefactoringBundle.message("replace.this.code.fragment.and.change.signature", signature);
}
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 7e9b37f..b967928 100644
--- a/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java
@@ -30,11 +30,11 @@
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.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.RefactorJBundle;
-import com.intellij.refactoring.psi.PropertyUtils;
import com.intellij.refactoring.psi.TypeParametersVisitor;
import com.intellij.refactoring.util.FixableUsageInfo;
import com.intellij.refactoring.util.FixableUsagesRefactoringProcessor;
@@ -111,7 +111,7 @@
return unboxedType.getCanonicalText() + "Value()";
}
- final PsiMethod getter = PropertyUtils.findGetterForField(myDelegateField);
+ final PsiMethod getter = PropertyUtil.findGetterForField(myDelegateField);
return getter != null ? getter.getName() : "";
}
return "";
diff --git a/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java b/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java
index e9f0888..05207ff 100644
--- a/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java
+++ b/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java
@@ -16,7 +16,7 @@
package com.intellij.testIntegration;
import com.intellij.codeInsight.CodeInsightActionHandler;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.generation.GenerateMembersUtil;
import com.intellij.codeInsight.generation.OverrideImplementUtil;
import com.intellij.codeInsight.generation.PsiGenerationInfo;
@@ -172,7 +172,7 @@
GenerateMembersUtil.insertMembersAtOffset(file, offset, Collections.singletonList(info));
final PsiMethod member = info.getPsiMember();
- return member != null ? CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(member) : null;
+ return member != null ? CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(member) : null;
}
private static int findOffsetToInsertMethodTo(Editor editor, PsiFile file) {
diff --git a/java/java-impl/src/com/intellij/ui/JavaReferenceEditorUtil.java b/java/java-impl/src/com/intellij/ui/JavaReferenceEditorUtil.java
index eae2183..b5323ad 100644
--- a/java/java-impl/src/com/intellij/ui/JavaReferenceEditorUtil.java
+++ b/java/java-impl/src/com/intellij/ui/JavaReferenceEditorUtil.java
@@ -43,11 +43,21 @@
}
@Nullable
- public static Document createDocument(final String text, Project project, boolean isClassesAccepted) {
+ public static Document createDocument(final String text,
+ Project project,
+ boolean isClassesAccepted) {
+ return createDocument(text, project, isClassesAccepted, JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE);
+ }
+
+ @Nullable
+ public static Document createDocument(final String text,
+ Project project,
+ boolean isClassesAccepted,
+ JavaCodeFragment.VisibilityChecker visibilityChecker) {
final PsiPackage defaultPackage = JavaPsiFacade.getInstance(project).findPackage("");
final JavaCodeFragmentFactory factory = JavaCodeFragmentFactory.getInstance(project);
final JavaCodeFragment fragment = factory.createReferenceCodeFragment(text, defaultPackage, true, isClassesAccepted);
- fragment.setVisibilityChecker(JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE);
+ fragment.setVisibilityChecker(visibilityChecker);
return PsiDocumentManager.getInstance(project).getDocument(fragment);
}
diff --git a/java/java-impl/src/com/intellij/ui/ReferenceEditorComboWithBrowseButton.java b/java/java-impl/src/com/intellij/ui/ReferenceEditorComboWithBrowseButton.java
index 718a8c2..e86cbb5 100644
--- a/java/java-impl/src/com/intellij/ui/ReferenceEditorComboWithBrowseButton.java
+++ b/java/java-impl/src/com/intellij/ui/ReferenceEditorComboWithBrowseButton.java
@@ -43,7 +43,7 @@
@NotNull final Project project,
boolean toAcceptClasses,
final JavaCodeFragment.VisibilityChecker visibilityChecker, final String recentsKey) {
- super(new EditorComboBox(createDocument(StringUtil.isEmpty(text) ? "" : text, project, toAcceptClasses, visibilityChecker), project, StdFileTypes.JAVA),
+ super(new EditorComboBox(JavaReferenceEditorUtil.createDocument(StringUtil.isEmpty(text) ? "" : text, project, toAcceptClasses, visibilityChecker), project, StdFileTypes.JAVA),
browseActionListener);
final List<String> recentEntries = RecentsManager.getInstance(project).getRecentEntries(recentsKey);
if (recentEntries != null) {
@@ -54,16 +54,6 @@
}
}
- private static Document createDocument(final String text,
- Project project,
- boolean isClassesAccepted,
- final JavaCodeFragment.VisibilityChecker visibilityChecker) {
- PsiPackage defaultPackage = JavaPsiFacade.getInstance(project).findPackage("");
- final JavaCodeFragment fragment = JavaCodeFragmentFactory.getInstance(project).createReferenceCodeFragment(text, defaultPackage, true, isClassesAccepted);
- fragment.setVisibilityChecker(visibilityChecker);
- return PsiDocumentManager.getInstance(project).getDocument(fragment);
- }
-
public String getText(){
return getChildComponent().getText().trim();
}
diff --git a/java/java-impl/src/com/intellij/unscramble/UnscrambleDialog.java b/java/java-impl/src/com/intellij/unscramble/UnscrambleDialog.java
index 4c51caf..2627fd2 100644
--- a/java/java-impl/src/com/intellij/unscramble/UnscrambleDialog.java
+++ b/java/java-impl/src/com/intellij/unscramble/UnscrambleDialog.java
@@ -213,6 +213,10 @@
return new Action[]{createNormalizeTextAction(), getOKAction(), getCancelAction(), getHelpAction()};
}
+ public JComponent getPreferredFocusedComponent() {
+ return getRootPane().getDefaultButton();
+ }
+
private void createLogFileChooser() {
myLogFile = new TextFieldWithHistory();
JPanel panel = GuiUtils.constructFieldWithBrowseButton(myLogFile, new ActionListener() {
@@ -417,10 +421,6 @@
return "#com.intellij.unscramble.UnscrambleDialog";
}
- public JComponent getPreferredFocusedComponent() {
- return myStacktraceEditorPanel.getEditorComponent();
- }
-
@Nullable
private static String getExceptionName(String unscrambledTrace) {
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
diff --git a/java/java-indexing-api/src/com/intellij/psi/search/searches/MethodReferencesSearch.java b/java/java-indexing-api/src/com/intellij/psi/search/searches/MethodReferencesSearch.java
index f13ae0f..5dd9726 100644
--- a/java/java-indexing-api/src/com/intellij/psi/search/searches/MethodReferencesSearch.java
+++ b/java/java-indexing-api/src/com/intellij/psi/search/searches/MethodReferencesSearch.java
@@ -38,7 +38,7 @@
private final SearchRequestCollector myOptimizer;
private final boolean isSharedOptimizer;
- public SearchParameters(PsiMethod method, SearchScope scope, boolean strictSignatureSearch, @Nullable SearchRequestCollector optimizer) {
+ public SearchParameters(@NotNull PsiMethod method, @NotNull SearchScope scope, boolean strictSignatureSearch, @Nullable SearchRequestCollector optimizer) {
myMethod = method;
myScope = scope;
myStrictSignatureSearch = strictSignatureSearch;
@@ -46,10 +46,11 @@
myOptimizer = optimizer != null ? optimizer : new SearchRequestCollector(new SearchSession());
}
- public SearchParameters(final PsiMethod aClass, SearchScope scope, final boolean strict) {
- this(aClass, scope, strict, null);
+ public SearchParameters(@NotNull PsiMethod method, @NotNull SearchScope scope, final boolean strict) {
+ this(method, scope, strict, null);
}
+ @NotNull
public PsiMethod getMethod() {
return myMethod;
}
@@ -62,6 +63,7 @@
return myOptimizer;
}
+ @NotNull
public SearchScope getScope() {
return myScope;
}
@@ -69,7 +71,7 @@
private MethodReferencesSearch() {}
- public static Query<PsiReference> search(final PsiMethod method, SearchScope scope, final boolean strictSignatureSearch) {
+ public static Query<PsiReference> search(@NotNull PsiMethod method, SearchScope scope, final boolean strictSignatureSearch) {
return search(new SearchParameters(method, scope, strictSignatureSearch));
}
diff --git a/java/java-indexing-impl/java-indexing-impl.iml b/java/java-indexing-impl/java-indexing-impl.iml
index 0379d94..bd58ec0 100644
--- a/java/java-indexing-impl/java-indexing-impl.iml
+++ b/java/java-indexing-impl/java-indexing-impl.iml
@@ -11,9 +11,9 @@
<orderEntry type="module" module-name="java-psi-impl" exported="" />
<orderEntry type="module" module-name="indexing-api" exported="" />
<orderEntry type="module" module-name="indexing-impl" exported="" />
- <orderEntry type="module" module-name="projectModel-api" />
+ <orderEntry type="module" module-name="projectModel-api" exported="" />
<orderEntry type="module" module-name="projectModel-impl" />
- <orderEntry type="module" module-name="java-indexing-api" />
+ <orderEntry type="module" module-name="java-indexing-api" exported="" />
</component>
</module>
diff --git a/java/java-impl/src/com/intellij/codeInsight/ConditionCheckManager.java b/java/java-indexing-impl/src/com/intellij/codeInsight/ConditionCheckManager.java
similarity index 91%
rename from java/java-impl/src/com/intellij/codeInsight/ConditionCheckManager.java
rename to java/java-indexing-impl/src/com/intellij/codeInsight/ConditionCheckManager.java
index f7edb1e..1fec41c 100644
--- a/java/java-impl/src/com/intellij/codeInsight/ConditionCheckManager.java
+++ b/java/java-indexing-impl/src/com/intellij/codeInsight/ConditionCheckManager.java
@@ -40,14 +40,14 @@
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) private State state;
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.ConditionCheckManager");
- private List<ConditionChecker> myIsNullCheckMethods = new ArrayList<ConditionChecker>();
- private List<ConditionChecker> myIsNotNullCheckMethods = new ArrayList<ConditionChecker>();
+ private final List<ConditionChecker> myIsNullCheckMethods = new ArrayList<ConditionChecker>();
+ private final List<ConditionChecker> myIsNotNullCheckMethods = new ArrayList<ConditionChecker>();
- private List<ConditionChecker> myAssertIsNullMethods = new ArrayList<ConditionChecker>();
- private List<ConditionChecker> myAssertIsNotNullMethods = new ArrayList<ConditionChecker>();
+ private final List<ConditionChecker> myAssertIsNullMethods = new ArrayList<ConditionChecker>();
+ private final List<ConditionChecker> myAssertIsNotNullMethods = new ArrayList<ConditionChecker>();
- private List<ConditionChecker> myAssertTrueMethods = new ArrayList<ConditionChecker>();
- private List<ConditionChecker> myAssertFalseMethods = new ArrayList<ConditionChecker>();
+ private final List<ConditionChecker> myAssertTrueMethods = new ArrayList<ConditionChecker>();
+ private final List<ConditionChecker> myAssertFalseMethods = new ArrayList<ConditionChecker>();
public static ConditionCheckManager getInstance(Project project) {
return ServiceManager.getService(project, ConditionCheckManager.class);
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java
index 2aad613..600bfc0 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java
@@ -1,5 +1,8 @@
package com.intellij.psi.impl.search;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ReadActionProcessor;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.TextRange;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
@@ -12,6 +15,7 @@
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.PairProcessor;
import com.intellij.util.Processor;
+import org.jetbrains.annotations.NotNull;
/**
* @author max
@@ -19,31 +23,30 @@
public class ConstructorReferencesSearchHelper {
private final PsiManager myManager;
- public ConstructorReferencesSearchHelper(final PsiManager manager) {
+ public ConstructorReferencesSearchHelper(@NotNull PsiManager manager) {
myManager = manager;
}
- public boolean processConstructorReferences(final Processor<PsiReference> processor,
- final PsiMethod constructor,
- final SearchScope searchScope,
+ public boolean processConstructorReferences(@NotNull final Processor<PsiReference> processor,
+ @NotNull final PsiMethod constructor,
+ @NotNull final PsiClass containingClass,
+ @NotNull final SearchScope searchScope,
boolean ignoreAccessScope,
- final boolean isStrictSignatureSearch, SearchRequestCollector collector) {
- PsiClass aClass = constructor.getContainingClass();
- if (aClass == null) {
- return true;
- }
-
- if (aClass.isEnum()) {
- for (PsiField field : aClass.getFields()) {
- if (field instanceof PsiEnumConstant) {
- PsiReference reference = field.getReference();
- if (reference != null && reference.isReferenceTo(constructor)) {
- if (!processor.process(reference)) {
- return false;
- }
- }
- }
+ final boolean isStrictSignatureSearch,
+ @NotNull SearchRequestCollector collector) {
+ final boolean[] constructorCanBeCalledImplicitly = new boolean[1];
+ final boolean[] isEnum = new boolean[1];
+ final boolean[] isUnder18 = new boolean[1];
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ public void run() {
+ constructorCanBeCalledImplicitly[0] = constructor.getParameterList().getParametersCount() == 0;
+ isEnum[0] = containingClass.isEnum();
+ isUnder18[0] = PsiUtil.getLanguageLevel(containingClass).isAtLeast(LanguageLevel.JDK_1_8);
}
+ });
+
+ if (isEnum[0]) {
+ if (!processEnumReferences(processor, constructor, containingClass)) return false;
}
// search usages like "new XXX(..)"
@@ -63,7 +66,7 @@
}
}
else {
- if (myManager.areElementsEquivalent(constructor.getContainingClass(), constructor1.getContainingClass())) {
+ if (myManager.areElementsEquivalent(containingClass, constructor1.getContainingClass())) {
return processor.process(reference);
}
}
@@ -73,30 +76,18 @@
}
};
- ReferencesSearch.searchOptimized(aClass, searchScope, ignoreAccessScope, collector, true, processor1);
- if (PsiUtil.getLanguageLevel(aClass).isAtLeast(LanguageLevel.JDK_1_8)) {
- ReferencesSearch.search(aClass).forEach(new Processor<PsiReference>() {
- @Override
- public boolean process(PsiReference reference) {
- final PsiElement element = reference.getElement();
- if (element != null) {
- final PsiElement parent = element.getParent();
- if (parent instanceof PsiMethodReferenceExpression &&
- ((PsiMethodReferenceExpression)parent).getReferenceNameElement() instanceof PsiKeyword) {
- if (((PsiMethodReferenceExpression)parent).isReferenceTo(constructor)) {
- processor.process((PsiReference)parent);
- }
- }
- }
- return true;
- }
- });
+ ReferencesSearch.searchOptimized(containingClass, searchScope, ignoreAccessScope, collector, true, processor1);
+ if (isUnder18[0]) {
+ if (!process18MethodPointers(processor, constructor, containingClass)) return false;
}
- final boolean constructorCanBeCalledImplicitly = constructor.getParameterList().getParametersCount() == 0;
// search usages like "this(..)"
- if (!processSuperOrThis(processor, aClass, constructor, constructorCanBeCalledImplicitly, searchScope, isStrictSignatureSearch,
- PsiKeyword.THIS)) {
+ if (!ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ public Boolean compute() {
+ return processSuperOrThis(containingClass, constructor, constructorCanBeCalledImplicitly[0], searchScope, isStrictSignatureSearch,
+ PsiKeyword.THIS, processor);
+ }
+ })) {
return false;
}
@@ -104,22 +95,69 @@
Processor<PsiClass> processor2 = new Processor<PsiClass>() {
@Override
public boolean process(PsiClass inheritor) {
- return processSuperOrThis(processor, (PsiClass)inheritor.getNavigationElement(), constructor, constructorCanBeCalledImplicitly, searchScope, isStrictSignatureSearch,
- PsiKeyword.SUPER);
+ final PsiElement navigationElement = inheritor.getNavigationElement();
+ if (navigationElement instanceof PsiClass) {
+ return processSuperOrThis((PsiClass)navigationElement, constructor, constructorCanBeCalledImplicitly[0], searchScope,
+ isStrictSignatureSearch, PsiKeyword.SUPER, processor);
+ }
+ return true;
}
};
- return ClassInheritorsSearch.search(aClass, searchScope, false).forEach(processor2);
+ return ClassInheritorsSearch.search(containingClass, searchScope, false).forEach(processor2);
}
- private boolean processSuperOrThis(final Processor<PsiReference> processor,
- final PsiClass inheritor,
- final PsiMethod constructor, final boolean constructorCanBeCalledImplicitly, final SearchScope searchScope,
- final boolean isStrictSignatureSearch,
- final String superOrThisKeyword) {
+ private static boolean processEnumReferences(@NotNull final Processor<PsiReference> processor,
+ @NotNull final PsiMethod constructor,
+ @NotNull final PsiClass aClass) {
+ return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ public Boolean compute() {
+ for (PsiField field : aClass.getFields()) {
+ if (field instanceof PsiEnumConstant) {
+ PsiReference reference = field.getReference();
+ if (reference != null && reference.isReferenceTo(constructor)) {
+ if (!processor.process(reference)) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+ });
+ }
+
+ private static boolean process18MethodPointers(@NotNull final Processor<PsiReference> processor,
+ @NotNull final PsiMethod constructor,
+ @NotNull PsiClass aClass) {
+ return ReferencesSearch.search(aClass).forEach(new ReadActionProcessor<PsiReference>() {
+ @Override
+ public boolean processInReadAction(PsiReference reference) {
+ final PsiElement element = reference.getElement();
+ if (element != null) {
+ final PsiElement parent = element.getParent();
+ if (parent instanceof PsiMethodReferenceExpression &&
+ ((PsiMethodReferenceExpression)parent).getReferenceNameElement() instanceof PsiKeyword) {
+ if (((PsiMethodReferenceExpression)parent).isReferenceTo(constructor)) {
+ if (!processor.process((PsiReference)parent)) return false;
+ }
+ }
+ }
+ return true;
+ }
+ });
+ }
+
+ private boolean processSuperOrThis(@NotNull PsiClass inheritor,
+ @NotNull PsiMethod constructor,
+ final boolean constructorCanBeCalledImplicitly,
+ @NotNull SearchScope searchScope,
+ final boolean isStrictSignatureSearch,
+ @NotNull String superOrThisKeyword,
+ @NotNull Processor<PsiReference> processor) {
PsiMethod[] constructors = inheritor.getConstructors();
if (constructors.length == 0 && constructorCanBeCalledImplicitly) {
- processImplicitConstructorCall(inheritor, processor, constructor, inheritor);
+ if (!processImplicitConstructorCall(inheritor, processor, constructor, inheritor)) return false;
}
for (PsiMethod method : constructors) {
PsiCodeBlock body = method.getBody();
@@ -134,7 +172,7 @@
if (expr instanceof PsiMethodCallExpression) {
PsiReferenceExpression refExpr = ((PsiMethodCallExpression)expr).getMethodExpression();
if (PsiSearchScopeUtil.isInScope(searchScope, refExpr)) {
- if (refExpr.getText().equals(superOrThisKeyword)) {
+ if (refExpr.textMatches(superOrThisKeyword)) {
PsiElement referencedElement = refExpr.resolve();
if (referencedElement instanceof PsiMethod) {
PsiMethod constructor1 = (PsiMethod)referencedElement;
@@ -151,43 +189,48 @@
}
}
if (constructorCanBeCalledImplicitly) {
- processImplicitConstructorCall(method, processor, constructor, inheritor);
+ if (!processImplicitConstructorCall(method, processor, constructor, inheritor)) return false;
}
}
return true;
}
- private void processImplicitConstructorCall(final PsiMember usage,
- final Processor<PsiReference> processor,
- final PsiMethod constructor,
- final PsiClass containingClass) {
- if (containingClass instanceof PsiAnonymousClass) return;
- PsiClass superClass = containingClass.getSuperClass();
- if (myManager.areElementsEquivalent(constructor.getContainingClass(), superClass)) {
- processor.process(new LightMemberReference(myManager, usage, PsiSubstitutor.EMPTY) {
- @Override
- public PsiElement getElement() {
- return usage;
- }
-
- @Override
- public TextRange getRangeInElement() {
- if (usage instanceof PsiClass) {
- PsiIdentifier identifier = ((PsiClass)usage).getNameIdentifier();
- if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
- }
- else if (usage instanceof PsiField) {
- PsiIdentifier identifier = ((PsiField)usage).getNameIdentifier();
- return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
- }
- else if (usage instanceof PsiMethod) {
- PsiIdentifier identifier = ((PsiMethod)usage).getNameIdentifier();
- if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
- }
- return super.getRangeInElement();
- }
- });
+ private boolean processImplicitConstructorCall(@NotNull final PsiMember usage,
+ @NotNull final Processor<PsiReference> processor,
+ @NotNull final PsiMethod constructor,
+ @NotNull final PsiClass containingClass) {
+ if (containingClass instanceof PsiAnonymousClass) return true;
+ boolean same = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ public Boolean compute() {
+ return myManager.areElementsEquivalent(constructor.getContainingClass(), containingClass.getSuperClass());
+ }
+ });
+ if (!same) {
+ return true;
}
+ return processor.process(new LightMemberReference(myManager, usage, PsiSubstitutor.EMPTY) {
+ @Override
+ public PsiElement getElement() {
+ return usage;
+ }
+
+ @Override
+ public TextRange getRangeInElement() {
+ if (usage instanceof PsiClass) {
+ PsiIdentifier identifier = ((PsiClass)usage).getNameIdentifier();
+ if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
+ }
+ else if (usage instanceof PsiField) {
+ PsiIdentifier identifier = ((PsiField)usage).getNameIdentifier();
+ return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
+ }
+ else if (usage instanceof PsiMethod) {
+ PsiIdentifier identifier = ((PsiMethod)usage).getNameIdentifier();
+ if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
+ }
+ return super.getRangeInElement();
+ }
+ });
}
}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearcher.java
index 933a748..5bc07cb 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearcher.java
@@ -1,9 +1,9 @@
package com.intellij.psi.impl.search;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.QueryExecutorBase;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiReference;
+import com.intellij.openapi.util.Computable;
+import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
@@ -12,16 +12,26 @@
* @author max
*/
public class ConstructorReferencesSearcher extends QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters> {
- public ConstructorReferencesSearcher() {
- super(true);
- }
-
@Override
public void processQuery(@NotNull ReferencesSearch.SearchParameters p, @NotNull Processor<PsiReference> consumer) {
final PsiElement element = p.getElementToSearch();
- if (element instanceof PsiMethod && ((PsiMethod)element).isConstructor()) {
- new ConstructorReferencesSearchHelper(element.getManager())
- .processConstructorReferences(consumer, (PsiMethod)p.getElementToSearch(), p.getScope(), p.isIgnoreAccessScope(), true, p.getOptimizer());
+ if (!(element instanceof PsiMethod)) {
+ return;
}
+ final PsiMethod method = (PsiMethod)element;
+ final PsiManager[] manager = new PsiManager[1];
+ PsiClass aClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+ public PsiClass compute() {
+ if (!method.isConstructor()) return null;
+ PsiClass aClass = method.getContainingClass();
+ manager[0] = aClass == null ? null : aClass.getManager();
+ return aClass;
+ }
+ });
+ if (aClass == null) {
+ return;
+ }
+ new ConstructorReferencesSearchHelper(manager[0])
+ .processConstructorReferences(consumer, method, aClass, p.getScope(), p.isIgnoreAccessScope(), true, p.getOptimizer());
}
}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
index 49bd3f3..ec298ce 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
@@ -1,7 +1,8 @@
package com.intellij.psi.impl.search;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.QueryExecutorBase;
-import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.search.SearchRequestCollector;
@@ -17,66 +18,77 @@
* @author max
*/
public class MethodUsagesSearcher extends QueryExecutorBase<PsiReference, MethodReferencesSearch.SearchParameters> {
- private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.MethodUsagesSearcher");
- public MethodUsagesSearcher() {
- super(true);
- }
-
@Override
public void processQuery(@NotNull MethodReferencesSearch.SearchParameters p, @NotNull final Processor<PsiReference> consumer) {
final PsiMethod method = p.getMethod();
+ final boolean[] isConstructor = new boolean[1];
+ final PsiManager[] psiManager = new PsiManager[1];
+ final String[] methodName = new String[1];
+ final boolean[] isValueAnnotation = new boolean[1];
+ final boolean[] needStrictSignatureSearch = new boolean[1];
+ final boolean strictSignatureSearch = p.isStrictSignatureSearch();
+
+ final PsiClass aClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+ public PsiClass compute() {
+ PsiClass aClass = method.getContainingClass();
+ if (aClass == null) return null;
+ isConstructor[0] = method.isConstructor();
+ psiManager[0] = aClass.getManager();
+ methodName[0] = method.getName();
+ isValueAnnotation[0] = PsiUtil.isAnnotationMethod(method) &&
+ PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(methodName[0]) &&
+ method.getParameterList().getParametersCount() == 0;
+ needStrictSignatureSearch[0] = strictSignatureSearch && (aClass instanceof PsiAnonymousClass
+ || aClass.hasModifierProperty(PsiModifier.FINAL)
+ || method.hasModifierProperty(PsiModifier.STATIC)
+ || method.hasModifierProperty(PsiModifier.FINAL)
+ || method.hasModifierProperty(PsiModifier.PRIVATE));
+ return aClass;
+ }
+ });
+ if (aClass == null) return;
+
final SearchRequestCollector collector = p.getOptimizer();
final SearchScope searchScope = p.getScope();
- final PsiManager psiManager = method.getManager();
-
- final PsiClass aClass = method.getContainingClass();
- if (aClass == null) return;
-
- final boolean strictSignatureSearch = p.isStrictSignatureSearch();
-
- if (method.isConstructor()) {
- new ConstructorReferencesSearchHelper(psiManager).
- processConstructorReferences(consumer, method, searchScope, !strictSignatureSearch, strictSignatureSearch, collector);
+ if (isConstructor[0]) {
+ new ConstructorReferencesSearchHelper(psiManager[0]).
+ processConstructorReferences(consumer, method, aClass, searchScope, !strictSignatureSearch, strictSignatureSearch, collector);
}
- if (PsiUtil.isAnnotationMethod(method) &&
- PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(method.getName()) &&
- method.getParameterList().getParametersCount() == 0) {
- ReferencesSearch.search(aClass, p.getScope()).forEach(PsiAnnotationMethodReferencesSearcher.createImplicitDefaultAnnotationMethodConsumer( consumer));
+ if (isValueAnnotation[0]) {
+ Processor<PsiReference> refProcessor = PsiAnnotationMethodReferencesSearcher.createImplicitDefaultAnnotationMethodConsumer(consumer);
+ ReferencesSearch.search(aClass, searchScope).forEach(refProcessor);
}
- boolean needStrictSignatureSearch = strictSignatureSearch && (aClass instanceof PsiAnonymousClass
- || aClass.hasModifierProperty(PsiModifier.FINAL)
- || method.hasModifierProperty(PsiModifier.STATIC)
- || method.hasModifierProperty(PsiModifier.FINAL)
- || method.hasModifierProperty(PsiModifier.PRIVATE));
- if (needStrictSignatureSearch) {
+ if (needStrictSignatureSearch[0]) {
ReferencesSearch.searchOptimized(method, searchScope, false, collector, consumer);
return;
}
- final String textToSearch = method.getName();
- if (StringUtil.isEmpty(textToSearch)) {
+ if (StringUtil.isEmpty(methodName[0])) {
return;
}
- final PsiMethod[] methods = strictSignatureSearch ? new PsiMethod[]{method} : aClass.findMethodsByName(textToSearch, false);
- SearchScope accessScope = methods[0].getUseScope();
- for (int i = 1; i < methods.length; i++) {
- PsiMethod method1 = methods[i];
- accessScope = accessScope.union(method1.getUseScope());
- }
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ public void run() {
+ final PsiMethod[] methods = strictSignatureSearch ? new PsiMethod[]{method} : aClass.findMethodsByName(methodName[0], false);
+ SearchScope accessScope = methods[0].getUseScope();
+ for (int i = 1; i < methods.length; i++) {
+ PsiMethod method1 = methods[i];
+ accessScope = accessScope.union(method1.getUseScope());
+ }
- final SearchScope restrictedByAccess = searchScope.intersectWith(accessScope);
+ SearchScope restrictedByAccessScope = searchScope.intersectWith(accessScope);
- short searchContext = UsageSearchContext.IN_CODE | UsageSearchContext.IN_COMMENTS | UsageSearchContext.IN_FOREIGN_LANGUAGES;
- collector.searchWord(textToSearch, restrictedByAccess, searchContext, true,
- new MethodTextOccurrenceProcessor(aClass, strictSignatureSearch, methods));
+ short searchContext = UsageSearchContext.IN_CODE | UsageSearchContext.IN_COMMENTS | UsageSearchContext.IN_FOREIGN_LANGUAGES;
+ collector.searchWord(methodName[0], restrictedByAccessScope, searchContext, true,
+ new MethodTextOccurrenceProcessor(aClass, strictSignatureSearch, methods));
- SimpleAccessorReferenceSearcher.addPropertyAccessUsages(method, restrictedByAccess, collector);
-
+ SimpleAccessorReferenceSearcher.addPropertyAccessUsages(method, restrictedByAccessScope, collector);
+ }
+ });
}
}
diff --git a/java/java-psi-api/java-psi-api.iml b/java/java-psi-api/java-psi-api.iml
index 4256838..caff682 100644
--- a/java/java-psi-api/java-psi-api.iml
+++ b/java/java-psi-api/java-psi-api.iml
@@ -8,7 +8,6 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="core-api" exported="" />
- <orderEntry type="module" module-name="projectModel-api" />
</component>
</module>
diff --git a/java/java-psi-api/src/com/intellij/pom/java/LanguageLevel.java b/java/java-psi-api/src/com/intellij/pom/java/LanguageLevel.java
index 9774133..e980c0a 100644
--- a/java/java-psi-api/src/com/intellij/pom/java/LanguageLevel.java
+++ b/java/java-psi-api/src/com/intellij/pom/java/LanguageLevel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -17,6 +17,8 @@
import com.intellij.core.JavaCoreBundle;
import com.intellij.openapi.util.Key;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -35,38 +37,22 @@
private final String myPresentableText;
- private LanguageLevel(final String presentableText) {
+ LanguageLevel(@NotNull @Nls String presentableText) {
myPresentableText = presentableText;
}
- /** @deprecated (to remove in IDEA 13) */
- @SuppressWarnings("UnusedDeclaration")
- public int getIndex() {
- return ordinal() + 3; // solely for backward compatibility
- }
-
- /** @deprecated (to remove in IDEA 13) */
- @SuppressWarnings("UnusedDeclaration")
- public boolean hasAssertKeyword() {
- return isAtLeast(JDK_1_4);
- }
-
- /** @deprecated use {@linkplain com.intellij.psi.util.PsiUtil#isLanguageLevel5OrHigher(com.intellij.psi.PsiElement)} (to remove in IDEA 13) */
- @SuppressWarnings("UnusedDeclaration")
- public boolean hasEnumKeywordAndAutoboxing() {
- return isAtLeast(JDK_1_5);
- }
-
+ @NotNull
+ @Nls
public String getPresentableText() {
return myPresentableText;
}
- public boolean isAtLeast(final LanguageLevel level) {
+ public boolean isAtLeast(@NotNull LanguageLevel level) {
return compareTo(level) >= 0;
}
@Nullable
- public static LanguageLevel parse(final String value) {
+ public static LanguageLevel parse(@Nullable String value) {
if ("1.3".equals(value)) return JDK_1_3;
if ("1.4".equals(value)) return JDK_1_4;
if ("1.5".equals(value)) return JDK_1_5;
diff --git a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
index f2a6236..7c25697 100644
--- a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
@@ -16,6 +16,7 @@
package com.intellij.psi;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.search.GlobalSearchScope;
@@ -47,6 +48,7 @@
if (TypeConversionUtil.isPrimitiveAndNotNull(type1) || TypeConversionUtil.isPrimitiveAndNotNull(type2)) return null;
if (TypeConversionUtil.isNullType(type1)) return type2;
if (TypeConversionUtil.isNullType(type2)) return type1;
+ if (Comparing.equal(type1, type2)) return type1;
return getLeastUpperBound(type1, type2, new LinkedHashSet<Pair<PsiType, PsiType>>(), manager);
}
diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
index d669624..ab97463 100644
--- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
@@ -789,6 +789,18 @@
return null;
}
+ public static boolean isValidQualifier4InterfaceStaticMethodCall(@NotNull PsiMethod method, @NotNull PsiReferenceExpression methodReferenceExpression) {
+ if (PsiUtil.isLanguageLevel8OrHigher(methodReferenceExpression)) {
+ final PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression();
+ final PsiClass containingClass = method.getContainingClass();
+ if (containingClass != null && containingClass.isInterface() && method.hasModifierProperty(PsiModifier.STATIC)) {
+ return qualifierExpression == null && PsiTreeUtil.isAncestor(containingClass, methodReferenceExpression, true)||
+ qualifierExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifierExpression).resolve() == containingClass;
+ }
+ }
+ return true;
+ }
+
static class TypeParamsChecker extends PsiTypeVisitor<Boolean> {
private PsiMethod myMethod;
private final PsiClass myClass;
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java b/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java
index 85fae45..6fe40d8 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java
@@ -99,7 +99,7 @@
}
else {
return bound instanceof PsiCapturedWildcardType
- ? ((PsiCapturedWildcardType)bound).getUpperBound()
+ ? PsiWildcardType.createSuper(myContext.getManager(), ((PsiCapturedWildcardType)bound).getUpperBound())
: PsiType.getJavaLangObject(myContext.getManager(), getResolveScope());
}
}
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiJavaCodeReferenceElement.java b/java/java-psi-api/src/com/intellij/psi/PsiJavaCodeReferenceElement.java
index a0eaeae..f32eb81 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiJavaCodeReferenceElement.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiJavaCodeReferenceElement.java
@@ -23,7 +23,7 @@
* Represents a reference found in Java code (either an identifier or a sequence of identifiers
* separated by periods, optionally with generic type arguments).
*/
-public interface PsiJavaCodeReferenceElement extends PsiJavaReference, PsiQualifiedReference {
+public interface PsiJavaCodeReferenceElement extends PsiJavaReference, PsiQualifiedReferenceElement {
/**
* The empty array of PSI Java code references which can be reused to avoid unnecessary allocations.
*/
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
index b051604..c5b282c 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
@@ -19,6 +19,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.util.*;
+import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -165,7 +166,12 @@
if (interfaceReturnType == PsiType.VOID) return true;
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (resolve == JavaPsiFacade.getElementFactory(resolve.getProject()).getArrayClass(PsiUtil.getLanguageLevel(resolve))) {
- if (parameters.length != 1 || parameters[0].getType() != PsiType.INT) return false;
+ if (!arrayCompatibleSignature(parameters, new Function<PsiParameter[], PsiType>() {
+ @Override
+ public PsiType fun(PsiParameter[] parameters) {
+ return resolveResult.getSubstitutor().substitute(parameters[0].getType());
+ }
+ })) return false;
final PsiTypeParameter[] typeParameters = ((PsiClass)resolve).getTypeParameters();
if (typeParameters.length == 1) {
final PsiType arrayComponentType = result.getSubstitutor().substitute(typeParameters[0]);
@@ -281,7 +287,12 @@
public static boolean onArrayType(PsiClass containingClass, MethodSignature signature) {
- if (signature.getParameterTypes().length == 1 && signature.getParameterTypes()[0] == PsiType.INT) {
+ if (arrayCompatibleSignature(signature.getParameterTypes(), new Function<PsiType[], PsiType>() {
+ @Override
+ public PsiType fun(PsiType[] types) {
+ return types[0];
+ }
+ })) {
if (containingClass != null) {
final Project project = containingClass.getProject();
final LanguageLevel level = PsiUtil.getLanguageLevel(containingClass);
@@ -291,6 +302,14 @@
return false;
}
+ private static <T> boolean arrayCompatibleSignature(T[] paramTypes, Function<T[], PsiType> fun) {
+ if (paramTypes.length == 1) {
+ final PsiType paramType = fun.fun(paramTypes);
+ if (paramType != null && TypeConversionUtil.isAssignable(PsiType.INT, paramType)) return true;
+ }
+ return false;
+ }
+
private static PsiType getExpandedType(PsiType type, @NotNull PsiElement typeElement) {
if (type instanceof PsiArrayType) {
type = JavaPsiFacade.getElementFactory(typeElement.getProject()).getArrayClassType(((PsiArrayType)type).getComponentType(),
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiTemplateStatement.java b/java/java-psi-api/src/com/intellij/psi/PsiTemplateStatement.java
new file mode 100644
index 0000000..3aa87c0
--- /dev/null
+++ b/java/java-psi-api/src/com/intellij/psi/PsiTemplateStatement.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2000-2013 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.psi;
+
+public interface PsiTemplateStatement extends PsiStatement {
+}
diff --git a/java/openapi/src/com/intellij/psi/SmartTypePointer.java b/java/java-psi-api/src/com/intellij/psi/SmartTypePointer.java
similarity index 100%
rename from java/openapi/src/com/intellij/psi/SmartTypePointer.java
rename to java/java-psi-api/src/com/intellij/psi/SmartTypePointer.java
diff --git a/java/openapi/src/com/intellij/psi/SmartTypePointerManager.java b/java/java-psi-api/src/com/intellij/psi/SmartTypePointerManager.java
similarity index 100%
rename from java/openapi/src/com/intellij/psi/SmartTypePointerManager.java
rename to java/java-psi-api/src/com/intellij/psi/SmartTypePointerManager.java
diff --git a/java/java-psi-api/src/com/intellij/psi/util/PropertyUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PropertyUtil.java
index 6452f52..9bb742f 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/PropertyUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/PropertyUtil.java
@@ -626,4 +626,256 @@
}
return null;
}
+
+ public static PsiMethod findSetterForField(PsiField field) {
+ final PsiClass containingClass = field.getContainingClass();
+ final Project project = field.getProject();
+ final String propertyName = suggestPropertyName(project, field);
+ final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
+ return findPropertySetter(containingClass, propertyName, isStatic, true);
+ }
+
+ public static PsiMethod findGetterForField(PsiField field) {
+ final PsiClass containingClass = field.getContainingClass();
+ final Project project = field.getProject();
+ final String propertyName = suggestPropertyName(project, field);
+ final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
+ return findPropertyGetter(containingClass, propertyName, isStatic, true);
+ }
+
+ /**
+ * If the name of the method looks like a getter and the body consists of a single return statement,
+ * returns the returned expression. Otherwise, returns null.
+ *
+ * @param method the method to check
+ * @return the return value, or null if it doesn't match the condotions.
+ */
+@Nullable
+public static PsiExpression getGetterReturnExpression(PsiMethod method) {
+ return method != null && hasGetterSignature(method) ? getSingleReturnValue(method) : null;
+}
+
+ private static boolean hasGetterSignature(@NotNull PsiMethod method) {
+ return isSimplePropertyGetter(method) && !method.hasModifierProperty(PsiModifier.SYNCHRONIZED);
+}
+
+ @Nullable
+public static PsiExpression getSingleReturnValue(@NotNull PsiMethod method) {
+ final PsiCodeBlock body = method.getBody();
+ if (body == null) {
+ return null;
+ }
+ final PsiStatement[] statements = body.getStatements();
+ final PsiStatement statement = statements.length != 1 ? null : statements[0];
+ return statement instanceof PsiReturnStatement ? ((PsiReturnStatement)statement).getReturnValue() : null;
+}
+
+ @Nullable
+public static PsiField getFieldOfGetter(PsiMethod method) {
+ PsiField field = getSimplyReturnedField(method, getGetterReturnExpression(method));
+ if (field != null) {
+ final PsiType returnType = method.getReturnType();
+ if (returnType != null && field.getType().equalsToText(returnType.getCanonicalText())) {
+ return field;
+ }
+ }
+ return null;
+}
+
+ @Nullable
+public static PsiField getSimplyReturnedField(PsiMethod method, @Nullable PsiExpression value) {
+ if (!(value instanceof PsiReferenceExpression)) {
+ return null;
+ }
+
+ final PsiReferenceExpression reference = (PsiReferenceExpression)value;
+ if (hasSubstantialQualifier(reference)) {
+ return null;
+ }
+
+ final PsiElement referent = reference.resolve();
+ if (!(referent instanceof PsiField)) {
+ return null;
+ }
+
+ final PsiField field = (PsiField)referent;
+ return InheritanceUtil.isInheritorOrSelf(method.getContainingClass(), field.getContainingClass(), true) ? field : null;
+}
+
+ private static boolean hasSubstantialQualifier(PsiReferenceExpression reference) {
+ final PsiExpression qualifier = reference.getQualifierExpression();
+ if (qualifier == null) return false;
+
+ if (qualifier instanceof PsiThisExpression || qualifier instanceof PsiSuperExpression) {
+ return false;
+ }
+
+ if (qualifier instanceof PsiReferenceExpression) {
+ return !(((PsiReferenceExpression)qualifier).resolve() instanceof PsiClass);
+ }
+ return true;
+}
+
+ public static boolean isSimpleGetter(PsiMethod method) {
+ return getFieldOfGetter(method) != null;
+}
+
+ @Nullable
+public static PsiField getFieldOfSetter(PsiMethod method) {
+ if (method == null) {
+ return null;
+ }
+ final PsiParameterList parameterList = method.getParameterList();
+ if (parameterList.getParametersCount() != 1) {
+ return null;
+ }
+ @NonNls final String name = method.getName();
+ if (!name.startsWith("set")) {
+ return null;
+ }
+ if (method.hasModifierProperty(PsiModifier.SYNCHRONIZED)) {
+ return null;
+ }
+ final PsiCodeBlock body = method.getBody();
+ if (body == null) {
+ return null;
+ }
+ final PsiStatement[] statements = body.getStatements();
+ if (statements.length != 1) {
+ return null;
+ }
+ final PsiStatement statement = statements[0];
+ if (!(statement instanceof PsiExpressionStatement)) {
+ return null;
+ }
+ final PsiExpressionStatement possibleAssignmentStatement = (PsiExpressionStatement)statement;
+ final PsiExpression possibleAssignment = possibleAssignmentStatement.getExpression();
+ if (!(possibleAssignment instanceof PsiAssignmentExpression)) {
+ return null;
+ }
+ final PsiAssignmentExpression assignment = (PsiAssignmentExpression)possibleAssignment;
+ if (!JavaTokenType.EQ.equals(assignment.getOperationTokenType())) {
+ return null;
+ }
+ final PsiExpression lhs = assignment.getLExpression();
+ if (!(lhs instanceof PsiReferenceExpression)) {
+ return null;
+ }
+ final PsiReferenceExpression reference = (PsiReferenceExpression)lhs;
+ final PsiExpression qualifier = reference.getQualifierExpression();
+ if (qualifier instanceof PsiReferenceExpression) {
+ final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)qualifier;
+ final PsiElement target = referenceExpression.resolve();
+ if (!(target instanceof PsiClass)) {
+ return null;
+ }
+ }
+ else if (qualifier != null && !(qualifier instanceof PsiThisExpression) && !(qualifier instanceof PsiSuperExpression)) {
+ return null;
+ }
+ final PsiElement referent = reference.resolve();
+ if (referent == null) {
+ return null;
+ }
+ if (!(referent instanceof PsiField)) {
+ return null;
+ }
+ final PsiField field = (PsiField)referent;
+ final PsiClass fieldContainingClass = field.getContainingClass();
+ final PsiClass methodContainingClass = method.getContainingClass();
+ if (!InheritanceUtil.isInheritorOrSelf(methodContainingClass, fieldContainingClass, true)) {
+ return null;
+ }
+ final PsiExpression rhs = assignment.getRExpression();
+ if (!(rhs instanceof PsiReferenceExpression)) {
+ return null;
+ }
+ final PsiReferenceExpression rReference = (PsiReferenceExpression)rhs;
+ final PsiExpression rQualifier = rReference.getQualifierExpression();
+ if (rQualifier != null) {
+ return null;
+ }
+ final PsiElement rReferent = rReference.resolve();
+ if (rReferent == null) {
+ return null;
+ }
+ if (!(rReferent instanceof PsiParameter)) {
+ return null;
+ }
+ final PsiType fieldType = field.getType();
+ final PsiType parameterType = ((PsiVariable)rReferent).getType();
+ if (fieldType.equalsToText(parameterType.getCanonicalText())) {
+ return field;
+ }
+ else {
+ return null;
+ }
+}
+
+ public static boolean isSimpleSetter(PsiMethod method) {
+ return getFieldOfSetter(method) != null;
+}
+
+ @Nullable
+public static PsiMethod getReversePropertyMethod(PsiMethod propertyMethod) {
+ if (propertyMethod == null) {
+ return null;
+ }
+ final PsiClass aClass = propertyMethod.getContainingClass();
+ if (aClass == null) {
+ return null;
+ }
+ final String methodName = propertyMethod.getName();
+ final String prefix;
+ if (methodName.startsWith("get")) {
+ prefix = "get";
+ }
+ else if (methodName.startsWith("is")) {
+ prefix = "is";
+ }
+ else if (methodName.startsWith("set")) {
+ prefix = "set";
+ }
+ else {
+ return null;
+ }
+ final String name = methodName.substring(prefix.length());
+ final PsiField field;
+ if (prefix.equals("set")) {
+ field = getFieldOfSetter(propertyMethod);
+ }
+ else {
+ field = getFieldOfGetter(propertyMethod);
+ }
+ if (field == null) {
+ return null;
+ }
+ if (prefix.equals("set")) {
+ final PsiMethod result = findPropertyMethod(aClass, "get", name, field);
+ if (result != null) {
+ return result;
+ }
+ return findPropertyMethod(aClass, "is", name, field);
+ }
+ else {
+ return findPropertyMethod(aClass, "set", name, field);
+ }
+}
+
+ private static PsiMethod findPropertyMethod(@NotNull PsiClass aClass, @NotNull String prefix, @NotNull String propertyName, @NotNull PsiField field1) {
+ final PsiMethod[] methods = aClass.findMethodsByName(prefix + propertyName, true);
+ for (PsiMethod method : methods) {
+ final PsiField field2;
+ if (prefix.equals("set")) {
+ field2 = getFieldOfSetter(method);
+ }
+ else {
+ field2 = getFieldOfGetter(method);
+ }
+ if (field1.equals(field2)) {
+ return method;
+ }
+ }
+ return null;
+}
}
diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
index b0f7d45..386490d 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
@@ -467,7 +467,7 @@
if (args.length < parms.length - 1) return ApplicabilityLevel.NOT_APPLICABLE;
final PsiClass containingClass = method.getContainingClass();
- final boolean isRaw = containingClass != null && isRawSubstitutor(containingClass, substitutorForMethod);
+ final boolean isRaw = containingClass != null && isRawSubstitutor(method, substitutorForMethod) && isRawSubstitutor(containingClass, substitutorForMethod);
if (!areFirstArgumentsApplicable(args, parms, languageLevel, substitutorForMethod, isRaw)) return ApplicabilityLevel.NOT_APPLICABLE;
if (args.length == parms.length) {
if (parms.length == 0) return ApplicabilityLevel.FIXED_ARITY;
@@ -839,21 +839,29 @@
@NotNull
public static LanguageLevel getLanguageLevel(@NotNull PsiElement element) {
- if (element instanceof PsiDirectory) return JavaDirectoryService.getInstance().getLanguageLevel((PsiDirectory)element);
- final PsiFile file = element.getContainingFile();
- if (file == null) {
- LanguageLevelProjectExtension instance = LanguageLevelProjectExtension.getInstance(element.getProject());
- return instance == null ? LanguageLevel.HIGHEST : instance.getLanguageLevel();
+ if (element instanceof PsiDirectory) {
+ return JavaDirectoryService.getInstance().getLanguageLevel((PsiDirectory)element);
}
- if (!(file instanceof PsiJavaFile)) {
- final PsiElement context = file.getContext();
- if (context != null) return getLanguageLevel(context);
- LanguageLevelProjectExtension instance = LanguageLevelProjectExtension.getInstance(file.getProject());
- return instance == null ? LanguageLevel.HIGHEST : instance.getLanguageLevel();
+ PsiFile file = element.getContainingFile();
+ if (file instanceof PsiJavaFile) {
+ return ((PsiJavaFile)file).getLanguageLevel();
}
- return ((PsiJavaFile)file).getLanguageLevel();
+ if (file != null) {
+ PsiElement context = file.getContext();
+ if (context != null) {
+ return getLanguageLevel(context);
+ }
+ }
+
+ return getLanguageLevel(element.getProject());
+ }
+
+ @NotNull
+ public static LanguageLevel getLanguageLevel(@NotNull Project project) {
+ LanguageLevelProjectExtension instance = LanguageLevelProjectExtension.getInstance(project);
+ return instance != null ? instance.getLanguageLevel() : LanguageLevel.HIGHEST;
}
public static boolean isInstantiatable(@NotNull PsiClass clazz) {
diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java b/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java
index df1be58..7ad51b2 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java
@@ -146,7 +146,7 @@
if (superBoundClass instanceof PsiTypeParameter) return false;
return !InheritanceUtil.isInheritorOrSelf(superBoundClass, extendsBoundClass, true);
}
- return true;
+ return provablyDistinct(extendsBound, superBound);
}
if (!type1.isBounded() || !type2.isBounded()) {
diff --git a/java/openapi/src/com/intellij/util/VisibilityUtil.java b/java/java-psi-api/src/com/intellij/util/VisibilityUtil.java
similarity index 92%
rename from java/openapi/src/com/intellij/util/VisibilityUtil.java
rename to java/java-psi-api/src/com/intellij/util/VisibilityUtil.java
index ed44304..373e5be 100644
--- a/java/openapi/src/com/intellij/util/VisibilityUtil.java
+++ b/java/java-psi-api/src/com/intellij/util/VisibilityUtil.java
@@ -19,7 +19,7 @@
* User: dsl
* Date: 07.06.2002
* Time: 18:48:01
- * To change template for new class use
+ * To change template for new class use
* Code Style | Class Templates options (Tools | IDE Options).
*/
package com.intellij.util;
@@ -28,7 +28,6 @@
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
-import com.intellij.usageView.UsageInfo;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
@@ -46,7 +45,7 @@
}
public static int compare(@PsiModifier.ModifierConstant String v1, @PsiModifier.ModifierConstant String v2) {
- return ArrayUtil.find(visibilityModifiers, v2) - ArrayUtil.find(visibilityModifiers, v1);
+ return ArrayUtilRt.find(visibilityModifiers, v2) - ArrayUtilRt.find(visibilityModifiers, v1);
}
@PsiModifier.ModifierConstant
@@ -123,11 +122,10 @@
return PsiBundle.visibilityPresentation(modifier);
}
- public static void fixVisibility(UsageInfo[] usageInfos, PsiMember member, @PsiModifier.ModifierConstant String newVisibility) {
+ public static void fixVisibility(PsiElement[] elements, PsiMember member, @PsiModifier.ModifierConstant String newVisibility) {
if (newVisibility == null) return;
if (ESCALATE_VISIBILITY.equals(newVisibility)) {
- for (UsageInfo info : usageInfos) {
- final PsiElement element = info.getElement();
+ for (PsiElement element : elements) {
if (element != null) {
escalateVisibility(member, element);
}
diff --git a/java/java-psi-impl/java-psi-impl.iml b/java/java-psi-impl/java-psi-impl.iml
index 8fa9e62..a53ad4d 100644
--- a/java/java-psi-impl/java-psi-impl.iml
+++ b/java/java-psi-impl/java-psi-impl.iml
@@ -11,8 +11,7 @@
<orderEntry type="module" module-name="core-impl" exported="" />
<orderEntry type="module" module-name="resources-en" />
<orderEntry type="library" name="asm4" level="project" />
- <orderEntry type="module" module-name="openapi" />
- <orderEntry type="module" module-name="external-system-api" />
+ <orderEntry type="module" module-name="indexing-api" />
</component>
</module>
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java b/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
index 4b3be84..1045dcd 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
@@ -18,8 +18,10 @@
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.java.parser.JavaParser;
import com.intellij.lang.java.parser.JavaParserUtil;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.JDOMUtil;
@@ -43,6 +45,7 @@
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
+import java.io.StringWriter;
import java.util.*;
import java.util.concurrent.ConcurrentMap;
@@ -184,84 +187,104 @@
private final ConcurrentMap<PsiFile, Pair<MostlySingularMultiMap<String, AnnotationData>, Long>> annotationFileToDataAndModStamp = new ConcurrentSoftHashMap<PsiFile, Pair<MostlySingularMultiMap<String, AnnotationData>, Long>>();
@NotNull
- private MostlySingularMultiMap<String, AnnotationData> getDataFromFile(@NotNull PsiFile file) {
+ private MostlySingularMultiMap<String, AnnotationData> getDataFromFile(@NotNull final PsiFile file) {
Pair<MostlySingularMultiMap<String, AnnotationData>, Long> cached = annotationFileToDataAndModStamp.get(file);
- if (cached != null && cached.getSecond() == file.getModificationStamp()) {
+ final long fileModificationStamp = file.getModificationStamp();
+ if (cached != null && cached.getSecond() == fileModificationStamp) {
return cached.getFirst();
}
MostlySingularMultiMap<String, AnnotationData> data = new MostlySingularMultiMap<String, AnnotationData>();
try {
Document document = JDOMUtil.loadDocument(escapeAttributes(file.getText()));
Element rootElement = document.getRootElement();
- if (rootElement != null) {
- boolean sorted = true;
- boolean modified = false;
- String prevItemName = null;
//noinspection unchecked
- for (Element element : (List<Element>) rootElement.getChildren("item")) {
- String externalName = element.getAttributeValue("name");
- if (externalName == null) {
- element.detach();
- modified = true;
- continue;
- }
- if (prevItemName != null && prevItemName.compareTo(externalName) > 0) {
- sorted = false;
- }
- prevItemName = externalName;
-
- //noinspection unchecked
- for (Element annotationElement : (List<Element>) element.getChildren("annotation")) {
- String annotationFQN = annotationElement.getAttributeValue("name");
- if (StringUtil.isEmpty(annotationFQN)) continue;
- annotationFQN = intern(annotationFQN);
- //noinspection unchecked
- List<Element> children = (List<Element>)annotationElement.getChildren();
- StringBuilder buf = new StringBuilder(children.size() * "name=value,".length()); // just guess
- for (Element annotationParameter : children) {
- if (buf.length() != 0) {
- buf.append(",");
- }
- String nameValue = annotationParameter.getAttributeValue("name");
- if (nameValue != null) {
- buf.append(nameValue);
- buf.append("=");
- }
- buf.append(annotationParameter.getAttributeValue("val"));
- }
- String annotationParameters = buf.length() == 0 ? "" : intern(buf.toString());
- for (AnnotationData existingData : data.get(externalName)) {
- if (existingData.annotationClassFqName.equals(annotationFQN)) {
- LOG.error("Duplicate annotation '" + annotationFQN+"' for signature: '" + externalName + "' in the file " + file.getVirtualFile().getPresentableUrl());
- }
- }
- AnnotationData annData = internAnnotationData(new AnnotationData(annotationFQN, annotationParameters, file.getVirtualFile()));
-
- data.add(externalName, annData);
- }
- }
- if (!sorted) {
+ List<Element> itemElements = rootElement == null ? Collections.<Element>emptyList() : (List<Element>)rootElement.getChildren("item");
+ boolean sorted = true;
+ boolean modified = false;
+ String prevItemName = null;
+ for (Element element : itemElements) {
+ String externalName = element.getAttributeValue("name");
+ if (externalName == null) {
+ element.detach();
modified = true;
- List<Element> items = new ArrayList<Element>(rootElement.getChildren("item"));
- rootElement.removeChildren("item");
- Collections.sort(items, new Comparator<Element>() {
- @Override
- public int compare(Element item1, Element item2) {
- String externalName1 = item1.getAttributeValue("name");
- String externalName2 = item2.getAttributeValue("name");
- return externalName1.compareTo(externalName2);
+ continue;
+ }
+ if (prevItemName != null && prevItemName.compareTo(externalName) > 0) {
+ sorted = false;
+ }
+ prevItemName = externalName;
+
+ //noinspection unchecked
+ for (Element annotationElement : (List<Element>) element.getChildren("annotation")) {
+ String annotationFQN = annotationElement.getAttributeValue("name");
+ if (StringUtil.isEmpty(annotationFQN)) continue;
+ annotationFQN = intern(annotationFQN);
+ //noinspection unchecked
+ List<Element> children = (List<Element>)annotationElement.getChildren();
+ StringBuilder buf = new StringBuilder(children.size() * "name=value,".length()); // just guess
+ for (Element annotationParameter : children) {
+ if (buf.length() != 0) {
+ buf.append(",");
}
- });
- for (Element item : items) {
- rootElement.addContent(item);
+ String nameValue = annotationParameter.getAttributeValue("name");
+ if (nameValue != null) {
+ buf.append(nameValue);
+ buf.append("=");
+ }
+ buf.append(annotationParameter.getAttributeValue("val"));
}
+ String annotationParameters = buf.length() == 0 ? "" : intern(buf.toString());
+ for (AnnotationData existingData : data.get(externalName)) {
+ if (existingData.annotationClassFqName.equals(annotationFQN)) {
+ duplicateError(file, externalName, "Duplicate annotation '" + annotationFQN + "' ");
+ }
+ }
+ AnnotationData annData = internAnnotationData(new AnnotationData(annotationFQN, annotationParameters, file.getVirtualFile()));
+
+ data.add(externalName, annData);
}
- VirtualFile virtualFile = file.getVirtualFile();
- if (modified && virtualFile.isInLocalFileSystem() && virtualFile.isWritable()) {
- String lineSeparator = FileDocumentManager.getInstance().getLineSeparator(virtualFile, file.getProject());
- JDOMUtil.writeDocument(document, virtualFile.getPath(), lineSeparator);
+ }
+ if (!sorted) {
+ modified = true;
+ List<Element> items = new ArrayList<Element>(rootElement.getChildren("item"));
+ rootElement.removeChildren("item");
+ Collections.sort(items, new Comparator<Element>() {
+ @Override
+ public int compare(Element item1, Element item2) {
+ String externalName1 = item1.getAttributeValue("name");
+ String externalName2 = item2.getAttributeValue("name");
+ return externalName1.compareTo(externalName2);
+ }
+ });
+ for (Element item : items) {
+ rootElement.addContent(item);
}
}
+ final VirtualFile virtualFile = file.getVirtualFile();
+ if (modified && virtualFile.isInLocalFileSystem() && virtualFile.isWritable()) {
+ final Project project = file.getProject();
+ final FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
+ final StringWriter string = new StringWriter(file.getTextLength());
+ JDOMUtil.writeDocument(document, string, "\n");
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ if (file.getModificationStamp() == fileModificationStamp && !fileDocumentManager.isFileModified(virtualFile)) {
+ // modify .xml in write action to avoid conflicts and torn reads
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ com.intellij.openapi.editor.Document editorDoc = PsiDocumentManager.getInstance(project).getDocument(file);
+ if (editorDoc != null) {
+ editorDoc.setText(string.toString());
+ fileDocumentManager.saveDocument(editorDoc);
+ }
+ }
+ });
+ }
+ }
+ }, project.getDisposed());
+ }
}
catch (IOException e) {
LOG.error(e);
@@ -279,6 +302,10 @@
return data;
}
+ protected void duplicateError(@NotNull PsiFile file, @NotNull String externalName, @NotNull String text) {
+ LOG.error(text + "; for signature: '" + externalName + "' in the file " + file.getVirtualFile().getPresentableUrl());
+ }
+
@NotNull
private String intern(@NotNull String annotationFQN) {
synchronized (charTable) {
@@ -315,7 +342,7 @@
return result;
}
- private static void addAnnotations(@NotNull List<AnnotationData> result,
+ private void addAnnotations(@NotNull List<AnnotationData> result,
@NotNull String externalName,
@NotNull PsiFile file,
@NotNull MostlySingularMultiMap<String, AnnotationData> fileData) {
@@ -324,7 +351,7 @@
if (result.contains(ad)) {
// there can be compatible annotations in different files
if (Comparing.equal(ad.virtualFile, file.getVirtualFile())) {
- LOG.error("Duplicate signature: '" + externalName + "'; in " + file.getVirtualFile());
+ duplicateError(file, externalName, "Duplicate signature");
}
}
else {
diff --git a/java/java-impl/src/com/intellij/codeInsight/ConditionChecker.java b/java/java-psi-impl/src/com/intellij/codeInsight/ConditionChecker.java
similarity index 96%
rename from java/java-impl/src/com/intellij/codeInsight/ConditionChecker.java
rename to java/java-psi-impl/src/com/intellij/codeInsight/ConditionChecker.java
index de3871d..22769dd 100644
--- a/java/java-impl/src/com/intellij/codeInsight/ConditionChecker.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/ConditionChecker.java
@@ -56,7 +56,7 @@
* Creation Date: 8/14/12
*/
public class ConditionChecker implements Serializable {
- private final @NotNull Type myConditionCheckType;
+ @NotNull private final Type myConditionCheckType;
public enum Type {
IS_NULL_METHOD("IsNull Method"),
@@ -77,9 +77,9 @@
}
}
- private final @NotNull String myClassName;
- private final @NotNull String myMethodName;
- private final @NotNull List<String> myParameterClassList;
+ @NotNull private final String myClassName;
+ @NotNull private final String myMethodName;
+ @NotNull private final List<String> myParameterClassList;
private final int myCheckedParameterIndex;
private final String myFullName;
@@ -217,8 +217,8 @@
static class FromConfigBuilder extends Builder {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.ConditionCheck.FromConfigBuilder");
- private final @NotNull String serializedRepresentation;
- private final @NotNull Type type;
+ @NotNull private final String serializedRepresentation;
+ @NotNull private final Type type;
FromConfigBuilder(@NotNull String serializedRepresentation, @NotNull Type type) {
this.serializedRepresentation = serializedRepresentation;
@@ -265,7 +265,7 @@
throw new IllegalArgumentException(
"Name should contain 1+ parameter (between opening and closing parenthesis). " + serializedRepresentation);
}
- else if (allParametersSubString.contains("*") && allParametersSubString.indexOf("*") == allParametersSubString.lastIndexOf("*")) {
+ if (allParametersSubString.contains("*") && allParametersSubString.indexOf("*") == allParametersSubString.lastIndexOf("*")) {
throw new IllegalArgumentException("Selected Parameter should be surrounded by asterisks. " + serializedRepresentation);
}
@@ -303,9 +303,9 @@
public static class FromPsiBuilder extends Builder {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.ConditionCheck.FromPsiBuilder");
- private final @NotNull PsiMethod psiMethod;
- private final @NotNull PsiParameter psiParameter;
- private final @NotNull Type type;
+ @NotNull private final PsiMethod psiMethod;
+ @NotNull private final PsiParameter psiParameter;
+ @NotNull private final Type type;
public FromPsiBuilder(@NotNull PsiMethod psiMethod, @NotNull PsiParameter psiParameter, @NotNull Type type) {
this.psiMethod = psiMethod;
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/JavaPsiEquivalenceUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/JavaPsiEquivalenceUtil.java
new file mode 100644
index 0000000..7308203
--- /dev/null
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/JavaPsiEquivalenceUtil.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2013 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.codeInsight;
+
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.PsiDiamondTypeElementImpl;
+
+import java.util.Comparator;
+
+public class JavaPsiEquivalenceUtil {
+ public static boolean areExpressionsEquivalent(PsiExpression expr1, PsiExpression expr2) {
+ return PsiEquivalenceUtil.areElementsEquivalent(expr1, expr2, new Comparator<PsiElement>() {
+ @Override
+ public int compare(PsiElement o1, PsiElement o2) {
+ if (o1 instanceof PsiParameter && o2 instanceof PsiParameter && ((PsiParameter)o1).getDeclarationScope() instanceof PsiMethod) {
+ return ((PsiParameter)o1).getName().compareTo(((PsiParameter)o2).getName());
+ }
+ return 1;
+ }
+ }, new Comparator<PsiElement>() {
+ @Override
+ public int compare(PsiElement o1, PsiElement o2) {
+ if (!o1.textMatches(o2)) return 1;
+
+ if (o1 instanceof PsiDiamondTypeElementImpl && o2 instanceof PsiDiamondTypeElementImpl) {
+ final PsiDiamondType.DiamondInferenceResult thisInferenceResult = new PsiDiamondTypeImpl(o1.getManager(), (PsiTypeElement)o1).resolveInferredTypes();
+ final PsiDiamondType.DiamondInferenceResult otherInferenceResult = new PsiDiamondTypeImpl(o2.getManager(), (PsiTypeElement)o2).resolveInferredTypes();
+ return thisInferenceResult.equals(otherInferenceResult) ? 0 : 1;
+ }
+ return 0;
+ }
+ }, null, false);
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/TestFrameworksImpl.java b/java/java-psi-impl/src/com/intellij/codeInsight/TestFrameworksImpl.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInsight/TestFrameworksImpl.java
rename to java/java-psi-impl/src/com/intellij/codeInsight/TestFrameworksImpl.java
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java
rename to java/java-psi-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java
index b34be36..608d539 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java
@@ -625,11 +625,12 @@
}
private void addCodeBlockFolds(PsiElement scope, final List<FoldingDescriptor> foldElements,
- final @NotNull Set<PsiElement> processedComments, final Document document, final boolean quick)
- {
+ final @NotNull Set<PsiElement> processedComments, final Document document, final boolean quick) {
+ final boolean dumb = DumbService.isDumb(scope.getProject());
scope.accept(new JavaRecursiveElementWalkingVisitor() {
- @Override public void visitClass(PsiClass aClass) {
- if (!addClosureFolding(aClass, document, foldElements, processedComments, quick)) {
+ @Override
+ public void visitClass(PsiClass aClass) {
+ if (dumb || !addClosureFolding(aClass, document, foldElements, processedComments, quick)) {
addToFold(foldElements, aClass, document, true);
addElementsToFold(foldElements, aClass, document, false, quick);
}
@@ -637,14 +638,18 @@
@Override
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
- addMethodGenericParametersFolding(expression, foldElements, document, quick);
+ if (!dumb) {
+ addMethodGenericParametersFolding(expression, foldElements, document, quick);
+ }
super.visitMethodCallExpression(expression);
}
@Override
public void visitNewExpression(PsiNewExpression expression) {
- addGenericParametersFolding(expression, foldElements, document, quick);
+ if (!dumb) {
+ addGenericParametersFolding(expression, foldElements, document, quick);
+ }
super.visitNewExpression(expression);
}
@@ -659,7 +664,7 @@
private boolean addClosureFolding(final PsiClass aClass, final Document document, final List<FoldingDescriptor> foldElements,
@NotNull Set<PsiElement> processedComments, final boolean quick) {
- if (!JavaCodeFoldingSettings.getInstance().isCollapseLambdas() || DumbService.isDumb(aClass.getProject())) {
+ if (!JavaCodeFoldingSettings.getInstance().isCollapseLambdas()) {
return false;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java
index 1177603..c315644 100644
--- a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java
@@ -405,6 +405,14 @@
if (parent instanceof PsiClass) {
final PsiClass clss = (PsiClass)parent;
if (PsiTreeUtil.isAncestor(targetClassMember, clss, false)) return false;
+ PsiClass containingClass = PsiTreeUtil.getParentOfType(ref, PsiClass.class);
+ while (containingClass != null) {
+ if (containingClass.isInheritor(clss, true) &&
+ PsiTreeUtil.isAncestor(targetClassMember, containingClass, false)) {
+ return false;
+ }
+ containingClass = containingClass.getContainingClass();
+ }
}
}
diff --git a/java/java-impl/src/com/intellij/psi/controlFlow/DefUseUtil.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/DefUseUtil.java
similarity index 99%
rename from java/java-impl/src/com/intellij/psi/controlFlow/DefUseUtil.java
rename to java/java-psi-impl/src/com/intellij/psi/controlFlow/DefUseUtil.java
index 658164e..cfe3620 100644
--- a/java/java-impl/src/com/intellij/psi/controlFlow/DefUseUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/controlFlow/DefUseUtil.java
@@ -20,7 +20,7 @@
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.containers.IntArrayList;
import com.intellij.util.containers.Queue;
import gnu.trove.THashSet;
@@ -435,7 +435,7 @@
}
}
new Inner ().traverse (elem);
- return PsiUtilBase.toPsiElementArray(res);
+ return PsiUtilCore.toPsiElementArray(res);
}
return PsiElement.EMPTY_ARRAY;
}
diff --git a/java/java-impl/src/com/intellij/psi/controlFlow/LocalsControlFlowPolicy.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/LocalsControlFlowPolicy.java
similarity index 100%
rename from java/java-impl/src/com/intellij/psi/controlFlow/LocalsControlFlowPolicy.java
rename to java/java-psi-impl/src/com/intellij/psi/controlFlow/LocalsControlFlowPolicy.java
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/ElementPresentationUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/ElementPresentationUtil.java
index 517bd7e..11ee141 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/ElementPresentationUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/ElementPresentationUtil.java
@@ -140,9 +140,9 @@
if (TestFrameworks.getInstance().isTestClass(aClass)) {
return CLASS_KIND_JUNIT_TEST;
}
- }
- if (PsiClassUtil.isRunnableClass(aClass, false) && PsiMethodUtil.findMainMethod(aClass) != null) {
- return CLASS_KIND_RUNNABLE;
+ if (PsiClassUtil.isRunnableClass(aClass, false) && PsiMethodUtil.findMainMethod(aClass) != null) {
+ return CLASS_KIND_RUNNABLE;
+ }
}
return CLASS_KIND_CLASS;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java
index c16225b..f80a099 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java
@@ -36,6 +36,7 @@
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.reference.SoftReference;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.Processor;
import com.intellij.util.SmartList;
@@ -58,11 +59,10 @@
private PsiElementFinder[] myElementFinders; //benign data race
private final PsiNameHelper myNameHelper;
private final PsiConstantEvaluationHelper myConstantEvaluationHelper;
- private final ConcurrentMap<String, PsiPackage> myPackageCache = new ConcurrentHashMap<String, PsiPackage>();
+ private volatile SoftReference<ConcurrentMap<String, PsiPackage>> myPackageCache;
private final Project myProject;
private final JavaFileManager myFileManager;
-
public JavaPsiFacadeImpl(Project project,
PsiManagerImpl psiManager,
JavaFileManager javaFileManager,
@@ -83,7 +83,7 @@
final long now = modificationTracker.getJavaStructureModificationCount();
if (lastTimeSeen != now) {
lastTimeSeen = now;
- myPackageCache.clear();
+ myPackageCache = null;
}
}
});
@@ -177,7 +177,13 @@
@Override
public PsiPackage findPackage(@NotNull String qualifiedName) {
- PsiPackage aPackage = myPackageCache.get(qualifiedName);
+ SoftReference<ConcurrentMap<String, PsiPackage>> ref = myPackageCache;
+ ConcurrentMap<String, PsiPackage> cache = ref == null ? null : ref.get();
+ if (cache == null) {
+ myPackageCache = new SoftReference<ConcurrentMap<String, PsiPackage>>(cache = new ConcurrentHashMap<String, PsiPackage>());
+ }
+
+ PsiPackage aPackage = cache.get(qualifiedName);
if (aPackage != null) {
return aPackage;
}
@@ -185,7 +191,7 @@
for (PsiElementFinder finder : filteredFinders()) {
aPackage = finder.findPackage(qualifiedName);
if (aPackage != null) {
- return ConcurrencyUtil.cacheOrGet(myPackageCache, qualifiedName, aPackage);
+ return ConcurrencyUtil.cacheOrGet(cache, qualifiedName, aPackage);
}
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java
similarity index 98%
rename from java/java-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java
rename to java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java
index 7d11223..8539b55 100644
--- a/java/java-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java
@@ -39,7 +39,7 @@
public static boolean canCollapseToDiamond(final PsiNewExpression expression,
final PsiNewExpression context,
- final @Nullable PsiType expectedType) {
+ @Nullable final PsiType expectedType) {
return canCollapseToDiamond(expression, context, expectedType, false);
}
@@ -50,7 +50,7 @@
private static boolean canCollapseToDiamond(final PsiNewExpression expression,
final PsiNewExpression context,
- final @Nullable PsiType expectedType,
+ @Nullable final PsiType expectedType,
boolean skipDiamonds) {
if (PsiUtil.getLanguageLevel(context).isAtLeast(LanguageLevel.JDK_1_7)) {
final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
index 62df787..90f63f6 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
@@ -432,7 +432,7 @@
public PsiSubstitutor put(@NotNull PsiTypeParameter typeParameter, PsiType mapping) {
PsiSubstitutorImpl ret = clone();
if (mapping != null && !mapping.isValid()) {
- LOG.error("Invalid type in substitutor: " + mapping);
+ LOG.error("Invalid type in substitutor: " + mapping + "; " + mapping.getClass());
}
ret.mySubstitutionMap.put(typeParameter, mapping);
return ret;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/cache/TypeInfo.java b/java/java-psi-impl/src/com/intellij/psi/impl/cache/TypeInfo.java
index d9d3b06..2adc6f1 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/cache/TypeInfo.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/cache/TypeInfo.java
@@ -65,8 +65,10 @@
"null",
"short",
"void",
- CommonClassNames.JAVA_LANG_OBJECT_SHORT, CommonClassNames.JAVA_LANG_OBJECT,
- CommonClassNames.JAVA_LANG_STRING_SHORT, CommonClassNames.JAVA_LANG_STRING
+ CommonClassNames.JAVA_LANG_OBJECT_SHORT,
+ CommonClassNames.JAVA_LANG_OBJECT,
+ CommonClassNames.JAVA_LANG_STRING_SHORT,
+ CommonClassNames.JAVA_LANG_STRING
};
ourFrequentTypeIndex = new TObjectIntHashMap<String>();
@@ -273,11 +275,11 @@
buf.append("...");
}
- return buf.toString();
+ return internFrequentType(buf.toString());
}
@NotNull
- private static String internFrequentType(@NotNull String type) {
+ public static String internFrequentType(@NotNull String type) {
int frequentIndex = ourFrequentTypeIndex.get(type);
return frequentIndex == 0 ? type : ourIndexFrequentType[frequentIndex];
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java
index 118af69..466a53c 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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,19 +23,25 @@
import com.intellij.psi.stubs.PsiFileStub;
import com.intellij.psi.stubs.StubElement;
import com.intellij.util.cls.ClsFormatException;
+import com.intellij.util.indexing.FileContent;
/**
* @author max
*/
public class ClassFileStubBuilder implements BinaryFileStubBuilder {
+ public static final int STUB_VERSION = JavaFileElementType.STUB_VERSION + 6;
+
@Override
public boolean acceptsFile(final VirtualFile file) {
return true;
}
@Override
- public StubElement buildStubTree(final VirtualFile file, final byte[] content, final Project project) {
+ public StubElement buildStubTree(FileContent fileContent) {
try {
+ VirtualFile file = fileContent.getFile();
+ Project project = fileContent.getProject();
+ byte[] content = fileContent.getContent();
final ClsStubBuilderFactory[] factories = Extensions.getExtensions(ClsStubBuilderFactory.EP_NAME);
for (ClsStubBuilderFactory factory : factories) {
if (!factory.isInnerClass(file) && factory.canBeProcessed(file, content)) {
@@ -52,6 +58,6 @@
@Override
public int getStubVersion() {
- return JavaFileElementType.STUB_VERSION + 6;
+ return STUB_VERSION;
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsAnnotationImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsAnnotationImpl.java
index c0d9ca7..3cdc7df 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsAnnotationImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsAnnotationImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -15,6 +15,8 @@
*/
package com.intellij.psi.impl.compiled;
+import com.intellij.openapi.util.AtomicNotNullLazyValue;
+import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.pom.Navigatable;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
@@ -33,16 +35,32 @@
* @author ven
*/
public class ClsAnnotationImpl extends ClsRepositoryPsiElement<PsiAnnotationStub> implements PsiAnnotation, Navigatable {
- private ClsJavaCodeReferenceElementImpl myReferenceElement;
- private ClsAnnotationParameterListImpl myParameterList;
+ private final NotNullLazyValue<ClsJavaCodeReferenceElementImpl> myReferenceElement;
+ private final NotNullLazyValue<ClsAnnotationParameterListImpl> myParameterList;
public ClsAnnotationImpl(final PsiAnnotationStub stub) {
super(stub);
+ myReferenceElement = new AtomicNotNullLazyValue<ClsJavaCodeReferenceElementImpl>() {
+ @NotNull
+ @Override
+ protected ClsJavaCodeReferenceElementImpl compute() {
+ String text = PsiTreeUtil.getRequiredChildOfType(getStub().getPsiElement(), PsiJavaCodeReferenceElement.class).getText();
+ return new ClsJavaCodeReferenceElementImpl(ClsAnnotationImpl.this, text);
+ }
+ };
+ myParameterList = new AtomicNotNullLazyValue<ClsAnnotationParameterListImpl>() {
+ @NotNull
+ @Override
+ protected ClsAnnotationParameterListImpl compute() {
+ PsiAnnotationParameterList paramList = PsiTreeUtil.getRequiredChildOfType(getStub().getPsiElement(), PsiAnnotationParameterList.class);
+ return new ClsAnnotationParameterListImpl(ClsAnnotationImpl.this, paramList.getAttributes());
+ }
+ };
}
@Override
public void appendMirrorText(int indentLevel, @NotNull StringBuilder buffer) {
- buffer.append("@").append(getReferenceElement().getCanonicalText());
+ buffer.append("@").append(myReferenceElement.getValue().getCanonicalText());
appendText(getParameterList(), indentLevel, buffer);
}
@@ -57,7 +75,7 @@
@Override
@NotNull
public PsiElement[] getChildren() {
- return new PsiElement[]{getReferenceElement(), getParameterList()};
+ return new PsiElement[]{myReferenceElement.getValue(), getParameterList()};
}
@Override
@@ -73,25 +91,18 @@
@Override
@NotNull
public PsiAnnotationParameterList getParameterList() {
- synchronized (LAZY_BUILT_LOCK) {
- if (myParameterList == null) {
- PsiAnnotationParameterList paramList = PsiTreeUtil.getRequiredChildOfType(getStub().getPsiElement(), PsiAnnotationParameterList.class);
- myParameterList = new ClsAnnotationParameterListImpl(this, paramList.getAttributes());
- }
- return myParameterList;
- }
+ return myParameterList.getValue();
}
@Override
@Nullable
public String getQualifiedName() {
- if (getReferenceElement() == null) return null;
- return getReferenceElement().getCanonicalText();
+ return myReferenceElement.getValue().getCanonicalText();
}
@Override
public PsiJavaCodeReferenceElement getNameReferenceElement() {
- return getReferenceElement();
+ return myReferenceElement.getValue();
}
@Override
@@ -122,17 +133,6 @@
return MetaRegistry.getMetaBase(this);
}
- private ClsJavaCodeReferenceElementImpl getReferenceElement() {
- synchronized (LAZY_BUILT_LOCK) {
- if (myReferenceElement == null) {
- String text = PsiTreeUtil.getRequiredChildOfType(getStub().getPsiElement(), PsiJavaCodeReferenceElement.class).getText();
- myReferenceElement = new ClsJavaCodeReferenceElementImpl(this, text);
- }
-
- return myReferenceElement;
- }
- }
-
@Override
public PsiAnnotationOwner getOwner() {
return (PsiAnnotationOwner)getParent();//todo
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsElementImpl.java
index 060ed38..5f55a5b 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsElementImpl.java
@@ -42,7 +42,6 @@
public abstract class ClsElementImpl extends PsiElementBase implements PsiCompiledElement {
public static final Key<PsiCompiledElement> COMPILED_ELEMENT = Key.create("COMPILED_ELEMENT");
- protected static final Object LAZY_BUILT_LOCK = new String("lazy cls tree initialization lock");
protected static final String CAN_NOT_MODIFY_MESSAGE = JavaCoreBundle.message("psi.error.attempt.to.edit.class.file");
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsElementImpl");
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFieldImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFieldImpl.java
index 55d35bd..0a3091f 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFieldImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFieldImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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,7 +18,7 @@
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.ItemPresentationProviders;
import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.*;
import com.intellij.psi.*;
import com.intellij.psi.impl.*;
import com.intellij.psi.impl.cache.TypeInfo;
@@ -33,17 +33,36 @@
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Set;
public class ClsFieldImpl extends ClsMemberImpl<PsiFieldStub> implements PsiField, PsiVariableEx, ClsModifierListOwner {
- private PsiTypeElement myType = null;
- private PsiExpression myInitializer = null;
- private boolean myInitializerInitialized = false;
+ private final NotNullLazyValue<PsiTypeElement> myType;
+ private final NullableLazyValue<PsiExpression> myInitializer;
public ClsFieldImpl(@NotNull PsiFieldStub stub) {
super(stub);
+ myType = new AtomicNotNullLazyValue<PsiTypeElement>() {
+ @NotNull
+ @Override
+ protected PsiTypeElement compute() {
+ PsiFieldStub stub = getStub();
+ String typeText = TypeInfo.createTypeText(stub.getType(false));
+ assert typeText != null : stub;
+ return new ClsTypeElementImpl(ClsFieldImpl.this, typeText, ClsTypeElementImpl.VARIANCE_NONE);
+ }
+ };
+ myInitializer = new VolatileNullableLazyValue<PsiExpression>() {
+ @Nullable
+ @Override
+ protected PsiExpression compute() {
+ String initializerText = getStub().getInitializerText();
+ return initializerText != null && !Comparing.equal(PsiFieldStub.INITIALIZER_TOO_LONG, initializerText) ?
+ ClsParsingUtil.createExpressionFromText(initializerText, getManager(), ClsFieldImpl.this) : null;
+ }
+ };
}
@Override
@@ -66,15 +85,7 @@
@Override
@NotNull
public PsiTypeElement getTypeElement() {
- synchronized (LAZY_BUILT_LOCK) {
- if (myType == null) {
- PsiFieldStub stub = getStub();
- String typeText = TypeInfo.createTypeText(stub.getType(false));
- assert typeText != null : stub;
- myType = new ClsTypeElementImpl(this, typeText, ClsTypeElementImpl.VARIANCE_NONE);
- }
- return myType;
- }
+ return myType.getValue();
}
@Override
@@ -89,17 +100,7 @@
@Override
public PsiExpression getInitializer() {
- synchronized (LAZY_BUILT_LOCK) {
- if (!myInitializerInitialized) {
- myInitializerInitialized = true;
- String initializerText = getStub().getInitializerText();
- if (initializerText != null && !Comparing.equal(PsiFieldStub.INITIALIZER_TOO_LONG, initializerText)) {
- myInitializer = ClsParsingUtil.createExpressionFromText(initializerText, getManager(), this);
- }
- }
-
- return myInitializer;
- }
+ return myInitializer.getValue();
}
@Override
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java
index 1920043..0565534 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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,7 +31,10 @@
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
-import com.intellij.psi.impl.*;
+import com.intellij.psi.impl.JavaPsiImplementationHelper;
+import com.intellij.psi.impl.PsiFileEx;
+import com.intellij.psi.impl.PsiManagerEx;
+import com.intellij.psi.impl.PsiManagerImpl;
import com.intellij.psi.impl.java.stubs.PsiClassStub;
import com.intellij.psi.impl.java.stubs.impl.PsiJavaFileStubImpl;
import com.intellij.psi.impl.source.PsiFileImpl;
@@ -42,22 +45,27 @@
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.stubs.*;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.reference.SoftReference;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import java.lang.ref.SoftReference;
-import java.util.*;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
-public class ClsFileImpl extends ClsRepositoryPsiElement<PsiClassHolderFileStub> implements PsiJavaFile, PsiFileWithStubSupport, PsiFileEx,
- Queryable, PsiClassOwnerEx, PsiCompiledFile {
+import static com.intellij.reference.SoftReference.dereference;
+
+public class ClsFileImpl extends ClsRepositoryPsiElement<PsiClassHolderFileStub>
+ implements PsiJavaFile, PsiFileWithStubSupport, PsiFileEx, Queryable, PsiClassOwnerEx, PsiCompiledFile {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsFileImpl");
- /** YOU absolutely MUST NOT hold PsiLock under the MIRROR_LOCK */
- private static final MirrorLock MIRROR_LOCK = new MirrorLock();
- private static class MirrorLock {}
+ /** NOTE: you absolutely MUST NOT hold PsiLock under the mirror lock */
+ private final Object myMirrorLock = new Object();
+ private final Object myStubLock = new Object();
private final PsiManagerImpl myManager;
private final boolean myIsForDecompiling;
@@ -73,7 +81,7 @@
myManager = manager;
myIsForDecompiling = forDecompiling;
myViewProvider = viewProvider;
- JavaElementType.CLASS.getIndex(); // Initialize java stubs...
+ JavaElementType.CLASS.getIndex(); // initialize Java stubs
}
public ClsFileImpl(PsiManagerImpl manager, FileViewProvider viewProvider) {
@@ -207,8 +215,7 @@
@Override
@NotNull
public LanguageLevel getLanguageLevel() {
- final List stubs = getStub().getChildrenStubs();
- return stubs.size() > 0 ? ((PsiClassStub<?>)stubs.get(0)).getLanguageLevel() : LanguageLevel.HIGHEST;
+ return LanguageLevel.HIGHEST; // library classes should inherit language level from modules where they are referenced
}
@Override
@@ -270,43 +277,45 @@
@Override
public PsiElement getMirror() {
- String mirrorText = null;
- VirtualFile file = null;
- if (myMirrorFileElement == null) {
- file = getVirtualFile();
- // avoid decompiling under MIRROR_LOCK as decompiling can need other locks
- // (e.g. nice parameter names in mirror need resolve and FQN stub index lock) and stub indices (under own lock) need to access stub
- // tree with MIRROR_LOCK, see IDEA-98468
- mirrorText = decompile(getManager(), file);
- }
+ TreeElement mirrorTreeElement = myMirrorFileElement;
+ if (mirrorTreeElement == null) {
+ synchronized (myMirrorLock) {
+ mirrorTreeElement = myMirrorFileElement;
+ if (mirrorTreeElement == null) {
+ VirtualFile file = getVirtualFile();
+ String mirrorText = decompile(getManager(), file);
- synchronized (MIRROR_LOCK) {
- if (myMirrorFileElement == null) {
- String ext = JavaFileType.INSTANCE.getDefaultExtension();
- PsiClass[] classes = getClasses();
- String fileName = (classes.length > 0 ? classes[0].getName() : file.getNameWithoutExtension()) + "." + ext;
- PsiFileFactory factory = PsiFileFactory.getInstance(getManager().getProject());
- PsiFile mirror = factory.createFileFromText(fileName, JavaLanguage.INSTANCE, mirrorText, false, false);
- TreeElement mirrorTreeElement = SourceTreeToPsiMap.psiToTreeNotNull(mirror);
+ String ext = JavaFileType.INSTANCE.getDefaultExtension();
+ PsiClass[] classes = getClasses();
+ String fileName = (classes.length > 0 ? classes[0].getName() : file.getNameWithoutExtension()) + "." + ext;
+ PsiFileFactory factory = PsiFileFactory.getInstance(getManager().getProject());
+ PsiFile mirror = factory.createFileFromText(fileName, JavaLanguage.INSTANCE, mirrorText, false, false);
+ mirror.putUserData(PsiUtil.FILE_LANGUAGE_LEVEL_KEY, getSourceLanguageLevel());
+ mirrorTreeElement = SourceTreeToPsiMap.psiToTreeNotNull(mirror);
- //IMPORTANT: do not take lock too early - FileDocumentManager.getInstance().saveToString() can run write action...
- final NonCancelableSection section = ProgressIndicatorProvider.startNonCancelableSectionIfSupported();
- try {
- setMirror(mirrorTreeElement);
- }
- catch (InvalidMirrorException e) {
- // todo[r.sh] use logging API once available (to attach .class file)
- LOG.error(file.getPath(), e);
- }
- finally {
- section.done();
- }
+ // IMPORTANT: do not take lock too early - FileDocumentManager.saveToString() can run write action
+ NonCancelableSection section = ProgressIndicatorProvider.startNonCancelableSectionIfSupported();
+ try {
+ setMirror(mirrorTreeElement);
+ }
+ catch (InvalidMirrorException e) {
+ LOG.error(file.getPath(), e);
+ }
+ finally {
+ section.done();
+ }
- myMirrorFileElement = mirrorTreeElement;
+ myMirrorFileElement = mirrorTreeElement;
+ }
}
-
- return myMirrorFileElement.getPsi();
}
+ return mirrorTreeElement.getPsi();
+ }
+
+ @NotNull
+ public LanguageLevel getSourceLanguageLevel() {
+ final List stubs = getStub().getChildrenStubs();
+ return stubs.size() > 0 ? ((PsiClassStub<?>)stubs.get(0)).getLanguageLevel() : LanguageLevel.HIGHEST;
}
@Override
@@ -398,58 +407,30 @@
return (PsiClassHolderFileStub)getStubTree().getRoot();
}
- private final Object lock = new Object();
-
@Override
@NotNull
public StubTree getStubTree() {
ApplicationManager.getApplication().assertReadAccessAllowed();
- final StubTree derefd = derefStub();
- if (derefd != null) return derefd;
+ StubTree stubTree = dereference(myStub);
+ if (stubTree != null) return stubTree;
- StubTree stubHolder = (StubTree)StubTreeLoader.getInstance().readOrBuild(getProject(), getVirtualFile(), this);
- if (stubHolder == null) {
- // Must be corrupted .class file
- LOG.info("Class file is corrupted: " + getVirtualFile().getPresentableUrl());
+ synchronized (myStubLock) {
+ stubTree = dereference(myStub);
+ if (stubTree != null) return stubTree;
- StubTree emptyTree = new StubTree(new PsiJavaFileStubImpl("corrupted.classfiles", true));
- setStubTree(emptyTree);
- resetMirror();
- return emptyTree;
+ stubTree = (StubTree)StubTreeLoader.getInstance().readOrBuild(getProject(), getVirtualFile(), this);
+ if (stubTree == null) {
+ LOG.warn("Class file is corrupted: " + getVirtualFile().getPresentableUrl());
+ stubTree = new StubTree(new PsiJavaFileStubImpl("corrupted.classfiles", true));
+ }
+
+ myStub = new SoftReference<StubTree>(stubTree);
+ //noinspection unchecked
+ ((PsiFileStubImpl)stubTree.getRoot()).setPsi(this);
}
- synchronized (lock) {
- final StubTree derefdOnLock = derefStub();
- if (derefdOnLock != null) return derefdOnLock;
-
- setStubTree(stubHolder);
- }
-
- resetMirror();
- return stubHolder;
- }
-
- private void setStubTree(StubTree tree) {
- synchronized (lock) {
- myStub = new SoftReference<StubTree>(tree);
- ((PsiFileStubImpl)tree.getRoot()).setPsi(this);
- }
- }
-
- private void resetMirror() {
- ClsPackageStatementImpl clsPackageStatement = new ClsPackageStatementImpl(this);
- synchronized (MIRROR_LOCK) {
- myMirrorFileElement = null;
- myPackageStatement = clsPackageStatement;
- }
- }
-
- @Nullable
- private StubTree derefStub() {
- synchronized (lock) {
- return myStub != null ? myStub.get() : null;
- }
+ return stubTree;
}
@Override
@@ -464,18 +445,21 @@
@Override
public void onContentReload() {
- SoftReference<StubTree> stub = myStub;
- StubTree stubHolder = stub == null ? null : stub.get();
- if (stubHolder != null) {
- ((StubBase<?>)stubHolder.getRoot()).setPsi(null);
- }
- myStub = null;
-
ApplicationManager.getApplication().assertWriteAccessAllowed();
- synchronized (MIRROR_LOCK) {
+ synchronized (myStubLock) {
+ StubTree stubTree = dereference(myStub);
+ myStub = null;
+ if (stubTree != null) {
+ //noinspection unchecked
+ ((PsiFileStubImpl)stubTree.getRoot()).setPsi(null);
+ }
+ }
+
+ ClsPackageStatementImpl packageStatement = new ClsPackageStatementImpl(this);
+ synchronized (myMirrorLock) {
myMirrorFileElement = null;
- myPackageStatement = null;
+ myPackageStatement = packageStatement;
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java
index c69391d..7c2e8e0 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java
@@ -20,6 +20,7 @@
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiSubstitutorImpl;
+import com.intellij.psi.impl.cache.TypeInfo;
import com.intellij.psi.impl.source.resolve.ResolveCache;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.TreeElement;
@@ -45,8 +46,10 @@
public ClsJavaCodeReferenceElementImpl(PsiElement parent, String canonicalText) {
myParent = parent;
- myCanonicalText = canonicalText;
- myQualifiedName = PsiNameHelper.getQualifiedClassName(myCanonicalText, false);
+ String canonical = TypeInfo.internFrequentType(canonicalText);
+ myCanonicalText = canonical;
+ String qName = TypeInfo.internFrequentType(PsiNameHelper.getQualifiedClassName(myCanonicalText, false));
+ myQualifiedName = qName.equals(canonical) ? canonical : qName;
String[] classParameters = PsiNameHelper.getClassParametersText(canonicalText);
myRefParameterList = classParameters.length == 0 ? null : new ClsReferenceParameterListImpl(this, classParameters);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsMemberImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsMemberImpl.java
index e59d910..c5f072c 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsMemberImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsMemberImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -15,6 +15,8 @@
*/
package com.intellij.psi.impl.compiled;
+import com.intellij.openapi.util.AtomicNotNullLazyValue;
+import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.psi.PsiDocCommentOwner;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiIdentifier;
@@ -25,38 +27,37 @@
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
-public abstract class ClsMemberImpl<T extends NamedStub>
- extends ClsRepositoryPsiElement<T>
- implements PsiDocCommentOwner, PsiNameIdentifierOwner {
-
- private PsiDocComment myDocComment;
- private PsiIdentifier myNameIdentifier;
+public abstract class ClsMemberImpl<T extends NamedStub> extends ClsRepositoryPsiElement<T> implements PsiDocCommentOwner, PsiNameIdentifierOwner {
+ private final NotNullLazyValue<PsiDocComment> myDocComment;
+ private final NotNullLazyValue<PsiIdentifier> myNameIdentifier;
protected ClsMemberImpl(T stub) {
super(stub);
+ myDocComment = !isDeprecated() ? null : new AtomicNotNullLazyValue<PsiDocComment>() {
+ @NotNull
+ @Override
+ protected PsiDocComment compute() {
+ return new ClsDocCommentImpl(ClsMemberImpl.this);
+ }
+ };
+ myNameIdentifier = new AtomicNotNullLazyValue<PsiIdentifier>() {
+ @NotNull
+ @Override
+ protected PsiIdentifier compute() {
+ return new ClsIdentifierImpl(ClsMemberImpl.this, getName());
+ }
+ };
}
@Override
public PsiDocComment getDocComment() {
- if (!isDeprecated()) return null;
-
- synchronized (LAZY_BUILT_LOCK) {
- if (myDocComment == null) {
- myDocComment = new ClsDocCommentImpl(this);
- }
- return myDocComment;
- }
+ return myDocComment != null ? myDocComment.getValue() : null;
}
@Override
@NotNull
public PsiIdentifier getNameIdentifier() {
- synchronized (LAZY_BUILT_LOCK) {
- if (myNameIdentifier == null) {
- myNameIdentifier = new ClsIdentifierImpl(this, getName());
- }
- return myNameIdentifier;
- }
+ return myNameIdentifier.getValue();
}
@Override
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsMethodImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsMethodImpl.java
index deb912d..ac0ccfb 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsMethodImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsMethodImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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,8 @@
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.ItemPresentationProviders;
import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.util.AtomicNotNullLazyValue;
+import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.ElementPresentationUtil;
@@ -44,11 +46,31 @@
import java.util.List;
public class ClsMethodImpl extends ClsMemberImpl<PsiMethodStub> implements PsiAnnotationMethod {
- private PsiTypeElement myReturnType = null;
- private PsiAnnotationMemberValue myDefaultValue = null;
+ private final NotNullLazyValue<PsiTypeElement> myReturnType;
+ private final NotNullLazyValue<PsiAnnotationMemberValue> myDefaultValue;
public ClsMethodImpl(final PsiMethodStub stub) {
super(stub);
+
+ myReturnType = isConstructor() ? null : new AtomicNotNullLazyValue<PsiTypeElement>() {
+ @NotNull
+ @Override
+ protected PsiTypeElement compute() {
+ PsiMethodStub stub = getStub();
+ String typeText = TypeInfo.createTypeText(stub.getReturnTypeText(false));
+ assert typeText != null : stub;
+ return new ClsTypeElementImpl(ClsMethodImpl.this, typeText, ClsTypeElementImpl.VARIANCE_NONE);
+ }
+ };
+
+ final String text = getStub().getDefaultValueText();
+ myDefaultValue = StringUtil.isEmptyOrSpaces(text) ? null : new AtomicNotNullLazyValue<PsiAnnotationMemberValue>() {
+ @NotNull
+ @Override
+ protected PsiAnnotationMemberValue compute() {
+ return ClsParsingUtil.createMemberValueFromText(text, getManager(), ClsMethodImpl.this);
+ }
+ };
}
@Override
@@ -106,17 +128,7 @@
@Override
public PsiTypeElement getReturnTypeElement() {
- if (isConstructor()) return null;
-
- synchronized (LAZY_BUILT_LOCK) {
- if (myReturnType == null) {
- PsiMethodStub stub = getStub();
- String typeText = TypeInfo.createTypeText(stub.getReturnTypeText(false));
- assert typeText != null : stub;
- myReturnType = new ClsTypeElementImpl(this, typeText, ClsTypeElementImpl.VARIANCE_NONE);
- }
- return myReturnType;
- }
+ return myReturnType != null ? myReturnType.getValue() : null;
}
@Override
@@ -165,14 +177,7 @@
@Override
public PsiAnnotationMemberValue getDefaultValue() {
- synchronized (LAZY_BUILT_LOCK) {
- if (myDefaultValue == null) {
- final String text = getStub().getDefaultValueText();
- if (text == null || StringUtil.isEmpty(text)) return null;
- myDefaultValue = ClsParsingUtil.createMemberValueFromText(text, getManager(), this);
- }
- return myDefaultValue;
- }
+ return myDefaultValue != null ? myDefaultValue.getValue() : null;
}
@Override
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java
index 553a5fe..e75c320 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.psi.impl.compiled;
import com.intellij.openapi.project.DumbService;
+import com.intellij.openapi.util.AtomicNotNullLazyValue;
+import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
@@ -32,18 +34,27 @@
import com.intellij.ui.RowIcon;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.PlatformIcons;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class ClsParameterImpl extends ClsRepositoryPsiElement<PsiParameterStub> implements PsiParameter {
- private PsiTypeElement myType = null;
- private String myName;
- private volatile String myMirrorName = null;
+ private final NotNullLazyValue<PsiTypeElement> myType;
+ private volatile String myName;
+ private volatile String myMirrorName;
public ClsParameterImpl(@NotNull PsiParameterStub stub) {
super(stub);
+ myType = new AtomicNotNullLazyValue<PsiTypeElement>() {
+ @NotNull
+ @Override
+ protected PsiTypeElement compute() {
+ PsiParameterStub stub = getStub();
+ String typeText = TypeInfo.createTypeText(stub.getType(false));
+ assert typeText != null : stub;
+ return new ClsTypeElementImpl(ClsParameterImpl.this, typeText, ClsTypeElementImpl.VARIANCE_NONE);
+ }
+ };
}
@Override
@@ -53,24 +64,27 @@
@Override
public String getName() {
- if (myName == null) {
+ String name = myName;
+ if (name == null) {
if (DumbService.getInstance(getProject()).isDumb()) {
return null;
}
ClsMethodImpl method = (ClsMethodImpl)getDeclarationScope();
PsiMethod sourceMethod = method.getSourceMirrorMethod();
- if (sourceMethod == null) {
- final PsiParameterStubImpl parameterStub = (PsiParameterStubImpl) getStub();
- if (!parameterStub.isAutoGeneratedName()) {
- return parameterStub.getName();
- }
- return null;
+ if (sourceMethod != null) {
+ assert sourceMethod != method : method;
+ myName = name = sourceMethod.getParameterList().getParameters()[getIndex()].getName();
}
- assert sourceMethod != method;
- myName = sourceMethod.getParameterList().getParameters()[getIndex()].getName();
+
+ if (name == null) {
+ PsiParameterStubImpl parameterStub = (PsiParameterStubImpl)getStub();
+ if (!parameterStub.isAutoGeneratedName()) {
+ name = parameterStub.getName();
+ }
+ }
}
- return myName;
+ return name;
}
@Override
@@ -81,15 +95,7 @@
@Override
@NotNull
public PsiTypeElement getTypeElement() {
- synchronized (LAZY_BUILT_LOCK) {
- if (myType == null) {
- PsiParameterStub stub = getStub();
- String typeText = TypeInfo.createTypeText(stub.getType(false));
- assert typeText != null : stub;
- myType = new ClsTypeElementImpl(this, typeText, ClsTypeElementImpl.VARIANCE_NONE);
- }
- return myType;
- }
+ return myType.getValue();
}
@Override
@@ -144,12 +150,11 @@
private String getMirrorName() {
String mirrorName = myMirrorName;
if (mirrorName == null) {
- // avoid calculation of nice parameter name under lock as we might need indices for coolness
- // and latter might produce deadlock, see IDEA-99248
- mirrorName = calcNiceParameterName();
- synchronized (LAZY_BUILT_LOCK) {
- if (myMirrorName == null) {
- myMirrorName = mirrorName;
+ // parameter name may depend on a name of a previous one in a same parameter list
+ synchronized (getParent()) {
+ mirrorName = myMirrorName;
+ if (mirrorName == null) {
+ myMirrorName = mirrorName = calcNiceParameterName();
}
}
}
@@ -157,63 +162,40 @@
}
private String calcNiceParameterName() {
- @NonNls String name;
+ String name = null;
- final PsiParameterStubImpl stub = (PsiParameterStubImpl)getStub();
+ PsiParameterStubImpl stub = (PsiParameterStubImpl)getStub();
if (!stub.isAutoGeneratedName() || DumbService.getInstance(getProject()).isDumb()) {
name = stub.getName();
}
- else {
+
+ if (name == null) {
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(getProject());
String[] nameSuggestions = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, getType()).names;
name = "p";
- if (nameSuggestions.length > 0) {
+ if (nameSuggestions.length > 0 && nameSuggestions[0] != null) {
name = nameSuggestions[0];
}
- PsiParameter[] parameters = ((PsiParameterList) getParent()).getParameters();
+ String base = name;
+ int n = 0;
AttemptsLoop:
while (true) {
- for (PsiParameter parameter : parameters) {
+ for (PsiParameter parameter : ((PsiParameterList)getParent()).getParameters()) {
if (parameter == this) break AttemptsLoop;
- String name1 = ((ClsParameterImpl) parameter).getMirrorName();
- if (name.equals(name1)) {
- name = nextName(name);
+ String prevName = ((ClsParameterImpl)parameter).getMirrorName();
+ if (name.equals(prevName)) {
+ name = base + (++n);
continue AttemptsLoop;
}
}
}
}
- assert name != null : stub;
return name;
}
- private static String nextName(String name) {
- int count = 0;
- while (true) {
- if (count == name.length()) break;
- char c = name.charAt(name.length() - count - 1);
- if ('0' <= c && c <= '9') {
- count++;
- }
- else {
- break;
- }
- }
-
- try {
- int n = count > 0 ? Integer.parseInt(name.substring(name.length() - count)) : 0;
- n++;
- return name.substring(0, name.length() - count) + n;
- }
- catch (NumberFormatException e) {
- assert false : e.getMessage();
- return null;
- }
- }
-
@Override
public void setMirror(@NotNull TreeElement element) throws InvalidMirrorException {
setMirrorCheckingType(element, null);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParsingUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParsingUtil.java
index e3a27d8..39c1829 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParsingUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParsingUtil.java
@@ -126,20 +126,20 @@
if (expr instanceof PsiLiteralExpression) {
return new ClsLiteralExpressionImpl(parent, expr.getText(), expr.getType(), ((PsiLiteralExpression)expr).getValue());
}
- else if (expr instanceof PsiPrefixExpression) {
+ if (expr instanceof PsiPrefixExpression) {
final PsiPrefixExpression prefixExpr = (PsiPrefixExpression)expr;
final ClsJavaTokenImpl operation = new ClsJavaTokenImpl(null, prefixExpr.getOperationTokenType(), prefixExpr.getOperationSign().getText());
final ClsLiteralExpressionImpl literal = (ClsLiteralExpressionImpl) psiToClsExpression(prefixExpr.getOperand(), null);
return new ClsPrefixExpressionImpl(parent, operation, literal);
}
- else if (expr instanceof PsiClassObjectAccessExpression) {
+ if (expr instanceof PsiClassObjectAccessExpression) {
final String canonicalClassText = ((PsiClassObjectAccessExpression)expr).getOperand().getType().getCanonicalText();
return new ClsClassObjectAccessExpressionImpl(parent, canonicalClassText);
}
- else if (expr instanceof PsiReferenceExpression) {
+ if (expr instanceof PsiReferenceExpression) {
return new ClsReferenceExpressionImpl(parent, (PsiReferenceExpression)expr);
}
- else if (expr instanceof PsiBinaryExpression) {
+ if (expr instanceof PsiBinaryExpression) {
final PsiBinaryExpression binaryExpr = (PsiBinaryExpression)expr;
final PsiExpression lOperand = psiToClsExpression(binaryExpr.getLOperand(), null);
final ClsJavaTokenImpl operation = new ClsJavaTokenImpl(null, binaryExpr.getOperationTokenType(), binaryExpr.getOperationSign().getText());
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsReferenceListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsReferenceListImpl.java
index 88ec13c..f3193f9 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsReferenceListImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsReferenceListImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -15,40 +15,44 @@
*/
package com.intellij.psi.impl.compiled;
+import com.intellij.openapi.util.AtomicNotNullLazyValue;
+import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.psi.*;
import com.intellij.psi.impl.java.stubs.PsiClassReferenceListStub;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.tree.TreeElement;
import org.jetbrains.annotations.NotNull;
-@SuppressWarnings({"HardCodedStringLiteral"})
public class ClsReferenceListImpl extends ClsRepositoryPsiElement<PsiClassReferenceListStub> implements PsiReferenceList {
private static final ClsJavaCodeReferenceElementImpl[] EMPTY_REFS_ARRAY = new ClsJavaCodeReferenceElementImpl[0];
- private ClsJavaCodeReferenceElementImpl[] myRefs;
+ private final NotNullLazyValue<ClsJavaCodeReferenceElementImpl[]> myRefs;
public ClsReferenceListImpl(@NotNull PsiClassReferenceListStub stub) {
super(stub);
+ myRefs = new AtomicNotNullLazyValue<ClsJavaCodeReferenceElementImpl[]>() {
+ @NotNull
+ @Override
+ protected ClsJavaCodeReferenceElementImpl[] compute() {
+ String[] strings = getStub().getReferencedNames();
+ if (strings.length > 0) {
+ ClsJavaCodeReferenceElementImpl[] refs = new ClsJavaCodeReferenceElementImpl[strings.length];
+ for (int i = 0; i < strings.length; i++) {
+ refs[i] = new ClsJavaCodeReferenceElementImpl(ClsReferenceListImpl.this, strings[i]);
+ }
+ return refs;
+ }
+ else {
+ return EMPTY_REFS_ARRAY;
+ }
+ }
+ };
}
@Override
@NotNull
public PsiJavaCodeReferenceElement[] getReferenceElements() {
- synchronized (LAZY_BUILT_LOCK) {
- if (myRefs == null) {
- final String[] strings = getStub().getReferencedNames();
- if (strings.length > 0) {
- myRefs = new ClsJavaCodeReferenceElementImpl[strings.length];
- for (int i = 0; i < strings.length; i++) {
- myRefs[i] = new ClsJavaCodeReferenceElementImpl(this, strings[i]);
- }
- }
- else {
- myRefs = EMPTY_REFS_ARRAY;
- }
- }
- return myRefs;
- }
+ return myRefs.getValue();
}
@Override
@@ -76,13 +80,13 @@
switch (role) {
case EXTENDS_BOUNDS_LIST:
case EXTENDS_LIST:
- buffer.append("extends ");
+ buffer.append(PsiKeyword.EXTENDS).append(' ');
break;
case IMPLEMENTS_LIST:
- buffer.append("implements ");
+ buffer.append(PsiKeyword.IMPLEMENTS).append(' ');
break;
case THROWS_LIST:
- buffer.append("throws ");
+ buffer.append(PsiKeyword.THROWS).append(' ');
break;
}
for (int i = 0; i < names.length; i++) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java
index f8b821b..2fded2d 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -15,40 +15,59 @@
*/
package com.intellij.psi.impl.compiled;
+import com.intellij.openapi.util.AtomicNotNullLazyValue;
+import com.intellij.openapi.util.NotNullLazyValue;
+import com.intellij.openapi.util.NullableLazyValue;
+import com.intellij.openapi.util.VolatileNullableLazyValue;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
+import com.intellij.psi.impl.cache.TypeInfo;
import com.intellij.psi.impl.source.PsiClassReferenceType;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.TreeElement;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
public class ClsTypeElementImpl extends ClsElementImpl implements PsiTypeElement {
- static final char VARIANCE_NONE = '\0';
- static final char VARIANCE_EXTENDS = '+';
- static final char VARIANCE_SUPER = '-';
- static final char VARIANCE_INVARIANT = '*';
- @NonNls private static final String VARIANCE_EXTENDS_PREFIX = "? extends ";
- @NonNls private static final String VARIANCE_SUPER_PREFIX = "? super ";
+ @NonNls static final char VARIANCE_NONE = '\0';
+ @NonNls static final char VARIANCE_EXTENDS = '+';
+ @NonNls static final char VARIANCE_SUPER = '-';
+ @NonNls static final char VARIANCE_INVARIANT = '*';
+ @NonNls static final String VARIANCE_EXTENDS_PREFIX = "? extends ";
+ @NonNls static final String VARIANCE_SUPER_PREFIX = "? super ";
private final PsiElement myParent;
private final String myTypeText;
- private volatile ClsElementImpl myChild = null;
- private boolean myChildSet = false;
- private volatile PsiType myCachedType;
private final char myVariance;
+ private final NullableLazyValue<ClsElementImpl> myChild;
+ private final NotNullLazyValue<PsiType> myCachedType;
public ClsTypeElementImpl(@NotNull PsiElement parent, @NotNull String typeText, char variance) {
myParent = parent;
- myTypeText = typeText;
+ myTypeText = TypeInfo.internFrequentType(typeText);
myVariance = variance;
+ myChild = new VolatileNullableLazyValue<ClsElementImpl>() {
+ @Nullable
+ @Override
+ protected ClsElementImpl compute() {
+ return calculateChild();
+ }
+ };
+ myCachedType = new AtomicNotNullLazyValue<PsiType>() {
+ @NotNull
+ @Override
+ protected PsiType compute() {
+ return calculateType();
+ }
+ };
}
@Override
@NotNull
public PsiElement[] getChildren() {
- loadChild();
- return myChild != null ? new PsiElement[]{myChild} : PsiElement.EMPTY_ARRAY;
+ ClsElementImpl child = myChild.getValue();
+ return child != null ? new PsiElement[]{child} : PsiElement.EMPTY_ARRAY;
}
@Override
@@ -91,33 +110,12 @@
public void setMirror(@NotNull TreeElement element) throws InvalidMirrorException {
setMirrorCheckingType(element, JavaElementType.TYPE);
- loadChild();
-
- if (myChild != null) {
- myChild.setMirror(element.getFirstChildNode());
+ ClsElementImpl child = myChild.getValue();
+ if (child != null) {
+ child.setMirror(element.getFirstChildNode());
}
}
- private void loadChild() {
- if (isPrimitive()) {
- synchronized (LAZY_BUILT_LOCK) {
- myChildSet = true;
- }
- return;
- }
-
- if (isArray() || isVarArgs()) {
- createComponentTypeChild();
- }
- else {
- createClassReferenceChild();
- }
- }
-
- private boolean isPrimitive() {
- return JavaPsiFacade.getInstance(getProject()).getElementFactory().createPrimitiveType(myTypeText) != null;
- }
-
private boolean isArray() {
return myTypeText.endsWith("[]");
}
@@ -129,14 +127,7 @@
@Override
@NotNull
public PsiType getType() {
- if (myCachedType == null) {
- synchronized (LAZY_BUILT_LOCK) {
- if (myCachedType == null) {
- myCachedType = calculateType();
- }
- }
- }
- return myCachedType;
+ return myCachedType.getValue();
}
@Override
@@ -154,82 +145,66 @@
return getType();
}
+ private ClsElementImpl calculateChild() {
+ if (JavaPsiFacade.getInstance(getProject()).getElementFactory().createPrimitiveType(myTypeText) != null) {
+ return null;
+ }
+ else if (isArray()) {
+ return myVariance == VARIANCE_NONE
+ ? new ClsTypeElementImpl(this, myTypeText.substring(0, myTypeText.length() - 2), myVariance)
+ : new ClsTypeElementImpl(this, myTypeText, VARIANCE_NONE);
+ }
+ else if (isVarArgs()) {
+ return new ClsTypeElementImpl(this, myTypeText.substring(0, myTypeText.length() - 3), myVariance);
+ }
+ else {
+ return myVariance != VARIANCE_INVARIANT ? new ClsJavaCodeReferenceElementImpl(this, myTypeText) : null;
+ }
+ }
+
private PsiType calculateType() {
PsiType result = JavaPsiFacade.getInstance(getProject()).getElementFactory().createPrimitiveType(myTypeText);
if (result != null) return result;
- if (isArray()) {
- createComponentTypeChild();
- if (myVariance == VARIANCE_NONE) return ((PsiTypeElement)myChild).getType().createArrayType();
+ ClsElementImpl childElement = myChild.getValue();
+ if (childElement instanceof ClsTypeElementImpl) {
+ if (isArray()) {
+ switch (myVariance) {
+ case VARIANCE_NONE:
+ return ((PsiTypeElement)childElement).getType().createArrayType();
+ case VARIANCE_EXTENDS:
+ return PsiWildcardType.createExtends(getManager(), ((PsiTypeElement)childElement).getType());
+ case VARIANCE_SUPER:
+ return PsiWildcardType.createSuper(getManager(), ((PsiTypeElement)childElement).getType());
+ default:
+ assert false : myVariance;
+ return null;
+ }
+ }
+ else {
+ assert isVarArgs() : this;
+ return new PsiEllipsisType(((PsiTypeElement)childElement).getType());
+ }
+ }
+ else if (childElement instanceof ClsJavaCodeReferenceElementImpl) {
+ PsiClassReferenceType psiClassReferenceType = new PsiClassReferenceType((PsiJavaCodeReferenceElement)childElement, null);
switch (myVariance) {
+ case VARIANCE_NONE:
+ return psiClassReferenceType;
case VARIANCE_EXTENDS:
- return PsiWildcardType.createExtends(getManager(), ((PsiTypeElement)myChild).getType());
+ return PsiWildcardType.createExtends(getManager(), psiClassReferenceType);
case VARIANCE_SUPER:
- return PsiWildcardType.createSuper(getManager(), ((PsiTypeElement)myChild).getType());
+ return PsiWildcardType.createSuper(getManager(), psiClassReferenceType);
+ case VARIANCE_INVARIANT:
+ return PsiWildcardType.createUnbounded(getManager());
default:
assert false : myVariance;
return null;
}
}
- else if (isVarArgs()) {
- createComponentTypeChild();
- return new PsiEllipsisType(((PsiTypeElement)myChild).getType());
- }
-
- createClassReferenceChild();
- final PsiClassReferenceType psiClassReferenceType;
- if (myVariance != VARIANCE_INVARIANT) {
- psiClassReferenceType = new PsiClassReferenceType((PsiJavaCodeReferenceElement)myChild, null);
- }
else {
- psiClassReferenceType = null;
- }
-
- switch (myVariance) {
- case VARIANCE_NONE:
- return psiClassReferenceType;
- case VARIANCE_EXTENDS:
- return PsiWildcardType.createExtends(getManager(), psiClassReferenceType);
- case VARIANCE_SUPER:
- return PsiWildcardType.createSuper(getManager(), psiClassReferenceType);
- case VARIANCE_INVARIANT:
- return PsiWildcardType.createUnbounded(getManager());
- default:
- assert false : myVariance;
- return null;
- }
- }
-
- private void createClassReferenceChild() {
- synchronized (LAZY_BUILT_LOCK) {
- if (!myChildSet) {
- if (myVariance != VARIANCE_INVARIANT) {
- myChild = new ClsJavaCodeReferenceElementImpl(this, myTypeText);
- }
- myChildSet = true;
- }
- }
- }
-
- private void createComponentTypeChild() {
- synchronized (LAZY_BUILT_LOCK) {
- if (!myChildSet) {
- if (isArray()) {
- if (myVariance == VARIANCE_NONE) {
- myChild = new ClsTypeElementImpl(this, myTypeText.substring(0, myTypeText.length() - 2), myVariance);
- }
- else {
- myChild = new ClsTypeElementImpl(this, myTypeText, VARIANCE_NONE);
- }
- }
- else if (isVarArgs()) {
- myChild = new ClsTypeElementImpl(this, myTypeText.substring(0, myTypeText.length() - 3), myVariance);
- }
- else {
- assert false : myTypeText;
- }
- myChildSet = true;
- }
+ assert childElement == null : this;
+ return PsiWildcardType.createUnbounded(getManager());
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java
index 9693582..20ab202 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java
@@ -31,20 +31,23 @@
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.*;
+import com.intellij.reference.SoftReference;
import com.intellij.util.CommonProcessors;
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.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Queryable {
public static boolean DEBUG = false;
private volatile CachedValue<PsiModifierList> myAnnotationList;
private volatile CachedValue<Collection<PsiDirectory>> myDirectories;
- private volatile Set<String> myPublicClassNamesCache;
- private final Object myPublicClassNamesCacheLock = new Object();
+ private volatile SoftReference<Set<String>> myPublicClassNamesCache;
public PsiPackageImpl(PsiManager manager, String qualifiedName) {
super(manager, qualifiedName);
@@ -100,9 +103,7 @@
@Override
public boolean isValid() {
- final CommonProcessors.FindFirstProcessor<PsiDirectory> processor = new CommonProcessors.FindFirstProcessor<PsiDirectory>();
- getFacade().processPackageDirectories(this, allScope(), processor);
- return processor.getFoundValue() != null || PsiPackageImplementationHelper.getInstance().packagePrefixExists(this);
+ return PsiPackageImplementationHelper.getInstance().packagePrefixExists(this) || !getAllDirectories().isEmpty();
}
@Override
@@ -161,14 +162,14 @@
}
private Set<String> getClassNamesCache() {
- if (myPublicClassNamesCache == null) {
- Set<String> classNames = getFacade().getClassNames(this, allScope());
- synchronized (myPublicClassNamesCacheLock) {
- myPublicClassNamesCache = classNames;
- }
+ SoftReference<Set<String>> ref = myPublicClassNamesCache;
+ Set<String> cache = ref == null ? null : ref.get();
+ if (cache == null) {
+ cache = getFacade().getClassNames(this, allScope());
+ myPublicClassNamesCache = new SoftReference<Set<String>>(cache);
}
- return myPublicClassNamesCache;
+ return cache;
}
@NotNull
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java
index 95888e0..8d60006 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java
@@ -18,6 +18,7 @@
import com.intellij.lang.ASTNode;
import com.intellij.lang.LighterAST;
import com.intellij.lang.LighterASTNode;
+import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiNameHelper;
@@ -152,6 +153,7 @@
if (!stub.isAnonymous()) {
dataStream.writeName(stub.getName());
dataStream.writeName(stub.getQualifiedName());
+ dataStream.writeByte(stub.getLanguageLevel().ordinal());
dataStream.writeName(stub.getSourceFileName());
}
else {
@@ -163,16 +165,17 @@
@Override
public PsiClassStub deserialize(@NotNull final StubInputStream dataStream, final StubElement parentStub) throws IOException {
byte flags = dataStream.readByte();
-
- final boolean isAnonymous = PsiClassStubImpl.isAnonymous(flags);
- final boolean isEnumConst = PsiClassStubImpl.isEnumConstInitializer(flags);
- final JavaClassElementType type = typeForClass(isAnonymous, isEnumConst);
+ boolean isAnonymous = PsiClassStubImpl.isAnonymous(flags);
+ boolean isEnumConst = PsiClassStubImpl.isEnumConstInitializer(flags);
+ JavaClassElementType type = typeForClass(isAnonymous, isEnumConst);
if (!isAnonymous) {
StringRef name = dataStream.readName();
StringRef qname = dataStream.readName();
- final StringRef sourceFileName = dataStream.readName();
- final PsiClassStubImpl classStub = new PsiClassStubImpl(type, parentStub, qname, name, null, flags);
+ int languageLevelId = dataStream.readByte();
+ StringRef sourceFileName = dataStream.readName();
+ PsiClassStubImpl classStub = new PsiClassStubImpl(type, parentStub, qname, name, null, flags);
+ classStub.setLanguageLevel(LanguageLevel.values()[languageLevelId]);
classStub.setSourceFileName(sourceFileName);
return classStub;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiClassStubImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiClassStubImpl.java
index 38009e7..b1e530e 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiClassStubImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiClassStubImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -133,7 +133,7 @@
@Override
public LanguageLevel getLanguageLevel() {
- return myLanguageLevel != null ? myLanguageLevel : LanguageLevel.HIGHEST; // TODO!!!
+ return myLanguageLevel != null ? myLanguageLevel : LanguageLevel.HIGHEST;
}
@Override
@@ -185,8 +185,7 @@
@SuppressWarnings({"HardCodedStringLiteral"})
public String toString() {
StringBuilder builder = new StringBuilder();
- builder.
- append("PsiClassStub[");
+ builder.append("PsiClassStub[");
if (isInterface()) {
builder.append("interface ");
@@ -216,15 +215,12 @@
builder.append("deprecatedA ");
}
- builder.
- append("name=").append(getName()).
- append(" fqn=").append(getQualifiedName());
+ builder.append("name=").append(getName()).append(" fqn=").append(getQualifiedName());
if (getBaseClassReferenceText() != null) {
builder.append(" baseref=").append(getBaseClassReferenceText());
}
-
if (isAnonymousInQualifiedNew()) {
builder.append(" inqualifnew");
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java
similarity index 100%
rename from java/java-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java
rename to java/java-psi-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java
index f62ca49..f9244e2 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java
@@ -38,7 +38,7 @@
* @author max
*/
public class JavaFileElementType extends ILightStubFileElementType<PsiJavaFileStub> {
- public static final int STUB_VERSION = 16;
+ public static final int STUB_VERSION = 17;
public JavaFileElementType() {
super("java.FILE", JavaLanguage.INSTANCE);
@@ -92,8 +92,7 @@
}
@Override
- public void serialize(@NotNull final PsiJavaFileStub stub, @NotNull final StubOutputStream dataStream)
- throws IOException {
+ public void serialize(@NotNull final PsiJavaFileStub stub, @NotNull final StubOutputStream dataStream) throws IOException {
dataStream.writeBoolean(stub.isCompiled());
dataStream.writeName(stub.getPackageName());
}
@@ -107,6 +106,5 @@
}
@Override
- public void indexStub(@NotNull final PsiJavaFileStub stub, @NotNull final IndexSink sink) {
- }
+ public void indexStub(@NotNull final PsiJavaFileStub stub, @NotNull final IndexSink sink) { }
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java
index 6b88ae6..e71bf63 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java
@@ -445,19 +445,22 @@
}
private LanguageLevel getLanguageLevelInner() {
- if (myOriginalFile instanceof PsiJavaFile) return ((PsiJavaFile)myOriginalFile).getLanguageLevel();
- final LanguageLevel forcedLanguageLevel = getUserData(PsiUtil.FILE_LANGUAGE_LEVEL_KEY);
- if (forcedLanguageLevel != null) return forcedLanguageLevel;
- VirtualFile virtualFile = getVirtualFile();
-
- if (virtualFile == null) {
- virtualFile = getUserData(IndexingDataKeys.VIRTUAL_FILE);
+ if (myOriginalFile instanceof PsiJavaFile) {
+ return ((PsiJavaFile)myOriginalFile).getLanguageLevel();
}
+ LanguageLevel forcedLanguageLevel = getUserData(PsiUtil.FILE_LANGUAGE_LEVEL_KEY);
+ if (forcedLanguageLevel != null) return forcedLanguageLevel;
+
+ VirtualFile virtualFile = getVirtualFile();
+ if (virtualFile == null) virtualFile = getUserData(IndexingDataKeys.VIRTUAL_FILE);
+
final Project project = getProject();
if (virtualFile == null) {
final PsiFile originalFile = getOriginalFile();
- if (originalFile instanceof PsiJavaFile && originalFile != this) return ((PsiJavaFile)originalFile).getLanguageLevel();
+ if (originalFile instanceof PsiJavaFile && originalFile != this) {
+ return ((PsiJavaFile)originalFile).getLanguageLevel();
+ }
return LanguageLevelProjectExtension.getInstance(project).getLanguageLevel();
}
@@ -471,7 +474,8 @@
if (classesLanguageLevel != null) {
return classesLanguageLevel;
}
- return LanguageLevelProjectExtension.getInstance(project).getLanguageLevel();
+
+ return PsiUtil.getLanguageLevel(project);
}
private static class MyCacheBuilder implements CachedValueProvider<MostlySingularMultiMap<String, SymbolCollectingProcessor.ResultWithContext>> {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiInlineDocTagImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiInlineDocTagImpl.java
index 38466a5..1adf3a5 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiInlineDocTagImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiInlineDocTagImpl.java
@@ -38,7 +38,7 @@
private static final TokenSet TAG_VALUE_BIT_SET = TokenSet.create(
DOC_TAG_VALUE_ELEMENT, DOC_METHOD_OR_FIELD_REF);
private static final TokenSet VALUE_BIT_SET = TokenSet.orSet(TAG_VALUE_BIT_SET, TokenSet.create(
- JAVA_CODE_REFERENCE, DOC_TAG_VALUE_TOKEN, DOC_COMMENT_DATA, DOC_INLINE_TAG, DOC_REFERENCE_HOLDER, WHITE_SPACE, DOC_COMMENT_BAD_CHARACTER));
+ JAVA_CODE_REFERENCE, DOC_TAG_VALUE_TOKEN, DOC_COMMENT_DATA, DOC_INLINE_TAG, DOC_REFERENCE_HOLDER, DOC_COMMENT_BAD_CHARACTER));
public PsiInlineDocTagImpl() {
super(DOC_INLINE_TAG);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java
index 9fc420f..981739b 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java
@@ -128,6 +128,12 @@
PsiClass topMemberClass = getTopLevelClass(memberClass, accessObjectClass);
PsiClass topAccessClass = getTopLevelClass(accessObjectClass, memberClass);
if (!manager.areElementsEquivalent(topMemberClass, topAccessClass)) return false;
+ if (accessObjectClass instanceof PsiAnonymousClass && accessObjectClass.isInheritor(memberClass, true)) {
+ if (place instanceof PsiMethodCallExpression &&
+ ((PsiMethodCallExpression)place).getMethodExpression().getQualifierExpression() instanceof PsiThisExpression) {
+ return false;
+ }
+ }
}
if (fileResolveScope == null) {
@@ -183,7 +189,7 @@
PsiClass lastClass = null;
Boolean isAtLeast17 = null;
for (PsiElement placeParent = place; placeParent != null; placeParent = placeParent.getContext()) {
- if (placeParent instanceof PsiClass) {
+ if (placeParent instanceof PsiClass && !(placeParent instanceof PsiAnonymousClass)) {
final boolean isTypeParameter = placeParent instanceof PsiTypeParameter;
if (isTypeParameter && isAtLeast17 == null) {
isAtLeast17 = JavaVersionService.getInstance().isAtLeast(place, JavaSdkVersion.JDK_1_7);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java
index ee65e92..3509fd9 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java
@@ -56,6 +56,7 @@
final JavaResolveResult[] results = getResults(contextCall, i);
final PsiType innerReturnType = owner.getReturnType();
for (final JavaResolveResult result : results) {
+ if (result == null) continue;
final PsiSubstitutor substitutor = getSubstitutor(contextCall, expressions, i, result);
final Pair<PsiType, ConstraintType> constraint = inferConstraint(typeParameter, innerMethodCall, i, innerReturnType, result, substitutor);
if (constraint != null) return constraint;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
index c9fbfbf..c22269d 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
@@ -398,6 +398,9 @@
final ConstraintType currentConstraintType = currentConstraint.getSecond();
if (currentConstraintType == ConstraintType.EQUALS) {
substitutionFromBounds = currentSubstitution;
+ if (currentSubstitution == null) {
+ constraints[i] = FAILED_INFERENCE;
+ }
break OtherParameters;
}
else if (currentConstraintType == ConstraintType.SUPERTYPE) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
index e092c9e..109d32d 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
@@ -45,12 +45,14 @@
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -356,12 +358,21 @@
PsiSubstitutor substitutor,
LanguageLevel languageLevel) {
if (signature == null) return PsiSubstitutor.EMPTY;
- final PsiType[] types = method.getSignature(PsiUtil.isRawSubstitutor(method, substitutor) ? PsiSubstitutor.EMPTY : substitutor).getParameterTypes();
- final PsiType[] rightTypes = signature.getParameterTypes();
- if (types.length < rightTypes.length) {
- return getSubstitutor(rightTypes[0]);
- } else if (types.length > rightTypes.length) {
- return getSubstitutor(types[0]);
+ PsiType[] types = method.getSignature(PsiUtil.isRawSubstitutor(method, substitutor) ? PsiSubstitutor.EMPTY : substitutor).getParameterTypes();
+ PsiType[] rightTypes = signature.getParameterTypes();
+ if (!method.isVarArgs() || types.length == 0) {
+ if (types.length < rightTypes.length) {
+ return getSubstitutor(rightTypes[0]);
+ } else if (types.length > rightTypes.length) {
+ return getSubstitutor(types[0]);
+ }
+ } else {
+ if (rightTypes.length != types.length || rightTypes[rightTypes.length - 1].getArrayDimensions() != types[types.length-1].getArrayDimensions()) {
+ types[types.length - 1] = ((PsiArrayType)types[types.length - 1]).getComponentType();
+ int min = Math.min(types.length, rightTypes.length);
+ types = Arrays.copyOf(types, min);
+ rightTypes = Arrays.copyOf(rightTypes, min);
+ }
}
for (int i = 0; i < rightTypes.length; i++) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java
index 2e84a19..b93bf2a 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java
@@ -25,10 +25,8 @@
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleSettingsFacade;
-import com.intellij.psi.filters.AndFilter;
-import com.intellij.psi.filters.ConstructorFilter;
-import com.intellij.psi.filters.NotFilter;
-import com.intellij.psi.filters.OrFilter;
+import com.intellij.psi.filters.*;
+import com.intellij.psi.filters.element.ModifierFilter;
import com.intellij.psi.impl.CheckUtil;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.PsiManagerEx;
@@ -440,7 +438,7 @@
// optimization: methodCallExpression should resolve to a method
if (parentIsMethodCall != resolvingToMethod) return false;
- return super.isReferenceTo(element);
+ return element.getManager().areElementsEquivalent(element, advancedResolve(true).getElement());
}
@Override
@@ -450,7 +448,17 @@
if (isQualified()) {
filter.addFilter(ElementClassFilter.PACKAGE_FILTER);
}
- filter.addFilter(new AndFilter(ElementClassFilter.METHOD, new NotFilter(new ConstructorFilter())));
+ filter.addFilter(new AndFilter(ElementClassFilter.METHOD, new NotFilter(new ConstructorFilter()), new ElementFilter() {
+ @Override
+ public boolean isAcceptable(Object element, @Nullable PsiElement context) {
+ return LambdaUtil.isValidQualifier4InterfaceStaticMethodCall((PsiMethod)element, PsiReferenceExpressionImpl.this);
+ }
+
+ @Override
+ public boolean isClassAcceptable(Class hintClass) {
+ return true;
+ }
+ }));
filter.addFilter(ElementClassFilter.VARIABLE);
FilterScopeProcessor filterProcessor = new FilterScopeProcessor<CandidateInfo>(filter, processor) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiThisExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiThisExpressionImpl.java
index ff7c042..2a8a620 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiThisExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiThisExpressionImpl.java
@@ -42,9 +42,8 @@
public PsiType getType() {
PsiJavaCodeReferenceElement qualifier = getQualifier();
if (qualifier != null){
- PsiClass qualifierResolve = (PsiClass)qualifier.resolve();
- if (qualifierResolve != null) return new PsiImmediateClassType(qualifierResolve, PsiSubstitutor.EMPTY);
-
+ PsiElement qualifierResolve = qualifier.resolve();
+ if (qualifierResolve instanceof PsiClass) return new PsiImmediateClassType((PsiClass)qualifierResolve, PsiSubstitutor.EMPTY);
return new PsiClassReferenceType(qualifier, null);
}
for(PsiElement scope = getContext(); scope != null; scope = scope.getContext()){
diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
index cf75c7e..f4b8aea 100644
--- a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
+++ b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
@@ -16,6 +16,7 @@
package com.intellij.psi.scope.conflictResolvers;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.JavaVersionService;
import com.intellij.openapi.util.Comparing;
@@ -106,6 +107,7 @@
if (parameterType instanceof PsiLambdaExpressionType) {
final PsiLambdaExpression lambdaExpression = ((PsiLambdaExpressionType)parameterType).getExpression();
for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext(); ) {
+ ProgressManager.checkCanceled();
final CandidateInfo conflict = iterator.next();
final PsiMethod method = (PsiMethod)conflict.getElement();
if (method != null) {
@@ -145,6 +147,7 @@
for (int i = 1; i < conflictsCount; i++) {
final CandidateInfo method = newConflictsArray[i];
for (int j = 0; j < i; j++) {
+ ProgressManager.checkCanceled();
final CandidateInfo conflict = newConflictsArray[j];
assert conflict != method;
switch (isMoreSpecific(method, conflict, applicabilityLevel)) {
@@ -169,6 +172,7 @@
int[] checkLevels = new int[conflictsCount];
int index = 0;
for (final CandidateInfo conflict : conflicts) {
+ ProgressManager.checkCanceled();
final MethodCandidateInfo method = (MethodCandidateInfo)conflict;
final int level = checkAccessible ? getCheckAccessLevel(method) : getCheckStaticLevel(method);
checkLevels[index++] = level;
@@ -189,12 +193,14 @@
Map<MethodSignature, CandidateInfo> signatures = new HashMap<MethodSignature, CandidateInfo>();
nextConflict:
for (int i=0; i<conflicts.size();i++) {
+ ProgressManager.checkCanceled();
CandidateInfo info = conflicts.get(i);
PsiMethod method = (PsiMethod)info.getElement();
assert method != null;
if (!method.hasModifierProperty(PsiModifier.STATIC)) {
for (int k=i-1; k>=0; k--) {
+ ProgressManager.checkCanceled();
PsiMethod existingMethod = (PsiMethod)conflicts.get(k).getElement();
if (PsiSuperMethodImplUtil.isSuperMethodSmart(existingMethod, method)) {
conflicts.remove(i);
@@ -240,7 +246,7 @@
i--;
continue;
}
- else if (!existingTypeParamAgree && infoTypeParamAgree && !PsiSuperMethodImplUtil.isSuperMethodSmart(existingMethod, method)) {
+ if (!existingTypeParamAgree && infoTypeParamAgree && !PsiSuperMethodImplUtil.isSuperMethodSmart(existingMethod, method)) {
signatures.put(signature, info);
int index = conflicts.indexOf(existing);
conflicts.remove(index);
@@ -315,6 +321,7 @@
boolean atLeastOneMatch = false;
TIntArrayList unmatchedIndices = null;
for (int i = 0; i < conflicts.size(); i++) {
+ ProgressManager.checkCanceled();
CandidateInfo info = conflicts.get(i);
if (ignoreIfStaticsProblem && !info.isStaticsScopeCorrect()) return true;
if (!(info instanceof MethodCandidateInfo)) continue;
@@ -350,6 +357,7 @@
@MethodCandidateInfo.ApplicabilityLevelConstant int maxApplicabilityLevel = 0;
boolean toFilter = false;
for (CandidateInfo conflict : conflicts) {
+ ProgressManager.checkCanceled();
final @MethodCandidateInfo.ApplicabilityLevelConstant int level = preferVarargs((MethodCandidateInfo)conflict);
if (maxApplicabilityLevel > 0 && maxApplicabilityLevel != level) {
toFilter = true;
@@ -361,6 +369,7 @@
if (toFilter) {
for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext();) {
+ ProgressManager.checkCanceled();
CandidateInfo info = iterator.next();
final int level = preferVarargs(info);
if (level < maxApplicabilityLevel) {
@@ -464,10 +473,11 @@
PsiType[] types1 = new PsiType[max];
PsiType[] types2 = new PsiType[max];
for (int i = 0; i < max; i++) {
+ ProgressManager.checkCanceled();
PsiType type1 = params1.length > 0 ? params1[Math.min(i, params1.length - 1)].getType() : null;
PsiType type2 = params2.length > 0 ? params2[Math.min(i, params2.length - 1)].getType() : null;
if (applicabilityLevel == MethodCandidateInfo.ApplicabilityLevel.VARARGS) {
- if (type1 instanceof PsiEllipsisType && type2 instanceof PsiEllipsisType &&
+ if (type1 instanceof PsiEllipsisType && type2 instanceof PsiEllipsisType &&
(!JavaVersionService.getInstance().isAtLeast(class1, JavaSdkVersion.JDK_1_7) || ((PsiArrayType)type1).getComponentType().equalsToText(CommonClassNames.JAVA_LANG_OBJECT) || ((PsiArrayType)type2).getComponentType().equalsToText(CommonClassNames.JAVA_LANG_OBJECT))) {
type1 = ((PsiEllipsisType)type1).toArrayType();
type2 = ((PsiEllipsisType)type2).toArrayType();
@@ -484,6 +494,7 @@
int[] boxingHappened = new int[2];
for (int i = 0; i < types1.length; i++) {
+ ProgressManager.checkCanceled();
PsiType type1 = classSubstitutor1.substitute(types1[i]);
PsiType type2 = classSubstitutor2.substitute(types2[i]);
PsiType argType = i < myActualParameterTypes.length ? myActualParameterTypes[i] : null;
@@ -496,6 +507,7 @@
Specifics isMoreSpecific = null;
for (int i = 0; i < types1.length; i++) {
+ ProgressManager.checkCanceled();
Specifics specifics = checkSubstitutorSpecific(method1, method2, classSubstitutor1, classSubstitutor2, types1[i], types2[i]);
if (specifics == null) {
PsiSubstitutor methodSubstitutor1 = PsiSubstitutor.EMPTY;
@@ -581,10 +593,10 @@
if (aClass1 instanceof PsiTypeParameter && aClass2 instanceof PsiTypeParameter) {
return checkTypeParams(method1, method2, classSubstitutor1, classSubstitutor2, type1, type2, (PsiTypeParameter)aClass1, (PsiTypeParameter)aClass2);
}
- if (aClass1 instanceof PsiTypeParameter) {
+ if (aClass1 instanceof PsiTypeParameter && aClass2 != null) {
return chooseHigherDimension(type1, type2);
}
- else if (aClass2 instanceof PsiTypeParameter) {
+ else if (aClass2 instanceof PsiTypeParameter && aClass1 != null) {
return chooseHigherDimension(type2, type1);
}
@@ -599,15 +611,11 @@
if (!raw1 && raw2) return Specifics.FIRST;
if (raw1 && !raw2) return Specifics.SECOND;
- final Specifics substArraySpecifics = chooseHigherDimension(t1, t2);
- if (substArraySpecifics != null) {
- return substArraySpecifics;
- }
- else {
- final PsiTypeParameter p1 = map1.keySet().iterator().next();
- final PsiTypeParameter p2 = map2.keySet().iterator().next();
- return checkTypeParams(method1, method2, classSubstitutor1, classSubstitutor2, type1, type2, p1, p2);
- }
+ final PsiTypeParameter p1 = map1.keySet().iterator().next();
+ final PsiTypeParameter p2 = map2.keySet().iterator().next();
+ final Specifics specifics = checkTypeParams(method1, method2, classSubstitutor1, classSubstitutor2, type1, type2, p1, p2);
+ if (specifics != null) return specifics;
+ return chooseHigherDimension(t1, t2);
}
return null;
}
@@ -635,6 +643,7 @@
PsiTypeParameter p2) {
final Map<PsiClass, PsiClassType> resolved1 = new HashMap<PsiClass, PsiClassType>();
for (PsiClassType referenceElement : p1.getExtendsList().getReferencedTypes()) {
+ ProgressManager.checkCanceled();
final PsiClass aClass = referenceElement.resolve();
if (aClass != null) {
resolved1.put(aClass, referenceElement);
@@ -643,6 +652,7 @@
final Map<PsiClass, PsiClassType> resolved2 = new HashMap<PsiClass, PsiClassType>();
for (PsiClassType referenceElement : p2.getExtendsList().getReferencedTypes()) {
+ ProgressManager.checkCanceled();
final PsiClass aClass = referenceElement.resolve();
if (aClass != null) {
resolved2.put(aClass, referenceElement);
@@ -660,7 +670,7 @@
TypeConversionUtil.erasure(PsiSubstitutor.EMPTY.substitute(p2)), method1, method2);
if (specifics != null) {
return specifics;
- } else {
+ } else {
final PsiType ctype1 = classSubstitutor1.substitute(type1);
final PsiType ctype2 = classSubstitutor2.substitute(type2);
return checkSubtyping(ctype1, ctype2, method1, method2);
@@ -676,6 +686,7 @@
PsiClass psiClass = iterator.next();
final PsiClassType baseType = resolved1.get(psiClass);
for (PsiClassType childType : resolved2.values()) {
+ ProgressManager.checkCanceled();
if (TypeConversionUtil.isAssignable(baseType, childType, false)) {
iterator.remove();
break;
@@ -694,6 +705,7 @@
final PsiResolveHelper resolveHelper) {
PsiSubstitutor substitutor = resolveHelper.inferTypeArguments(typeParameters, types1, types2, PsiUtil.getLanguageLevel(myArgumentsList));
for (PsiTypeParameter typeParameter : typeParameters) {
+ ProgressManager.checkCanceled();
LOG.assertTrue(typeParameter != null);
if (!substitutor.getSubstitutionMap().containsKey(typeParameter)) {
substitutor = substitutor.put(typeParameter, TypeConversionUtil.typeParameterErasure(typeParameter));
@@ -707,6 +719,7 @@
if (JavaVersionService.getInstance().isAtLeast(myArgumentsList, JavaSdkVersion.JDK_1_7)) return;
CandidateInfo objectVararg = null;
for (CandidateInfo conflict : conflicts) {
+ ProgressManager.checkCanceled();
final PsiMethod method = (PsiMethod)conflict.getElement();
final int parametersCount = method.getParameterList().getParametersCount();
if (method.isVarArgs() && parametersCount - 1 == argumentsCount) {
@@ -721,6 +734,7 @@
if (objectVararg != null) {
for (CandidateInfo conflict : conflicts) {
+ ProgressManager.checkCanceled();
PsiMethod method = (PsiMethod)conflict.getElement();
if (method != objectVararg && method != null && method.isVarArgs()) {
final int paramsCount = method.getParameterList().getParametersCount();
diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java b/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java
index 3cf132e..46036ea 100644
--- a/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java
@@ -310,6 +310,18 @@
if (referenceName instanceof PsiIdentifier && qualifier instanceof PsiExpression) {
PsiType type = ((PsiExpression)qualifier).getType();
+ if (type != null && qualifier instanceof PsiReferenceExpression) {
+ final PsiElement resolve = ((PsiReferenceExpression)qualifier).resolve();
+ if (resolve instanceof PsiVariable && ((PsiVariable)resolve).hasModifierProperty(PsiModifier.FINAL)) {
+ final PsiExpression initializer = ((PsiVariable)resolve).getInitializer();
+ if (initializer instanceof PsiNewExpression) {
+ final PsiAnonymousClass anonymousClass = ((PsiNewExpression)initializer).getAnonymousClass();
+ if (anonymousClass != null && type.equals(anonymousClass.getBaseClassType())) {
+ type = initializer.getType();
+ }
+ }
+ }
+ }
if (type == null) {
if (qualifier instanceof PsiJavaCodeReferenceElement) {
final JavaResolveResult result = ((PsiJavaCodeReferenceElement)qualifier).advancedResolve(false);
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java b/java/java-psi-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java
similarity index 86%
rename from java/java-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java
rename to java/java-psi-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java
index 441f908..369613c 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java
+++ b/java/java-psi-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java
@@ -30,7 +30,7 @@
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
-import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
import com.intellij.refactoring.util.duplicates.DuplicatesFinder;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.Nullable;
@@ -38,7 +38,7 @@
import java.util.*;
public class InputVariables {
- private final List<ParameterTablePanel.VariableData> myInputVariables;
+ private final List<VariableData> myInputVariables;
private List<? extends PsiVariable> myInitialParameters;
private final Project myProject;
@@ -62,20 +62,20 @@
/**
* copy use only
*/
- public InputVariables(List<ParameterTablePanel.VariableData> inputVariables,
+ public InputVariables(List<VariableData> inputVariables,
Project project,
LocalSearchScope scope) {
myProject = project;
myScope = scope;
- myInputVariables = new ArrayList<ParameterTablePanel.VariableData>(inputVariables);
+ myInputVariables = new ArrayList<VariableData>(inputVariables);
}
public boolean isFoldable() {
return myFolding.isFoldable();
}
- public ArrayList<ParameterTablePanel.VariableData> wrapInputVariables(final List<? extends PsiVariable> inputVariables) {
- final ArrayList<ParameterTablePanel.VariableData> inputData = new ArrayList<ParameterTablePanel.VariableData>(inputVariables.size());
+ public ArrayList<VariableData> wrapInputVariables(final List<? extends PsiVariable> inputVariables) {
+ final ArrayList<VariableData> inputData = new ArrayList<VariableData>(inputVariables.size());
for (PsiVariable var : inputVariables) {
String name = var.getName();
if (!(var instanceof PsiParameter)) {
@@ -117,7 +117,7 @@
}
}
- ParameterTablePanel.VariableData data = new ParameterTablePanel.VariableData(var, type);
+ VariableData data = new VariableData(var, type);
data.name = name;
data.passAsParameter = true;
inputData.add(data);
@@ -127,9 +127,9 @@
if (myFoldingAvailable) {
- final Set<ParameterTablePanel.VariableData> toDelete = new HashSet<ParameterTablePanel.VariableData>();
+ final Set<VariableData> toDelete = new HashSet<VariableData>();
for (int i = inputData.size() - 1; i >=0; i--) {
- final ParameterTablePanel.VariableData data = inputData.get(i);
+ final VariableData data = inputData.get(i);
if (myFolding.isParameterSafeToDelete(data, myScope)) {
toDelete.add(data);
}
@@ -189,7 +189,7 @@
return currentType;
}
- public List<ParameterTablePanel.VariableData> getInputVariables() {
+ public List<VariableData> getInputVariables() {
return myInputVariables;
}
@@ -197,15 +197,15 @@
if (!myFoldingAvailable) return expression;
boolean update = elements[0] == expression;
- for (ParameterTablePanel.VariableData inputVariable : myInputVariables) {
+ for (VariableData inputVariable : myInputVariables) {
myFolding.foldParameterUsagesInBody(inputVariable, elements, myScope);
}
return update ? (PsiExpression)elements[0] : expression;
}
public boolean toDeclareInsideBody(PsiVariable variable) {
- final ArrayList<ParameterTablePanel.VariableData> knownVars = new ArrayList<ParameterTablePanel.VariableData>(myInputVariables);
- for (ParameterTablePanel.VariableData data : knownVars) {
+ final ArrayList<VariableData> knownVars = new ArrayList<VariableData>(myInputVariables);
+ for (VariableData data : knownVars) {
if (data.variable.equals(variable)) {
return false;
}
@@ -214,7 +214,7 @@
}
public boolean contains(PsiVariable variable) {
- for (ParameterTablePanel.VariableData data : myInputVariables) {
+ for (VariableData data : myInputVariables) {
if (data.variable.equals(variable)) return true;
}
return false;
@@ -227,8 +227,8 @@
int endOffset) {
final LocalSearchScope scope = new LocalSearchScope(codeFragment);
Variables:
- for (Iterator<ParameterTablePanel.VariableData> iterator = myInputVariables.iterator(); iterator.hasNext();) {
- final ParameterTablePanel.VariableData data = iterator.next();
+ for (Iterator<VariableData> iterator = myInputVariables.iterator(); iterator.hasNext();) {
+ final VariableData data = iterator.next();
for (PsiReference ref : ReferencesSearch.search(data.variable, scope)) {
PsiElement element = ref.getElement();
int elementOffset = controlFlow.getStartOffset(element);
@@ -257,7 +257,7 @@
}
- public void appendCallArguments(ParameterTablePanel.VariableData data, StringBuilder buffer) {
+ public void appendCallArguments(VariableData data, StringBuilder buffer) {
if (myFoldingAvailable) {
buffer.append(myFolding.getGeneratedCallArgument(data));
} else {
@@ -277,7 +277,7 @@
}
public void annotateWithParameter(PsiJavaCodeReferenceElement reference) {
- for (ParameterTablePanel.VariableData data : myInputVariables) {
+ for (VariableData data : myInputVariables) {
final PsiElement element = reference.resolve();
if (data.variable.equals(element)) {
PsiType type = data.variable.getType();
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ParametersFolder.java b/java/java-psi-impl/src/com/intellij/refactoring/extractMethod/ParametersFolder.java
similarity index 93%
rename from java/java-impl/src/com/intellij/refactoring/extractMethod/ParametersFolder.java
rename to java/java-psi-impl/src/com/intellij/refactoring/extractMethod/ParametersFolder.java
index a6fed17..eac9b18 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ParametersFolder.java
+++ b/java/java-psi-impl/src/com/intellij/refactoring/extractMethod/ParametersFolder.java
@@ -31,7 +31,7 @@
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
-import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
import com.intellij.refactoring.util.duplicates.DuplicatesFinder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -54,7 +54,7 @@
myDeleted.clear();
}
- public boolean isParameterSafeToDelete(@NotNull ParameterTablePanel.VariableData data, @NotNull LocalSearchScope scope) {
+ public boolean isParameterSafeToDelete(@NotNull VariableData data, @NotNull LocalSearchScope scope) {
Next:
for (PsiReference reference : ReferencesSearch.search(data.variable, scope)) {
PsiElement expression = reference.getElement();
@@ -82,7 +82,7 @@
return false;
}
- public void foldParameterUsagesInBody(@NotNull ParameterTablePanel.VariableData data, PsiElement[] elements, SearchScope scope) {
+ public void foldParameterUsagesInBody(@NotNull VariableData data, PsiElement[] elements, SearchScope scope) {
if (myDeleted.contains(data.variable)) return;
final PsiExpression psiExpression = myExpressions.get(data.variable);
if (psiExpression == null) return;
@@ -108,7 +108,7 @@
}
}
- public boolean isParameterFoldable(@NotNull ParameterTablePanel.VariableData data,
+ public boolean isParameterFoldable(@NotNull VariableData data,
@NotNull LocalSearchScope scope,
@NotNull final List<? extends PsiVariable> inputVariables) {
final List<PsiExpression> mentionedInExpressions = getMentionedExpressions(data.variable, scope, inputVariables);
@@ -164,8 +164,8 @@
}
return false;
}
-
- private void setUniqueName(ParameterTablePanel.VariableData data) {
+
+ private void setUniqueName(VariableData data) {
int idx = 1;
while (myUsedNames.contains(data.name)) {
data.name += idx;
@@ -173,7 +173,7 @@
myUsedNames.add(data.name);
}
- private static Set<PsiVariable> findUsedVariables(ParameterTablePanel.VariableData data, final List<? extends PsiVariable> inputVariables,
+ private static Set<PsiVariable> findUsedVariables(VariableData data, final List<? extends PsiVariable> inputVariables,
PsiExpression expression) {
final Set<PsiVariable> found = new HashSet<PsiVariable>();
expression.accept(new JavaRecursiveElementVisitor() {
@@ -275,11 +275,11 @@
}
@NotNull
- public String getGeneratedCallArgument(@NotNull ParameterTablePanel.VariableData data) {
+ public String getGeneratedCallArgument(@NotNull VariableData data) {
return myExpressions.containsKey(data.variable) ? myExpressions.get(data.variable).getText() : data.variable.getName();
}
- public boolean annotateWithParameter(@NotNull ParameterTablePanel.VariableData data, @NotNull PsiElement element) {
+ public boolean annotateWithParameter(@NotNull VariableData data, @NotNull PsiElement element) {
final PsiExpression psiExpression = myExpressions.get(data.variable);
if (psiExpression != null) {
final PsiExpression expression = findEquivalent(psiExpression, element);
diff --git a/java/java-psi-impl/src/com/intellij/refactoring/util/VariableData.java b/java/java-psi-impl/src/com/intellij/refactoring/util/VariableData.java
new file mode 100644
index 0000000..0fd6cc0
--- /dev/null
+++ b/java/java-psi-impl/src/com/intellij/refactoring/util/VariableData.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2013 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.refactoring.util;
+
+import com.intellij.psi.PsiType;
+import com.intellij.psi.PsiVariable;
+import com.intellij.psi.SmartTypePointerManager;
+import org.jetbrains.annotations.NotNull;
+
+public class VariableData {
+ public final PsiVariable variable;
+ public PsiType type;
+ public String name;
+ public boolean passAsParameter;
+
+ public VariableData(@NotNull PsiVariable var) {
+ variable = var;
+ type = var.getType();
+ }
+
+ public VariableData(@NotNull PsiVariable var, @NotNull PsiType type) {
+ variable = var;
+ this.type = SmartTypePointerManager.getInstance(var.getProject()).createSmartTypePointer(type).getType();
+ }
+}
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/BreakReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/BreakReturnValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/BreakReturnValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/BreakReturnValue.java
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/ConditionalReturnStatementValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ConditionalReturnStatementValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/ConditionalReturnStatementValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ConditionalReturnStatementValue.java
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/ContinueReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ContinueReturnValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/ContinueReturnValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ContinueReturnValue.java
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java
similarity index 99%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java
index b6d8a55..d44b9d8 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java
+++ b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java
@@ -634,7 +634,7 @@
array.add(child);
}
}
- return PsiUtilBase.toPsiElementArray(array);
+ return PsiUtilCore.toPsiElementArray(array);
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/ExpressionReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ExpressionReturnValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/ExpressionReturnValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ExpressionReturnValue.java
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/FieldReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/FieldReturnValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/FieldReturnValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/FieldReturnValue.java
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/GotoReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/GotoReturnValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/GotoReturnValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/GotoReturnValue.java
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/Match.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/Match.java
similarity index 82%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/Match.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/Match.java
index 2ba06af..ef633f7 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/duplicates/Match.java
+++ b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/Match.java
@@ -26,13 +26,13 @@
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.controlFlow.*;
-import com.intellij.psi.util.*;
-import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor;
-import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashMap;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -53,7 +53,7 @@
private final Map<PsiElement, PsiElement> myDeclarationCorrespondence = new HashMap<PsiElement, PsiElement>();
private ReturnValue myReturnValue = null;
private Ref<PsiExpression> myInstanceExpression = null;
- private final Map<PsiVariable, PsiType> myChangedParams = new HashMap<PsiVariable, PsiType>();
+ final Map<PsiVariable, PsiType> myChangedParams = new HashMap<PsiVariable, PsiType>();
private final boolean myIgnoreParameterTypes;
Match(PsiElement start, PsiElement end, boolean ignoreParameterTypes) {
@@ -339,75 +339,7 @@
}
@Nullable
- public String getChangedSignature(final PsiMethod method, final boolean shouldBeStatic, String visibility) {
- final PsiType returnType = getChangedReturnType(method);
- if (!myChangedParams.isEmpty() || returnType != null) {
- @NonNls StringBuilder buffer = new StringBuilder();
- buffer.append(visibility);
- if (buffer.length() > 0) {
- buffer.append(" ");
- }
- if (shouldBeStatic) {
- buffer.append("static ");
- }
- final PsiTypeParameterList typeParameterList = method.getTypeParameterList();
- if (typeParameterList != null) {
- buffer.append(typeParameterList.getText());
- buffer.append(" ");
- }
-
- buffer.append(PsiFormatUtil.formatType(returnType != null ? returnType : method.getReturnType(), 0, PsiSubstitutor.EMPTY));
- buffer.append(" ");
- buffer.append(method.getName());
- buffer.append("(");
- int count = 0;
- final String INDENT = " ";
- final ArrayList<ParameterInfoImpl> params = patchParams(method);
- for (ParameterInfoImpl param : params) {
- String typeText = param.getTypeText();
- if (count > 0) {
- buffer.append(",");
- }
- buffer.append("\n");
- buffer.append(INDENT);
- buffer.append(typeText);
- buffer.append(" ");
- buffer.append(param.getName());
- count++;
- }
-
- if (count > 0) {
- buffer.append("\n");
- }
- buffer.append(")");
- final PsiClassType[] exceptions = method.getThrowsList().getReferencedTypes();
- if (exceptions.length > 0) {
- buffer.append("\n");
- buffer.append("throws\n");
- for (PsiType exception : exceptions) {
- buffer.append(INDENT);
- buffer.append(PsiFormatUtil.formatType(exception, 0, PsiSubstitutor.EMPTY));
- buffer.append("\n");
- }
- }
- return buffer.toString();
- }
- return null;
- }
-
- public void changeSignature(final PsiMethod psiMethod) {
- final PsiType expressionType = getChangedReturnType(psiMethod);
- if (expressionType == null && myChangedParams.isEmpty()) return;
- final ArrayList<ParameterInfoImpl> newParameters = patchParams(psiMethod);
- final ChangeSignatureProcessor csp = new ChangeSignatureProcessor(psiMethod.getProject(), psiMethod, false, null, psiMethod.getName(),
- expressionType != null ? expressionType : psiMethod.getReturnType(),
- newParameters.toArray(new ParameterInfoImpl[newParameters.size()]));
-
- csp.run();
- }
-
- @Nullable
- private PsiType getChangedReturnType(final PsiMethod psiMethod) {
+ public PsiType getChangedReturnType(final PsiMethod psiMethod) {
final PsiType returnType = psiMethod.getReturnType();
if (returnType != null) {
PsiElement parent = getMatchEnd().getParent();
@@ -487,23 +419,6 @@
return !TypeConversionUtil.isAssignable(currentType, substitutor.substitute(returnType));
}
- private ArrayList<ParameterInfoImpl> patchParams(final PsiMethod psiMethod) {
- final ArrayList<ParameterInfoImpl> newParameters = new ArrayList<ParameterInfoImpl>();
- final PsiParameter[] oldParameters = psiMethod.getParameterList().getParameters();
- for (int i = 0; i < oldParameters.length; i++) {
- final PsiParameter oldParameter = oldParameters[i];
- PsiType type = oldParameter.getType();
- for (PsiVariable variable : myChangedParams.keySet()) {
- if (PsiEquivalenceUtil.areElementsEquivalent(variable, oldParameter)) {
- type = myChangedParams.get(variable);
- break;
- }
- }
- newParameters.add(new ParameterInfoImpl(i, oldParameter.getName(), type));
- }
- return newParameters;
- }
-
public PsiFile getFile() {
return getMatchStart().getContainingFile();
}
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/ReturnStatementReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ReturnStatementReturnValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/ReturnStatementReturnValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ReturnStatementReturnValue.java
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/ReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ReturnValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/ReturnValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ReturnValue.java
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/VariableReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/VariableReturnValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/VariableReturnValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/VariableReturnValue.java
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/ComparisonFailureData.java b/java/java-runtime/src/com/intellij/rt/execution/junit/ComparisonFailureData.java
new file mode 100644
index 0000000..872fe86
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/ComparisonFailureData.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2000-2013 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.rt.execution.junit;
+
+import junit.framework.ComparisonFailure;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ComparisonFailureData {
+ private final String myExpected;
+ private final String myActual;
+ private final String myFilePath;
+
+ private static Map EXPECTED = new HashMap();
+ private static Map ACTUAL = new HashMap();
+
+ static {
+ try {
+ init(ComparisonFailure.class);
+ init(org.junit.ComparisonFailure.class);
+ }
+ catch (Throwable e) {
+ }
+ }
+
+ private static void init(Class exceptionClass) throws NoSuchFieldException {
+ final Field expectedField = exceptionClass.getDeclaredField("fExpected");
+ expectedField.setAccessible(true);
+ EXPECTED.put(exceptionClass, expectedField);
+
+ final Field actualField = exceptionClass.getDeclaredField("fActual");
+ actualField.setAccessible(true);
+ ACTUAL.put(exceptionClass, actualField);
+ }
+
+ public ComparisonFailureData(String expected, String actual) {
+ this(expected, actual, null);
+ }
+
+ public ComparisonFailureData(String expected, String actual, String filePath) {
+ myExpected = expected;
+ myActual = actual;
+ myFilePath = filePath;
+ }
+
+ public String getFilePath() {
+ return myFilePath;
+ }
+
+ public String getExpected() {
+ return myExpected;
+ }
+
+ public String getActual() {
+ return myActual;
+ }
+
+ public static ComparisonFailureData create(Throwable assertion) {
+ if (assertion instanceof FileComparisonFailure) {
+ final FileComparisonFailure comparisonFailure = (FileComparisonFailure)assertion;
+ return new ComparisonFailureData(comparisonFailure.getExpected(), comparisonFailure.getActual(), comparisonFailure.getFilePath());
+ }
+ try {
+ return new ComparisonFailureData(getExpected(assertion), getActual(assertion));
+ }
+ catch (Throwable e) {
+ return null;
+ }
+ }
+
+ public static String getActual(Throwable assertion) throws IllegalAccessException, NoSuchFieldException {
+ return get(assertion, ACTUAL, "fActual");
+ }
+
+ public static String getExpected(Throwable assertion) throws IllegalAccessException, NoSuchFieldException {
+ return get(assertion, EXPECTED, "fExpected");
+ }
+
+ private static String get(final Throwable assertion, final Map staticMap, final String fieldName) throws IllegalAccessException, NoSuchFieldException {
+ String actual;
+ if (assertion instanceof ComparisonFailure) {
+ actual = (String)((Field)staticMap.get(ComparisonFailure.class)).get(assertion);
+ }
+ else if (assertion instanceof org.junit.ComparisonFailure) {
+ actual = (String)((Field)staticMap.get(org.junit.ComparisonFailure.class)).get(assertion);
+ }
+ else {
+ Field field = assertion.getClass().getDeclaredField(fieldName);
+ field.setAccessible(true);
+ actual = (String)field.get(assertion);
+ }
+ return actual;
+ }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/FileComparisonFailure.java b/java/java-runtime/src/com/intellij/rt/execution/junit/FileComparisonFailure.java
index 0a66a53..788e872 100644
--- a/java/java-runtime/src/com/intellij/rt/execution/junit/FileComparisonFailure.java
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/FileComparisonFailure.java
@@ -31,6 +31,18 @@
myFilePath = filePath;
}
+ public String getFilePath() {
+ return myFilePath;
+ }
+
+ public String getExpected() {
+ return myExpected;
+ }
+
+ public String getActual() {
+ return myActual;
+ }
+
public PacketFactory getPacketFactory() {
return new MyPacketFactory(this, myExpected, myActual, myFilePath);
}
diff --git a/java/java-tests/java-tests.iml b/java/java-tests/java-tests.iml
index d74dcea..eb7ea31 100644
--- a/java/java-tests/java-tests.iml
+++ b/java/java-tests/java-tests.iml
@@ -30,6 +30,7 @@
<orderEntry type="module" module-name="IntentionPowerPackPlugin" scope="TEST" />
<orderEntry type="module" module-name="InspectionGadgetsPlugin" scope="TEST" />
<orderEntry type="module" module-name="java-indexing-api" scope="TEST" />
+ <orderEntry type="module" module-name="external-system-impl" scope="RUNTIME" />
</component>
</module>
diff --git a/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation.java b/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation.java
new file mode 100644
index 0000000..2cb308f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation.java
@@ -0,0 +1,6 @@
+class MyClass {
+ String hc = this.<caret>
+
+ @Annotation
+ public void myAnnotatedMethod() {}
+}
diff --git a/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation_After.java b/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation_After.java
new file mode 100644
index 0000000..71da13a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation_After.java
@@ -0,0 +1,6 @@
+class MyClass {
+ String hc = this.toString()<caret>
+
+ @Annotation
+ public void myAnnotatedMethod() {}
+}
diff --git a/java/java-tests/testData/codeInsight/completion/normal/MethodNoPairBrace_after.java b/java/java-tests/testData/codeInsight/completion/normal/MethodNoPairBrace_after.java
index c976d92..b7841df 100644
--- a/java/java-tests/testData/codeInsight/completion/normal/MethodNoPairBrace_after.java
+++ b/java/java-tests/testData/codeInsight/completion/normal/MethodNoPairBrace_after.java
@@ -3,6 +3,6 @@
void foo() {}
{
- foo(<caret>
+ foo();<caret>
}
}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/normal/MethodWithLeftParTailTypeNoPairBrace_after2.java b/java/java-tests/testData/codeInsight/completion/normal/MethodWithLeftParTailTypeNoPairBrace_after2.java
index c976d92..b7841df 100644
--- a/java/java-tests/testData/codeInsight/completion/normal/MethodWithLeftParTailTypeNoPairBrace_after2.java
+++ b/java/java-tests/testData/codeInsight/completion/normal/MethodWithLeftParTailTypeNoPairBrace_after2.java
@@ -3,6 +3,6 @@
void foo() {}
{
- foo(<caret>
+ foo();<caret>
}
}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/smartType/NewByteArray2.java b/java/java-tests/testData/codeInsight/completion/smartType/NewByteArray2.java
new file mode 100644
index 0000000..646b108
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/smartType/NewByteArray2.java
@@ -0,0 +1,10 @@
+public class Bug17 {
+
+ private void f(byte[] d) {
+ }
+
+ private void g() {
+ f(new <caret>);
+ }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/smartType/NoTailWhenNoPairBracket-out.java b/java/java-tests/testData/codeInsight/completion/smartType/NoTailWhenNoPairBracket-out.java
index 6d72b12..3580d9c 100644
--- a/java/java-tests/testData/codeInsight/completion/smartType/NoTailWhenNoPairBracket-out.java
+++ b/java/java-tests/testData/codeInsight/completion/smartType/NoTailWhenNoPairBracket-out.java
@@ -1,6 +1,6 @@
class A {
{
String x;
- Class c = x.getClass(<caret>
+ Class c = x.getClass()<caret>
}
}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/smartType/NoTailWhenNoPairBracket2-out.java b/java/java-tests/testData/codeInsight/completion/smartType/NoTailWhenNoPairBracket2-out.java
index 5dbeaa6..63fd0d5 100644
--- a/java/java-tests/testData/codeInsight/completion/smartType/NoTailWhenNoPairBracket2-out.java
+++ b/java/java-tests/testData/codeInsight/completion/smartType/NoTailWhenNoPairBracket2-out.java
@@ -1,6 +1,6 @@
class A {
{
- Class c = this.xxxxx(<caret>
+ Class c = this.xxxxx()<caret>
}
Class xxxxx() {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/IDEA78916.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/IDEA78916.java
index 214a3ae..fa1ed55 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/IDEA78916.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/IDEA78916.java
@@ -35,4 +35,14 @@
public abstract void execute();
private void firstMethod() {}
+}
+
+class Test {
+ private class Foo {
+ private Foo() {}
+
+ {
+ new Foo(){};
+ }
+ }
}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA105846.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA105846.java
index 8b9c700..04d39bd 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA105846.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA105846.java
@@ -1,5 +1,6 @@
class MyClass {
public static void main(Class<? extends MyClass> clazz){
clazz = (Class<? extends MyClass>) clazz.getSuperclass();
+ <error descr="Incompatible types. Found: 'java.lang.Class<capture<? super capture<? extends MyClass>>>', required: 'java.lang.Class<? extends MyClass>'">clazz = clazz.getSuperclass()</error>;
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA106964.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA106964.java
new file mode 100644
index 0000000..8c8603e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA106964.java
@@ -0,0 +1,12 @@
+import java.io.Serializable;
+
+public abstract class Test {
+
+ abstract <T> T test(Class<T> cls);
+
+ abstract <T> T test(Serializable type);
+
+ private void call(){
+ <error descr="Incompatible types. Found: 'java.lang.String[]', required: 'java.lang.String'">String s = test(String[].class);</error>
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA107782.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA107782.java
new file mode 100644
index 0000000..a078c65
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA107782.java
@@ -0,0 +1,15 @@
+public class Test {
+ {
+ final <error descr="Incompatible types. Found: 'java.lang.Object', required: 'MyResult'">MyResult hello = parseXML(new Parser());</error>
+ }
+ public <R, P extends AbstractParser & Result<R>> R parseXML(P parser) {
+ R result = null;
+ return result;
+ }
+}
+class MyResult {}
+
+class AbstractParser {}
+interface Result<T> {}
+class Parser extends AbstractParser implements Result {}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA107957.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA107957.java
new file mode 100644
index 0000000..1228be1
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA107957.java
@@ -0,0 +1,37 @@
+class Test1 {
+
+ private static final Foo<Boolean> test = new Foo().method(Boolean.TRUE);
+
+ public static void main(String[] args) {
+ System.out.println(test);
+ }
+
+ public static class Foo<T> {
+ public Foo<Boolean> method(boolean arg) {
+ return null;
+ }
+
+ public <T extends Enum<T>> Foo<T> method(T arg) {
+ return null;
+ }
+ }
+}
+
+class Test2 {
+
+ private static final Foo<Boolean> test = Foo.method(Boolean.TRUE);
+
+ public static void main(String[] args) {
+ System.out.println(test);
+ }
+
+ public static class Foo<T> {
+ public static Foo<Boolean> method(boolean arg) {
+ return null;
+ }
+
+ public static <T extends Enum<T>> Foo<T> method(T arg) {
+ return null;
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/SelfStaticsOnly.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/SelfStaticsOnly.java
new file mode 100644
index 0000000..b9f90eb
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/SelfStaticsOnly.java
@@ -0,0 +1,14 @@
+interface Function<T, R> {
+ public R apply(T t);
+
+ static <K> Function<K, K> baz() {
+ return k -> k;
+ }
+}
+
+interface IFunction extends Function<Integer, Integer> {
+ static void bar() {}
+ static void ba() {
+ ba<caret>
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/StaticMethodCalls.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/StaticMethodCalls.java
new file mode 100644
index 0000000..0c517e9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/StaticMethodCalls.java
@@ -0,0 +1,25 @@
+
+class Bug {
+
+ interface Function<T, R> {
+ public R apply(T t);
+
+ static <K> Function<K, K> identity() {
+ return k -> k;
+ }
+ }
+
+ interface IFunction extends Function<Integer, Integer> {
+ static void a() {
+ Function<Integer, Integer> identity = <error descr="Static method may be invoked on containing interface class only">identity();</error>
+ }
+ }
+
+ public void foo() {
+ Function<Integer, Integer> f = Function.identity();
+
+ Function<Integer, Integer> g = <error descr="Static method may be invoked on containing interface class only">f.identity();</error>
+
+ Function<Integer, Integer> h = <error descr="Static method may be invoked on containing interface class only">IFunction.identity();</error>
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/RefOnArrayDeclaration.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/RefOnArrayDeclaration.java
index 3ed7e3e..0fa9c84 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/RefOnArrayDeclaration.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/RefOnArrayDeclaration.java
@@ -45,3 +45,16 @@
ObjectArrayReturnType a5 = Foo<? extends String>[]::new;
}
}
+
+
+class IDEA106973 {
+ interface Function<T, R> {
+ R apply(T t);
+ }
+
+ {
+ Function<Integer, String[]> a = String[] :: new;
+ <error descr="Incompatible types. Found: '<method reference>', required: 'IDEA106973.Function<java.lang.String,java.lang.String[]>'">Function<String, String[]> a1 = String[] :: new;</error>
+ Function<Short, String[]> a2 = String[] :: new;
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/VarargsMethodRef.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/VarargsMethodRef.java
new file mode 100644
index 0000000..7edfd28
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/VarargsMethodRef.java
@@ -0,0 +1,26 @@
+import java.util.List;
+
+class Test {
+ void a(List<String> range1, List<String> range2) {
+ zip(range1, range2, Test::<String>asList);
+ I1<String> i = Test :: asList;
+ }
+
+ public static <A, B, C> List<C> zip(List<? extends A> a,
+ List<? extends B> b,
+ BiFunction<? super A, ? super B, ? extends C> zipper) {
+ return null;
+ }
+
+ public interface BiFunction<T, U, R> {
+ R apply(T t, U u);
+ }
+
+ public static <T> List<T> asList(T... a) {
+ return null;
+ }
+
+ interface I1<T> {
+ List<T> a(T... t);
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createPropertyFromUsage/afterFieldExist.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createPropertyFromUsage/afterFieldExist.java
index e9baac3..f20329a 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createPropertyFromUsage/afterFieldExist.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createPropertyFromUsage/afterFieldExist.java
@@ -6,7 +6,7 @@
setI(0);
}
- public void setI(int i) {
+ void setI(int i) {
this.i = i;
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createPropertyFromUsage/afterSimple.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createPropertyFromUsage/afterSimple.java
index b28d93d..69c33eb 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createPropertyFromUsage/afterSimple.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createPropertyFromUsage/afterSimple.java
@@ -6,7 +6,7 @@
setI(0);
}
- public void setI(int i) {
+ void setI(int i) {
this.i = i;
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/iterateOver/before4.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/iterateOver/before4.java
new file mode 100644
index 0000000..a355f5b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/iterateOver/before4.java
@@ -0,0 +1,6 @@
+// "Iterate" "false"
+class Test {
+ void foo() {
+ java.lang.thi<caret>s
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/afterChain.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/afterChain.java
index 7d3370d..cd556b8 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/afterChain.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/afterChain.java
@@ -5,6 +5,6 @@
class A{
void test(){
Integer integer = null;
- int i = integer != null ? integer.toString().length() : <selection>0</selection>;
+ int i = integer != null ? integer.toString().length() : <caret><selection>0</selection>;
}
}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/after1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/after1.java
index a89027d..f5d44db 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/after1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/after1.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'List<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'List<java.lang.Integer>'" "true"
public class Test {
void foo() {
List<Integer> list = new List<>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/after2TypeParamsInOneCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/after2TypeParamsInOneCall.java
index 622c3e2..a7a54e2 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/after2TypeParamsInOneCall.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/after2TypeParamsInOneCall.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'Lost<java.lang.String,java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'Lost<java.lang.String,java.lang.Integer>'" "true"
public class Test {
void foo() {
Lost<String, Integer> list = new Lost<>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterAnotherParamTypeChange.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterAnotherParamTypeChange.java
index 1b85916..fbae0b9 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterAnotherParamTypeChange.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterAnotherParamTypeChange.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'Lost<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'Lost<java.lang.Integer>'" "true"
public class Test {
void foo() {
Lost<Integer> list = new Lost<>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterBoxing.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterBoxing.java
index 1b43850..0818ad2 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterBoxing.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterBoxing.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'List<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'List<java.lang.Integer>'" "true"
public class Test {
void foo() {
List<Integer> list = new List<>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterCompound.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterCompound.java
index a6e6d60..67cc9ed 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterCompound.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterCompound.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'Lost<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'Lost<java.lang.Integer>'" "true"
public class Test {
void foo() {
Lost<Integer> list = new Lost<>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterMixed.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterMixed.java
index 802baaf..ce1f568 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterMixed.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterMixed.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'Lost<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'Lost<java.lang.Integer>'" "true"
public class Test {
void foo() {
Lost<Integer> list = new Lost<>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/before1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/before1.java
index c14b834..d35d424 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/before1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/before1.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'List<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'List<java.lang.Integer>'" "true"
public class Test {
void foo() {
List<String> list = new List<String>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/before2TypeParamsInOneCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/before2TypeParamsInOneCall.java
index ee27ed3..9dd0ab1 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/before2TypeParamsInOneCall.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/before2TypeParamsInOneCall.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'Lost<java.lang.String,java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'Lost<java.lang.String,java.lang.Integer>'" "true"
public class Test {
void foo() {
Lost<String, String> list = new Lost<String, String>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeAnotherParamTypeChange.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeAnotherParamTypeChange.java
index 61e8684..f4558d1 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeAnotherParamTypeChange.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeAnotherParamTypeChange.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'Lost<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'Lost<java.lang.Integer>'" "true"
public class Test {
void foo() {
Lost<String> list = new Lost<String>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeBoxing.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeBoxing.java
index 1d02b91..88778ca 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeBoxing.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeBoxing.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'List<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'List<java.lang.Integer>'" "true"
public class Test {
void foo() {
List<String> list = new List<String>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeChangeSignatureAvailable.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeChangeSignatureAvailable.java
index 9f5ec3b..a2206b0 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeChangeSignatureAvailable.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeChangeSignatureAvailable.java
@@ -1,4 +1,4 @@
-// "Change 'var' type to 'Foo" "false"
+// "Change variable 'var' type to 'Foo" "false"
public class Test {
void foo() {
final Foo var = new Foo();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeCompound.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeCompound.java
index aa2eb0c..7f2dc11 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeCompound.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeCompound.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'Lost<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'Lost<java.lang.Integer>'" "true"
public class Test {
void foo() {
Lost<String> list = new Lost<String>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeMixed.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeMixed.java
index b0d6cab..074e647 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeMixed.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeMixed.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'Lost<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'Lost<java.lang.Integer>'" "true"
public class Test {
void foo() {
Lost<String> list = new Lost<String>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after1.java
index b7f7e63..06c81a4 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after1.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'int[][]'" "true"
+// "Change variable 'test' type to 'int[][]'" "true"
class A {
void m() {
final int[][] test = {new int<caret>[]{1}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after2.java
index 1cadb61..2f4ebd3 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after2.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after2.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'int[][]'" "true"
+// "Change variable 'test' type to 'int[][]'" "true"
class A {
void m() {
int[][] test = new int[][]{<caret>{1}, {2}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after3.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after3.java
index 1cadb61..2f4ebd3 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after3.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after3.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'int[][]'" "true"
+// "Change variable 'test' type to 'int[][]'" "true"
class A {
void m() {
int[][] test = new int[][]{<caret>{1}, {2}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after4.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after4.java
index 89ddf94..0a68cc2 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after4.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after4.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'int[][]'" "true"
+// "Change variable 'test' type to 'int[][]'" "true"
class A {
void m() {
int[][] test = new int[][]{{<caret>1}, {2}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after5.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after5.java
index 8893a91..9534a4f 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after5.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after5.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'char[]'" "true"
+// "Change variable 'test' type to 'char[]'" "true"
class A {
void m() {
final char[] test = new char[]{<caret>'a'};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after6.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after6.java
index 0debead..5aec9e2 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after6.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after6.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'char[]'" "true"
+// "Change variable 'test' type to 'char[]'" "true"
class A {
void m() {
final char[] test = {<caret>'a'};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after9.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after9.java
index a74a518..896709f 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after9.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after9.java
@@ -1,4 +1,4 @@
-// "Change 'myArr' type to 'char[][]'" "true"
+// "Change field 'myArr' type to 'char[][]'" "true"
class A extends B {
void m() {
myArr = new char[][]{{<caret>'a'}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before1.java
index 34cc492..e61ec51 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before1.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'int[][]'" "true"
+// "Change variable 'test' type to 'int[][]'" "true"
class A {
void m() {
final Long[][] test = {new int<caret>[]{1}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before2.java
index be9e287..e79fc74 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before2.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before2.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'int[][]'" "true"
+// "Change variable 'test' type to 'int[][]'" "true"
class A {
void m() {
Long[][][] test = new Long[]{<caret>{1}, {2}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before3.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before3.java
index 35e45cd..c191198 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before3.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before3.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'int[][]'" "true"
+// "Change variable 'test' type to 'int[][]'" "true"
class A {
void m() {
Long[] test = new Long[]{<caret>{1}, {2}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before4.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before4.java
index 007800e..4fa4be4 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before4.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before4.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'int[][]'" "true"
+// "Change variable 'test' type to 'int[][]'" "true"
class A {
void m() {
Long test = new Long[][][][]{{<caret>1}, {2}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before5.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before5.java
index a048c22..f9e177a 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before5.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before5.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'char[]'" "true"
+// "Change variable 'test' type to 'char[]'" "true"
class A {
void m() {
final Long[] test = new Long[]{<caret>'a'};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before6.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before6.java
index 2e5b97f..be8d3f8 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before6.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before6.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'char[]'" "true"
+// "Change variable 'test' type to 'char[]'" "true"
class A {
void m() {
final Long[] test = {<caret>'a'};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before7.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before7.java
index 769d870..ca5e5ea 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before7.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before7.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'char[]'" "false"
+// "Change variable 'test' type to 'char[]'" "false"
class A {
void m() {
final Long[] test = {<caret>'a', 1};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before8.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before8.java
index 0d64ee5..cd07ae8 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before8.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before8.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'char[][]'" "false"
+// "Change variable 'test' type to 'char[][]'" "false"
class A {
void m() {
final Long[] test = {<caret>{'a'}, {1}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before9.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before9.java
index de63666..24cc6b3 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before9.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before9.java
@@ -1,4 +1,4 @@
-// "Change 'myArr' type to 'char[][]'" "true"
+// "Change field 'myArr' type to 'char[][]'" "true"
class A extends B {
void m() {
myArr = new String[][]{{<caret>'a'}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/after1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/after1.java
index ea910a3..7c815dc 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/after1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/after1.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'a.i.ii<java.lang.String>'" "true"
+// "Change variable 'i' type to 'a.i.ii<java.lang.String>'" "true"
class a
{
class i {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/before1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/before1.java
index defc656..74da8a6 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/before1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/before1.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'a.i.ii<java.lang.String>'" "true"
+// "Change variable 'i' type to 'a.i.ii<java.lang.String>'" "true"
class a
{
class i {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/before2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/before2.java
index 88cad2e..c3533aa 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/before2.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/before2.java
@@ -1,4 +1,4 @@
-// "Change 's' type to 'O.f<java.lang.String>'" "false"
+// "Change variable 's' type to 'O.f<java.lang.String>'" "false"
class O {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after1.java
index a588bf7..4a73de6 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after1.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'double'" "true"
+// "Change variable 'i' type to 'double'" "true"
import java.io.*;
class a {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after2.java
index 3ee033e..d2f02db 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after2.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after2.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'java.lang.String'" "true"
+// "Change variable 'i' type to 'java.lang.String'" "true"
import java.io.*;
class a {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after3.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after3.java
index 61d52c1..e29ef26 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after3.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after3.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'char'" "true"
+// "Change variable 'i' type to 'char'" "true"
import java.io.*;
class a {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after4.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after4.java
index d7b4163..4b4f439 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after4.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after4.java
@@ -1,4 +1,4 @@
-// "Change 's' type to 'java.lang.Runnable'" "true"
+// "Change field 's' type to 'java.lang.Runnable'" "true"
class a {
Runnable s = new Runnable() {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after5.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after5.java
index 6a7f841..84d6850 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after5.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after5.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'java.lang.String'" "true"
+// "Change parameter 'i' type to 'java.lang.String'" "true"
class Base {
void foo(String i) {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterInCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterInCall.java
index 35b2904..f707135 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterInCall.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterInCall.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'java.lang.String'" "true"
+// "Change parameter 'i' type to 'java.lang.String'" "true"
class Ex{
void foo(String i) {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before1.java
index 4e8742b..245c148 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before1.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'double'" "true"
+// "Change variable 'i' type to 'double'" "true"
import java.io.*;
class a {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before2.java
index 6b80da6..9591611 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before2.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before2.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'java.lang.String'" "true"
+// "Change variable 'i' type to 'java.lang.String'" "true"
import java.io.*;
class a {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before3.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before3.java
index f94ad9a..de69713 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before3.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before3.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'char'" "true"
+// "Change variable 'i' type to 'char'" "true"
import java.io.*;
class a {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before4.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before4.java
index 6265e56..b93daef 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before4.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before4.java
@@ -1,4 +1,4 @@
-// "Change 's' type to 'java.lang.Runnable'" "true"
+// "Change field 's' type to 'java.lang.Runnable'" "true"
class a {
String s = <caret>new Runnable() {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before5.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before5.java
index 7ead738..e2ce5b4 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before5.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before5.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'java.lang.String'" "true"
+// "Change parameter 'i' type to 'java.lang.String'" "true"
class Base {
void foo(int i) {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeInCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeInCall.java
index 92a32c9..4c4999a 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeInCall.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeInCall.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'java.lang.String'" "true"
+// "Change parameter 'i' type to 'java.lang.String'" "true"
class Ex{
void foo(int i) {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeInLibCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeInLibCall.java
index 337af8a..62fde5e 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeInLibCall.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeInLibCall.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'long'" "false"
+// "Change parameter 'i' type to 'long'" "false"
class M extends Thread {
@Override
diff --git a/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods.java b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods.java
new file mode 100644
index 0000000..b7c36e9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods.java
@@ -0,0 +1,30 @@
+import java.lang.Override;
+import java.lang.String;
+
+class BaseClass {
+ public void method() {
+ //do nothing
+ }
+
+ public void method2() {
+
+ }
+}
+
+class ClassEx1 extends BaseClass {
+ @Override
+ public void method() {
+ }
+}
+
+class ClassEx2 extends BaseClass {
+ public void method() {
+ }
+
+ public void method(String aString) {
+ }
+}
+
+class MyClass extends B<caret>aseClass {
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods2.java b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods2.java
new file mode 100644
index 0000000..931d40b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods2.java
@@ -0,0 +1,31 @@
+import java.lang.Override;
+import java.lang.String;
+
+class BaseClass {
+ public void method() {
+ //do nothing
+ }
+
+ public void method(String s) {
+ //do nothing
+ }
+}
+
+class ClassEx1 extends BaseClass {
+ @Override
+ public void method() {
+ }
+
+ @Override
+ public void method(String s) {
+ }
+}
+
+class ClassEx2 extends BaseClass {
+ public void method() {
+ }
+}
+
+class MyClass extends B<caret>aseClass {
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods3.java b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods3.java
new file mode 100644
index 0000000..d79ab2f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods3.java
@@ -0,0 +1,39 @@
+import java.lang.Override;
+import java.lang.String;
+
+class BaseClass {
+ public void method() {
+ //do nothing
+ }
+
+ public void method(String s) {
+ //do nothing
+ }
+}
+
+class ClassEx1 extends BaseClass {
+ @Override
+ public void method() {
+ }
+
+ @Override
+ public void method(String s) {
+ }
+
+ public void method2() {
+ }
+}
+
+class ClassEx11 extends ClassEx1 {
+ public void method2() {
+ }
+}
+
+class ClassEx2 extends BaseClass {
+ public void method() {
+ }
+}
+
+class MyClass extends Cl<caret>assEx1 {
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods4.java b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods4.java
new file mode 100644
index 0000000..0295f9f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods4.java
@@ -0,0 +1,40 @@
+import java.lang.Override;
+import java.lang.String;
+
+class BaseClass {
+ public void method() {
+ //do nothing
+ }
+
+ public void method(String s) {
+ //do nothing
+ }
+}
+
+class ClassEx1 extends BaseClass {
+ @Override
+ public void method(String s) {
+ }
+
+ public void method2() {
+ }
+}
+
+class ClassEx11 extends ClassEx1 {
+ public void method2() {
+ }
+}
+
+class ClassEx2 extends BaseClass {
+ public void method() {
+ }
+}
+
+class ClassEx3 extends BaseClass {
+ public void method() {
+ }
+}
+
+class MyClass extends Cl<caret>assEx1 {
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods5.java b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods5.java
new file mode 100644
index 0000000..a330bf3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods5.java
@@ -0,0 +1,63 @@
+import java.lang.Override;
+import java.lang.String;
+
+class BaseClass {
+ public void method() {
+ //do nothing
+ }
+
+ public void method(String s) {
+ //do nothing
+ }
+}
+
+class ClassEx2 extends BaseClass {
+ public void method() {
+ }
+}
+
+class ClassEx3 extends BaseClass {
+ public void method() {
+ }
+}
+
+class ClassEx1 extends BaseClass {
+ @Override
+ public void method(String s) {
+ }
+
+ public void method2() {
+ }
+}
+
+class ClassEx11 extends ClassEx1 {
+ @Override
+ public void method(String s) {
+ }
+
+ public void method2() {
+ }
+}
+
+class ClassEx12 extends ClassEx1 {
+ @Override
+ public void method(String s) {
+ }
+
+ public void method2() {
+ }
+}
+
+class ClassEx13 extends ClassEx1 {
+ @Override
+ public void method(String s) {
+ }
+
+ public void method2() {
+ }
+}
+
+
+class MyClass extends Cl<caret>assEx1 {
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/afterParenthesis.java b/java/java-tests/testData/codeInsight/invertIfCondition/afterParenthesis.java
new file mode 100644
index 0000000..19bb377
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/invertIfCondition/afterParenthesis.java
@@ -0,0 +1,10 @@
+// "Invert If Condition" "true"
+class A {
+ public boolean foo(boolean a, boolean b, boolean c, boolean d) {
+
+ if ((a || b) && !c && !d) {
+ return true;
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/beforeParenthesis.java b/java/java-tests/testData/codeInsight/invertIfCondition/beforeParenthesis.java
new file mode 100644
index 0000000..269790e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/invertIfCondition/beforeParenthesis.java
@@ -0,0 +1,9 @@
+// "Invert If Condition" "true"
+class A {
+ public boolean foo(boolean a, boolean b, boolean c, boolean d) {
+
+ if (!(a |<caret>| b) || c || d)
+ return false;
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/javadocIG/literal.html b/java/java-tests/testData/codeInsight/javadocIG/literal.html
new file mode 100644
index 0000000..bc3d265
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/javadocIG/literal.html
@@ -0,0 +1,2 @@
+<html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><small><b><a href="psi_element://Foo"><code>Foo</code></a></b></small><PRE>int <b>foo</b></PRE>
+ foo<></body></html>
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/javadocIG/literal.java b/java/java-tests/testData/codeInsight/javadocIG/literal.java
new file mode 100644
index 0000000..a6413f5
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/javadocIG/literal.java
@@ -0,0 +1,6 @@
+class Foo {
+ /**
+ * foo{@literal <>}
+ */
+ int foo;
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/overrideImplement/afterRawInheritance.java b/java/java-tests/testData/codeInsight/overrideImplement/afterRawInheritance.java
new file mode 100644
index 0000000..75297f7
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/overrideImplement/afterRawInheritance.java
@@ -0,0 +1,11 @@
+class Obj<T> {}
+abstract class A1<X>{
+ abstract void foo(Obj<String> x);
+}
+
+class B1 extends A1{
+ @Override
+ void foo(Obj x) {
+ <caret>
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/overrideImplement/beforeRawInheritance.java b/java/java-tests/testData/codeInsight/overrideImplement/beforeRawInheritance.java
new file mode 100644
index 0000000..f546cae
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/overrideImplement/beforeRawInheritance.java
@@ -0,0 +1,8 @@
+class Obj<T> {}
+abstract class A1<X>{
+ abstract void foo(Obj<String> x);
+}
+
+class B1 extends A1{
+ <caret>
+}
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/EqualsHasNoSideEffects.java b/java/java-tests/testData/inspection/dataFlow/fixture/EqualsHasNoSideEffects.java
index 20d33e1..a3780aa 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/EqualsHasNoSideEffects.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/EqualsHasNoSideEffects.java
@@ -13,7 +13,7 @@
else if (((user == null && <warning descr="Condition 'identifier.user == null' is always 'true' when reached">identifier.user == null</warning>)
|| (this.user.equals(identifier.user)))
&&
- ((requestorClass == null && <warning descr="Condition 'identifier.requestorClass == null' is always 'true' when reached">identifier.requestorClass == null</warning>)
+ ((requestorClass == null && identifier.requestorClass == null)
|| this.requestorClass.equals(identifier.requestorClass)))
return true;
else
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/FieldChangedBetweenSynchronizedBlocks.java b/java/java-tests/testData/inspection/dataFlow/fixture/FieldChangedBetweenSynchronizedBlocks.java
index 411e3a0..63e606b 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/FieldChangedBetweenSynchronizedBlocks.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/FieldChangedBetweenSynchronizedBlocks.java
@@ -12,7 +12,7 @@
if (field != null) {
return;
}
- if (<warning descr="Condition 'field == null' is always 'true'">field == null</warning>) {
+ if (field == null) {
System.out.println();
}
}
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/MutableNotAnnotatedFieldsTreatment.java b/java/java-tests/testData/inspection/dataFlow/fixture/MutableNotAnnotatedFieldsTreatment.java
index c542ba8..038315f 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/MutableNotAnnotatedFieldsTreatment.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/MutableNotAnnotatedFieldsTreatment.java
@@ -54,12 +54,12 @@
System.out.println(data.hashCode());
}
- void warnWhenDoubleChecked_This_WithMethodCall() {
+ void doNotWarnWhenDoubleChecked_This_WithMethodCall() {
if (data == null) {
return;
}
System.out.println(data.hashCode());
- if (<warning descr="Condition 'data == null' is always 'false'">data == null</warning>) {
+ if (data == null) {
return;
}
System.out.println(data.hashCode());
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/MutableNullableFieldsTreatment.java b/java/java-tests/testData/inspection/dataFlow/fixture/MutableNullableFieldsTreatment.java
index 107d11f..282c63e 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/MutableNullableFieldsTreatment.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/MutableNullableFieldsTreatment.java
@@ -56,12 +56,12 @@
System.out.println(data.hashCode());
}
- void warnWhenDoubleChecked_This_WithMethodCall() {
+ void doNotWarnWhenDoubleChecked_This_WithMethodCall() {
if (data == null) {
return;
}
System.out.println(data.hashCode());
- if (<warning descr="Condition 'data == null' is always 'false'">data == null</warning>) {
+ if (data == null) {
return;
}
System.out.println(data.hashCode());
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/NotNullPrimitive.java b/java/java-tests/testData/inspection/dataFlow/fixture/NotNullPrimitive.java
new file mode 100644
index 0000000..d76f214
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/NotNullPrimitive.java
@@ -0,0 +1,24 @@
+import org.jetbrains.annotations.NotNull;
+
+class Foo {
+ public int getValue() {
+ return 5;
+ }
+
+ public void nullcheck() {
+ Integer x = getValue();
+ System.out.println(<warning descr="Condition 'x == null' is always 'false'">x == null</warning> ? "NULL" : Integer.toHexString(x));
+ }
+}
+
+class Bar {
+ @NotNull
+ public Integer getValue() {
+ return 5;
+ }
+
+ public void nullcheck() {
+ Integer x = getValue();
+ System.out.println(<warning descr="Condition 'x == null' is always 'false'">x == null</warning> ? "NULL" : Integer.toHexString(x));
+ }
+}
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/OtherCallMayChangeFields.java b/java/java-tests/testData/inspection/dataFlow/fixture/OtherCallMayChangeFields.java
new file mode 100644
index 0000000..9b7ee85
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/OtherCallMayChangeFields.java
@@ -0,0 +1,26 @@
+class Ref {
+ int i;
+ Object obj;
+}
+
+class Modifier {
+ void foo(Ref r) { r.i = 239; r.obj = null; }
+}
+
+class Test {
+ void foo(Ref r, Modifier m) {
+ if (r.i == 0) {
+ m.foo(r);
+ if (r.i == 0) {
+ return;
+ }
+ }
+ if (r.obj == null) {
+ m.foo(r);
+ if (r.obj == null) {
+ return;
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/StringConcatAlwaysNotNull.java b/java/java-tests/testData/inspection/dataFlow/fixture/StringConcatAlwaysNotNull.java
new file mode 100644
index 0000000..dd38e5a
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/StringConcatAlwaysNotNull.java
@@ -0,0 +1,15 @@
+import org.jetbrains.annotations.NotNull;
+
+class X {
+ @NotNull
+ String foo() {return "";}
+
+ void bar() {
+ String o = foo();
+ o += "";
+ if (<warning descr="Condition 'o != null' is always 'true'">o != null</warning>) {
+
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/cls/mirror/ClassRefs.txt b/java/java-tests/testData/psi/cls/mirror/ClassRefs.txt
index ce11e0e..f0da4d5 100644
--- a/java/java-tests/testData/psi/cls/mirror/ClassRefs.txt
+++ b/java/java-tests/testData/psi/cls/mirror/ClassRefs.txt
@@ -5,7 +5,8 @@
package pkg;
class ClassRefs {
- @pkg.AnnWithTypeLocal(type = java.lang.String.class)
+ @pkg.DefaultArgAnno(java.lang.String.class)
+ @pkg.NamedArgAnno(type = java.lang.String.class)
public static final java.lang.Class<?> cls;
ClassRefs() { /* compiled code */ }
diff --git a/java/java-tests/testData/psi/cls/mirror/ValuedEnum.txt b/java/java-tests/testData/psi/cls/mirror/ValuedEnum.txt
new file mode 100644
index 0000000..eec6980
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/ValuedEnum.txt
@@ -0,0 +1,19 @@
+
+ // IntelliJ API Decompiler stub source generated from a class file
+ // Implementation of methods is not available
+
+package org.apache.commons.lang.enum;
+
+public abstract class ValuedEnum extends org.apache.commons.lang.enum.Enum {
+ private final int iValue;
+
+ protected ValuedEnum(java.lang.String name, int value) { /* compiled code */ }
+
+ protected static org.apache.commons.lang.enum.Enum getEnum(java.lang.Class enumClass, int value) { /* compiled code */ }
+
+ public final int getValue() { /* compiled code */ }
+
+ public int compareTo(java.lang.Object other) { /* compiled code */ }
+
+ public java.lang.String toString() { /* compiled code */ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/AnnWithTypeLocal.class b/java/java-tests/testData/psi/cls/mirror/pkg/AnnWithTypeLocal.class
deleted file mode 100644
index 9252a8e..0000000
--- a/java/java-tests/testData/psi/cls/mirror/pkg/AnnWithTypeLocal.class
+++ /dev/null
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/ClassRefs.class b/java/java-tests/testData/psi/cls/mirror/pkg/ClassRefs.class
index ca03e1b..693426f 100644
--- a/java/java-tests/testData/psi/cls/mirror/pkg/ClassRefs.class
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/ClassRefs.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/DefaultArgAnno.class b/java/java-tests/testData/psi/cls/mirror/pkg/DefaultArgAnno.class
new file mode 100644
index 0000000..1709f6e
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/DefaultArgAnno.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/NamedArgAnno.class b/java/java-tests/testData/psi/cls/mirror/pkg/NamedArgAnno.class
new file mode 100644
index 0000000..ae31837
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/NamedArgAnno.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/ValuedEnum.class b/java/java-tests/testData/psi/cls/mirror/pkg/ValuedEnum.class
new file mode 100644
index 0000000..5dbc74d
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/ValuedEnum.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/src/pkg/ClassRefs.java b/java/java-tests/testData/psi/cls/mirror/src/pkg/ClassRefs.java
index af3784c..9bbfe0d 100644
--- a/java/java-tests/testData/psi/cls/mirror/src/pkg/ClassRefs.java
+++ b/java/java-tests/testData/psi/cls/mirror/src/pkg/ClassRefs.java
@@ -1,10 +1,15 @@
package pkg;
class ClassRefs {
- @AnnWithTypeLocal(type = String.class)
+ @DefaultArgAnno(String.class)
+ @NamedArgAnno(type = String.class)
public static final Class<?> cls = String.class; // class refs are set from class initaializer
}
-@interface AnnWithTypeLocal {
- Class type();
+@interface DefaultArgAnno {
+ Class<?> value();
+}
+
+@interface NamedArgAnno {
+ Class<?> type();
}
diff --git a/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous.java b/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous.java
new file mode 100644
index 0000000..fa5180a
--- /dev/null
+++ b/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous.java
@@ -0,0 +1,13 @@
+public class Foo {
+ public void update() {}
+}
+
+class FooBar {
+ {
+ Foo tm = new Foo() {
+ {
+ <selection>update()</selection>;
+ }
+ };
+ }
+}
diff --git a/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous_after.java b/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous_after.java
new file mode 100644
index 0000000..575b821
--- /dev/null
+++ b/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous_after.java
@@ -0,0 +1,17 @@
+public class Foo {
+ public void update() {}
+}
+
+class FooBar {
+ {
+ Foo tm = new Foo() {
+ {
+ newMethod();
+ }
+
+ private void newMethod() {
+ update();
+ }
+ };
+ }
+}
diff --git a/java/java-tests/testData/refactoring/introduceParameterObject/copyJavadoc1/after/Test.java b/java/java-tests/testData/refactoring/introduceParameterObject/copyJavadoc1/after/Test.java
new file mode 100644
index 0000000..8152842
--- /dev/null
+++ b/java/java-tests/testData/refactoring/introduceParameterObject/copyJavadoc1/after/Test.java
@@ -0,0 +1,27 @@
+class Test {
+ /**
+ * foo comment
+ * @param param
+ * @param s1 long1 description1
+ */
+ void foo(Param param, String s1) {
+ bar(param.getS(), s1);
+ }
+
+ void bar(String s, String s1){}
+
+ private static class Param {
+ private final String s;
+
+ /**
+ * @param s long description
+ */
+ private Param(String s) {
+ this.s = s;
+ }
+
+ public String getS() {
+ return s;
+ }
+ }
+}
diff --git a/java/java-tests/testData/refactoring/introduceParameterObject/copyJavadoc1/before/Test.java b/java/java-tests/testData/refactoring/introduceParameterObject/copyJavadoc1/before/Test.java
new file mode 100644
index 0000000..af7c82f
--- /dev/null
+++ b/java/java-tests/testData/refactoring/introduceParameterObject/copyJavadoc1/before/Test.java
@@ -0,0 +1,12 @@
+class Test {
+ /**
+ * foo comment
+ * @param s long description
+ * @param s1 long1 description1
+ */
+ void foo(String s, String s1) {
+ bar(s, s1);
+ }
+
+ void bar(String s, String s1){}
+}
diff --git a/java/java-tests/testData/refactoring/renameInplace/Incomplete.java b/java/java-tests/testData/refactoring/renameInplace/Incomplete.java
new file mode 100644
index 0000000..78eaf1b
--- /dev/null
+++ b/java/java-tests/testData/refactoring/renameInplace/Incomplete.java
@@ -0,0 +1,3 @@
+class Klaz {
+ final static Class K = Klaz<caret>
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/renameInplace/Incomplete_after.java b/java/java-tests/testData/refactoring/renameInplace/Incomplete_after.java
new file mode 100644
index 0000000..93fbccb
--- /dev/null
+++ b/java/java-tests/testData/refactoring/renameInplace/Incomplete_after.java
@@ -0,0 +1,3 @@
+class Klazz {
+ final static Class K = Klazz<caret>
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/safeDelete/InterfaceAsTypeParameterBound.java b/java/java-tests/testData/refactoring/safeDelete/InterfaceAsTypeParameterBound.java
new file mode 100644
index 0000000..855ed15
--- /dev/null
+++ b/java/java-tests/testData/refactoring/safeDelete/InterfaceAsTypeParameterBound.java
@@ -0,0 +1,3 @@
+interface Foo1 {}
+interface FooTo<caret>Delete extends Foo1 {}
+class TypeParamOwner<B extends FooToDelete> {}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/safeDelete/InterfaceAsTypeParameterBound_after.java b/java/java-tests/testData/refactoring/safeDelete/InterfaceAsTypeParameterBound_after.java
new file mode 100644
index 0000000..c0c81b0
--- /dev/null
+++ b/java/java-tests/testData/refactoring/safeDelete/InterfaceAsTypeParameterBound_after.java
@@ -0,0 +1,3 @@
+interface Foo1 {}
+
+class TypeParamOwner<B extends Foo1> {}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/TestClassesFilterTest.java b/java/java-tests/testSrc/com/intellij/TestClassesFilterTest.java
index 2a00e76..2bbdb91 100644
--- a/java/java-tests/testSrc/com/intellij/TestClassesFilterTest.java
+++ b/java/java-tests/testSrc/com/intellij/TestClassesFilterTest.java
@@ -1,49 +1,35 @@
/*
- * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * 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
*
- * -Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * -Redistribution in binary form must reproduct the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the distribution.
- *
- * Neither the name of JetBrains or IntelliJ IDEA
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * This software is provided "AS IS," without a warranty of any kind. ALL
- * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
- * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT
- * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT
- * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS
- * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST
- * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
- * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
- * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN
- * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
+ * 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;
import com.intellij.openapi.diagnostic.Logger;
-import junit.framework.TestCase;
+import org.junit.Test;
import java.io.ByteArrayInputStream;
-import java.io.IOException;
import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
-public class TestClassesFilterTest extends TestCase {
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class TestClassesFilterTest {
private static final Logger LOG = Logger.getInstance("#com.intellij.TestClassesFilterTest");
- @SuppressWarnings({"IOResourceOpenedButNotSafelyClosed"})
- public void test() throws IOException {
-
+ @Test
+ public void test() throws Exception {
LOG.info("test");
String filterText = "[Group1]\n" +
@@ -55,9 +41,7 @@
"com.intellij.package6.ExcludedTest\n" +
"com.intellij.package7.*package8";
-
- TestClassesFilter classesFilter = GroupBasedTestClassFilter
- .createOn(new InputStreamReader(new ByteArrayInputStream(filterText.getBytes())), "Group1");
+ TestClassesFilter classesFilter = GroupBasedTestClassFilter.createOn(getReader(filterText), "Group1");
assertTrue(classesFilter.matches("com.intellij.package1.Test"));
assertTrue(classesFilter.matches("com.intellij.package1.Test2"));
assertFalse(classesFilter.matches("com.intellij.package2.Test"));
@@ -67,7 +51,6 @@
assertFalse(classesFilter.matches("com.intellij.package3"));
assertFalse(classesFilter.matches("com.intellij"));
assertFalse(classesFilter.matches("com.intellij.Test"));
-
assertFalse(classesFilter.matches("com.intellij.package5.Test"));
assertFalse(classesFilter.matches("com.intellij.package5.Test2"));
assertFalse(classesFilter.matches("com.intellij.package6.Test"));
@@ -76,8 +59,7 @@
assertFalse(classesFilter.matches("com.intellij.package7.package5.package8"));
assertFalse(classesFilter.matches("com.intellij.package7"));
- classesFilter = GroupBasedTestClassFilter
- .createOn(new InputStreamReader(new ByteArrayInputStream(filterText.getBytes())), "Group2");
+ classesFilter = GroupBasedTestClassFilter.createOn(getReader(filterText), "Group2");
assertFalse(classesFilter.matches("com.intellij.package1.Test"));
assertFalse(classesFilter.matches("com.intellij.package1.Test2"));
assertFalse(classesFilter.matches("com.intellij.package2.Test"));
@@ -87,7 +69,6 @@
assertFalse(classesFilter.matches("com.intellij.package3"));
assertFalse(classesFilter.matches("com.intellij"));
assertFalse(classesFilter.matches("com.intellij.Test"));
-
assertTrue(classesFilter.matches("com.intellij.package5.Test"));
assertTrue(classesFilter.matches("com.intellij.package5.Test2"));
assertFalse(classesFilter.matches("com.intellij.package6.Test"));
@@ -96,14 +77,18 @@
assertTrue(classesFilter.matches("com.intellij.package7.package5.package8"));
assertFalse(classesFilter.matches("com.intellij.package7"));
- checkForNullGroup(filterText, null);
- checkForNullGroup(filterText, GroupBasedTestClassFilter.ALL_EXCLUDE_DEFINED);
+ classesFilter = GroupBasedTestClassFilter.createOn(getReader(filterText), null);
+ checkForNullGroup(classesFilter);
+ classesFilter = GroupBasedTestClassFilter.createOn(getReader(filterText), GroupBasedTestClassFilter.ALL_EXCLUDE_DEFINED);
+ checkForNullGroup(classesFilter);
}
- private static void checkForNullGroup(String filterText, String group0Name) {
- TestClassesFilter classesFilter = GroupBasedTestClassFilter.createOn(new InputStreamReader(new ByteArrayInputStream(filterText.getBytes())), group0Name);
+ private static InputStreamReader getReader(String filterText) throws UnsupportedEncodingException {
+ return new InputStreamReader(new ByteArrayInputStream(filterText.getBytes("UTF-8")));
+ }
+ private static void checkForNullGroup(TestClassesFilter classesFilter) {
assertFalse(classesFilter.matches("com.intellij.package1.Test"));
assertFalse(classesFilter.matches("com.intellij.package1.Test2"));
assertTrue(classesFilter.matches("com.intellij.package2.Test"));
@@ -113,7 +98,6 @@
assertTrue(classesFilter.matches("com.intellij.package3"));
assertTrue(classesFilter.matches("com.intellij"));
assertTrue(classesFilter.matches("com.intellij.Test"));
-
assertFalse(classesFilter.matches("com.intellij.package5.Test"));
assertFalse(classesFilter.matches("com.intellij.package5.Test2"));
assertTrue(classesFilter.matches("com.intellij.package6.Test"));
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy
index 2ec1ed6..7cc14eb 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy
@@ -38,6 +38,28 @@
public void testIdentifierSeparator() throws Exception { doTest(); }
public void testMethodFromAnonymousClass() throws Exception { doTest(); }
+ public void testAddImport() {
+ myFixture.addClass("package foo; public class Foo {}")
+ myFixture.configureByText "a.java", "import foo.F<caret>oo;"
+ performCopy();
+ myFixture.configureByText "b.java", "class Goo { <caret> }"
+ performPaste();
+ myFixture.checkResult """import foo.Foo;
+
+class Goo { Foo }"""
+
+ }
+
+ public void testFqnInImport() {
+ myFixture.addClass("package foo; public class Foo {}")
+ myFixture.configureByText "a.java", "import foo.F<caret>oo;"
+ performCopy();
+ myFixture.configureByText "b.java", "import <caret>"
+ performPaste();
+ myFixture.checkResult """import foo.Foo<caret>"""
+
+ }
+
public void testCopyFile() throws Exception {
PsiFile psiFile = myFixture.addFileToProject("x/x.txt", "");
assertTrue(CopyReferenceAction.doCopy(psiFile, getProject()));
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java
index 3ed1526..95de823 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java
@@ -65,6 +65,7 @@
public void testErasureWildcard() { doTest(false); }
public void testMultipleInterfaceInheritance() { doTest(false); }
public void testResolveTypeParamConflict() { doTest(false); }
+ public void testRawInheritance() { doTest(false); }
public void testImplementExtensionMethods() { doTest8(false, true); }
public void testOverrideExtensionMethods() { doTest8(false, false); }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
index 11cfb31..226dbfb 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
@@ -385,50 +385,64 @@
assert !lookup
}
- void testArrow(boolean up, boolean cycleScrolling, boolean lookupAbove, int index) {
- myFixture.configureByText("a.java", """
- class A {
- { ArrayIndexOutOfBoundsException <caret> }
- }
- """)
+ void testArrows(String toType, int indexDown, int indexUp) {
+ Closure checkArrow = { String action, int expectedIndex ->
+ myFixture.configureByText("a.java", """
+ class A {
+ void foo() {}
+ void farObject() {}
+ void fzrObject() {}
+ { <caret> }
+ }
+ """)
- type 'ind'
- assert lookup
- assert !lookup.focused
- assert lookup.items.size() == 2
+ type toType
+ assert lookup
+ assert !lookup.focused
- lookup.positionedAbove = lookupAbove
- UISettings.instance.CYCLE_SCROLLING = cycleScrolling
-
- def action = up ? IdeActions.ACTION_EDITOR_MOVE_CARET_UP : IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN
- try {
edt { myFixture.performEditorAction(action) }
if (lookup) {
assert lookup.focused
- assert index >= 0
- assert lookup.items[index] == lookup.currentItem
+ assert expectedIndex >= 0
+ assert lookup.items[expectedIndex] == lookup.currentItem
edt { lookup.hide() }
} else {
- assert index == -1
+ assert expectedIndex == -1
}
type '\b'
}
+
+ checkArrow(IdeActions.ACTION_EDITOR_MOVE_CARET_UP, indexUp)
+ checkArrow(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN, indexDown)
+ }
+
+ public void "test vertical arrows in non-focused lookup"() {
+ String toType = "ArrayIndexOutOfBoundsException ind"
+ testArrows toType, 0, 1
+
+ UISettings.instance.CYCLE_SCROLLING = false
+ try {
+ testArrows toType, 0, -1
+ }
finally {
UISettings.instance.CYCLE_SCROLLING = true
}
-
}
- void testArrows(boolean cycleScrolling, boolean lookupAbove, int indexDown, int indexUp) {
- testArrow true, cycleScrolling, lookupAbove, indexUp
- testArrow false, cycleScrolling, lookupAbove, indexDown
- }
+ public void "test vertical arrows in semi-focused lookup"() {
+ CodeInsightSettings.instance.SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS = false
+ UISettings.getInstance().SORT_LOOKUP_ELEMENTS_LEXICOGRAPHICALLY = true
- public void testVerticalArrows() {
- testArrows false, false, 0, -1
- testArrows false, true, 0, -1
- testArrows true, false, 0, 1
- testArrows true, true, 0, 1
+ String toType = "fo"
+ testArrows toType, 2, 0
+
+ UISettings.instance.CYCLE_SCROLLING = false
+ try {
+ testArrows toType, 2, 0
+ }
+ finally {
+ UISettings.instance.CYCLE_SCROLLING = true
+ }
}
public void testHideOnOnePrefixVariant() {
@@ -517,7 +531,7 @@
@Override
void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
result.runRemainingContributors(parameters, true)
- Thread.sleep 1000
+ Thread.sleep 500
}
}
@@ -634,9 +648,9 @@
}
public void testNoSingleTemplateLookup() {
- myFixture.configureByText 'a.java', 'class Foo {{ ite<caret> }}'
- type 'r'
- assert !lookup
+ myFixture.configureByText 'a.java', 'class Foo { psv<caret> }'
+ type 'm'
+ assert !lookup : myFixture.lookupElementStrings
}
public void testTemplatesWithNonImportedClasses() {
@@ -666,7 +680,7 @@
}
""")
type 'er '
- assert myFixture.editor.document.text.contains('iter ')
+ assert !myFixture.editor.document.text.contains('for ')
}
public void testNewClassParenthesis() {
@@ -780,24 +794,21 @@
private void joinSomething(int degree) {
if (degree == 0) return
- joinAlarm()
+ joinCommit()
if (degree == 1) return
joinCommit()
if (degree == 2) return
- joinCommit()
- if (degree == 3) return
edt {}
- if (degree == 4) return
+ if (degree == 3) return
joinCompletion()
}
public void testEveryPossibleWayToTypeIf() {
def src = "class Foo { { int ifa; <caret> } }"
def result = "class Foo { { int ifa; if <caret> } }"
- int actions = 5
+ int actions = 4
for (a1 in 0..actions) {
- println "a1 = $a1"
for (a2 in 0..actions) {
myFixture.configureByText("$a1 $a2 .java", src)
myFixture.type 'i'
@@ -1140,9 +1151,7 @@
myFixture.addClass("package bar; public class Abcdefg {}")
myFixture.configureByText 'a.java', 'class Foo extends <caret>'
type 'Abcde'
- assert lookup.items.size() == 1
- type ' '
- myFixture.checkResult 'class Foo extends Abcdefg <caret>'
+ assert lookup.items.size() == 2
}
public void testClassNameInProperties() {
@@ -1186,8 +1195,8 @@
public void testAmbiguousClassQualifier() {
myFixture.addClass("package foo; public class Util<T> { public static void foo() {}; public static final int CONSTANT = 2; }")
myFixture.addClass("package bar; public class Util { public static void bar() {} }")
- myFixture.configureByText 'a.java', 'class Foo {{ <caret> }}'
- type 'Util.'
+ myFixture.configureByText 'a.java', 'class Foo {{ Util<caret> }}'
+ type '.'
assert myFixture.lookupElementStrings == ['Util.bar', 'Util.CONSTANT', 'Util.foo']
def p = LookupElementPresentation.renderElement(myFixture.lookupElements[1])
@@ -1231,7 +1240,7 @@
}
'''
type 'File('
- assert myFixture.file.text.contains('new File()')
+ assert myFixture.editor.document.text.contains('new File()')
}
public void "test inaccessible class in another package shouldn't prevent choosing by space"() {
@@ -1289,7 +1298,7 @@
type 'System.out.pr'
assert lookup.currentItem.lookupString == 'println'
type '\n2'
- assert myFixture.file.text.contains('.println();2')
+ assert myFixture.editor.document.text.contains('.println();2')
}
public void testQuickBackspaceEnter() {
@@ -1312,10 +1321,6 @@
myTester.joinAutopopup()
}
- protected def joinAlarm() {
- myTester.joinAlarm()
- }
-
public void "test new primitive array in Object variable"() {
CodeInsightSettings.instance.COMPLETION_CASE_SENSITIVE = CodeInsightSettings.NONE
myFixture.configureByText 'a.java', '''
@@ -1402,7 +1407,37 @@
'''
type 'sette'
myFixture.assertPreferredCompletionItems 1, 'setHorizontalText', 'setText'
+ edt { myFixture.performEditorAction IdeActions.ACTION_EDITOR_MOVE_CARET_UP }
+ myFixture.assertPreferredCompletionItems 0, 'setHorizontalText', 'setText'
}
+ public void "test pressing enter while autopopup is calculating variants should cancel autopopup"() {
+ registerContributor(LongContributor, LoadingOrder.FIRST)
+ myFixture.configureByText "a.java", "class Foo {{ <caret> }}"
+ myFixture.type('a')
+ joinAutopopup()
+ type('\n')
+ assert !lookup
+ }
+
+ public void "test pressing enter and a letter while autopopup is calculating variants should restart autopopup"() {
+ registerContributor(LongContributor, LoadingOrder.FIRST)
+ myFixture.configureByText "a.java", "class Foo {{ <caret> }}"
+ myFixture.type('a')
+ joinAutopopup()
+ myFixture.type('\na')
+ joinCompletion()
+ assert lookup
+ }
+
+ public void "test a random write action shouldn't cancel autopopup"() {
+ registerContributor(LongContributor, LoadingOrder.FIRST)
+ myFixture.configureByText "a.java", "class Foo {{ <caret> }}"
+ myFixture.type('a')
+ joinAutopopup()
+ edt { ApplicationManager.application.runWriteAction {} }
+ joinCompletion()
+ assert lookup
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
index 0ce04d2..4882f8b 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
@@ -536,7 +536,11 @@
}
public void testNoThisInComment() throws Throwable { doAntiTest() }
- public void testIncNull() throws Throwable { doAntiTest() }
+ public void testIncNull() throws Throwable {
+ configure()
+ checkResultByFile(getTestName(false) + ".java")
+ assert !('null' in myFixture.lookupElementStrings)
+ }
public void testLastExpressionInFor() throws Throwable { doTest(); }
@@ -1363,6 +1367,32 @@
}}'''
}
+ public void "test complete lowercase class name"() {
+ myFixture.addClass("package foo; public class myClass {}")
+ myFixture.configureByText "a.java", """
+class Foo extends my<caret>
+"""
+ myFixture.completeBasic()
+ myFixture.type('\n')
+ myFixture.checkResult '''import foo.myClass;
+class Foo extends myClass
+'''
+ }
+
+ public void "test don't show static inner class after instance qualifier"() {
+ myFixture.configureByText "a.java", """
+class Foo {
+ static class Inner {}
+}
+class Bar {
+ void foo(Foo f) {
+ f.<caret>
+ }
+}
+"""
+ myFixture.completeBasic()
+ assert !('Inner' in myFixture.lookupElementStrings)
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java
index a8fc06a..ed7e90d 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java
@@ -613,7 +613,13 @@
configureByTestName();
assertStringItems("byte");
assertEquals("[]", LookupElementPresentation.renderElement(myItems[0]).getTailText());
+ }
+ public void testNewByteArray2() {
+ configureByTestName();
+ assertStringItems("byte", "byte");
+ assertEquals("[]", LookupElementPresentation.renderElement(myItems[0]).getTailText());
+ assertEquals("[]{...}", LookupElementPresentation.renderElement(myItems[1]).getTailText());
}
public void testInsideStringLiteral() throws Throwable { doAntiTest(); }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/TabCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/TabCompletionTest.java
index a2481a4..212ced5 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/TabCompletionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/TabCompletionTest.java
@@ -14,6 +14,14 @@
checkResultByFile("MethodLookup3_After.java");
}
+ public void _testMethodCallBeforeAnnotation() {
+ String name = getTestName(false);
+ myFixture.configureByFile(name + ".java");
+ myFixture.completeBasic();
+ myFixture.type("tos\t");
+ checkResultByFile(name + "_After.java");
+ }
+
public void testReplaceThisWithSuper() throws Throwable {
configureByFile("ReplaceThisWithSuper.java");
checkResultByFile("ReplaceThisWithSuper_After.java");
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
index ca4c17a..dd144e5 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
@@ -236,6 +236,9 @@
public void testIDEA20244() throws Exception { doTest5(false);}
public void testIDEA22005() throws Exception { doTest5(false);}
public void testIDEA57259() throws Exception { doTest5(false);}
+ public void testIDEA107957() throws Exception { doTest6(false);}
+ public void testIDEA106964() throws Exception { doTest5(false);}
+ public void testIDEA107782() throws Exception { doTest5(false);}
public void testInheritedWithDifferentArgsInTypeParams() throws Exception { doTest5(false);}
public void testIllegalForwardReferenceInTypeParameterDefinition() throws Exception { doTest5(false);}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ImportHelperTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ImportHelperTest.java
index a66134f..9761eb4 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ImportHelperTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ImportHelperTest.java
@@ -228,7 +228,7 @@
((UndoManagerImpl)UndoManager.getInstance(getProject())).clearUndoRedoQueueInTests(getFile().getVirtualFile());
type(" ");
backspace();
-
+
assertOneElement(highlightErrors());
int offset = myEditor.getCaretModel().getOffset();
@@ -260,7 +260,7 @@
((UndoManagerImpl)UndoManager.getInstance(getProject())).clearUndoRedoQueueInTests(getFile().getVirtualFile());
type(" ");
backspace();
-
+
assertEquals(2, highlightErrors().size());
UIUtil.dispatchAllInvocationEvents();
@@ -429,6 +429,30 @@
}
}
+ public void testAutoImportSkipsClassReferenceInMethodPosition() throws Throwable {
+ @NonNls String text = "package x; import java.util.HashMap; class S { HashMap<String,String> f(){ return Hash<caret>Map <String, String >();} } ";
+ configureByText(StdFileTypes.JAVA, text);
+
+ boolean old = CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY;
+ CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY = true;
+ DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(true);
+
+ try {
+ List<HighlightInfo> errs = highlightErrors();
+ assertTrue(errs.size() > 1);
+
+ PsiJavaFile javaFile = (PsiJavaFile)getFile();
+ assertEquals(1, javaFile.getImportList().getAllImportStatements().length);
+
+ PsiReference ref = javaFile.findReferenceAt(getEditor().getCaretModel().getOffset());
+ ImportClassFix fix = new ImportClassFix((PsiJavaCodeReferenceElement)ref);
+ assertFalse(fix.isAvailable(getProject(), getEditor(), getFile()));
+ }
+ finally {
+ CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY = old;
+ }
+ }
+
public void testAutoImportDoNotBreakCode() throws Throwable {
@NonNls String text = "package x; class S {{ S.<caret>\n Runnable r; }}";
configureByText(StdFileTypes.JAVA, text);
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
index e77dff3..cf99110 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
@@ -30,6 +30,7 @@
public void testStaticMethodsInFunctionalInterface() { doTest(false, false); }
public void testCyclicSubstitutor() { doTest(false, false); }
public void testThisAccessibility() { doTest(false, false); }
+ public void testStaticMethodCalls() { doTest(false, false); }
private void doTest() {
doTest(false, false);
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
index fb83e99..c47059e 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
@@ -78,6 +78,7 @@
public void testGetClassSpecifics() { doTest(); }
public void testAbstractMethod() { doTest(); }
public void testMethodRefAcceptance() { doTest(); }
+ public void testVarargsMethodRef() { doTest(); }
public void testTypeParameterWithExtendsList() throws Exception {
doTest();
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Normal8CompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Normal8CompletionTest.java
new file mode 100644
index 0000000..bb5f0a2
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Normal8CompletionTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2013 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.codeInsight.daemon.lambda;
+
+import com.intellij.JavaTestUtil;
+import com.intellij.codeInsight.completion.LightFixtureCompletionTestCase;
+import com.intellij.testFramework.LightProjectDescriptor;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * User: anna
+ */
+public class Normal8CompletionTest extends LightFixtureCompletionTestCase {
+ @NotNull
+ @Override
+ protected LightProjectDescriptor getProjectDescriptor() {
+ return JAVA_LATEST;
+ }
+
+ @Override
+ protected String getBasePath() {
+ return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/";
+ }
+
+ public void testSelfStaticsOnly() throws Exception {
+ configureByFile("SelfStaticsOnly.java");
+ assertStringItems("ba", "bar");
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AnnotateMethodTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AnnotateMethodTest.java
index f285ee4..1b92a0c 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AnnotateMethodTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AnnotateMethodTest.java
@@ -24,7 +24,7 @@
protected AnnotateMethodFix createAnnotateMethodFix(String defaultNotNull, String[] annotationsToRemove) {
return new AnnotateMethodFix(defaultNotNull, annotationsToRemove){
@Override
- public int annotateBaseMethod(final PsiMethod method, final PsiMethod superMethod, final Project project) {
+ public int shouldAnnotateBaseMethod(final PsiMethod method, final PsiMethod superMethod, final Project project) {
@NonNls String name = method.getName();
int ret = name.startsWith("annotateBase") ? 0 // yes, annotate all
: name.startsWith("dontAnnotateBase") ? 1 // do not annotate base
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/generation/methodsOverridingStatistics/JavaMethodsOverridingStatisticsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/generation/methodsOverridingStatistics/JavaMethodsOverridingStatisticsTest.java
new file mode 100644
index 0000000..e41125c
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/generation/methodsOverridingStatistics/JavaMethodsOverridingStatisticsTest.java
@@ -0,0 +1,77 @@
+package com.intellij.codeInsight.generation.methodsOverridingStatistics;
+
+import com.intellij.JavaTestUtil;
+import com.intellij.codeInsight.generation.OverrideImplementExploreUtil;
+import com.intellij.codeInsight.generation.OverrideImplementUtil;
+import com.intellij.codeInsight.generation.PsiMethodWithOverridingPercentMember;
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.infos.CandidateInfo;
+import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
+import com.intellij.util.containers.ContainerUtil;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Dmitry Batkovich <dmitry.batkovich@jetbrains.com>
+ */
+@SuppressWarnings("unchecked")
+public class JavaMethodsOverridingStatisticsTest extends JavaCodeInsightFixtureTestCase {
+
+ @Override
+ protected String getTestDataPath() {
+ return JavaTestUtil.getJavaTestDataPath() + "/codeInsight/generation/javaMethodsOverridingStatistics/";
+ }
+
+ public void testMethods() {
+ doTest(1, pair("method", 100));
+ }
+
+ public void testMethods2() {
+ doTest(2, pair("method", 50), pair("method", 100));
+ }
+
+ public void testMethods3() {
+ doTest(1, pair("method2", 100));
+ }
+
+ public void testMethods4() {
+ doTest(2, pair("method2", 100), pair("method", 50));
+ }
+
+ public void testMethods5() {
+ doTest(3, pair("method", 100), pair("method2", 100), pair("method", 33));
+ }
+
+ private void doTest(final int resultSize, final Pair<String, Integer>... expectedValues) {
+ myFixture.configureByFile(getTestName(false) + ".java");
+
+ final PsiClass contextClass =
+ OverrideImplementUtil.getContextClass(myFixture.getProject(), myFixture.getEditor(), myFixture.getFile(), true);
+ assert contextClass != null;
+
+ if (OverrideImplementExploreUtil.getMethodSignaturesToOverride(contextClass).isEmpty() && expectedValues.length != 0) {
+ fail();
+ }
+
+ final Collection<CandidateInfo> candidateInfos = OverrideImplementExploreUtil.getMethodsToOverrideImplement(contextClass, false);
+ final PsiMethodWithOverridingPercentMember[] searchResults = PsiMethodWithOverridingPercentMember
+ .calculateOverridingPercents(candidateInfos);
+ assertSize(resultSize, searchResults);
+
+ final Set<Pair<String, Integer>> actualValues = new HashSet<Pair<String, Integer>>();
+ for (PsiMethodWithOverridingPercentMember searchResult : searchResults) {
+ actualValues.add(Pair.<String, Integer>create(searchResult.getElement().getName(), searchResult.getOverridingPercent()));
+ }
+
+ final Set<Pair<String, Integer>> expectedValuesSet = ContainerUtil.newHashSet(expectedValues);
+
+ assertEquals(expectedValuesSet, actualValues);
+ }
+
+ private static Pair<String, Integer> pair(final String methodName, final int percent) {
+ return Pair.create(methodName, percent);
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
index 9fefc23..28644e9 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
@@ -64,6 +64,10 @@
doTestField();
}
+ public void testLiteral() throws Exception {
+ doTestField();
+ }
+
public void testEnumConstantOrdinal() throws Exception {
PsiClass psiClass = getTestClass();
PsiField field = psiClass.getFields() [0];
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy
index 372c180..af208b0 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy
@@ -540,4 +540,15 @@
}
}
+ public void "test expand current live template on no suggestions in lookup"() {
+ myFixture.configureByText "a.java", "class Foo {{ <caret> }}"
+ myFixture.completeBasic()
+ assert myFixture.lookup
+ myFixture.type("sout")
+ assert myFixture.lookup
+ assert myFixture.lookupElementStrings == []
+ myFixture.type('\t')
+ myFixture.checkResult "class Foo {{\n System.out.println(<caret>); }}"
+ }
+
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
index 82650d6..fc5824c 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
@@ -68,7 +68,9 @@
public void testIDEA84489() throws Throwable { doTest(); }
public void testComparingToNotNullShouldNotAffectNullity() throws Throwable { doTest(); }
public void testStringTernaryAlwaysTrue() throws Throwable { doTest(); }
+ public void testStringConcatAlwaysNotNull() throws Throwable { doTest(); }
+ public void testNotNullPrimitive() throws Throwable { doTest(); }
public void testBoxing128() throws Throwable { doTest(); }
public void testFinalFieldsInitializedByAnnotatedParameters() throws Throwable { doTest(); }
public void testMultiCatch() throws Throwable { doTest(); }
@@ -147,6 +149,7 @@
public void testMutableVolatileNullableFieldsTreatment() { doTest(); }
public void testMutableNotAnnotatedFieldsTreatment() { doTest(); }
public void testSuperCallMayChangeFields() { doTest(); }
+ public void testOtherCallMayChangeFields() { doTest(); }
public void testMethodCallFlushesField() { doTest(); }
public void testUnknownFloatMayBeNaN() { doTest(); }
diff --git a/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java b/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java
index abbb152..75c7bf1 100644
--- a/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java
+++ b/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java
@@ -38,10 +38,10 @@
public void testSelectLeafFirst3() throws Exception {checkTree("clear");}
public void testSelectLeafFirst4() throws Exception {checkTree("clear");}
- @Bombed(user = "peter", month = Calendar.MAY, day = 10)
+ @Bombed(user = "peter", month = Calendar.JUNE, day = 10)
public void testMatcher1() throws Exception {checkTree("ico");}
- @Bombed(user = "peter", month = Calendar.MAY, day = 10)
+ @Bombed(user = "peter", month = Calendar.JUNE, day = 10)
public void testMatcher2() throws Exception {checkTree("ico");}
- @Bombed(user = "peter", month = Calendar.MAY, day = 10)
+ @Bombed(user = "peter", month = Calendar.JUNE, day = 10)
public void testAnonymousMatcher2() throws Exception {checkTree("ico");}
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
index 14c2e29..0217607 100644
--- a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
@@ -42,6 +42,7 @@
public void testEA40568() { doTest(); }
public void testBooleans() { doTest(); }
public void testClassRefs() { doTest(); }
+ public void testEA46236() { doTest("ValuedEnum"); }
private void doTest() {
doTest(getTestName(false));
diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerSpecialRuleTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerSpecialRuleTest.groovy
new file mode 100644
index 0000000..024f0cd
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerSpecialRuleTest.groovy
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2000-2013 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.psi.codeStyle.arrangement
+
+import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Modifier.*
+import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Order.BY_NAME
+
+import org.junit.Before
+
+/**
+ * @author Svetlana.Zemlyanskaya
+ */
+
+class JavaRearrangerSpecialRuleTest extends AbstractJavaRearrangerTest {
+
+ @Before
+ void setUp() {
+ super.setUp()
+ commonSettings.BLANK_LINES_AROUND_METHOD = 0
+ commonSettings.BLANK_LINES_AROUND_CLASS = 0
+ }
+
+ void "test name and visibility conditions"() {
+ doTest(
+ initial: '''\
+class Test {
+ public void getI() {}
+ public void setI() {}
+ private void test() {}
+}''',
+ expected: '''\
+class Test {
+ public void setI() {}
+ public void getI() {}
+ private void test() {}
+}''',
+ rules: [rule(PUBLIC), nameRule("get.*", PUBLIC)]
+ )
+ }
+
+ void "test modifier conditions"() {
+ doTest(
+ initial: '''\
+class Test {
+ public static void a() {}
+ public voic b() {}
+}
+''',
+ expected: '''\
+class Test {
+ public voic b() {}
+ public static void a() {}
+}
+''',
+ rules: [rule(PUBLIC), rule(PUBLIC, STATIC)]
+ )
+ }
+
+ void "test multi modifier condition"() {
+ doTest(
+ initial: '''\
+class Test {
+ public abstract void a() {}
+ public static void b() {}
+ public voic c() {}
+}
+''',
+ expected: '''\
+class Test {
+ public voic c() {}
+ public static void b() {}
+ public abstract void a() {}
+}
+''',
+ rules: [rule(PUBLIC), rule(PUBLIC, STATIC), rule(PUBLIC, ABSTRACT)]
+ )
+ }
+
+ void "test modifier conditions with sort"() {
+ doTest(
+ initial: '''\
+class Test {
+ public void e() {}
+ public static void d() {}
+ public void c() {}
+ public static void b() {}
+ public void a() {}
+}
+''',
+ expected: '''\
+class Test {
+ public void a() {}
+ public void c() {}
+ public void e() {}
+ public static void b() {}
+ public static void d() {}
+}
+''',
+ rules: [ruleWithOrder(BY_NAME, rule(PUBLIC)), ruleWithOrder(BY_NAME, rule(PUBLIC, STATIC))]
+ )
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/source/tree/java/JavadocParamTagsTest.java b/java/java-tests/testSrc/com/intellij/psi/impl/source/tree/java/JavadocParamTagsTest.java
index 2cb329b..5fa7fa8 100644
--- a/java/java-tests/testSrc/com/intellij/psi/impl/source/tree/java/JavadocParamTagsTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/impl/source/tree/java/JavadocParamTagsTest.java
@@ -1,6 +1,6 @@
package com.intellij.psi.impl.source.tree.java;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.psi.*;
@@ -163,7 +163,7 @@
final PsiDocTag[] tags = docComment.getTags();
final PsiDocTag tag2 = factory.createParamTag("p2", "");
docComment.addAfter(tag2, tags[0]);
- docComment = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(docComment);
+ docComment = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(docComment);
assertEquals(
"/**\n" +
" * Javadoc\n" +
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java
index 3191c09..3639cbd 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java
@@ -583,6 +583,10 @@
doDuplicatesTest();
}
+ public void testTargetAnonymous() throws Exception {
+ doTest();
+ }
+
private void doTestDisabledParam() throws PrepareFailedException {
final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
settings.ELSE_ON_NEW_LINE = true;
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterObjectTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterObjectTest.java
index bd70e5d..905f87e 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterObjectTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterObjectTest.java
@@ -27,7 +27,7 @@
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.introduceparameterobject.IntroduceParameterObjectProcessor;
-import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
import com.intellij.util.Function;
import com.intellij.util.VisibilityUtil;
@@ -46,9 +46,9 @@
}
private void doTest(final boolean delegate, final boolean createInner) throws Exception {
- doTest(delegate, createInner, new Function<PsiMethod, ParameterTablePanel.VariableData[]>() {
+ doTest(delegate, createInner, new Function<PsiMethod, VariableData[]>() {
@Override
- public ParameterTablePanel.VariableData[] fun(PsiMethod psiMethod) {
+ public VariableData[] fun(PsiMethod psiMethod) {
return generateParams(psiMethod);
}
});
@@ -56,7 +56,7 @@
private void doTest(final boolean delegate,
final boolean createInner,
- final Function<PsiMethod, ParameterTablePanel.VariableData[]> function) throws Exception {
+ final Function<PsiMethod, VariableData[]> function) throws Exception {
doTest(new PerformAction() {
@Override
public void performAction(final VirtualFile rootDir, final VirtualFile rootAfter) throws Exception {
@@ -65,7 +65,7 @@
assertNotNull("Class Test not found", aClass);
final PsiMethod method = aClass.findMethodsByName("foo", false)[0];
- final ParameterTablePanel.VariableData[] datas = function.fun(method);
+ final VariableData[] datas = function.fun(method);
IntroduceParameterObjectProcessor processor = new IntroduceParameterObjectProcessor("Param", "", null, method, datas, delegate, false,
createInner, null, false);
@@ -74,13 +74,13 @@
});
}
- private static ParameterTablePanel.VariableData[] generateParams(final PsiMethod method) {
+ private static VariableData[] generateParams(final PsiMethod method) {
final PsiParameter[] parameters = method.getParameterList().getParameters();
- final ParameterTablePanel.VariableData[] datas = new ParameterTablePanel.VariableData[parameters.length];
+ final VariableData[] datas = new VariableData[parameters.length];
for (int i = 0; i < parameters.length; i++) {
PsiParameter parameter = parameters[i];
- datas[i] = new ParameterTablePanel.VariableData(parameter);
+ datas[i] = new VariableData(parameter);
datas[i].name = parameter.getName();
datas[i].passAsParameter = true;
}
@@ -132,15 +132,33 @@
}
public void testSameTypeAndVarargs() throws Exception {
- doTest(false, false, new Function<PsiMethod, ParameterTablePanel.VariableData[]>() {
+ doTest(false, false, new Function<PsiMethod, VariableData[]>() {
@Override
- public ParameterTablePanel.VariableData[] fun(PsiMethod method) {
+ public VariableData[] fun(PsiMethod method) {
final PsiParameter[] parameters = method.getParameterList().getParameters();
- final ParameterTablePanel.VariableData[] datas = new ParameterTablePanel.VariableData[parameters.length - 1];
+ final VariableData[] datas = new VariableData[parameters.length - 1];
for (int i = 0; i < parameters.length - 1; i++) {
PsiParameter parameter = parameters[i];
- datas[i] = new ParameterTablePanel.VariableData(parameter);
+ datas[i] = new VariableData(parameter);
+ datas[i].name = parameter.getName();
+ datas[i].passAsParameter = true;
+ }
+ return datas;
+ }
+ });
+ }
+
+ public void testCopyJavadoc1() throws Exception {
+ doTest(false, true, new Function<PsiMethod, VariableData[]>() {
+ @Override
+ public VariableData[] fun(PsiMethod method) {
+ final PsiParameter[] parameters = method.getParameterList().getParameters();
+
+ final VariableData[] datas = new VariableData[parameters.length - 1];
+ for (int i = 0; i < parameters.length - 1; i++) {
+ PsiParameter parameter = parameters[i];
+ datas[i] = new VariableData(parameter);
datas[i].name = parameter.getName();
datas[i].passAsParameter = true;
}
@@ -150,16 +168,16 @@
}
public void testTypeParametersWithChosenSubtype() throws Exception {
- doTest(false, true, new Function<PsiMethod, ParameterTablePanel.VariableData[]>() {
+ doTest(false, true, new Function<PsiMethod, VariableData[]>() {
@Override
- public ParameterTablePanel.VariableData[] fun(PsiMethod psiMethod) {
+ public VariableData[] fun(PsiMethod psiMethod) {
final PsiParameter parameter = psiMethod.getParameterList().getParameters()[0];
final PsiClass collectionClass = getJavaFacade().findClass(CommonClassNames.JAVA_UTIL_COLLECTION);
- final ParameterTablePanel.VariableData variableData =
- new ParameterTablePanel.VariableData(parameter, JavaPsiFacade.getElementFactory(getProject()).createType(collectionClass));
+ final VariableData variableData =
+ new VariableData(parameter, JavaPsiFacade.getElementFactory(getProject()).createType(collectionClass));
variableData.name = parameter.getName();
variableData.passAsParameter = true;
- return new ParameterTablePanel.VariableData[]{variableData};
+ return new VariableData[]{variableData};
}
});
}
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/MakeClassStaticTest.java b/java/java-tests/testSrc/com/intellij/refactoring/MakeClassStaticTest.java
index af309f3..e8121b1 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/MakeClassStaticTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/MakeClassStaticTest.java
@@ -12,7 +12,7 @@
import com.intellij.refactoring.makeStatic.MakeClassStaticProcessor;
import com.intellij.refactoring.makeStatic.MakeStaticUtil;
import com.intellij.refactoring.makeStatic.Settings;
-import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -83,7 +83,7 @@
PsiElement element = TargetElementUtilBase.findTargetElement(myEditor, TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
assertTrue(element instanceof PsiClass);
PsiClass aClass = (PsiClass)element;
- final ArrayList<ParameterTablePanel.VariableData> parametersForFields = new ArrayList<ParameterTablePanel.VariableData>();
+ final ArrayList<VariableData> parametersForFields = new ArrayList<VariableData>();
final boolean addClassParameter = MakeStaticUtil.buildVariableData(aClass, parametersForFields);
new MakeClassStaticProcessor(
@@ -91,7 +91,7 @@
aClass,
new Settings(true, addClassParameter ? "anObject" : null,
parametersForFields.toArray(
- new ParameterTablePanel.VariableData[parametersForFields.size()]))).run();
+ new VariableData[parametersForFields.size()]))).run();
checkResultByFile(TEST_ROOT + getTestName(false) + "_after.java");
}
}
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/MakeMethodStaticTest.java b/java/java-tests/testSrc/com/intellij/refactoring/MakeMethodStaticTest.java
index db89b94..0ef8510 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/MakeMethodStaticTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/MakeMethodStaticTest.java
@@ -22,7 +22,7 @@
import com.intellij.refactoring.makeStatic.MakeMethodStaticProcessor;
import com.intellij.refactoring.makeStatic.MakeStaticUtil;
import com.intellij.refactoring.makeStatic.Settings;
-import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -176,7 +176,7 @@
configureByFile("/refactoring/makeMethodStatic/beforePreserveTypeParams.java");
performWithFields();
checkResultByFile("/refactoring/makeMethodStatic/afterPreserveTypeParams.java");
- }
+ }
public void testInnerStaticClassUsed() throws Exception {
configureByFile("/refactoring/makeMethodStatic/beforeInnerStaticClassUsed.java");
@@ -218,7 +218,7 @@
PsiElement element = TargetElementUtilBase.findTargetElement(myEditor, TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
assertTrue(element instanceof PsiMethod);
PsiMethod method = (PsiMethod) element;
- final ArrayList<ParameterTablePanel.VariableData> parametersForFields = new ArrayList<ParameterTablePanel.VariableData>();
+ final ArrayList<VariableData> parametersForFields = new ArrayList<VariableData>();
final boolean addClassParameter = MakeStaticUtil.buildVariableData(method, parametersForFields);
new MakeMethodStaticProcessor(
@@ -226,6 +226,6 @@
method,
new Settings(true, addClassParameter ? "anObject" : null,
parametersForFields.toArray(
- new ParameterTablePanel.VariableData[parametersForFields.size()]))).run();
+ new VariableData[parametersForFields.size()]))).run();
}
}
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/RenameDirectoryTest.groovy b/java/java-tests/testSrc/com/intellij/refactoring/RenameDirectoryTest.groovy
index 401de72..7794c69 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/RenameDirectoryTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/refactoring/RenameDirectoryTest.groovy
@@ -26,12 +26,12 @@
public void testRenameSrcRootWithTextOccurrences() {
VirtualFile srcRoot = myFixture.tempDirFixture.findOrCreateDir("")
- def fooClass = myFixture.addClass """
+ def fooClass = myFixture.addClass("""
// PsiPackage:
class Foo {
String s1 = "PsiPackage:"
}
-"""
+""")
myFixture.configureFromExistingVirtualFile(fooClass.containingFile.virtualFile)
new RenameProcessor(getProject(), psiManager.findDirectory(srcRoot), "newName", true, true).run();
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/RenameMembersInplaceTest.java b/java/java-tests/testSrc/com/intellij/refactoring/RenameMembersInplaceTest.java
index 314f6ed..f72add5 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/RenameMembersInplaceTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/RenameMembersInplaceTest.java
@@ -40,6 +40,10 @@
doTestInplaceRename("NEW_NAME");
}
+ public void testIncomplete() throws Exception {
+ doTestInplaceRename("Klazz");
+ }
+
public void testConstructor() throws Exception {
doTestInplaceRename("Bar");
}
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java b/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java
index 44f927f..0cf3fc3 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java
@@ -127,6 +127,10 @@
doTest("Super");
}
+ public void testInterfaceAsTypeParameterBound() throws Exception {
+ doSingleFileTest();
+ }
+
public void testLocalVariableSideEffect() throws Exception {
myDoCompare = false;
try {
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/SuggestedParamTypesTest.java b/java/java-tests/testSrc/com/intellij/refactoring/SuggestedParamTypesTest.java
index 28f0935..57582d5 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/SuggestedParamTypesTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/SuggestedParamTypesTest.java
@@ -31,6 +31,7 @@
import com.intellij.refactoring.ui.TypeSelectorManager;
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
import com.intellij.testFramework.LightCodeInsightTestCase;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -110,7 +111,7 @@
processor.prepare();
- for (final ParameterTablePanel.VariableData data : processor.getInputVariables().getInputVariables()) {
+ for (final VariableData data : processor.getInputVariables().getInputVariables()) {
final PsiExpression[] occurrences = ParameterTablePanel.findVariableOccurrences(elements, data.variable);
final TypeSelectorManager manager = new TypeSelectorManagerImpl(project, data.type, occurrences, true) {
@Override
diff --git a/java/java-tests/testSrc/com/intellij/util/indexing/FileBasedIndexTest.java b/java/java-tests/testSrc/com/intellij/util/indexing/FileBasedIndexTest.java
new file mode 100644
index 0000000..426afcb
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/util/indexing/FileBasedIndexTest.java
@@ -0,0 +1,18 @@
+package com.intellij.util.indexing;
+
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
+
+/**
+ * @author Dmitry Avdeev
+ * Date: 5/23/13
+ */
+public class FileBasedIndexTest extends LightCodeInsightFixtureTestCase {
+
+ public void testSurviveOnFileTypeChange() throws Exception {
+ myFixture.configureByText("Foo.java", "class Foo { String bar; }");
+ myFixture.testHighlighting();
+ FileTypeIndexTest.addAndRemoveFileType();
+ myFixture.configureByText("Bar.java", "class Bar { String bar; }");
+ myFixture.testHighlighting();
+ }
+}
diff --git a/java/jdkAnnotations/java/io/annotations.xml b/java/jdkAnnotations/java/io/annotations.xml
index 955ece0..df2f353 100644
--- a/java/jdkAnnotations/java/io/annotations.xml
+++ b/java/jdkAnnotations/java/io/annotations.xml
@@ -1,5 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<root>
+ <item name="java.io.BufferedInputStream BufferedInputStream(java.io.InputStream) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.BufferedInputStream BufferedInputStream(java.io.InputStream, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.BufferedInputStream int read(byte[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.BufferedOutputStream BufferedOutputStream(java.io.OutputStream) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.BufferedOutputStream BufferedOutputStream(java.io.OutputStream, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.BufferedOutputStream void write(byte[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.BufferedReader BufferedReader(java.io.Reader) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.BufferedReader BufferedReader(java.io.Reader, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.BufferedReader int read(char[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.BufferedWriter BufferedWriter(java.io.Writer) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.BufferedWriter BufferedWriter(java.io.Writer, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.BufferedWriter void write(char[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.BufferedWriter void write(java.lang.String, int, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
<item name="java.io.DataInput java.lang.String readUTF()">
<annotation name="org.jetbrains.annotations.NotNull" />
</item>
@@ -83,14 +122,131 @@
<item name="java.io.File java.nio.file.Path toPath()">
<annotation name="org.jetbrains.annotations.NotNull" />
</item>
+ <item name="java.io.FileOutputStream FileOutputStream(java.io.File) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.FileOutputStream FileOutputStream(java.io.File, boolean) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.FileOutputStream FileOutputStream(java.io.FileDescriptor) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.FileOutputStream FileOutputStream(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.FileOutputStream FileOutputStream(java.lang.String, boolean) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.FileOutputStream java.io.FileDescriptor getFD()">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.FileOutputStream java.nio.channels.FileChannel getChannel()">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.FileOutputStream void write(byte[]) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.FileOutputStream void write(byte[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
<item name="java.io.FilterInputStream FilterInputStream(java.io.InputStream) 0">
<annotation name="org.jetbrains.annotations.NotNull" />
</item>
+ <item name="java.io.FilterInputStream int read(byte[]) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.FilterInputStream int read(byte[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.FilterOutputStream FilterOutputStream(java.io.OutputStream) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.FilterOutputStream void write(byte[]) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.FilterOutputStream void write(byte[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.FilterReader FilterReader(java.io.Reader) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.InputStream int read(byte[]) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
<item name="java.io.InputStream int read(byte[], int, int) 0">
<annotation name="org.jetbrains.annotations.NotNull" />
</item>
+ <item name="java.io.OutputStreamWriter OutputStreamWriter(java.io.OutputStream) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.OutputStreamWriter OutputStreamWriter(java.io.OutputStream, java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.OutputStreamWriter OutputStreamWriter(java.io.OutputStream, java.lang.String) 1">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.OutputStreamWriter OutputStreamWriter(java.io.OutputStream, java.nio.charset.Charset) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.OutputStreamWriter OutputStreamWriter(java.io.OutputStream, java.nio.charset.Charset) 1">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.OutputStreamWriter OutputStreamWriter(java.io.OutputStream, java.nio.charset.CharsetEncoder) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.OutputStreamWriter OutputStreamWriter(java.io.OutputStream, java.nio.charset.CharsetEncoder) 1">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.OutputStreamWriter void write(char[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.OutputStreamWriter void write(java.lang.String, int, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
<item name="java.io.RandomAccessFile RandomAccessFile(java.io.File, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NonNls" />
</item>
+ <item name="java.io.Reader Reader(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.Reader int read(char[]) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.Reader int read(char[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.Reader int read(java.nio.CharBuffer) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.StringReader StringReader(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.StringReader int read(char[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.StringWriter void write(char[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.StringWriter void write(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.StringWriter void write(java.lang.String, int, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.Writer Writer(java.lang.Object) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.Writer void write(char[]) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.Writer void write(char[], int, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.Writer void write(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.io.Writer void write(java.lang.String, int, int) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
</root>
diff --git a/java/jdkAnnotations/java/lang/annotations.xml b/java/jdkAnnotations/java/lang/annotations.xml
index 4337ee6..bb5f521 100644
--- a/java/jdkAnnotations/java/lang/annotations.xml
+++ b/java/jdkAnnotations/java/lang/annotations.xml
@@ -11,6 +11,9 @@
<item name="java.lang.Class java.lang.Class<?> forName(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NonNls" />
</item>
+ <item name="java.lang.Class java.lang.Class<?> forName(java.lang.String, boolean, java.lang.ClassLoader) 0">
+ <annotation name="org.jetbrains.annotations.NonNls" />
+ </item>
<item name="java.lang.Class java.lang.reflect.Field getDeclaredField(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NonNls" />
</item>
@@ -44,6 +47,9 @@
<item name="java.lang.Iterable Iterator<T> iterator()">
<annotation name="org.jetbrains.annotations.NotNull" />
</item>
+ <item name="java.lang.Readable int read(java.nio.CharBuffer) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
<item name="java.lang.Runtime Process exec(java.lang.String[]) 0">
<annotation name="org.jetbrains.annotations.NonNls" />
</item>
diff --git a/java/jdkAnnotations/java/net/annotations.xml b/java/jdkAnnotations/java/net/annotations.xml
index ccc7e16..0fb0120 100644
--- a/java/jdkAnnotations/java/net/annotations.xml
+++ b/java/jdkAnnotations/java/net/annotations.xml
@@ -1,5 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<root>
+ <item name="java.net.URI URI(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.net.URI java.net.URI create(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.net.URI java.net.URI normalize()">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.net.URI java.net.URI parseServerAuthority()">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.net.URI java.net.URI relativize(java.net.URI)">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.net.URI java.net.URI relativize(java.net.URI) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.net.URI java.net.URI resolve(java.lang.String)">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.net.URI java.net.URI resolve(java.lang.String) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.net.URI java.net.URI resolve(java.net.URI)">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.net.URI java.net.URI resolve(java.net.URI) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.net.URI java.net.URL toURL()">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
<item name="java.net.URL URL(java.lang.String) 0">
<annotation name="org.jetbrains.annotations.NonNls" />
</item>
diff --git a/java/jdkAnnotations/java/nio/annotations.xml b/java/jdkAnnotations/java/nio/annotations.xml
new file mode 100644
index 0000000..59c7057
--- /dev/null
+++ b/java/jdkAnnotations/java/nio/annotations.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root>
+ <item name="java.nio.ByteBuffer byte[] array()">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.ByteBuffer compact()">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.ByteBuffer order(java.nio.ByteOrder)">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.ByteBuffer order(java.nio.ByteOrder) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.ByteBuffer putChar(char)">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.ByteBuffer putChar(int, char)">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.ByteBuffer putDouble(double)">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.ByteBuffer putDouble(int, double)">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.ByteBuffer putFloat(float)">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.ByteBuffer putFloat(int, float)">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.ByteBuffer putInt(int)">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.ByteBuffer putInt(int, int)">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.ByteBuffer putLong(int, long)">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.ByteBuffer putLong(long)">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.ByteBuffer putShort(int, short)">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.ByteBuffer putShort(short)">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.ByteOrder order()">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.CharBuffer asCharBuffer()">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.DoubleBuffer asDoubleBuffer()">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.FloatBuffer asFloatBuffer()">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.IntBuffer asIntBuffer()">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.LongBuffer asLongBuffer()">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.ByteBuffer java.nio.ShortBuffer asShortBuffer()">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+ <item name="java.nio.CharBuffer int read(java.nio.CharBuffer) 0">
+ <annotation name="org.jetbrains.annotations.NotNull" />
+ </item>
+</root>
+
diff --git a/java/jsp-openapi/src/com/intellij/psi/impl/source/jsp/jspJava/JspTemplateStatement.java b/java/jsp-openapi/src/com/intellij/psi/impl/source/jsp/jspJava/JspTemplateStatement.java
index c889ede..228d072 100644
--- a/java/jsp-openapi/src/com/intellij/psi/impl/source/jsp/jspJava/JspTemplateStatement.java
+++ b/java/jsp-openapi/src/com/intellij/psi/impl/source/jsp/jspJava/JspTemplateStatement.java
@@ -15,10 +15,10 @@
*/
package com.intellij.psi.impl.source.jsp.jspJava;
-import com.intellij.psi.PsiStatement;
+import com.intellij.psi.PsiTemplateStatement;
/**
* @author peter
*/
-public interface JspTemplateStatement extends PsiStatement {
+public interface JspTemplateStatement extends PsiTemplateStatement {
}
diff --git a/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java b/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java
index e06b22a..7e350d9 100644
--- a/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java
+++ b/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java
@@ -68,7 +68,11 @@
if (expression.getOperationTokenType() == JavaTokenType.EXCL) {
PsiExpression operand = expression.getOperand();
if (operand instanceof PsiParenthesizedExpression) {
- operand = ((PsiParenthesizedExpression)operand).getExpression();
+ final PsiElement parent = booleanExpression.getParent();
+ if (parent instanceof PsiPolyadicExpression &&
+ ((PsiPolyadicExpression)parent).getOperationTokenType() == JavaTokenType.ANDAND) {
+ operand = ((PsiParenthesizedExpression)operand).getExpression();
+ }
}
return operand;
}
diff --git a/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java b/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java
index 87ad87d..5dca4c3 100644
--- a/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java
+++ b/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java
@@ -16,6 +16,7 @@
package com.intellij.codeInsight.intention;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
+import com.intellij.codeInspection.LocalQuickFixOnPsiElement;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.psi.*;
import com.intellij.psi.util.PropertyMemberType;
@@ -48,7 +49,7 @@
*/
public abstract LocalQuickFixAndIntentionActionOnPsiElement createImplementMethodsFix(@NotNull PsiElement psiElement);
public abstract LocalQuickFixAndIntentionActionOnPsiElement createImplementMethodsFix(@NotNull PsiClass psiElement);
- public abstract LocalQuickFixAndIntentionActionOnPsiElement createMethodThrowsFix(@NotNull PsiMethod method, @NotNull PsiClassType exceptionClass, boolean shouldThrow, boolean showContainingClass);
+ public abstract LocalQuickFixOnPsiElement createMethodThrowsFix(@NotNull PsiMethod method, @NotNull PsiClassType exceptionClass, boolean shouldThrow, boolean showContainingClass);
public abstract LocalQuickFixAndIntentionActionOnPsiElement createAddDefaultConstructorFix(@NotNull PsiClass aClass);
@Nullable
public abstract LocalQuickFixAndIntentionActionOnPsiElement createAddConstructorFix(@NotNull PsiClass aClass, @PsiModifier.ModifierConstant String modifier);
diff --git a/java/openapi/src/com/intellij/codeInspection/SuppressManager.java b/java/openapi/src/com/intellij/codeInspection/SuppressManager.java
index df9cfdd..5e12940 100644
--- a/java/openapi/src/com/intellij/codeInspection/SuppressManager.java
+++ b/java/openapi/src/com/intellij/codeInspection/SuppressManager.java
@@ -30,7 +30,6 @@
import org.jetbrains.annotations.NotNull;
public abstract class SuppressManager implements BatchSuppressManager {
- public static final String SUPPRESS_INSPECTIONS_ANNOTATION_NAME = "java.lang.SuppressWarnings";
public static SuppressManager getInstance() {
return ServiceManager.getService(SuppressManager.class);
diff --git a/java/openapi/src/com/intellij/openapi/module/LanguageLevelUtil.java b/java/openapi/src/com/intellij/openapi/module/LanguageLevelUtil.java
index 1fa919b..39028e7 100644
--- a/java/openapi/src/com/intellij/openapi/module/LanguageLevelUtil.java
+++ b/java/openapi/src/com/intellij/openapi/module/LanguageLevelUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -15,43 +15,26 @@
*/
package com.intellij.openapi.module;
-import com.intellij.openapi.projectRoots.JavaSdk;
-import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* @author yole
*/
public class LanguageLevelUtil extends EffectiveLanguageLevelUtil {
- private LanguageLevelUtil() {
- }
+ private LanguageLevelUtil() { }
@NotNull
- public static LanguageLevel getLanguageLevelForFile(final VirtualFile file) {
+ public static LanguageLevel getLanguageLevelForFile(@Nullable VirtualFile file) {
if (file == null) return LanguageLevel.HIGHEST;
if (file.isDirectory()) {
- final LanguageLevel ll = file.getUserData(LanguageLevel.KEY);
- return ll != null ? ll : LanguageLevel.HIGHEST;
+ LanguageLevel languageLevel = file.getUserData(LanguageLevel.KEY);
+ return languageLevel != null ? languageLevel : LanguageLevel.HIGHEST;
}
return getLanguageLevelForFile(file.getParent());
}
-
- /**
- * @deprecated use {@link com.intellij.openapi.projectRoots.JavaSdkVersion#getMaxLanguageLevel()} instead
- */
- public static LanguageLevel getDefaultLanguageLevel(@NotNull String versionString) {
- JavaSdkVersion version = JavaSdk.getInstance().getVersion(versionString);
- return version != null ? version.getMaxLanguageLevel() : LanguageLevel.JDK_1_3;
- }
-
- /**
- * @deprecated use {@link com.intellij.openapi.projectRoots.JavaSdkVersion#isAtLeast(com.intellij.openapi.projectRoots.JavaSdkVersion)} instead
- */
- public static boolean isOfVersionOrHigher(@NotNull String versionString, String checkedVersion) {
- return JavaSdk.getInstance().compareTo(versionString, checkedVersion) >= 0;
- }
}
diff --git a/java/openapi/src/com/intellij/patterns/PsiJavaElementPattern.java b/java/openapi/src/com/intellij/patterns/PsiJavaElementPattern.java
index e91eb87..e72731b 100644
--- a/java/openapi/src/com/intellij/patterns/PsiJavaElementPattern.java
+++ b/java/openapi/src/com/intellij/patterns/PsiJavaElementPattern.java
@@ -24,7 +24,7 @@
* @author peter
*/
public class PsiJavaElementPattern<T extends PsiElement,Self extends PsiJavaElementPattern<T,Self>> extends PsiElementPattern<T,Self> {
- private static final @NonNls String VALUE = "value";
+ @NonNls private static final String VALUE = "value";
public PsiJavaElementPattern(final Class<T> aClass) {
super(aClass);
@@ -61,11 +61,12 @@
}
public Self nameIdentifierOf(final Class<? extends PsiMember> aClass) {
- return nameIdentifierOf(PsiJavaPatterns.instanceOf(aClass));
+ return nameIdentifierOf(StandardPatterns.instanceOf(aClass));
}
-
+
public Self nameIdentifierOf(final ElementPattern<? extends PsiMember> pattern) {
return with(new PatternCondition<T>("nameIdentifierOf") {
+ @Override
public boolean accepts(@NotNull final T t, final ProcessingContext context) {
if (!(t instanceof PsiIdentifier)) return false;
@@ -81,6 +82,7 @@
public Self methodCallParameter(final int index, final ElementPattern<? extends PsiMethod> methodPattern) {
return with(new PatternCondition<T>("methodCallParameter") {
+ @Override
public boolean accepts(@NotNull final T literal, final ProcessingContext context) {
final PsiElement parent = literal.getParent();
if (parent instanceof PsiExpressionList) {
@@ -106,6 +108,7 @@
public Self constructorParameter(final int index, final String... fqns) {
return with(new PatternCondition<T>("methodCallParameter") {
+ @Override
public boolean accepts(@NotNull final T literal, final ProcessingContext context) {
final PsiElement parent = literal.getParent();
if (parent instanceof PsiExpressionList) {
diff --git a/java/openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java b/java/openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java
index fa8b3fa..ebefeef 100644
--- a/java/openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java
+++ b/java/openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java
@@ -72,8 +72,12 @@
}
@Override
- public boolean contains(VirtualFile file, NamedScopesHolder holder) {
- Project project = holder.getProject();
+ public boolean contains(VirtualFile file, @NotNull NamedScopesHolder holder) {
+ return contains(file, holder.getProject(), holder);
+ }
+
+ @Override
+ public boolean contains(VirtualFile file, @NotNull Project project, @Nullable NamedScopesHolder holder) {
ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
return matchesScope(file, holder.getProject(), fileIndex) && (myPattern == null || myPattern.matcher(getPackageName(file, fileIndex)).matches());
}
diff --git a/java/testFramework/src/com/intellij/testFramework/CompilerTester.java b/java/testFramework/src/com/intellij/testFramework/CompilerTester.java
index 23a63e6..f899cc1 100644
--- a/java/testFramework/src/com/intellij/testFramework/CompilerTester.java
+++ b/java/testFramework/src/com/intellij/testFramework/CompilerTester.java
@@ -124,7 +124,7 @@
path.getChildren();
assert path != null;
path.refresh(false, true);
- return path.findChild(className + ".class");
+ return path.findChild(className.replace('.', '/') + ".class");
}
public void touch(VirtualFile file) throws IOException {
diff --git a/java/testFramework/testFramework-java.iml b/java/testFramework/testFramework-java.iml
index 408e30d..9d48d3d 100644
--- a/java/testFramework/testFramework-java.iml
+++ b/java/testFramework/testFramework-java.iml
@@ -21,6 +21,7 @@
<orderEntry type="module" module-name="testFramework" exported="" />
<orderEntry type="module" module-name="relaxng" exported="" scope="TEST" />
<orderEntry type="module" module-name="idea-ui" exported="" />
+ <orderEntry type="module" module-name="external-system-impl" exported="" scope="TEST" />
</component>
<component name="copyright">
<Base>