mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
Generated
+18
@@ -0,0 +1,18 @@
|
||||
<component name="libraryTable">
|
||||
<library name="JUnit5" type="repository">
|
||||
<properties maven-id="org.junit.jupiter:junit-jupiter-api:5.0.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter-api/5.0.0/junit-jupiter-api-5.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apiguardian/apiguardian-api/1.0.0/apiguardian-api-1.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/opentest4j/opentest4j/1.0.0/opentest4j-1.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-commons/1.0.0/junit-platform-commons-1.0.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter-api/5.0.0/junit-jupiter-api-5.0.0-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apiguardian/apiguardian-api/1.0.0/apiguardian-api-1.0.0-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/opentest4j/opentest4j/1.0.0/opentest4j-1.0.0-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-commons/1.0.0/junit-platform-commons-1.0.0-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
Generated
+14
-10
@@ -1,16 +1,20 @@
|
||||
<component name="libraryTable">
|
||||
<library name="junit5_rt">
|
||||
<library name="junit5_rt" type="repository">
|
||||
<properties maven-id="org.junit.platform:junit-platform-launcher:1.0.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/plugins/junit5_rt/lib/apiguardian-api-1.0.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/plugins/junit5_rt/lib/junit-jupiter-engine-5.0.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/plugins/junit5_rt/lib/junit-platform-commons-1.0.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/plugins/junit5_rt/lib/junit-platform-engine-1.0.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/plugins/junit5_rt/lib/junit-platform-launcher-1.0.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/plugins/junit5_rt/lib/junit-platform-runner-1.0.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/plugins/junit5_rt/lib/junit-vintage-engine-4.12.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/plugins/junit5_rt/lib/junit-platform-suite-api-1.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-launcher/1.0.0/junit-platform-launcher-1.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apiguardian/apiguardian-api/1.0.0/apiguardian-api-1.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-engine/1.0.0/junit-platform-engine-1.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-commons/1.0.0/junit-platform-commons-1.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/opentest4j/opentest4j/1.0.0/opentest4j-1.0.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-launcher/1.0.0/junit-platform-launcher-1.0.0-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apiguardian/apiguardian-api/1.0.0/apiguardian-api-1.0.0-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-engine/1.0.0/junit-platform-engine-1.0.0-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-commons/1.0.0/junit-platform-commons-1.0.0-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/opentest4j/opentest4j/1.0.0/opentest4j-1.0.0-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
Generated
-9
@@ -1,9 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="opentest4j">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/plugins/junit5_rt/lib/opentest4j-1.0.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
Generated
-1
@@ -20,7 +20,6 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/android.iml" filepath="$PROJECT_DIR$/android/android/android.iml" group="android" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/tools-base/annotations/android-annotations.iml" filepath="$PROJECT_DIR$/android/tools-base/annotations/android-annotations.iml" group="android" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/common/android-common.iml" filepath="$PROJECT_DIR$/android/common/android-common.iml" group="android" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-gradle-jps/android-gradle-jps.iml" filepath="$PROJECT_DIR$/android/android-gradle-jps/android-gradle-jps.iml" group="android" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/jps-plugin/android-jps-plugin.iml" filepath="$PROJECT_DIR$/android/jps-plugin/android-jps-plugin.iml" group="android" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-plugin/android-plugin.iml" filepath="$PROJECT_DIR$/android/android-plugin/android-plugin.iml" group="android" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/rt/android-rt.iml" filepath="$PROJECT_DIR$/android/rt/android-rt.iml" group="android" />
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -360,6 +360,7 @@ Function ConfirmDesktopShortcut
|
||||
${EndIf}
|
||||
customPreActions:
|
||||
Call customPreInstallActions
|
||||
SetRegView 32
|
||||
StrCmp "${ASSOCIATION}" "NoAssociation" skip_association
|
||||
StrCpy $R0 ${INSTALL_OPTION_ELEMENTS}
|
||||
push "${ASSOCIATION}"
|
||||
@@ -458,6 +459,7 @@ LicenseLangString myLicenseData ${LANG_JAPANESE} "${LICENSE_FILE}.txt"
|
||||
!endif
|
||||
|
||||
Function .onInit
|
||||
SetRegView 32
|
||||
StrCpy $baseRegKey "HKCU"
|
||||
IfSilent UAC_Done
|
||||
UAC_Elevate:
|
||||
@@ -823,6 +825,7 @@ next_association:
|
||||
|
||||
done:
|
||||
Call customInstallActions
|
||||
SetRegView 32
|
||||
|
||||
; registration application to be presented in Open With list
|
||||
call ProductRegistration
|
||||
@@ -873,6 +876,7 @@ skip_ipr:
|
||||
File "${PRODUCT_VM_OPTIONS_FILE}"
|
||||
|
||||
Call customPostInstallActions
|
||||
SetRegView 32
|
||||
StrCpy $0 $baseRegKey
|
||||
StrCpy $1 "Software\${MANUFACTURER}\${PRODUCT_REG_VER}"
|
||||
StrCpy $2 ""
|
||||
@@ -964,6 +968,7 @@ FunctionEnd
|
||||
|
||||
|
||||
Function un.onInit
|
||||
SetRegView 32
|
||||
Call un.getRegKey
|
||||
StrCmp $baseRegKey "HKLM" requred_admin_perm UAC_Done
|
||||
|
||||
@@ -1145,6 +1150,7 @@ FunctionEnd
|
||||
|
||||
Section "Uninstall"
|
||||
Call un.customUninstallActions
|
||||
SetRegView 32
|
||||
StrCpy $0 $baseRegKey
|
||||
StrCpy $1 "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_WITH_VER}"
|
||||
StrCpy $2 "InstallLocation"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# The file might be automatically updated. Comments and empty lines will be removed.
|
||||
kotlinPluginBuild=1.1.4-release-IJ2017.2-3
|
||||
jetSignBuild=42.30
|
||||
jdkBuild=u152b1008.1
|
||||
jdkBuild=u152b1012.1
|
||||
|
||||
@@ -115,7 +115,6 @@
|
||||
<orderEntry type="module" module-name="built-in-server-tests" scope="TEST" />
|
||||
<orderEntry type="module" module-name="updater" scope="TEST" />
|
||||
<orderEntry type="module" module-name="coverage" />
|
||||
<orderEntry type="module" module-name="android-gradle-jps" scope="TEST" />
|
||||
<orderEntry type="module" module-name="android-jps-plugin" scope="TEST" />
|
||||
<orderEntry type="module" module-name="script-debugger-ui" scope="TEST" />
|
||||
<orderEntry type="module" module-name="remote-servers-git-java" />
|
||||
|
||||
@@ -656,6 +656,7 @@ final class ThumbnailViewUI extends JPanel implements DataProvider, Disposable {
|
||||
}
|
||||
|
||||
private final class VFSListener implements VirtualFileListener {
|
||||
@Override
|
||||
public void contentsChanged(@NotNull VirtualFileEvent event) {
|
||||
VirtualFile file = event.getFile();
|
||||
if (list != null) {
|
||||
@@ -667,6 +668,7 @@ final class ThumbnailViewUI extends JPanel implements DataProvider, Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fileDeleted(@NotNull VirtualFileEvent event) {
|
||||
VirtualFile file = event.getFile();
|
||||
VirtualFile root = thumbnailView.getRoot();
|
||||
@@ -678,14 +680,17 @@ final class ThumbnailViewUI extends JPanel implements DataProvider, Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChanged(@NotNull VirtualFilePropertyEvent event) {
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fileCreated(@NotNull VirtualFileEvent event) {
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fileMoved(@NotNull VirtualFileMoveEvent event) {
|
||||
refresh();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.build;
|
||||
|
||||
import com.intellij.build.events.*;
|
||||
import com.intellij.execution.filters.Filter;
|
||||
import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.execution.ui.*;
|
||||
import com.intellij.execution.ui.layout.impl.RunnerLayoutUiImpl;
|
||||
@@ -44,16 +45,15 @@ import com.intellij.util.ui.EdtInvocationManager;
|
||||
import com.intellij.util.ui.EmptyIcon;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Supplier;
|
||||
@@ -62,8 +62,8 @@ import java.util.function.Supplier;
|
||||
* @author Vladislav.Soroka
|
||||
*/
|
||||
public abstract class AbstractViewManager implements BuildProgressListener, Disposable {
|
||||
private final Project myProject;
|
||||
private final BuildContentManager myBuildContentManager;
|
||||
protected final Project myProject;
|
||||
protected final BuildContentManager myBuildContentManager;
|
||||
private final AtomicBoolean isInitializeStarted;
|
||||
private final List<Runnable> myPostponedRunnables;
|
||||
private final ProgressWatcher myProgressWatcher;
|
||||
@@ -90,7 +90,7 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
SimpleColoredComponent mainComponent = new SimpleColoredComponent();
|
||||
mainComponent.setIcon(buildInfo.getIcon());
|
||||
mainComponent.append(buildInfo.title + ": ", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
|
||||
mainComponent.append(buildInfo.getTitle() + ": ", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
|
||||
mainComponent.append(buildInfo.message, SimpleTextAttributes.REGULAR_ATTRIBUTES);
|
||||
panel.add(mainComponent, BorderLayout.NORTH);
|
||||
if (buildInfo.statusMessage != null) {
|
||||
@@ -116,6 +116,10 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
return false;
|
||||
}
|
||||
|
||||
protected Map<BuildInfo, BuildView> getBuildsMap() {
|
||||
return Collections.unmodifiableMap(myViewMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(BuildEvent event) {
|
||||
List<Runnable> runnables = new SmartList<>();
|
||||
@@ -145,11 +149,18 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
myToolbarActions.removeAll();
|
||||
}
|
||||
}
|
||||
myBuildsMap.computeIfAbsent(ObjectUtils.chooseNotNull(
|
||||
event.getParentId(), event.getId()), o -> {
|
||||
StartBuildEvent startBuildEvent = (StartBuildEvent)event;
|
||||
return new BuildInfo(event.getId(), startBuildEvent.getBuildTitle(), startBuildEvent.getWorkingDir(), event.getEventTime());
|
||||
});
|
||||
}
|
||||
final BuildInfo buildInfo =
|
||||
myBuildsMap.computeIfAbsent(ObjectUtils.chooseNotNull(event.getParentId(), event.getId()), o -> new BuildInfo());
|
||||
if (event.getParentId() != null) {
|
||||
myBuildsMap.put(event.getId(), buildInfo);
|
||||
else {
|
||||
if (event.getParentId() != null) {
|
||||
BuildInfo buildInfo = myBuildsMap.get(event.getParentId());
|
||||
assert buildInfo != null;
|
||||
myBuildsMap.put(event.getId(), buildInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -157,8 +168,6 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
final BuildInfo buildInfo = myBuildsMap.get(event.getId());
|
||||
assert buildInfo != null;
|
||||
if (event instanceof StartBuildEvent) {
|
||||
buildInfo.title = ((StartBuildEvent)event).getBuildTitle();
|
||||
buildInfo.id = event.getId();
|
||||
buildInfo.message = event.getMessage();
|
||||
|
||||
if (!isTabbedView() && myBuildsList != null) {
|
||||
@@ -166,60 +175,77 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
listModel.addElement(buildInfo);
|
||||
}
|
||||
|
||||
final RunContentDescriptor contentDescriptor;
|
||||
Supplier<RunContentDescriptor> contentDescriptorSupplier = ((StartBuildEvent)event).getContentDescriptorSupplier();
|
||||
contentDescriptor = contentDescriptorSupplier != null ? contentDescriptorSupplier.get() : null;
|
||||
ProcessHandler processHandler = ((StartBuildEvent)event).getProcessHandler();
|
||||
BuildView view = myViewMap.computeIfAbsent(buildInfo, info -> {
|
||||
ExecutionConsole executionConsole = null;
|
||||
ComponentContainer componentContainer = null;
|
||||
Supplier<RunContentDescriptor> contentDescriptorSupplier = ((StartBuildEvent)event).getContentDescriptorSupplier();
|
||||
if (contentDescriptorSupplier != null) {
|
||||
RunContentDescriptor contentDescriptor = contentDescriptorSupplier.get();
|
||||
if (contentDescriptor != null) {
|
||||
executionConsole = contentDescriptor.getExecutionConsole();
|
||||
List<AnAction> leftToolbarActions = ContainerUtil.newArrayList();
|
||||
RunnerLayoutUi layoutUi = contentDescriptor.getRunnerLayoutUi();
|
||||
if (layoutUi instanceof RunnerLayoutUiImpl) {
|
||||
RunnerLayoutUiImpl layoutUiImpl = (RunnerLayoutUiImpl)layoutUi;
|
||||
layoutUiImpl.setLeftToolbarVisible(false);
|
||||
layoutUiImpl.setContentToolbarBefore(false);
|
||||
leftToolbarActions.addAll(layoutUiImpl.getActions());
|
||||
BuildConsoleView buildConsoleView = null;
|
||||
if (contentDescriptor != null) {
|
||||
executionConsole = contentDescriptor.getExecutionConsole();
|
||||
List<AnAction> leftToolbarActions = ContainerUtil.newArrayList();
|
||||
RunnerLayoutUi layoutUi = contentDescriptor.getRunnerLayoutUi();
|
||||
if (layoutUi instanceof RunnerLayoutUiImpl) {
|
||||
RunnerLayoutUiImpl layoutUiImpl = (RunnerLayoutUiImpl)layoutUi;
|
||||
layoutUiImpl.setLeftToolbarVisible(false);
|
||||
layoutUiImpl.setContentToolbarBefore(false);
|
||||
leftToolbarActions.addAll(layoutUiImpl.getActions());
|
||||
}
|
||||
JComponent component = contentDescriptor.getComponent();
|
||||
AnAction[] leftToolbarActionsArray = leftToolbarActions.toArray(new AnAction[leftToolbarActions.size()]);
|
||||
buildConsoleView = new BuildConsoleView() {
|
||||
@Override
|
||||
public void onEvent(BuildEvent event) {
|
||||
}
|
||||
JComponent component = contentDescriptor.getComponent();
|
||||
AnAction[] leftToolbarActionsArray = leftToolbarActions.toArray(new AnAction[leftToolbarActions.size()]);
|
||||
componentContainer = new BuildConsoleView() {
|
||||
@Override
|
||||
public void onEvent(BuildEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnAction[] createConsoleActions() {
|
||||
return leftToolbarActionsArray;
|
||||
}
|
||||
@Override
|
||||
public AnAction[] createConsoleActions() {
|
||||
return leftToolbarActionsArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
return component;
|
||||
}
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
return component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusableComponent() {
|
||||
return component;
|
||||
}
|
||||
@Override
|
||||
public JComponent getPreferredFocusableComponent() {
|
||||
ExecutionConsole console = contentDescriptor.getExecutionConsole();
|
||||
if (console != null) return console.getPreferredFocusableComponent();
|
||||
return (component instanceof ComponentContainer)
|
||||
? ((ComponentContainer)component).getPreferredFocusableComponent()
|
||||
: component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
};
|
||||
Disposer.register(buildConsoleView, contentDescriptor);
|
||||
}
|
||||
if (buildConsoleView == null) {
|
||||
buildConsoleView = new BuildTextConsoleView(myProject);
|
||||
executionConsole = (ExecutionConsole)buildConsoleView;
|
||||
}
|
||||
if (executionConsole instanceof ConsoleView) {
|
||||
for (Filter filter : ((StartBuildEvent)event).getExecutionFilters()) {
|
||||
((ConsoleView)executionConsole).addMessageFilter(filter);
|
||||
}
|
||||
}
|
||||
if (componentContainer == null) {
|
||||
componentContainer = executionConsole = new BuildTextConsoleView(myProject);
|
||||
}
|
||||
|
||||
final BuildView buildView =
|
||||
new BuildView(myProject, componentContainer, ((StartBuildEvent)event),
|
||||
new BuildView(myProject, buildConsoleView, ((StartBuildEvent)event),
|
||||
"build.toolwindow." + getViewName() + ".selection.state", isConsoleEnabledByDefault());
|
||||
if (processHandler != null) {
|
||||
if (executionConsole instanceof ConsoleView) {
|
||||
((ConsoleView)executionConsole).attachToProcess(processHandler);
|
||||
if (buildConsoleView instanceof ConsoleView) {
|
||||
((ConsoleView)buildConsoleView).attachToProcess(processHandler);
|
||||
Consumer<ConsoleView> attachedConsoleConsumer = ((StartBuildEvent)event).getAttachedConsoleConsumer();
|
||||
if (attachedConsoleConsumer != null) {
|
||||
attachedConsoleConsumer.consume((ConsoleView)buildConsoleView);
|
||||
}
|
||||
}
|
||||
else if (executionConsole instanceof ConsoleView) {
|
||||
Consumer<ConsoleView> attachedConsoleConsumer = ((StartBuildEvent)event).getAttachedConsoleConsumer();
|
||||
if (attachedConsoleConsumer != null) {
|
||||
attachedConsoleConsumer.consume((ConsoleView)executionConsole);
|
||||
@@ -237,22 +263,33 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
consoleComponent.add(ActionManager.getInstance().createActionToolbar(
|
||||
"BuildView", toolbarActions, false).getComponent(), BorderLayout.WEST);
|
||||
toolbarActions.addAll(buildView.createConsoleActions());
|
||||
Icon contentIcon = getContentIcon();
|
||||
myContent = myBuildContentManager.addTabbedContent(
|
||||
consoleComponent, getViewName(), buildInfo.title + ", " + DateFormatUtil.formatDateTime(System.currentTimeMillis()) + " ",
|
||||
true, AllIcons.CodeStyle.Gear, buildView);
|
||||
consoleComponent, getViewName(),
|
||||
buildInfo.getTitle() + ", " + DateFormatUtil.formatDateTime(System.currentTimeMillis()) + " ",
|
||||
contentIcon, buildView);
|
||||
}
|
||||
return buildView;
|
||||
});
|
||||
|
||||
if (contentDescriptor != null) {
|
||||
boolean activateToolWindow = contentDescriptor.isActivateToolWindowWhenAdded();
|
||||
buildInfo.activateToolWindowWhenAdded = activateToolWindow;
|
||||
boolean focusContent = contentDescriptor.isAutoFocusContent();
|
||||
myBuildContentManager.setSelectedContent(
|
||||
myContent, focusContent, focusContent, activateToolWindow, contentDescriptor.getActivationCallback());
|
||||
}
|
||||
else {
|
||||
myBuildContentManager.setSelectedContent(myContent, true, true, true, null);
|
||||
}
|
||||
buildInfo.content = myContent;
|
||||
|
||||
if (!isTabbedView() && myThreeComponentsSplitter.getLastComponent() == null) {
|
||||
myThreeComponentsSplitter.setLastComponent(view);
|
||||
myToolbarActions.removeAll();
|
||||
myToolbarActions.addAll(view.createConsoleActions());
|
||||
}
|
||||
if (!isTabbedView() &&
|
||||
myBuildsList != null &&
|
||||
myBuildsList.getModel().getSize() > 1 &&
|
||||
myThreeComponentsSplitter.getFirstComponent() == null) {
|
||||
if (!isTabbedView() && myBuildsList != null && myBuildsList.getModel().getSize() > 1) {
|
||||
JBScrollPane scrollPane = new JBScrollPane();
|
||||
scrollPane.setBorder(JBUI.Borders.empty());
|
||||
scrollPane.setViewportView(myBuildsList);
|
||||
@@ -271,10 +308,11 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
else {
|
||||
myThreeComponentsSplitter.setFirstComponent(null);
|
||||
}
|
||||
onBuildStart(buildInfo);
|
||||
myProgressWatcher.addBuild(buildInfo);
|
||||
//view.getPrimaryView().print("\r", ConsoleViewContentType.SYSTEM_OUTPUT);
|
||||
|
||||
((BuildContentManagerImpl)myBuildContentManager).startBuildNotified(myContent);
|
||||
((BuildContentManagerImpl)myBuildContentManager).startBuildNotified(buildInfo.content);
|
||||
}
|
||||
else {
|
||||
if (event instanceof FinishBuildEvent) {
|
||||
@@ -282,7 +320,8 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
buildInfo.message = event.getMessage();
|
||||
buildInfo.result = ((FinishBuildEvent)event).getResult();
|
||||
myProgressWatcher.stopBuild(buildInfo);
|
||||
((BuildContentManagerImpl)myBuildContentManager).finishBuildNotified(myContent);
|
||||
((BuildContentManagerImpl)myBuildContentManager).finishBuildNotified(buildInfo.content);
|
||||
onBuildFinish(buildInfo);
|
||||
}
|
||||
else {
|
||||
buildInfo.statusMessage = event.getMessage();
|
||||
@@ -299,7 +338,9 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
((BuildConsoleView)consoleView).onEvent(event);
|
||||
}
|
||||
else if ((consoleView instanceof ConsoleView)) {
|
||||
((ConsoleView)consoleView).print(event.getMessage(), ConsoleViewContentType.NORMAL_OUTPUT);
|
||||
((ConsoleView)consoleView).print(event.getMessage(), ((OutputBuildEvent)event).isStdOut()
|
||||
? ConsoleViewContentType.NORMAL_OUTPUT
|
||||
: ConsoleViewContentType.ERROR_OUTPUT);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -352,8 +393,9 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
|
||||
myContent = new ContentImpl(consoleComponent, getViewName(), true);
|
||||
myContent.setCloseable(false);
|
||||
Icon contentIcon = getContentIcon();
|
||||
myContent.setIcon(contentIcon);
|
||||
myBuildContentManager.addContent(myContent);
|
||||
myBuildContentManager.setSelectedContent(myContent);
|
||||
|
||||
List<Runnable> postponedRunnables = new ArrayList<>(myPostponedRunnables);
|
||||
myPostponedRunnables.clear();
|
||||
@@ -372,6 +414,21 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Icon getContentIcon() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void onBuildStart(BuildDescriptor buildDescriptor) {
|
||||
}
|
||||
|
||||
protected void onBuildFinish(BuildDescriptor buildDescriptor) {
|
||||
BuildInfo buildInfo = (BuildInfo)buildDescriptor;
|
||||
if (buildInfo.result instanceof FailureResult) {
|
||||
myBuildContentManager.setSelectedContent(buildInfo.content, true, true, true, null);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isConsoleEnabledByDefault() {
|
||||
return false;
|
||||
}
|
||||
@@ -411,13 +468,20 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
}
|
||||
}
|
||||
|
||||
private static class BuildInfo {
|
||||
Object id;
|
||||
String title;
|
||||
static class BuildInfo extends DefaultBuildDescriptor {
|
||||
String message;
|
||||
String statusMessage;
|
||||
long endTime = -1;
|
||||
EventResult result;
|
||||
Content content;
|
||||
public boolean activateToolWindowWhenAdded;
|
||||
|
||||
public BuildInfo(@NotNull Object id,
|
||||
@NotNull String title,
|
||||
@NotNull String workingDir,
|
||||
long startTime) {
|
||||
super(id, title, workingDir, startTime);
|
||||
}
|
||||
|
||||
public Icon getIcon() {
|
||||
return getIcon(result);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.build;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
import com.intellij.ui.content.Content;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -32,14 +33,15 @@ public interface BuildContentManager {
|
||||
|
||||
void removeContent(final Content content);
|
||||
|
||||
void setSelectedContent(final Content content);
|
||||
|
||||
void selectContent(final String tabName);
|
||||
|
||||
Content addTabbedContent(@NotNull JComponent contentComponent,
|
||||
@NotNull String groupPrefix,
|
||||
@NotNull String tabName,
|
||||
boolean select,
|
||||
@Nullable Icon icon,
|
||||
@Nullable Disposable childDisposable);
|
||||
|
||||
ActionCallback setSelectedContent(Content content,
|
||||
boolean requestFocus,
|
||||
boolean forcedFocus,
|
||||
boolean activate,
|
||||
Runnable activationCallback);
|
||||
}
|
||||
|
||||
@@ -18,8 +18,10 @@ package com.intellij.build;
|
||||
import com.intellij.execution.runners.ExecutionUtil;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
import com.intellij.openapi.wm.ToolWindowAnchor;
|
||||
@@ -51,6 +53,7 @@ public class BuildContentManagerImpl implements BuildContentManager {
|
||||
public static final String Build = "Build";
|
||||
public static final String Sync = "Sync";
|
||||
private static final String[] ourPresetOrder = {Build, Sync};
|
||||
private Project myProject;
|
||||
private ToolWindow myToolWindow;
|
||||
private final List<Runnable> myPostponedRunnables = new ArrayList<>();
|
||||
private Map<Content, Pair<Icon, AtomicInteger>> liveContentsMap = ContainerUtil.newConcurrentMap();
|
||||
@@ -60,6 +63,7 @@ public class BuildContentManagerImpl implements BuildContentManager {
|
||||
}
|
||||
|
||||
private void init(Project project) {
|
||||
myProject = project;
|
||||
final Runnable runnable = () -> {
|
||||
ToolWindow toolWindow = ToolWindowManager.getInstance(project)
|
||||
.registerToolWindow(ToolWindowId.BUILD, true, ToolWindowAnchor.BOTTOM, project, true);
|
||||
@@ -122,26 +126,35 @@ public class BuildContentManagerImpl implements BuildContentManager {
|
||||
for (Content existingContent : existingContents) {
|
||||
existingContent.setDisplayName(existingContent.getTabName());
|
||||
}
|
||||
Content firstContent = contentManager.getContent(0);
|
||||
assert firstContent != null;
|
||||
if (!Build.equals(firstContent.getTabName())) {
|
||||
if (contentManager.getContentCount() > 1) {
|
||||
setIdLabelHidden(false);
|
||||
}
|
||||
else {
|
||||
// we are going to adjust display name, so we need to ensure tab name is not retrieved based on display name
|
||||
content.setTabName(content.getTabName());
|
||||
content.setDisplayName(Build + ": " + content.getTabName());
|
||||
}
|
||||
String tabName = content.getTabName();
|
||||
updateTabDisplayName(content, tabName);
|
||||
});
|
||||
}
|
||||
|
||||
public void updateTabDisplayName(Content content, String tabName) {
|
||||
String displayName;
|
||||
ContentManager contentManager = myToolWindow.getContentManager();
|
||||
Content firstContent = contentManager.getContent(0);
|
||||
assert firstContent != null;
|
||||
if (!Build.equals(firstContent.getTabName())) {
|
||||
if (contentManager.getContentCount() > 1) {
|
||||
setIdLabelHidden(false);
|
||||
displayName = tabName;
|
||||
}
|
||||
else {
|
||||
setIdLabelHidden(true);
|
||||
displayName = Build + ": " + tabName;
|
||||
}
|
||||
}
|
||||
else {
|
||||
displayName = tabName;
|
||||
setIdLabelHidden(true);
|
||||
}
|
||||
|
||||
if (contentManager.getContentCount() == 1) {
|
||||
myToolWindow.show(null);
|
||||
}
|
||||
});
|
||||
if (!displayName.equals(content.getDisplayName())) {
|
||||
// we are going to adjust display name, so we need to ensure tab name is not retrieved based on display name
|
||||
content.setTabName(tabName);
|
||||
content.setDisplayName(displayName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -153,30 +166,27 @@ public class BuildContentManagerImpl implements BuildContentManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectedContent(Content content) {
|
||||
myToolWindow.getContentManager().setSelectedContent(content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectContent(String tabName) {
|
||||
ContentManager contentManager = myToolWindow.getContentManager();
|
||||
for (Content content : contentManager.getContents()) {
|
||||
if (content.getDisplayName().equals(tabName)) {
|
||||
contentManager.setSelectedContent(content, false);
|
||||
break;
|
||||
}
|
||||
public ActionCallback setSelectedContent(Content content,
|
||||
boolean requestFocus,
|
||||
boolean forcedFocus,
|
||||
boolean activate,
|
||||
Runnable activationCallback) {
|
||||
ActionCallback callback = myToolWindow.getContentManager().setSelectedContent(content, requestFocus, forcedFocus, false);
|
||||
if (activate) {
|
||||
ApplicationManager.getApplication().invokeLater(
|
||||
() -> myToolWindow.activate(activationCallback, requestFocus, requestFocus), myProject.getDisposed());
|
||||
}
|
||||
return callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Content addTabbedContent(@NotNull JComponent contentComponent,
|
||||
@NotNull String groupPrefix,
|
||||
@NotNull String tabName,
|
||||
boolean select,
|
||||
@Nullable Icon icon,
|
||||
@Nullable Disposable childDisposable) {
|
||||
ContentManager contentManager = myToolWindow.getContentManager();
|
||||
ContentUtilEx.addTabbedContent(contentManager, contentComponent, groupPrefix, tabName, select, childDisposable);
|
||||
ContentUtilEx.addTabbedContent(contentManager, contentComponent, groupPrefix, tabName, false, childDisposable);
|
||||
Content content = contentManager.findContent(getFullName(groupPrefix, tabName));
|
||||
if (icon != null) {
|
||||
TabbedContent tabbedContent = ContentUtilEx.findTabbedContent(contentManager, groupPrefix);
|
||||
@@ -191,14 +201,18 @@ public class BuildContentManagerImpl implements BuildContentManager {
|
||||
public void startBuildNotified(Content content) {
|
||||
Pair<Icon, AtomicInteger> pair = liveContentsMap.computeIfAbsent(content, c -> Pair.pair(c.getIcon(), new AtomicInteger(0)));
|
||||
pair.second.incrementAndGet();
|
||||
content.setIcon(ExecutionUtil.getLiveIndicator(pair.first));
|
||||
myToolWindow.setIcon(ExecutionUtil.getLiveIndicator(AllIcons.Actions.Compile));
|
||||
content.putUserData(ToolWindow.SHOW_CONTENT_ICON, Boolean.TRUE);
|
||||
content.setIcon(ExecutionUtil.getLiveIndicator(pair.first));
|
||||
JComponent component = content.getComponent();
|
||||
if (component != null) {
|
||||
component.invalidate();
|
||||
}
|
||||
myToolWindow.setIcon(ExecutionUtil.getLiveIndicator(AllIcons.Actions.Compile));
|
||||
}
|
||||
|
||||
public void finishBuildNotified(Content content) {
|
||||
Pair<Icon, AtomicInteger> pair = liveContentsMap.get(content);
|
||||
if (pair.second.decrementAndGet() == 0) {
|
||||
if (pair != null && pair.second.decrementAndGet() == 0) {
|
||||
content.setIcon(pair.first);
|
||||
if (pair.first == null) {
|
||||
content.putUserData(ToolWindow.SHOW_CONTENT_ICON, Boolean.FALSE);
|
||||
|
||||
+13
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,27 +13,22 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.vcs.changes;
|
||||
package com.intellij.build;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ChangesSelection {
|
||||
@NotNull private final List<Change> myChanges;
|
||||
private final int myIndex;
|
||||
|
||||
public ChangesSelection(@NotNull List<Change> changes, int index) {
|
||||
myChanges = changes;
|
||||
myIndex = index;
|
||||
}
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
*/
|
||||
public interface BuildDescriptor {
|
||||
@NotNull
|
||||
Object getId();
|
||||
|
||||
@NotNull
|
||||
public List<Change> getChanges() {
|
||||
return myChanges;
|
||||
}
|
||||
String getTitle();
|
||||
|
||||
public int getIndex() {
|
||||
return myIndex;
|
||||
}
|
||||
@NotNull
|
||||
String getWorkingDir();
|
||||
|
||||
long getStartTime();
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.build;
|
||||
|
||||
import com.intellij.build.events.BuildEvent;
|
||||
import com.intellij.build.events.OutputBuildEvent;
|
||||
import com.intellij.execution.impl.ConsoleViewImpl;
|
||||
import com.intellij.execution.process.AnsiEscapeDecoder;
|
||||
import com.intellij.execution.process.ProcessOutputTypes;
|
||||
@@ -40,7 +41,9 @@ public class BuildTextConsoleView extends ConsoleViewImpl implements BuildConsol
|
||||
|
||||
@Override
|
||||
public void onEvent(BuildEvent event) {
|
||||
myAnsiEscapeDecoder.escapeText(event.getMessage(), ProcessOutputTypes.STDOUT, this);
|
||||
Key outputType = event instanceof OutputBuildEvent && !((OutputBuildEvent)event).isStdOut()
|
||||
? ProcessOutputTypes.STDERR : ProcessOutputTypes.STDOUT;
|
||||
myAnsiEscapeDecoder.escapeText(event.getMessage(), outputType, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -45,6 +45,7 @@ import com.intellij.ui.treeStructure.treetable.TreeTableTree;
|
||||
import com.intellij.util.IJSwingUtilities;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.text.DateFormatUtil;
|
||||
import com.intellij.util.ui.ColumnInfo;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -259,7 +260,7 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusableComponent() {
|
||||
return null;
|
||||
return myBuilder.getTree();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -326,6 +327,10 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
|
||||
myBuilder.queueUpdateFrom(currentNode, false, false);
|
||||
|
||||
if (event instanceof FinishBuildEvent) {
|
||||
String aHint = event.getHint();
|
||||
String time = DateFormatUtil.formatDateTime(event.getEventTime());
|
||||
aHint = aHint == null ? " at " + time : aHint + " at " + time;
|
||||
currentNode.setHint(aHint);
|
||||
myProgressAnimator.stopMovie();
|
||||
updateTimeColumnWidth(myTimeColumnWidth);
|
||||
if (myDetailsHandler.myExecutionNode == null) {
|
||||
|
||||
@@ -82,7 +82,7 @@ public class CompositeView<S extends ComponentContainer, T extends ComponentCont
|
||||
CardLayout cl = (CardLayout)(getLayout());
|
||||
cl.show(this, primary ? PRIMARY_PANEL : SECONDARY_PANEL);
|
||||
IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(() -> {
|
||||
IdeFocusManager.getGlobalInstance().requestFocus(getView(primary).getComponent(), true);
|
||||
IdeFocusManager.getGlobalInstance().requestFocus(getView(primary).getPreferredFocusableComponent(), true);
|
||||
});
|
||||
myPrimary = primary;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.build;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
*/
|
||||
public class DebugTasksViewManager extends TasksViewManager {
|
||||
public DebugTasksViewManager(Project project, BuildContentManager buildContentManager) {
|
||||
super(project, buildContentManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getViewName() {
|
||||
return "Debug";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.build;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
*/
|
||||
public class DefaultBuildDescriptor implements BuildDescriptor {
|
||||
|
||||
private final Object myId;
|
||||
private final String myTitle;
|
||||
private final String myWorkingDir;
|
||||
private final long myStartTime;
|
||||
|
||||
public DefaultBuildDescriptor(@NotNull Object id, @NotNull String title, @NotNull String workingDir, long startTime) {
|
||||
myId = id;
|
||||
myTitle = title;
|
||||
myWorkingDir = workingDir;
|
||||
myStartTime = startTime;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object getId() {
|
||||
return myId;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return myTitle;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getWorkingDir() {
|
||||
return myWorkingDir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getStartTime() {
|
||||
return myStartTime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.build;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
*/
|
||||
public class RunTasksViewManager extends TasksViewManager {
|
||||
public RunTasksViewManager(Project project, BuildContentManager buildContentManager) {
|
||||
super(project, buildContentManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getViewName() {
|
||||
return "Run";
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.build;
|
||||
|
||||
import com.intellij.build.events.FailureResult;
|
||||
import com.intellij.openapi.project.Project;
|
||||
|
||||
/**
|
||||
@@ -29,4 +30,13 @@ public class SyncViewManager extends AbstractViewManager {
|
||||
public String getViewName() {
|
||||
return "Sync";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBuildFinish(BuildDescriptor buildDescriptor) {
|
||||
BuildInfo buildInfo = (BuildInfo)buildDescriptor;
|
||||
if (buildInfo.result instanceof FailureResult) {
|
||||
boolean activate = buildInfo.activateToolWindowWhenAdded;
|
||||
myBuildContentManager.setSelectedContent(buildInfo.content, activate, activate, activate, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,24 +15,41 @@
|
||||
*/
|
||||
package com.intellij.build;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.ui.content.Content;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
*/
|
||||
public class TasksViewManager extends AbstractViewManager {
|
||||
public abstract class TasksViewManager extends AbstractViewManager {
|
||||
public TasksViewManager(Project project, BuildContentManager buildContentManager) {
|
||||
super(project, buildContentManager);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getViewName() {
|
||||
return "Run";
|
||||
protected void onBuildStart(BuildDescriptor buildDescriptor) {
|
||||
if (!isTabbedView()) {
|
||||
BuildInfo buildInfo = (BuildInfo)buildDescriptor;
|
||||
Content content = buildInfo.content;
|
||||
Map<BuildInfo, BuildView> buildsMap = getBuildsMap();
|
||||
String tabName = buildsMap.size() > 1 ? getViewName() : getViewName() + ": " + buildInfo.getTitle();
|
||||
((BuildContentManagerImpl)myBuildContentManager).updateTabDisplayName(content, tabName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isTabbedView() {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Icon getContentIcon() {
|
||||
return AllIcons.CodeStyle.Gear;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,11 +16,15 @@
|
||||
package com.intellij.build.events;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public interface OutputBuildEvent {
|
||||
@NotNull
|
||||
String getMessage();
|
||||
|
||||
boolean isStdOut();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.build.events;
|
||||
|
||||
import com.intellij.execution.filters.Filter;
|
||||
import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.execution.ui.ConsoleView;
|
||||
@@ -34,6 +35,9 @@ import java.util.function.Supplier;
|
||||
public interface StartBuildEvent extends StartEvent {
|
||||
String getBuildTitle();
|
||||
|
||||
@NotNull
|
||||
String getWorkingDir();
|
||||
|
||||
@Nullable
|
||||
ProcessHandler getProcessHandler();
|
||||
|
||||
@@ -43,6 +47,9 @@ public interface StartBuildEvent extends StartEvent {
|
||||
@NotNull
|
||||
AnAction[] getRestartActions();
|
||||
|
||||
@NotNull
|
||||
Filter[] getExecutionFilters();
|
||||
|
||||
@Nullable
|
||||
Supplier<RunContentDescriptor> getContentDescriptorSupplier();
|
||||
|
||||
|
||||
@@ -23,11 +23,19 @@ import org.jetbrains.annotations.Nullable;
|
||||
* @author Vladislav.Soroka
|
||||
*/
|
||||
public class OutputBuildEventImpl extends AbstractBuildEvent implements OutputBuildEvent {
|
||||
private boolean myStdOut;
|
||||
|
||||
public OutputBuildEventImpl(@Nullable Object parentId, @NotNull String message, boolean stdOut) {
|
||||
this(new Object(), parentId, message, stdOut);
|
||||
}
|
||||
|
||||
public OutputBuildEventImpl(@NotNull Object eventId, @Nullable Object parentId, @NotNull String message, boolean stdOut) {
|
||||
super(eventId, parentId, -1, message);
|
||||
myStdOut = stdOut;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStdOut() {
|
||||
return myStdOut;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
package com.intellij.build.events.impl;
|
||||
|
||||
import com.intellij.build.BuildDescriptor;
|
||||
import com.intellij.build.events.StartBuildEvent;
|
||||
import com.intellij.execution.filters.Filter;
|
||||
import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.execution.ui.ConsoleView;
|
||||
@@ -36,22 +38,23 @@ import java.util.function.Supplier;
|
||||
public class StartBuildEventImpl extends StartEventImpl implements StartBuildEvent {
|
||||
|
||||
private final String myBuildTitle;
|
||||
private final String myWorkingDir;
|
||||
@Nullable
|
||||
private ProcessHandler myProcessHandler;
|
||||
private Consumer<ConsoleView> myAttachedConsoleConsumer;
|
||||
@NotNull
|
||||
private List<AnAction> myRestartActions = new SmartList<>();
|
||||
@NotNull
|
||||
private List<Filter> myFilters = new SmartList<>();
|
||||
@Nullable
|
||||
private ExecutionEnvironment myExecutionEnvironment;
|
||||
@Nullable
|
||||
private Supplier<RunContentDescriptor> myContentDescriptorSupplier;
|
||||
|
||||
public StartBuildEventImpl(@NotNull Object eventId,
|
||||
@NotNull String buildTitle,
|
||||
long eventTime,
|
||||
@NotNull String message) {
|
||||
super(eventId, null, eventTime, message);
|
||||
myBuildTitle = buildTitle;
|
||||
public StartBuildEventImpl(@NotNull BuildDescriptor descriptor, @NotNull String message) {
|
||||
super(descriptor.getId(), null, descriptor.getStartTime(), message);
|
||||
myBuildTitle = descriptor.getTitle();
|
||||
myWorkingDir = descriptor.getWorkingDir();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -59,6 +62,12 @@ public class StartBuildEventImpl extends StartEventImpl implements StartBuildEve
|
||||
return myBuildTitle;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getWorkingDir() {
|
||||
return myWorkingDir;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ProcessHandler getProcessHandler() {
|
||||
@@ -77,6 +86,12 @@ public class StartBuildEventImpl extends StartEventImpl implements StartBuildEve
|
||||
return myRestartActions.toArray(new AnAction[myRestartActions.size()]);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Filter[] getExecutionFilters() {
|
||||
return myFilters.toArray(new Filter[myFilters.size()]);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Supplier<RunContentDescriptor> getContentDescriptorSupplier() {
|
||||
@@ -96,7 +111,7 @@ public class StartBuildEventImpl extends StartEventImpl implements StartBuildEve
|
||||
return this;
|
||||
}
|
||||
|
||||
public StartBuildEventImpl withRestartAction(@Nullable AnAction anAction) {
|
||||
public StartBuildEventImpl withRestartAction(@NotNull AnAction anAction) {
|
||||
myRestartActions.add(anAction);
|
||||
return this;
|
||||
}
|
||||
@@ -115,4 +130,14 @@ public class StartBuildEventImpl extends StartEventImpl implements StartBuildEve
|
||||
myContentDescriptorSupplier = contentDescriptorSupplier;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StartBuildEventImpl withExecutionFilter(@NotNull Filter filter) {
|
||||
myFilters.add(filter);
|
||||
return this;
|
||||
}
|
||||
|
||||
public StartBuildEventImpl withExecutionFilters(Filter... filters) {
|
||||
myFilters.addAll(Arrays.asList(filters));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.build.internal;
|
||||
|
||||
import com.intellij.build.BuildContentManager;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
import com.intellij.ui.content.Content;
|
||||
import com.intellij.ui.content.impl.ContentImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -37,18 +38,18 @@ public class DummyBuildContentManager implements BuildContentManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectedContent(Content content) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectContent(String tabName) {
|
||||
public ActionCallback setSelectedContent(Content content,
|
||||
boolean requestFocus,
|
||||
boolean forcedFocus,
|
||||
boolean activate,
|
||||
Runnable activationCallback) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Content addTabbedContent(@NotNull JComponent contentComponent,
|
||||
@NotNull String groupPrefix,
|
||||
@NotNull String tabName,
|
||||
boolean select,
|
||||
@Nullable Icon icon,
|
||||
@Nullable Disposable childDisposable) {
|
||||
return new ContentImpl(contentComponent, tabName, false);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
package com.intellij.build.internal;
|
||||
|
||||
import com.intellij.build.BuildContentManager;
|
||||
import com.intellij.build.SyncViewManager;
|
||||
import com.intellij.build.TasksViewManager;
|
||||
import com.intellij.build.events.BuildEvent;
|
||||
import com.intellij.build.events.FinishBuildEvent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -24,11 +24,16 @@ import com.intellij.openapi.project.Project;
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
*/
|
||||
public class DummyTasksViewManager extends SyncViewManager {
|
||||
public class DummyTasksViewManager extends TasksViewManager {
|
||||
public DummyTasksViewManager(Project project, BuildContentManager buildContentManager) {
|
||||
super(project, buildContentManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getViewName() {
|
||||
return "Tasks";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(BuildEvent event) {
|
||||
if(event instanceof FinishBuildEvent) {
|
||||
|
||||
+2
-5
@@ -26,10 +26,7 @@ import com.intellij.psi.scope.BaseScopeProcessor;
|
||||
import com.intellij.psi.scope.ElementClassHint;
|
||||
import com.intellij.psi.scope.util.PsiScopesUtil;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.ClassUtil;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.FactoryMap;
|
||||
@@ -235,7 +232,7 @@ public class ChainCompletionContext {
|
||||
|
||||
@Override
|
||||
public boolean execute(@NotNull PsiElement element, @NotNull ResolveState state) {
|
||||
if ((!(element instanceof PsiMethod) || PropertyUtil.isSimplePropertyAccessor((PsiMethod)element)) &&
|
||||
if ((!(element instanceof PsiMethod) || PropertyUtilBase.isSimplePropertyAccessor((PsiMethod)element)) &&
|
||||
(!(element instanceof PsiVariable) || !myExcludedVariables.contains(element)) &&
|
||||
(!(element instanceof PsiMember) || myResolveHelper.isAccessible((PsiMember)element, myPlace, null))) {
|
||||
PsiType type = getType(element);
|
||||
|
||||
+7
-11
@@ -27,7 +27,6 @@ import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.java.stubs.index.JavaFullClassNameIndex;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.util.SystemProperties;
|
||||
@@ -179,17 +178,14 @@ public class FrequentlyUsedInheritorInspection extends BaseJavaLocalInspectionTo
|
||||
.filter(Objects::nonNull)
|
||||
.map(defAndCount -> {
|
||||
String name = compilerRefService.getName(defAndCount.myDef.getName());
|
||||
PsiClass inheritor =
|
||||
JavaFullClassNameIndex.getInstance().get(name.hashCode(), project, searchScope).stream()
|
||||
.filter(cls -> name.equals(cls.getQualifiedName()))
|
||||
.collect(MoreCollectors.onlyOne())
|
||||
.orElse(null);
|
||||
|
||||
if (inheritor == null || !inheritor.isInheritor(aClass, false)) {
|
||||
return null;
|
||||
PsiClass[] inheritors = JavaPsiFacade.getInstance(project).findClasses(name, searchScope);
|
||||
if (inheritors.length == 1) {
|
||||
PsiClass inheritor = inheritors[0];
|
||||
if (inheritor.isInheritor(aClass, false)) {
|
||||
return new ClassAndInheritorCount(inheritor, defAndCount.myDef, defAndCount.inheritorCount);
|
||||
}
|
||||
}
|
||||
|
||||
return new ClassAndInheritorCount(inheritor, defAndCount.myDef, defAndCount.inheritorCount);
|
||||
return null;
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.uiDesigner.core.GridConstraints;
|
||||
import com.intellij.util.NullableFunction;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
@@ -148,8 +149,7 @@ public class ValidationConfigurable implements SearchableConfigurable, Configura
|
||||
|
||||
private List<Compiler> getValidators() {
|
||||
final CompilerManager compilerManager = CompilerManager.getInstance(myProject);
|
||||
final List<Compiler> validators = new ArrayList<>();
|
||||
validators.addAll(Arrays.asList(compilerManager.getCompilers(Validator.class)));
|
||||
final List<Compiler> validators = new SmartList<>(compilerManager.getCompilers(Validator.class));
|
||||
for (GenericCompiler compiler : compilerManager.getCompilers(GenericCompiler.class)) {
|
||||
if (compiler.getOrderPlace() == GenericCompiler.CompileOrderPlace.VALIDATING) {
|
||||
validators.add(compiler);
|
||||
|
||||
@@ -71,13 +71,6 @@ public class InternalProjectTaskRunner extends ProjectTaskRunner {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionEnvironment createExecutionEnvironment(@NotNull Project project,
|
||||
@NotNull ExecuteRunConfigurationTask task,
|
||||
@Nullable Executor executor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Map<Class<? extends ProjectTask>, List<ProjectTask>> groupBy(@NotNull Collection<? extends ProjectTask> tasks) {
|
||||
return tasks.stream().collect(Collectors.groupingBy(o -> {
|
||||
if (o instanceof ModuleFilesBuildTask) return ModuleFilesBuildTask.class;
|
||||
|
||||
@@ -47,7 +47,10 @@ public abstract class ProjectTaskRunner {
|
||||
|
||||
public abstract boolean canRun(@NotNull ProjectTask projectTask);
|
||||
|
||||
public abstract ExecutionEnvironment createExecutionEnvironment(@NotNull Project project,
|
||||
@NotNull ExecuteRunConfigurationTask task,
|
||||
@Nullable Executor executor);
|
||||
@Nullable
|
||||
public ExecutionEnvironment createExecutionEnvironment(@NotNull Project project,
|
||||
@NotNull ExecuteRunConfigurationTask task,
|
||||
@Nullable Executor executor) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.debugger.engine;
|
||||
|
||||
import com.intellij.debugger.impl.DebuggerManagerImpl;
|
||||
import com.intellij.execution.ProgramRunnerUtil;
|
||||
import com.intellij.execution.RunManager;
|
||||
import com.intellij.execution.RunnerAndConfigurationSettings;
|
||||
@@ -29,6 +30,7 @@ import com.intellij.openapi.util.UserDataHolder;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import com.intellij.util.execution.ParametersListUtil;
|
||||
import com.intellij.xdebugger.attach.XDefaultLocalAttachGroup;
|
||||
import com.intellij.xdebugger.attach.XLocalAttachDebugger;
|
||||
import com.intellij.xdebugger.attach.XLocalAttachDebuggerProvider;
|
||||
@@ -71,7 +73,8 @@ public class JavaAttachDebuggerProvider implements XLocalAttachDebuggerProvider
|
||||
.createRunConfiguration(name, Objects.requireNonNull(ConfigurationTypeUtil.findConfigurationType("Remote")).getConfigurationFactories()[0]);
|
||||
|
||||
RunConfiguration remoteConfiguration = runSettings.getConfiguration();
|
||||
ReflectionUtil.setField(remoteConfiguration.getClass(), remoteConfiguration, String.class, "HOST", address.first);
|
||||
String host = address.first != null && !"*".equals(address.first) ? address.first : DebuggerManagerImpl.LOCALHOST_ADDRESS_FALLBACK;
|
||||
ReflectionUtil.setField(remoteConfiguration.getClass(), remoteConfiguration, String.class, "HOST", host);
|
||||
ReflectionUtil.setField(remoteConfiguration.getClass(), remoteConfiguration, String.class, "PORT", String.valueOf(address.second));
|
||||
ReflectionUtil.setField(remoteConfiguration.getClass(), remoteConfiguration, boolean.class, "USE_SOCKET_TRANSPORT", true);
|
||||
ReflectionUtil.setField(remoteConfiguration.getClass(), remoteConfiguration, boolean.class, "SERVER_MODE", false);
|
||||
@@ -124,6 +127,6 @@ public class JavaAttachDebuggerProvider implements XLocalAttachDebuggerProvider
|
||||
}
|
||||
|
||||
private static Pair<String, Integer> getAttachAddress(ProcessInfo processInfo) {
|
||||
return DebugAttachDetector.getAttachAddress(StringUtil.split(processInfo.getCommandLine(), " "));
|
||||
return DebugAttachDetector.getAttachAddress(ParametersListUtil.parse(processInfo.getCommandLine()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ import java.util.stream.Stream;
|
||||
@State(name = "DebuggerManager", storages = {@Storage(StoragePathMacros.WORKSPACE_FILE)})
|
||||
public class DebuggerManagerImpl extends DebuggerManagerEx implements PersistentStateComponent<Element> {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.DebuggerManagerImpl");
|
||||
public static final String LOCALHOST_ADDRESS_FALLBACK = "127.0.0.1";
|
||||
|
||||
private final Project myProject;
|
||||
private final HashMap<ProcessHandler, DebuggerSession> mySessions = new HashMap<>();
|
||||
@@ -449,7 +450,7 @@ public class DebuggerManagerImpl extends DebuggerManagerEx implements Persistent
|
||||
}
|
||||
|
||||
final TransportServiceWrapper transportService = TransportServiceWrapper.getTransportService(useSockets);
|
||||
final String debugAddress = debuggerInServerMode && useSockets ? "127.0.0.1:" + address : address;
|
||||
final String debugAddress = debuggerInServerMode && useSockets ? LOCALHOST_ADDRESS_FALLBACK + ":" + address : address;
|
||||
String debuggeeRunProperties = "transport=" + transportService.transportId() + ",address=" + debugAddress;
|
||||
if (debuggerInServerMode) {
|
||||
debuggeeRunProperties += ",suspend=y,server=n";
|
||||
@@ -498,7 +499,7 @@ public class DebuggerManagerImpl extends DebuggerManagerEx implements Persistent
|
||||
parameters.getVMParametersList().replaceOrPrepend("-classic", forceClassicVM ? "-classic" : "");
|
||||
});
|
||||
|
||||
return new RemoteConnection(useSockets, "127.0.0.1", address, debuggerInServerMode);
|
||||
return new RemoteConnection(useSockets, LOCALHOST_ADDRESS_FALLBACK, address, debuggerInServerMode);
|
||||
}
|
||||
|
||||
private static boolean shouldForceNoJIT(Sdk jdk) {
|
||||
|
||||
@@ -42,7 +42,6 @@ import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.java.stubs.index.JavaFullClassNameIndex;
|
||||
import com.intellij.psi.jsp.JspFile;
|
||||
import com.intellij.psi.search.EverythingGlobalScope;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
@@ -247,10 +246,10 @@ public class LineBreakpoint<P extends JavaBreakpointProperties> extends Breakpoi
|
||||
final GlobalSearchScope scope = debugProcess.getSearchScope();
|
||||
final boolean contains = scope.contains(breakpointFile);
|
||||
List<VirtualFile> files = ContainerUtil.map(
|
||||
JavaFullClassNameIndex.getInstance().get(className.hashCode(), myProject, scope),
|
||||
JavaPsiFacade.getInstance(myProject).findClasses(className, scope),
|
||||
aClass -> aClass.getContainingFile().getVirtualFile());
|
||||
List<VirtualFile> allFiles = ContainerUtil.map(
|
||||
JavaFullClassNameIndex.getInstance().get(className.hashCode(), myProject, new EverythingGlobalScope(myProject)),
|
||||
JavaPsiFacade.getInstance(myProject).findClasses(className, new EverythingGlobalScope(myProject)),
|
||||
aClass -> aClass.getContainingFile().getVirtualFile());
|
||||
final VirtualFile contentRoot = fileIndex.getContentRootForFile(breakpointFile);
|
||||
final Module module = fileIndex.getModuleForFile(breakpointFile);
|
||||
@@ -264,7 +263,7 @@ public class LineBreakpoint<P extends JavaBreakpointProperties> extends Breakpoi
|
||||
"; all possible files are: " + allFiles
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -357,7 +356,7 @@ public class LineBreakpoint<P extends JavaBreakpointProperties> extends Breakpoi
|
||||
final int dotIndex = className.lastIndexOf(".");
|
||||
if (dotIndex >= 0 && !isFile) {
|
||||
packageName = className.substring(0, dotIndex);
|
||||
className = className.substring(dotIndex + 1);
|
||||
className = className.substring(dotIndex + 1);
|
||||
}
|
||||
|
||||
if (totalTextLength != -1) {
|
||||
@@ -369,7 +368,7 @@ public class LineBreakpoint<P extends JavaBreakpointProperties> extends Breakpoi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
info.append(className);
|
||||
}
|
||||
if(hasMethodInfo) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.ide.util.projectWizard.WizardContext;
|
||||
import com.intellij.openapi.module.ModuleType;
|
||||
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -31,14 +32,14 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.*;
|
||||
|
||||
public class StepSequence {
|
||||
private final List<ModuleWizardStep> myCommonSteps = new ArrayList<>();
|
||||
private final List<ModuleWizardStep> myCommonSteps;
|
||||
private final List<Pair<ModuleWizardStep, Set<String>>> myCommonFinishingSteps = new ArrayList<>();
|
||||
private final MultiMap<String, ModuleWizardStep> mySpecificSteps = new MultiMap<>();
|
||||
@NonNls private List<String> myTypes = new ArrayList<>();
|
||||
private List<ModuleWizardStep> mySelectedSteps;
|
||||
|
||||
public StepSequence(ModuleWizardStep... commonSteps) {
|
||||
myCommonSteps.addAll(Arrays.asList(commonSteps));
|
||||
myCommonSteps = new SmartList<>(commonSteps);
|
||||
}
|
||||
|
||||
public void addCommonStep(@NotNull ModuleWizardStep step){
|
||||
|
||||
+9
-15
@@ -34,6 +34,7 @@ import com.intellij.openapi.roots.ui.configuration.LibrarySourceRootDetectorUtil
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileVisitor;
|
||||
@@ -68,12 +69,16 @@ public class DefaultLibraryRootsComponentDescriptor extends LibraryRootsComponen
|
||||
@Override
|
||||
public List<? extends RootDetector> getRootDetectors() {
|
||||
List<RootDetector> results = new ArrayList<>();
|
||||
results.add(new FileTypeBasedRootFilter(OrderRootType.CLASSES, false, StdFileTypes.CLASS, "classes"));
|
||||
results.add(new FileTypeBasedRootFilter(OrderRootType.CLASSES, true, StdFileTypes.CLASS, "jar directory"));
|
||||
results.add(new DescendentBasedRootFilter(OrderRootType.CLASSES, false, "classes",
|
||||
file -> StdFileTypes.CLASS.equals(file.getFileType())
|
||||
//some libraries store native libraries inside their JAR files and unpack them dynamically so we should detect such JARs as classes roots
|
||||
|| file.getFileSystem() instanceof JarFileSystem && isNativeLibrary(file)));
|
||||
results.add(DescendentBasedRootFilter.createFileTypeBasedFilter(OrderRootType.CLASSES, true, StdFileTypes.CLASS, "jar directory"));
|
||||
ContainerUtil.addAll(results, Extensions.getExtensions(LibrarySourceRootDetectorUtil.JAVA_SOURCE_ROOT_DETECTOR));
|
||||
results.add(new FileTypeBasedRootFilter(OrderRootType.SOURCES, true, StdFileTypes.JAVA, "source archive directory"));
|
||||
results.add(DescendentBasedRootFilter.createFileTypeBasedFilter(OrderRootType.SOURCES, true, StdFileTypes.JAVA, "source archive directory"));
|
||||
results.add(new JavadocRootDetector());
|
||||
results.add(new AnnotationsRootFilter());
|
||||
results.add(new DescendentBasedRootFilter(AnnotationOrderRootType.getInstance(), false, "external annotations",
|
||||
file -> ExternalAnnotationsManager.ANNOTATIONS_XML.equals(file.getName())));
|
||||
results.add(new NativeLibraryRootFilter());
|
||||
return results;
|
||||
}
|
||||
@@ -128,17 +133,6 @@ public class DefaultLibraryRootsComponentDescriptor extends LibraryRootsComponen
|
||||
}
|
||||
}
|
||||
|
||||
private static class AnnotationsRootFilter extends FileTypeBasedRootFilter {
|
||||
private AnnotationsRootFilter() {
|
||||
super(AnnotationOrderRootType.getInstance(), false, StdFileTypes.XML, "external annotations");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isFileAccepted(VirtualFile virtualFile) {
|
||||
return super.isFileAccepted(virtualFile) && virtualFile.getName().equals(ExternalAnnotationsManager.ANNOTATIONS_XML);
|
||||
}
|
||||
}
|
||||
|
||||
private static class NativeLibraryRootFilter extends RootDetector {
|
||||
private NativeLibraryRootFilter() {
|
||||
super(NativeLibraryOrderRootType.getInstance(), false, "native library location");
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.roots.ui.configuration.libraryEditor
|
||||
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator
|
||||
import com.intellij.openapi.roots.NativeLibraryOrderRootType
|
||||
import com.intellij.openapi.roots.OrderRootType
|
||||
import com.intellij.openapi.roots.libraries.ui.impl.LibraryRootsDetectorImpl
|
||||
import com.intellij.openapi.vfs.JarFileSystem
|
||||
import com.intellij.testFramework.LightPlatformTestCase
|
||||
import com.intellij.util.io.DirectoryContentBuilder
|
||||
import com.intellij.util.io.directoryContent
|
||||
import com.intellij.util.io.generateInVirtualTempDir
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
class JavaLibraryRootsDetectionTest : LightPlatformTestCase() {
|
||||
fun `test JAR with classes`() {
|
||||
assertRootType(OrderRootType.CLASSES, false) {
|
||||
zip("classes.jar") {
|
||||
file("A.class")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun `test directory with classes`() {
|
||||
assertRootType(OrderRootType.CLASSES, false) {
|
||||
dir("classes") {
|
||||
file("A.class")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun `test directory with sources`() {
|
||||
assertRootType(OrderRootType.SOURCES, false) {
|
||||
dir("src") {
|
||||
file("A.java", "class A {}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun `test JAR directory`() {
|
||||
assertRootType(OrderRootType.CLASSES, true) {
|
||||
dir("lib") {
|
||||
zip("a.jar") {
|
||||
file("A.class")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun `test sources zip directory`() {
|
||||
assertRootType(OrderRootType.SOURCES, true) {
|
||||
dir("lib") {
|
||||
zip("src.zip") {
|
||||
file("A.java", "class A {}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun `test native library`() {
|
||||
assertRootType(NativeLibraryOrderRootType.getInstance(), false) {
|
||||
dir("lib") {
|
||||
file("a.dll")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun `test native library in JAR`() {
|
||||
assertRootType(OrderRootType.CLASSES, false) {
|
||||
zip("a.jar") {
|
||||
file("a.dll")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun assertRootType(expectedType: OrderRootType, jarDirectory: Boolean, content: DirectoryContentBuilder.() -> Unit) {
|
||||
val dir = directoryContent(content).generateInVirtualTempDir()
|
||||
val detector = LibraryRootsDetectorImpl(DefaultLibraryRootsComponentDescriptor().rootDetectors)
|
||||
val root = assertOneElement(dir.children.flatMap { file ->
|
||||
val rootFile = if (file.fileType == StdFileTypes.ARCHIVE) JarFileSystem.getInstance().getJarRootForLocalFile(file)!! else file
|
||||
detector.detectRoots(rootFile, EmptyProgressIndicator())
|
||||
})
|
||||
val type = assertOneElement(root.types)
|
||||
assertEquals(expectedType, type.type)
|
||||
assertEquals(jarDirectory, type.isJarDirectory)
|
||||
}
|
||||
}
|
||||
+61
-7
@@ -15,18 +15,72 @@
|
||||
*/
|
||||
package com.intellij.openapi.roots.ui.configuration.projectRoot
|
||||
|
||||
import com.intellij.project.IntelliJProjectConfiguration
|
||||
import com.intellij.openapi.vfs.JarFileSystem
|
||||
import com.intellij.testFramework.LightPlatformTestCase
|
||||
import com.intellij.util.io.directoryContent
|
||||
import com.intellij.util.io.generateInVirtualTempDir
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
class ConvertToRepositoryLibraryActionTest : LightPlatformTestCase() {
|
||||
fun `test read Maven coordinates`() {
|
||||
val file = IntelliJProjectConfiguration.getJarFromSingleJarProjectLibrary("commons-codec")
|
||||
val coordinates = assertOneElement(ConvertToRepositoryLibraryActionBase.detectMavenCoordinates(arrayOf(file!!)))
|
||||
assertEquals("commons-codec", coordinates.groupId)
|
||||
assertEquals("commons-codec", coordinates.artifactId)
|
||||
assertEquals("1.9", coordinates.version)
|
||||
fun `test detect single coordinates`() {
|
||||
val file = directoryContent {
|
||||
zip("library.jar") {
|
||||
dir("META-INF") {
|
||||
dir("maven") {
|
||||
dir("myGroupId") {
|
||||
dir("myArtifactId") {
|
||||
file("pom.properties", """
|
||||
|version=1.0
|
||||
|groupId=myGroupId
|
||||
|artifactId=myArtifactId
|
||||
""".trimMargin())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.generateInVirtualTempDir().findChild("library.jar")!!
|
||||
val jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(file)!!
|
||||
val coordinates = assertOneElement(ConvertToRepositoryLibraryActionBase.detectMavenCoordinates(arrayOf(jarRoot)))
|
||||
assertEquals("myGroupId", coordinates.groupId)
|
||||
assertEquals("myArtifactId", coordinates.artifactId)
|
||||
assertEquals("1.0", coordinates.version)
|
||||
}
|
||||
|
||||
fun `test detect multiple coordinates`() {
|
||||
val file = directoryContent {
|
||||
zip("library2.jar") {
|
||||
dir("META-INF") {
|
||||
dir("maven") {
|
||||
dir("myGroupId") {
|
||||
dir("myArtifactId1") {
|
||||
file("pom.properties", """
|
||||
|version=1.0
|
||||
|groupId=myGroupId
|
||||
|artifactId=myArtifactId1
|
||||
""".trimMargin())
|
||||
}
|
||||
dir("myArtifactId2") {
|
||||
file("pom.properties", """
|
||||
|version=1.0
|
||||
|groupId=myGroupId
|
||||
|artifactId=myArtifactId2
|
||||
""".trimMargin())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.generateInVirtualTempDir().findChild("library2.jar")!!
|
||||
val jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(file)!!
|
||||
val (coordinates1, coordinates2) = ConvertToRepositoryLibraryActionBase.detectMavenCoordinates(arrayOf(jarRoot)).sortedBy { it.artifactId }
|
||||
assertEquals("myGroupId", coordinates1.groupId)
|
||||
assertEquals("myArtifactId1", coordinates1.artifactId)
|
||||
assertEquals("1.0", coordinates1.version)
|
||||
assertEquals("myGroupId", coordinates2.groupId)
|
||||
assertEquals("myArtifactId2", coordinates2.artifactId)
|
||||
assertEquals("1.0", coordinates2.version)
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -35,7 +35,9 @@ class JavaSoftKeywordHighlightingPassFactory(project: Project, registrar: TextEd
|
||||
}
|
||||
|
||||
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? {
|
||||
val visit = file is PsiJavaFile && file.name == PsiJavaModule.MODULE_INFO_FILE && file.languageLevel.isAtLeast(LanguageLevel.JDK_1_9)
|
||||
val visit = file is PsiJavaFile &&
|
||||
(file.name == PsiJavaModule.MODULE_INFO_FILE && file.languageLevel.isAtLeast(LanguageLevel.JDK_1_9) ||
|
||||
file.languageLevel.isAtLeast(LanguageLevel.JDK_X))
|
||||
return if (visit) JavaSoftKeywordHighlightingPass(file as PsiJavaFile, editor.document) else null
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -34,6 +34,7 @@ import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiSearchHelper;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -232,7 +233,7 @@ public class UnusedSymbolUtil {
|
||||
}
|
||||
|
||||
if (member instanceof PsiMethod) {
|
||||
String propertyName = PropertyUtil.getPropertyName(member);
|
||||
String propertyName = PropertyUtilBase.getPropertyName(member);
|
||||
if (propertyName != null) {
|
||||
SearchScope fileScope = containingFile.getUseScope();
|
||||
if (fileScope instanceof GlobalSearchScope &&
|
||||
@@ -286,7 +287,7 @@ public class UnusedSymbolUtil {
|
||||
if (!(containingFile instanceof PsiJavaFile)) return true; // Groovy field can be referenced from Java by getter
|
||||
if (member instanceof PsiField) return false; //Java field cannot be referenced by anything but its name
|
||||
if (member instanceof PsiMethod) {
|
||||
return PropertyUtil.isSimplePropertyAccessor((PsiMethod)member); //Java accessors can be referenced by field name from Groovy
|
||||
return PropertyUtilBase.isSimplePropertyAccessor((PsiMethod)member); //Java accessors can be referenced by field name from Groovy
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
+8
-1
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.extensions.AbstractExtensionPointBean;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.xmlb.annotations.Attribute;
|
||||
import one.util.streamex.StreamEx;
|
||||
@@ -48,7 +49,13 @@ public class ErrorFixExtensionPoint extends AbstractExtensionPointBean {
|
||||
try {
|
||||
return findClass(implementationClass).asSubclass(IntentionAction.class).getConstructor(PsiElement.class).newInstance(context);
|
||||
}
|
||||
catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | ClassNotFoundException e) {
|
||||
catch (InvocationTargetException e) {
|
||||
if(e.getCause() instanceof ProcessCanceledException) {
|
||||
throw ((ProcessCanceledException)e.getCause());
|
||||
}
|
||||
throw new RuntimeException("Error instantiating quick-fix " + implementationClass + " (error code: " + errorCode + ")", e.getCause());
|
||||
}
|
||||
catch (InstantiationException | IllegalAccessException | NoSuchMethodException | ClassNotFoundException e) {
|
||||
throw new RuntimeException("Error instantiating quick-fix " + implementationClass + " (error code: " + errorCode + ")", e);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -3063,7 +3063,7 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
final PsiClass containingClass = psiField.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
if (PsiUtil.isOnAssignmentLeftHand((PsiExpression)place)) {
|
||||
final PsiMethod setterPrototype = PropertyUtil.generateSetterPrototype(psiField);
|
||||
final PsiMethod setterPrototype = PropertyUtilBase.generateSetterPrototype(psiField);
|
||||
final PsiMethod setter = containingClass.findMethodBySignature(setterPrototype, true);
|
||||
if (setter != null && PsiUtil.isAccessible(setter, place, accessObjectClass)) {
|
||||
final PsiElement element = PsiTreeUtil.skipParentsOfType(place, PsiParenthesizedExpression.class);
|
||||
@@ -3073,7 +3073,7 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
}
|
||||
}
|
||||
else if (PsiUtil.isAccessedForReading((PsiExpression)place)) {
|
||||
final PsiMethod getterPrototype = PropertyUtil.generateGetterPrototype(psiField);
|
||||
final PsiMethod getterPrototype = PropertyUtilBase.generateGetterPrototype(psiField);
|
||||
final PsiMethod getter = containingClass.findMethodBySignature(getterPrototype, true);
|
||||
if (getter != null && PsiUtil.isAccessible(getter, place, accessObjectClass)) {
|
||||
QuickFixAction.registerQuickFixAction(error, QUICK_FIX_FACTORY.createReplaceInaccessibleFieldWithGetterSetterFix(place, getter, false));
|
||||
|
||||
+2
-5
@@ -50,10 +50,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.impl.PsiClassImplUtil;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
import com.intellij.psi.search.searches.SuperMethodsSearch;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.VisibilityUtil;
|
||||
import com.intellij.util.containers.ConcurrentFactoryMap;
|
||||
import com.intellij.codeInspection.unusedImport.UnusedImportInspection;
|
||||
@@ -227,7 +224,7 @@ class PostHighlightingVisitor {
|
||||
}
|
||||
}
|
||||
if (parent instanceof PsiMethod) {
|
||||
if (myUnusedSymbolInspection.isIgnoreAccessors() && PropertyUtil.isSimplePropertyAccessor((PsiMethod)parent)) {
|
||||
if (myUnusedSymbolInspection.isIgnoreAccessors() && PropertyUtilBase.isSimplePropertyAccessor((PsiMethod)parent)) {
|
||||
return null;
|
||||
}
|
||||
if (compareVisibilities((PsiModifierListOwner)parent, myUnusedSymbolInspection.getMethodVisibility())) {
|
||||
|
||||
@@ -568,8 +568,33 @@ public class CFGBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inlines given lambda. Lambda parameters are assumed to be assigned already (if necessary).
|
||||
* <p>
|
||||
* Stack before: ...
|
||||
* <p>
|
||||
* Stack after: ... lambdaResult
|
||||
*
|
||||
* @param lambda lambda to inline
|
||||
* @param resultNullness a required return value nullness
|
||||
* @return this builder
|
||||
*/
|
||||
public CFGBuilder inlineLambda(PsiLambdaExpression lambda, Nullness resultNullness) {
|
||||
myAnalyzer.inlineLambda(lambda, resultNullness);
|
||||
PsiElement body = lambda.getBody();
|
||||
PsiExpression expression = LambdaUtil.extractSingleExpressionFromBody(body);
|
||||
if (expression != null) {
|
||||
pushExpression(expression);
|
||||
boxUnbox(expression, LambdaUtil.getFunctionalInterfaceReturnType(lambda));
|
||||
if(resultNullness == Nullness.NOT_NULL) {
|
||||
checkNotNull(expression, NullabilityProblem.nullableFunctionReturn);
|
||||
}
|
||||
} else if(body instanceof PsiCodeBlock) {
|
||||
PsiVariable variable = createTempVariable(LambdaUtil.getFunctionalInterfaceReturnType(lambda));
|
||||
myAnalyzer.inlineBlock((PsiCodeBlock)body, resultNullness, variable);
|
||||
push(getFactory().getVarFactory().createVariableValue(variable, false));
|
||||
} else {
|
||||
pushUnknown();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
+61
-47
@@ -63,8 +63,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
private final ExceptionTransfer myRuntimeException;
|
||||
private final ExceptionTransfer myError;
|
||||
private final PsiType myAssertionError;
|
||||
private PsiLambdaExpression myLambdaExpression = null;
|
||||
private boolean myForceNotNullLambdaResult = false;
|
||||
private InlinedBlockContext myInlinedBlockContext;
|
||||
|
||||
ControlFlowAnalyzer(final DfaValueFactory valueFactory, @NotNull PsiElement codeFragment, boolean ignoreAssertions, boolean inlining) {
|
||||
myInlining = inlining;
|
||||
@@ -685,34 +684,42 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
startElement(statement);
|
||||
|
||||
PsiExpression returnValue = statement.getReturnValue();
|
||||
if (returnValue != null) {
|
||||
returnValue.accept(this);
|
||||
PsiMethod method = PsiTreeUtil.getParentOfType(statement, PsiMethod.class, true, PsiMember.class, PsiLambdaExpression.class);
|
||||
if (method != null) {
|
||||
generateBoxingUnboxingInstructionFor(returnValue, method.getReturnType());
|
||||
}
|
||||
else {
|
||||
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(statement, PsiLambdaExpression.class, true, PsiMember.class);
|
||||
if (lambdaExpression != null) {
|
||||
generateBoxingUnboxingInstructionFor(returnValue, LambdaUtil.getFunctionalInterfaceReturnType(lambdaExpression));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (myLambdaExpression == null) {
|
||||
if (myInlinedBlockContext != null) {
|
||||
if (returnValue != null) {
|
||||
DfaVariableValue var = myFactory.getVarFactory().createVariableValue(myInlinedBlockContext.myTarget, false);
|
||||
addInstruction(new PushInstruction(var, null, true));
|
||||
returnValue.accept(this);
|
||||
generateBoxingUnboxingInstructionFor(returnValue, var.getVariableType());
|
||||
if (myInlinedBlockContext.myForceNonNullBlockResult) {
|
||||
addInstruction(new CheckNotNullInstruction(returnValue, NullabilityProblem.nullableFunctionReturn));
|
||||
}
|
||||
addInstruction(new AssignInstruction(returnValue, null));
|
||||
addInstruction(new PopInstruction());
|
||||
}
|
||||
|
||||
controlTransfer(new InstructionTransfer(getEndOffset(myInlinedBlockContext.myCodeBlock), getVariablesInside(
|
||||
myInlinedBlockContext.myCodeBlock)), myTrapStack);
|
||||
} else {
|
||||
|
||||
if (returnValue != null) {
|
||||
returnValue.accept(this);
|
||||
PsiMethod method = PsiTreeUtil.getParentOfType(statement, PsiMethod.class, true, PsiMember.class, PsiLambdaExpression.class);
|
||||
if (method != null) {
|
||||
generateBoxingUnboxingInstructionFor(returnValue, method.getReturnType());
|
||||
}
|
||||
else {
|
||||
final PsiLambdaExpression lambdaExpression =
|
||||
PsiTreeUtil.getParentOfType(statement, PsiLambdaExpression.class, true, PsiMember.class);
|
||||
if (lambdaExpression != null) {
|
||||
generateBoxingUnboxingInstructionFor(returnValue, LambdaUtil.getFunctionalInterfaceReturnType(lambdaExpression));
|
||||
}
|
||||
}
|
||||
addInstruction(new CheckReturnValueInstruction(returnValue));
|
||||
}
|
||||
|
||||
addInstruction(new ReturnInstruction(myFactory.controlTransfer(ReturnTransfer.INSTANCE, myTrapStack), statement));
|
||||
}
|
||||
else {
|
||||
if (returnValue == null) {
|
||||
pushUnknown();
|
||||
} else if (myForceNotNullLambdaResult) {
|
||||
addInstruction(new CheckNotNullInstruction(returnValue, NullabilityProblem.nullableFunctionReturn));
|
||||
}
|
||||
controlTransfer(new InstructionTransfer(getEndOffset(myLambdaExpression), getVariablesInside(myLambdaExpression)), myTrapStack);
|
||||
}
|
||||
finishElement(statement);
|
||||
}
|
||||
|
||||
@@ -1765,34 +1772,41 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
@Override public void visitClass(PsiClass aClass) {
|
||||
}
|
||||
|
||||
void inlineLambda(PsiLambdaExpression lambda, Nullness resultNullness) {
|
||||
PsiLambdaExpression oldLambda = myLambdaExpression;
|
||||
boolean oldForceNotNullLambdaResult = myForceNotNullLambdaResult;
|
||||
/**
|
||||
* Inline code block (lambda or method body) into this CFG. Incoming parameters are assumed to be handled already (if necessary)
|
||||
*
|
||||
* @param block block to inline
|
||||
* @param resultNullness desired nullness returned by block return statement
|
||||
* @param target a variable to store the block result (returned via {@code return} statement)
|
||||
*/
|
||||
void inlineBlock(@NotNull PsiCodeBlock block, @NotNull Nullness resultNullness, @NotNull PsiVariable target) {
|
||||
InlinedBlockContext oldBlock = myInlinedBlockContext;
|
||||
// Transfer value is pushed to avoid emptying stack beyond this point
|
||||
addInstruction(new PushInstruction(myFactory.controlTransfer(ReturnTransfer.INSTANCE, this.myTrapStack), null));
|
||||
myLambdaExpression = lambda;
|
||||
myForceNotNullLambdaResult = resultNullness == Nullness.NOT_NULL;
|
||||
startElement(lambda);
|
||||
myInlinedBlockContext = new InlinedBlockContext(block, resultNullness == Nullness.NOT_NULL, target);
|
||||
startElement(block);
|
||||
try {
|
||||
PsiElement body = lambda.getBody();
|
||||
Objects.requireNonNull(body).accept(this);
|
||||
if (body instanceof PsiCodeBlock) {
|
||||
// return value for void or incomplete lambda
|
||||
pushUnknown();
|
||||
}
|
||||
else if (body instanceof PsiExpression) {
|
||||
generateBoxingUnboxingInstructionFor((PsiExpression)body, LambdaUtil.getFunctionalInterfaceReturnType(lambda));
|
||||
if (myForceNotNullLambdaResult) {
|
||||
addInstruction(new CheckNotNullInstruction((PsiExpression)body, NullabilityProblem.nullableFunctionReturn));
|
||||
}
|
||||
}
|
||||
block.accept(this);
|
||||
// return value for void or incomplete block
|
||||
pushUnknown();
|
||||
}
|
||||
finally {
|
||||
finishElement(lambda);
|
||||
myLambdaExpression = oldLambda;
|
||||
myForceNotNullLambdaResult = oldForceNotNullLambdaResult;
|
||||
// Pop transfer value (which is second value in stack now)
|
||||
addInstruction(new SpliceInstruction(2, 0));
|
||||
finishElement(block);
|
||||
myInlinedBlockContext = oldBlock;
|
||||
// Pop transfer value
|
||||
addInstruction(new PopInstruction());
|
||||
}
|
||||
}
|
||||
|
||||
public static class InlinedBlockContext {
|
||||
final PsiCodeBlock myCodeBlock;
|
||||
final boolean myForceNonNullBlockResult;
|
||||
final PsiVariable myTarget;
|
||||
|
||||
public InlinedBlockContext(PsiCodeBlock codeBlock, boolean forceNonNullBlockResult, PsiVariable target) {
|
||||
myCodeBlock = codeBlock;
|
||||
myForceNonNullBlockResult = forceNonNullBlockResult;
|
||||
myTarget = target;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -133,6 +133,48 @@ public abstract class DfaFactType<T> extends Key<T> {
|
||||
return fact.toString();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* This fact represents a set of possible types of this value
|
||||
* {@link TypeConstraint#EMPTY} value is equivalent to absent fact (not constrained)
|
||||
*/
|
||||
public static final DfaFactType<TypeConstraint> TYPE_CONSTRAINT = new DfaFactType<TypeConstraint>("Type") {
|
||||
@Nullable
|
||||
@Override
|
||||
TypeConstraint fromDfaValue(DfaValue value) {
|
||||
if(value instanceof DfaTypeValue) {
|
||||
TypeConstraint constraint = TypeConstraint.EMPTY.withInstanceofValue((DfaTypeValue)value);
|
||||
return constraint == null || constraint.isEmpty() ? null : constraint;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isSuper(@Nullable TypeConstraint superFact, @Nullable TypeConstraint subFact) {
|
||||
return superFact == null || (subFact != null && superFact.isSuperStateOf(subFact));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
TypeConstraint intersectFacts(@NotNull TypeConstraint left, @NotNull TypeConstraint right) {
|
||||
for (DfaPsiType type : right.getInstanceofValues()) {
|
||||
left = left.withInstanceofValue(type);
|
||||
if (left == null) return null;
|
||||
}
|
||||
for (DfaPsiType type : right.getNotInstanceofValues()) {
|
||||
left = left.withNotInstanceofValue(type);
|
||||
if (left == null) return null;
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
TypeConstraint unionFacts(@NotNull TypeConstraint left, @NotNull TypeConstraint right) {
|
||||
if(left.isSuperStateOf(right)) return left;
|
||||
if(right.isSuperStateOf(left)) return right;
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
private DfaFactType(String name) {
|
||||
super("DfaFactType: " + name);
|
||||
|
||||
@@ -19,7 +19,6 @@ import com.intellij.codeInspection.dataFlow.value.DfaConstValue;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaRelationValue;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaValue;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
|
||||
import com.intellij.psi.PsiType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -56,13 +55,6 @@ public interface DfaMemoryState {
|
||||
@Nullable
|
||||
<T> T getValueFact(@NotNull DfaFactType<T> factType, @NotNull DfaValue value);
|
||||
|
||||
/**
|
||||
* @param value to determine its type
|
||||
* @return value type at this state if known (possibly erased)
|
||||
*/
|
||||
@Nullable
|
||||
PsiType getValueType(DfaValue value);
|
||||
|
||||
void flushFields();
|
||||
|
||||
void flushVariable(DfaVariableValue variable);
|
||||
|
||||
-17
@@ -1068,23 +1068,6 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
return factType.fromDfaValue(value);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiType getValueType(DfaValue value) {
|
||||
if (value instanceof DfaTypeValue) {
|
||||
return ((DfaTypeValue)value).getDfaType().getPsiType();
|
||||
}
|
||||
if (value instanceof DfaVariableValue) {
|
||||
DfaVariableState state = getVariableState((DfaVariableValue)value);
|
||||
Set<DfaPsiType> values = state.getInstanceofValues();
|
||||
if (!values.isEmpty()) {
|
||||
return values.iterator().next().getPsiType();
|
||||
}
|
||||
return ((DfaVariableValue)value).getVariableType();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private DfaValue resolveVariableValue(DfaVariableValue var) {
|
||||
DfaConstValue constValue = getConstantValue(var);
|
||||
|
||||
+22
-115
@@ -20,117 +20,49 @@ import com.intellij.codeInspection.dataFlow.value.DfaPsiType;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaTypeValue;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaValue;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiPrimitiveType;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Objects;
|
||||
|
||||
class DfaVariableState {
|
||||
@NotNull final Set<DfaPsiType> myInstanceofValues;
|
||||
@NotNull final Set<DfaPsiType> myNotInstanceofValues;
|
||||
@NotNull final DfaFactMap myFactMap;
|
||||
private final int myHash;
|
||||
|
||||
DfaVariableState(@NotNull DfaVariableValue dfaVar) {
|
||||
this(Collections.emptySet(), Collections.emptySet(), dfaVar.getInherentFacts());
|
||||
this(dfaVar.getInherentFacts());
|
||||
}
|
||||
|
||||
public boolean isSuperStateOf(DfaVariableState that) {
|
||||
if(!that.myNotInstanceofValues.containsAll(myNotInstanceofValues)) return false;
|
||||
if(!that.myInstanceofValues.containsAll(myInstanceofValues)) return false;
|
||||
return myFactMap.isSuperStateOf(that.myFactMap);
|
||||
}
|
||||
|
||||
DfaVariableState(@NotNull Set<DfaPsiType> instanceofValues,
|
||||
@NotNull Set<DfaPsiType> notInstanceofValues,
|
||||
@NotNull DfaFactMap factMap) {
|
||||
myInstanceofValues = instanceofValues;
|
||||
myNotInstanceofValues = notInstanceofValues;
|
||||
DfaVariableState(@NotNull DfaFactMap factMap) {
|
||||
myFactMap = factMap;
|
||||
myHash = Objects.hash(myInstanceofValues, myNotInstanceofValues, myFactMap);
|
||||
}
|
||||
|
||||
private boolean checkInstanceofValue(@NotNull DfaPsiType dfaType) {
|
||||
if (myInstanceofValues.contains(dfaType)) return true;
|
||||
|
||||
for (DfaPsiType dfaTypeValue : myNotInstanceofValues) {
|
||||
if (dfaTypeValue.isAssignableFrom(dfaType)) return false;
|
||||
}
|
||||
|
||||
for (DfaPsiType dfaTypeValue : myInstanceofValues) {
|
||||
if (!dfaType.isConvertibleFrom(dfaTypeValue)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
myHash = myFactMap.hashCode();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
DfaVariableState withInstanceofValue(@NotNull DfaTypeValue dfaType) {
|
||||
if (dfaType.getDfaType().getPsiType() instanceof PsiPrimitiveType) return this;
|
||||
|
||||
if (checkInstanceofValue(dfaType.getDfaType())) {
|
||||
DfaVariableState result = dfaType.isNullable() ? withFact(DfaFactType.CAN_BE_NULL, true) : this;
|
||||
List<DfaPsiType> moreGeneric = ContainerUtil.newArrayList();
|
||||
for (DfaPsiType alreadyInstanceof : myInstanceofValues) {
|
||||
if (dfaType.getDfaType().isAssignableFrom(alreadyInstanceof)) {
|
||||
return result;
|
||||
}
|
||||
if (alreadyInstanceof.isAssignableFrom(dfaType.getDfaType())) {
|
||||
moreGeneric.add(alreadyInstanceof);
|
||||
}
|
||||
}
|
||||
|
||||
HashSet<DfaPsiType> newInstanceof = ContainerUtil.newHashSet(myInstanceofValues);
|
||||
newInstanceof.removeAll(moreGeneric);
|
||||
newInstanceof.add(dfaType.getDfaType());
|
||||
result = createCopy(newInstanceof, myNotInstanceofValues, result.myFactMap);
|
||||
return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
TypeConstraint typeConstraint = getTypeConstraint();
|
||||
TypeConstraint newTypeConstraint = typeConstraint.withInstanceofValue(dfaType);
|
||||
if (newTypeConstraint == null) return null;
|
||||
DfaVariableState result = dfaType.isNullable() ? withFact(DfaFactType.CAN_BE_NULL, true) : this;
|
||||
return result.withFact(DfaFactType.TYPE_CONSTRAINT, newTypeConstraint);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
DfaVariableState withNotInstanceofValue(@NotNull DfaTypeValue dfaType) {
|
||||
if (myNotInstanceofValues.contains(dfaType.getDfaType())) return this;
|
||||
|
||||
for (DfaPsiType dfaTypeValue : myInstanceofValues) {
|
||||
if (dfaType.getDfaType().isAssignableFrom(dfaTypeValue)) return null;
|
||||
}
|
||||
|
||||
List<DfaPsiType> moreSpecific = ContainerUtil.newArrayList();
|
||||
for (DfaPsiType alreadyNotInstanceof : myNotInstanceofValues) {
|
||||
if (alreadyNotInstanceof.isAssignableFrom(dfaType.getDfaType())) {
|
||||
return this;
|
||||
}
|
||||
if (dfaType.getDfaType().isAssignableFrom(alreadyNotInstanceof)) {
|
||||
moreSpecific.add(alreadyNotInstanceof);
|
||||
}
|
||||
}
|
||||
|
||||
HashSet<DfaPsiType> newNotInstanceof = ContainerUtil.newHashSet(myNotInstanceofValues);
|
||||
newNotInstanceof.removeAll(moreSpecific);
|
||||
newNotInstanceof.add(dfaType.getDfaType());
|
||||
return createCopy(myInstanceofValues, newNotInstanceof, myFactMap);
|
||||
TypeConstraint typeConstraint = getTypeConstraint();
|
||||
TypeConstraint newTypeConstraint = typeConstraint.withNotInstanceofValue(dfaType);
|
||||
return newTypeConstraint == null ? null : withFact(DfaFactType.TYPE_CONSTRAINT, newTypeConstraint);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
DfaVariableState withoutType(@NotNull DfaPsiType type) {
|
||||
if (myInstanceofValues.contains(type)) {
|
||||
HashSet<DfaPsiType> newInstanceof = ContainerUtil.newHashSet(myInstanceofValues);
|
||||
newInstanceof.remove(type);
|
||||
return createCopy(newInstanceof, myNotInstanceofValues, myFactMap);
|
||||
}
|
||||
if (myNotInstanceofValues.contains(type)) {
|
||||
HashSet<DfaPsiType> newNotInstanceof = ContainerUtil.newHashSet(myNotInstanceofValues);
|
||||
newNotInstanceof.remove(type);
|
||||
return createCopy(myInstanceofValues, newNotInstanceof, myFactMap);
|
||||
}
|
||||
return this;
|
||||
return withFact(DfaFactType.TYPE_CONSTRAINT, getTypeConstraint().withoutType(type));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
@@ -141,35 +73,16 @@ class DfaVariableState {
|
||||
if (obj == this) return true;
|
||||
if (!(obj instanceof DfaVariableState)) return false;
|
||||
DfaVariableState aState = (DfaVariableState) obj;
|
||||
return myHash == aState.myHash &&
|
||||
myInstanceofValues.equals(aState.myInstanceofValues) &&
|
||||
myNotInstanceofValues.equals(aState.myNotInstanceofValues) &&
|
||||
Objects.equals(myFactMap, aState.myFactMap);
|
||||
return myHash == aState.myHash && Objects.equals(myFactMap, aState.myFactMap);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected DfaVariableState createCopy(@NotNull Set<DfaPsiType> instanceofValues,
|
||||
@NotNull Set<DfaPsiType> notInstanceofValues,
|
||||
@NotNull DfaFactMap factMap) {
|
||||
return new DfaVariableState(instanceofValues, notInstanceofValues, factMap);
|
||||
protected DfaVariableState createCopy(@NotNull DfaFactMap factMap) {
|
||||
return new DfaVariableState(factMap);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
@NonNls StringBuilder buf = new StringBuilder("State:");
|
||||
|
||||
if (!myInstanceofValues.isEmpty()) {
|
||||
buf.append(" instanceof ").append(StringUtil.join(myInstanceofValues, ","));
|
||||
}
|
||||
|
||||
if (!myNotInstanceofValues.isEmpty()) {
|
||||
buf.append(" not instanceof ").append(StringUtil.join(myNotInstanceofValues, ","));
|
||||
}
|
||||
|
||||
String factString = myFactMap.toString();
|
||||
if(!factString.isEmpty()) {
|
||||
buf.append(" ").append(factString);
|
||||
}
|
||||
return buf.toString();
|
||||
return "State: " + myFactMap;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -189,7 +102,7 @@ class DfaVariableState {
|
||||
@NotNull
|
||||
<T> DfaVariableState withFact(DfaFactType<T> type, T value) {
|
||||
DfaFactMap factMap = myFactMap.with(type, value);
|
||||
return myFactMap.equals(factMap) ? this : createCopy(myInstanceofValues, myNotInstanceofValues, factMap);
|
||||
return myFactMap.equals(factMap) ? this : createCopy(factMap);
|
||||
}
|
||||
|
||||
<T> DfaVariableState withoutFact(DfaFactType<T> type) {
|
||||
@@ -199,9 +112,7 @@ class DfaVariableState {
|
||||
@Nullable
|
||||
<T> DfaVariableState intersectFact(DfaFactType<T> type, T value) {
|
||||
DfaFactMap factMap = myFactMap.intersect(type, value);
|
||||
return factMap == null
|
||||
? null
|
||||
: myFactMap.equals(factMap) ? this : createCopy(myInstanceofValues, myNotInstanceofValues, factMap);
|
||||
return factMap == null ? null : myFactMap.equals(factMap) ? this : createCopy(factMap);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -215,13 +126,9 @@ class DfaVariableState {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<DfaPsiType> getInstanceofValues() {
|
||||
return myInstanceofValues;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<DfaPsiType> getNotInstanceofValues() {
|
||||
return myNotInstanceofValues;
|
||||
public TypeConstraint getTypeConstraint() {
|
||||
TypeConstraint fact = getFact(DfaFactType.TYPE_CONSTRAINT);
|
||||
return fact == null ? TypeConstraint.EMPTY : fact;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+1
-3
@@ -33,7 +33,6 @@ import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -138,8 +137,7 @@ class NullParameterConstraintChecker extends DataFlowRunner {
|
||||
super(factory);
|
||||
for (PsiParameter parameter : myPossiblyViolatedParameters) {
|
||||
setVariableState(getFactory().getVarFactory().createVariableValue(parameter, false),
|
||||
new DfaVariableState(Collections.emptySet(), Collections.emptySet(),
|
||||
DfaFactMap.EMPTY.with(DfaFactType.CAN_BE_NULL, true)));
|
||||
new DfaVariableState(DfaFactMap.EMPTY.with(DfaFactType.CAN_BE_NULL, true)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+29
-14
@@ -23,6 +23,7 @@ import com.intellij.codeInspection.dataFlow.value.DfaRelationValue.RelationType;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.search.JavaOverridingMethodsSearcher;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -477,6 +478,26 @@ public class StandardInstructionVisitor extends InstructionVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiMethod findSpecificMethod(@NotNull PsiMethod method, @NotNull DfaMemoryState state, @Nullable DfaValue qualifier) {
|
||||
if (qualifier == null || !PsiUtil.canBeOverridden(method)) {
|
||||
return method;
|
||||
}
|
||||
TypeConstraint constraint = state.getValueFact(DfaFactType.TYPE_CONSTRAINT, qualifier);
|
||||
PsiClass specificQualifierClass = PsiUtil.resolveClassInClassTypeOnly(constraint == null ? null : constraint.getPsiType());
|
||||
PsiClass qualifierClass = method.getContainingClass();
|
||||
if (specificQualifierClass != null && qualifierClass != null &&
|
||||
!specificQualifierClass.equals(qualifierClass) &&
|
||||
InheritanceUtil.isInheritorOrSelf(specificQualifierClass, qualifierClass, true)) {
|
||||
PsiMethod realMethod =
|
||||
JavaOverridingMethodsSearcher.findOverridingMethod(method.getProject(), specificQualifierClass, method, qualifierClass);
|
||||
if (realMethod != null) {
|
||||
return realMethod;
|
||||
}
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static DfaValue getMethodResultValue(MethodCallInstruction instruction,
|
||||
@Nullable DfaValue qualifierValue,
|
||||
@@ -520,19 +541,13 @@ public class StandardInstructionVisitor extends InstructionVisitor {
|
||||
Nullness nullability = instruction.getReturnNullability();
|
||||
PsiMethod targetMethod = instruction.getTargetMethod();
|
||||
if (targetMethod != null) {
|
||||
PsiClass specificQualifierClass = PsiUtil.resolveClassInClassTypeOnly(state.getValueType(qualifierValue));
|
||||
PsiClass qualifierClass = targetMethod.getContainingClass();
|
||||
if (specificQualifierClass != null && qualifierClass != null &&
|
||||
!specificQualifierClass.equals(qualifierClass) &&
|
||||
InheritanceUtil.isInheritorOrSelf(specificQualifierClass, qualifierClass, true)) {
|
||||
PsiMethod realMethod = specificQualifierClass.findMethodBySignature(targetMethod, true);
|
||||
if (realMethod != null && realMethod != targetMethod) {
|
||||
nullability = DfaPsiUtil.getElementNullability(type, realMethod);
|
||||
PsiType returnType = realMethod.getReturnType();
|
||||
if(returnType != null && TypeConversionUtil.erasure(type).isAssignableFrom(returnType)) {
|
||||
// possibly covariant return type
|
||||
type = returnType;
|
||||
}
|
||||
PsiMethod realMethod = findSpecificMethod(targetMethod, state, qualifierValue);
|
||||
if (realMethod != targetMethod) {
|
||||
nullability = DfaPsiUtil.getElementNullability(type, realMethod);
|
||||
PsiType returnType = realMethod.getReturnType();
|
||||
if (returnType != null && TypeConversionUtil.erasure(type).isAssignableFrom(returnType)) {
|
||||
// possibly covariant return type
|
||||
type = returnType;
|
||||
}
|
||||
}
|
||||
if (nullability == Nullness.UNKNOWN) {
|
||||
@@ -700,7 +715,7 @@ public class StandardInstructionVisitor extends InstructionVisitor {
|
||||
return checkComparisonWithKnownValue(instruction, runner, memState, relationType, leftValue, rightValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (dfaRight instanceof DfaConstValue && dfaLeft instanceof DfaVariableValue) {
|
||||
Object value = ((DfaConstValue)dfaRight).getValue();
|
||||
if (value instanceof Number) {
|
||||
|
||||
@@ -430,10 +430,11 @@ class StateMerger {
|
||||
for (Map.Entry<DfaVariableValue, DfaVariableState> entry : states.entrySet()) {
|
||||
DfaVariableValue var = entry.getKey();
|
||||
DfaVariableState variableState = entry.getValue();
|
||||
for (DfaPsiType type : variableState.getInstanceofValues()) {
|
||||
TypeConstraint typeConstraint = variableState.getTypeConstraint();
|
||||
for (DfaPsiType type : typeConstraint.getInstanceofValues()) {
|
||||
result.add(new InstanceofFact(var, true, type));
|
||||
}
|
||||
for (DfaPsiType type : variableState.getNotInstanceofValues()) {
|
||||
for (DfaPsiType type : typeConstraint.getNotInstanceofValues()) {
|
||||
result.add(new InstanceofFact(var, false, type));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInspection.dataFlow;
|
||||
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaPsiType;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaTypeValue;
|
||||
import com.intellij.psi.PsiPrimitiveType;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import one.util.streamex.EntryStream;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Immutable class representing a number of non-primitive type constraints applied to some value.
|
||||
* There are two types of constrains: value is instance of some type and value is not an instance of some type.
|
||||
*/
|
||||
public final class TypeConstraint {
|
||||
/**
|
||||
* An instance representing no constraints
|
||||
*/
|
||||
public static final TypeConstraint EMPTY = new TypeConstraint(Collections.emptySet(), Collections.emptySet());
|
||||
|
||||
@NotNull private final Set<DfaPsiType> myInstanceofValues;
|
||||
@NotNull private final Set<DfaPsiType> myNotInstanceofValues;
|
||||
|
||||
private TypeConstraint(@NotNull Set<DfaPsiType> instanceofValues, @NotNull Set<DfaPsiType> notInstanceofValues) {
|
||||
myInstanceofValues = instanceofValues;
|
||||
myNotInstanceofValues = notInstanceofValues;
|
||||
}
|
||||
|
||||
private static TypeConstraint create(@NotNull Set<DfaPsiType> instanceofValues, @NotNull Set<DfaPsiType> notInstanceofValues) {
|
||||
if (instanceofValues.isEmpty() && notInstanceofValues.isEmpty()) {
|
||||
return EMPTY;
|
||||
}
|
||||
if (instanceofValues.isEmpty()) {
|
||||
instanceofValues = Collections.emptySet();
|
||||
}
|
||||
else if (instanceofValues.size() == 1) {
|
||||
instanceofValues = Collections.singleton(instanceofValues.iterator().next());
|
||||
}
|
||||
if (notInstanceofValues.isEmpty()) {
|
||||
notInstanceofValues = Collections.emptySet();
|
||||
}
|
||||
else if (notInstanceofValues.size() == 1) {
|
||||
notInstanceofValues = Collections.singleton(notInstanceofValues.iterator().next());
|
||||
}
|
||||
return new TypeConstraint(instanceofValues, notInstanceofValues);
|
||||
}
|
||||
|
||||
boolean checkInstanceofValue(@NotNull DfaPsiType dfaType) {
|
||||
if (myInstanceofValues.contains(dfaType)) return true;
|
||||
|
||||
for (DfaPsiType dfaTypeValue : myNotInstanceofValues) {
|
||||
if (dfaTypeValue.isAssignableFrom(dfaType)) return false;
|
||||
}
|
||||
|
||||
for (DfaPsiType dfaTypeValue : myInstanceofValues) {
|
||||
if (!dfaType.isConvertibleFrom(dfaTypeValue)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
TypeConstraint withInstanceofValue(@NotNull DfaTypeValue dfaType) {
|
||||
return withInstanceofValue(dfaType.getDfaType());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
TypeConstraint withInstanceofValue(@NotNull DfaPsiType type) {
|
||||
if (type.getPsiType() instanceof PsiPrimitiveType) return this;
|
||||
|
||||
if (!checkInstanceofValue(type)) {
|
||||
return null;
|
||||
}
|
||||
List<DfaPsiType> moreGeneric = new ArrayList<>();
|
||||
for (DfaPsiType alreadyInstanceof : myInstanceofValues) {
|
||||
if (type.isAssignableFrom(alreadyInstanceof)) {
|
||||
return this;
|
||||
}
|
||||
if (alreadyInstanceof.isAssignableFrom(type)) {
|
||||
moreGeneric.add(alreadyInstanceof);
|
||||
}
|
||||
}
|
||||
|
||||
Set<DfaPsiType> newInstanceof = ContainerUtil.newHashSet(myInstanceofValues);
|
||||
newInstanceof.removeAll(moreGeneric);
|
||||
newInstanceof.add(type);
|
||||
return create(newInstanceof, myNotInstanceofValues);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
TypeConstraint withNotInstanceofValue(@NotNull DfaTypeValue dfaType) {
|
||||
return withNotInstanceofValue(dfaType.getDfaType());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
TypeConstraint withNotInstanceofValue(DfaPsiType type) {
|
||||
if (myNotInstanceofValues.contains(type)) return this;
|
||||
|
||||
for (DfaPsiType dfaTypeValue : myInstanceofValues) {
|
||||
if (type.isAssignableFrom(dfaTypeValue)) return null;
|
||||
}
|
||||
|
||||
List<DfaPsiType> moreSpecific = new ArrayList<>();
|
||||
for (DfaPsiType alreadyNotInstanceof : myNotInstanceofValues) {
|
||||
if (alreadyNotInstanceof.isAssignableFrom(type)) {
|
||||
return this;
|
||||
}
|
||||
if (type.isAssignableFrom(alreadyNotInstanceof)) {
|
||||
moreSpecific.add(alreadyNotInstanceof);
|
||||
}
|
||||
}
|
||||
|
||||
Set<DfaPsiType> newNotInstanceof = ContainerUtil.newHashSet(myNotInstanceofValues);
|
||||
newNotInstanceof.removeAll(moreSpecific);
|
||||
newNotInstanceof.add(type);
|
||||
return create(myInstanceofValues, newNotInstanceof);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
TypeConstraint withoutType(@NotNull DfaPsiType type) {
|
||||
if (myInstanceofValues.contains(type)) {
|
||||
HashSet<DfaPsiType> newInstanceof = ContainerUtil.newHashSet(myInstanceofValues);
|
||||
newInstanceof.remove(type);
|
||||
return create(newInstanceof, myNotInstanceofValues);
|
||||
}
|
||||
if (myNotInstanceofValues.contains(type)) {
|
||||
HashSet<DfaPsiType> newNotInstanceof = ContainerUtil.newHashSet(myNotInstanceofValues);
|
||||
newNotInstanceof.remove(type);
|
||||
return create(myInstanceofValues, newNotInstanceof);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiType getPsiType() {
|
||||
if (myInstanceofValues.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return myInstanceofValues.iterator().next().getPsiType();
|
||||
}
|
||||
|
||||
boolean isSuperStateOf(@NotNull TypeConstraint that) {
|
||||
return that.myNotInstanceofValues.containsAll(myNotInstanceofValues) && that.myInstanceofValues.containsAll(myInstanceofValues);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<DfaPsiType> getInstanceofValues() {
|
||||
return Collections.unmodifiableSet(myInstanceofValues);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<DfaPsiType> getNotInstanceofValues() {
|
||||
return Collections.unmodifiableSet(myNotInstanceofValues);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return myInstanceofValues.isEmpty() && myNotInstanceofValues.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
TypeConstraint that = (TypeConstraint)o;
|
||||
return Objects.equals(myInstanceofValues, that.myInstanceofValues) &&
|
||||
Objects.equals(myNotInstanceofValues, that.myNotInstanceofValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(myInstanceofValues, myNotInstanceofValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return EntryStream.of("instanceof ", myInstanceofValues,
|
||||
"not instanceof ", myNotInstanceofValues)
|
||||
.removeValues(Set::isEmpty)
|
||||
.mapKeyValue((prefix, set) -> StreamEx.of(set).joining(",", prefix, ""))
|
||||
.joining(" ");
|
||||
}
|
||||
}
|
||||
+6
-13
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.intellij.codeInspection.dataFlow;
|
||||
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaPsiType;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaValue;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
|
||||
@@ -25,8 +24,6 @@ import com.intellij.util.containers.FList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Gregory.Shrago
|
||||
*/
|
||||
@@ -74,34 +71,30 @@ class ValuableDataFlowRunner extends DataFlowRunner {
|
||||
myConcatenation = FList.emptyList();
|
||||
}
|
||||
|
||||
private ValuableDfaVariableState(Set<DfaPsiType> instanceofValues,
|
||||
Set<DfaPsiType> notInstanceofValues,
|
||||
DfaValue value,
|
||||
private ValuableDfaVariableState(DfaValue value,
|
||||
@NotNull FList<PsiExpression> concatenation,
|
||||
@NotNull DfaFactMap factMap) {
|
||||
super(instanceofValues, notInstanceofValues, factMap);
|
||||
super(factMap);
|
||||
myValue = value;
|
||||
myConcatenation = concatenation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected DfaVariableState createCopy(@NotNull Set<DfaPsiType> instanceofValues,
|
||||
@NotNull Set<DfaPsiType> notInstanceofValues,
|
||||
@NotNull DfaFactMap factMap) {
|
||||
return new ValuableDfaVariableState(instanceofValues, notInstanceofValues, myValue, myConcatenation, factMap);
|
||||
protected DfaVariableState createCopy(@NotNull DfaFactMap factMap) {
|
||||
return new ValuableDfaVariableState(myValue, myConcatenation, factMap);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DfaVariableState withValue(@Nullable final DfaValue value) {
|
||||
if (value == myValue) return this;
|
||||
return new ValuableDfaVariableState(myInstanceofValues, myNotInstanceofValues, value, myConcatenation, myFactMap);
|
||||
return new ValuableDfaVariableState(value, myConcatenation, myFactMap);
|
||||
}
|
||||
|
||||
ValuableDfaVariableState withExpression(@NotNull final FList<PsiExpression> concatenation) {
|
||||
if (concatenation == myConcatenation) return this;
|
||||
return new ValuableDfaVariableState(myInstanceofValues, myNotInstanceofValues, myValue, concatenation, myFactMap);
|
||||
return new ValuableDfaVariableState(myValue, concatenation, myFactMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.javadoc.*;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -297,7 +297,7 @@ public class JavaDocLocalInspectionBase extends BaseJavaBatchLocalInspectionTool
|
||||
if (IGNORE_DEPRECATED && isDeprecated(psiMethod)) {
|
||||
return null;
|
||||
}
|
||||
if (myIgnoreSimpleAccessors && PropertyUtil.isSimplePropertyAccessor(psiMethod)) {
|
||||
if (myIgnoreSimpleAccessors && PropertyUtilBase.isSimplePropertyAccessor(psiMethod)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -384,7 +384,7 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo
|
||||
NullableNotNullManager manager, final String anno, final List<String> annoToRemove, @NotNull ProblemsHolder holder) {
|
||||
String propName = JavaCodeStyleManager.getInstance(project).variableNameToPropertyName(field.getName(), VariableKind.FIELD);
|
||||
final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
|
||||
final PsiMethod getter = PropertyUtil.findPropertyGetter(field.getContainingClass(), propName, isStatic, false);
|
||||
final PsiMethod getter = PropertyUtilBase.findPropertyGetter(field.getContainingClass(), propName, isStatic, false);
|
||||
final PsiIdentifier nameIdentifier = getter == null ? null : getter.getNameIdentifier();
|
||||
if (nameIdentifier != null && nameIdentifier.isPhysical()) {
|
||||
if (PropertyUtil.isSimpleGetter(getter)) {
|
||||
@@ -406,7 +406,7 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo
|
||||
}
|
||||
|
||||
final PsiClass containingClass = field.getContainingClass();
|
||||
final PsiMethod setter = PropertyUtil.findPropertySetter(containingClass, propName, isStatic, false);
|
||||
final PsiMethod setter = PropertyUtilBase.findPropertySetter(containingClass, propName, isStatic, false);
|
||||
if (setter != null && setter.isPhysical() && PropertyUtil.isSimpleSetter(setter)) {
|
||||
final PsiParameter[] parameters = setter.getParameterList().getParameters();
|
||||
assert parameters.length == 1 : setter.getText();
|
||||
|
||||
+2
-23
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.codeInspection.redundantCast;
|
||||
|
||||
import com.intellij.codeInsight.NullableNotNullManager;
|
||||
import com.intellij.codeInsight.daemon.GroupNames;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.miscGenerics.GenericsInspectionToolBase;
|
||||
@@ -45,7 +44,6 @@ public class RedundantCastInspection extends GenericsInspectionToolBase {
|
||||
private static final String DISPLAY_NAME = InspectionsBundle.message("inspection.redundant.cast.display.name");
|
||||
@NonNls private static final String SHORT_NAME = "RedundantCast";
|
||||
|
||||
public boolean IGNORE_ANNOTATED_METHODS;
|
||||
public boolean IGNORE_SUSPICIOUS_METHOD_CALLS;
|
||||
|
||||
|
||||
@@ -71,7 +69,7 @@ public class RedundantCastInspection extends GenericsInspectionToolBase {
|
||||
|
||||
@Override
|
||||
public void writeSettings(@NotNull Element node) throws WriteExternalException {
|
||||
if (IGNORE_ANNOTATED_METHODS || IGNORE_SUSPICIOUS_METHOD_CALLS) {
|
||||
if (IGNORE_SUSPICIOUS_METHOD_CALLS) {
|
||||
super.writeSettings(node);
|
||||
}
|
||||
}
|
||||
@@ -80,7 +78,6 @@ public class RedundantCastInspection extends GenericsInspectionToolBase {
|
||||
public JComponent createOptionsPanel() {
|
||||
final MultipleCheckboxOptionsPanel optionsPanel = new MultipleCheckboxOptionsPanel(this);
|
||||
optionsPanel.addCheckbox("Ignore casts in suspicious collections method calls", "IGNORE_SUSPICIOUS_METHOD_CALLS");
|
||||
optionsPanel.addCheckbox("Ignore casts to invoke @NotNull method which overrides @Nullable", "IGNORE_ANNOTATED_METHODS");
|
||||
return optionsPanel;
|
||||
}
|
||||
|
||||
@@ -90,25 +87,7 @@ public class RedundantCastInspection extends GenericsInspectionToolBase {
|
||||
PsiTypeElement castType = cast.getCastType();
|
||||
if (operand == null || castType == null) return null;
|
||||
PsiElement parent = PsiUtil.skipParenthesizedExprUp(cast.getParent());
|
||||
if (parent instanceof PsiReferenceExpression) {
|
||||
if (IGNORE_ANNOTATED_METHODS) {
|
||||
final PsiElement gParent = parent.getParent();
|
||||
if (gParent instanceof PsiMethodCallExpression) {
|
||||
final PsiMethod psiMethod = ((PsiMethodCallExpression)gParent).resolveMethod();
|
||||
if (psiMethod != null && NullableNotNullManager.isNotNull(psiMethod)) {
|
||||
final PsiClass superClass = PsiUtil.resolveClassInType(operand.getType());
|
||||
final PsiClass containingClass = psiMethod.getContainingClass();
|
||||
if (containingClass != null && superClass != null && containingClass.isInheritor(superClass, true)) {
|
||||
for (PsiMethod method : psiMethod.findSuperMethods(superClass)) {
|
||||
if (NullableNotNullManager.isNullable(method)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (parent instanceof PsiExpressionList) {
|
||||
if (parent instanceof PsiExpressionList) {
|
||||
final PsiElement gParent = parent.getParent();
|
||||
if (gParent instanceof PsiMethodCallExpression && IGNORE_SUSPICIOUS_METHOD_CALLS) {
|
||||
final String message = SuspiciousMethodCallUtil
|
||||
|
||||
+1
@@ -81,6 +81,7 @@ public class RedundantThrowsDeclarationInspection extends GlobalJavaBatchInspect
|
||||
if (unThrown == null) return null;
|
||||
|
||||
PsiMethod psiMethod = (PsiMethod)refMethod.getElement();
|
||||
if (psiMethod == null) return null;
|
||||
PsiClassType[] throwsList = psiMethod.getThrowsList().getReferencedTypes();
|
||||
PsiJavaCodeReferenceElement[] throwsRefs = psiMethod.getThrowsList().getReferenceElements();
|
||||
List<ProblemDescriptor> problems = null;
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -145,7 +146,7 @@ public class FieldNotUsedInToStringInspection extends AbstractToStringInspection
|
||||
}
|
||||
else {
|
||||
myUnusedMethods.remove(method);
|
||||
final PsiField field = PropertyUtil.findPropertyFieldByMember(method);
|
||||
final PsiField field = PropertyUtilBase.findPropertyFieldByMember(method);
|
||||
myUnusedFields.remove(field);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
@@ -492,7 +492,7 @@ public class PsiAdapter {
|
||||
if (!isGetterMethod(method)) {
|
||||
return null;
|
||||
}
|
||||
return PropertyUtil.getPropertyNameByGetter(method);
|
||||
return PropertyUtilBase.getPropertyNameByGetter(method);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -410,8 +410,8 @@ public class ExpectedTypesProvider {
|
||||
private void visitMethodReturnType(final PsiMethod scopeMethod, PsiType type, boolean tailTypeSemicolon) {
|
||||
if (type != null) {
|
||||
NullableComputable<String> expectedName;
|
||||
if (PropertyUtil.isSimplePropertyAccessor(scopeMethod)) {
|
||||
expectedName = () -> PropertyUtil.getPropertyName(scopeMethod);
|
||||
if (PropertyUtilBase.isSimplePropertyAccessor(scopeMethod)) {
|
||||
expectedName = () -> PropertyUtilBase.getPropertyName(scopeMethod);
|
||||
}
|
||||
else {
|
||||
expectedName = ExpectedTypeInfoImpl.NULL;
|
||||
|
||||
@@ -15,10 +15,14 @@
|
||||
*/
|
||||
package com.intellij.codeInsight;
|
||||
|
||||
import com.intellij.codeInspection.dataFlow.CommonDataflow;
|
||||
import com.intellij.codeInspection.dataFlow.DfaFactType;
|
||||
import com.intellij.codeInspection.dataFlow.TypeConstraint;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.search.JavaOverridingMethodsSearcher;
|
||||
import com.intellij.psi.javadoc.PsiDocTag;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
@@ -38,18 +42,19 @@ public class JavaTargetElementEvaluator extends TargetElementEvaluatorEx2 implem
|
||||
public static final int NEW_AS_CONSTRUCTOR = 0x04;
|
||||
public static final int THIS_ACCEPTED = 0x10;
|
||||
public static final int SUPER_ACCEPTED = 0x20;
|
||||
public static final int USE_DFA = 0x40;
|
||||
|
||||
@Override
|
||||
public int getAllAdditionalFlags() {
|
||||
return NEW_AS_CONSTRUCTOR | THIS_ACCEPTED | SUPER_ACCEPTED;
|
||||
return NEW_AS_CONSTRUCTOR | THIS_ACCEPTED | SUPER_ACCEPTED | USE_DFA;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts THIS or SUPER but not NEW_AS_CONSTRUCTOR.
|
||||
* Accepts THIS or SUPER or USE_DFA but not NEW_AS_CONSTRUCTOR.
|
||||
*/
|
||||
@Override
|
||||
public int getAdditionalDefinitionSearchFlags() {
|
||||
return THIS_ACCEPTED | SUPER_ACCEPTED;
|
||||
return THIS_ACCEPTED | SUPER_ACCEPTED | USE_DFA;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,9 +83,31 @@ public class JavaTargetElementEvaluator extends TargetElementEvaluatorEx2 implem
|
||||
return ((PsiClassType)type).resolve();
|
||||
}
|
||||
}
|
||||
if (targetElement instanceof PsiMethod && BitUtil.isSet(flags, USE_DFA)) {
|
||||
PsiElement realMethod = findOverridingMethod(editor, offset, (PsiMethod)targetElement);
|
||||
if (realMethod != null) return realMethod;
|
||||
}
|
||||
return super.adjustTargetElement(editor, offset, flags, targetElement);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement findOverridingMethod(Editor editor, int offset, PsiMethod method) {
|
||||
PsiClass qualifierClass = method.getContainingClass();
|
||||
if (qualifierClass == null || !PsiUtil.canBeOverridden(method)) return null;
|
||||
PsiReference reference = TargetElementUtil.findReference(editor, offset);
|
||||
if (!(reference instanceof PsiReferenceExpression) || !reference.isReferenceTo(method)) return null;
|
||||
PsiExpression qualifier = ((PsiReferenceExpression)reference).getQualifierExpression();
|
||||
if (qualifier == null) return null;
|
||||
TypeConstraint constraint = CommonDataflow.getExpressionFact(qualifier, DfaFactType.TYPE_CONSTRAINT);
|
||||
if (constraint == null) return null;
|
||||
PsiClass specificQualifierClass = PsiUtil.resolveClassInClassTypeOnly(constraint.getPsiType());
|
||||
if (specificQualifierClass == null || specificQualifierClass.equals(qualifierClass) ||
|
||||
!InheritanceUtil.isInheritorOrSelf(specificQualifierClass, qualifierClass, true)) {
|
||||
return null;
|
||||
}
|
||||
return JavaOverridingMethodsSearcher.findOverridingMethod(method.getProject(), specificQualifierClass, method, qualifierClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAcceptableNamedParent(@NotNull PsiElement parent) {
|
||||
return !(parent instanceof PsiDocTag);
|
||||
|
||||
+8
-3
@@ -23,6 +23,7 @@ import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
@@ -53,6 +54,7 @@ public class FunctionalExpressionCompletionProvider extends CompletionProvider<C
|
||||
JavaCompletionUtil.insertClassReference(psiClass, context.getFile(), start, start + insertedName.length());
|
||||
}
|
||||
};
|
||||
static final Key<Boolean> FUNCTIONAL_EXPR_ITEM = Key.create("FUNCTIONAL_EXPR_ITEM");
|
||||
|
||||
private static boolean isLambdaContext(@NotNull PsiElement element) {
|
||||
final PsiElement rulezzRef = element.getParent();
|
||||
@@ -105,13 +107,16 @@ public class FunctionalExpressionCompletionProvider extends CompletionProvider<C
|
||||
.withPresentableText(paramsString + " -> {}")
|
||||
.withTypeText(functionalInterfaceType.getPresentableText())
|
||||
.withIcon(AllIcons.Nodes.Function);
|
||||
LookupElement lambdaElement = builder.withAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
|
||||
result.consume(smart ? lambdaElement : PrioritizedLookupElement.withPriority(lambdaElement, 1));
|
||||
builder.putUserData(FUNCTIONAL_EXPR_ITEM, true);
|
||||
result.consume(builder.withAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE));
|
||||
}
|
||||
|
||||
addMethodReferenceVariants(
|
||||
smart, addInheritors, parameters, matcher, functionalInterfaceType, functionalInterfaceMethod, params, originalPosition, substitutor,
|
||||
element -> result.consume(smart ? JavaSmartCompletionContributor.decorate(element, Arrays.asList(expectedTypes)) : element));
|
||||
element -> {
|
||||
element.putUserData(FUNCTIONAL_EXPR_ITEM, true);
|
||||
result.consume(smart ? JavaSmartCompletionContributor.decorate(element, Arrays.asList(expectedTypes)) : element);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -252,7 +252,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
PrefixMatcher matcher = result.getPrefixMatcher();
|
||||
PsiElement parent = position.getParent();
|
||||
|
||||
if (JavaKeywordCompletion.addWildcardExtendsSuper(result, position)) {
|
||||
if (new JavaKeywordCompletion(parameters, session).addWildcardExtendsSuper(result, position)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -166,6 +166,7 @@ public class JavaKeywordCompletion {
|
||||
private final JavaCompletionSession mySession;
|
||||
private final PsiElement myPosition;
|
||||
private final String myPrefix;
|
||||
private final PrefixMatcher myKeywordMatcher;
|
||||
private final List<LookupElement> myResults = new ArrayList<>();
|
||||
private final PsiElement myPrevLeaf;
|
||||
|
||||
@@ -173,6 +174,7 @@ public class JavaKeywordCompletion {
|
||||
myParameters = parameters;
|
||||
mySession = session;
|
||||
myPrefix = session.getMatcher().getPrefix();
|
||||
myKeywordMatcher = new FixingLayoutPlainMatcher(myPrefix);
|
||||
myPosition = parameters.getPosition();
|
||||
myPrevLeaf = prevSignificantLeaf(myPosition);
|
||||
|
||||
@@ -185,7 +187,7 @@ public class JavaKeywordCompletion {
|
||||
}
|
||||
|
||||
private void addKeyword(LookupElement element) {
|
||||
if (element.getLookupString().startsWith(myPrefix)) {
|
||||
if (myKeywordMatcher.isStartMatch(element.getLookupString())) {
|
||||
myResults.add(element);
|
||||
}
|
||||
}
|
||||
@@ -313,10 +315,10 @@ public class JavaKeywordCompletion {
|
||||
addExtendsImplements();
|
||||
}
|
||||
|
||||
static boolean addWildcardExtendsSuper(CompletionResultSet result, PsiElement position) {
|
||||
boolean addWildcardExtendsSuper(CompletionResultSet result, PsiElement position) {
|
||||
if (JavaMemberNameCompletionContributor.INSIDE_TYPE_PARAMS_PATTERN.accepts(position)) {
|
||||
for (String keyword : ContainerUtil.ar(PsiKeyword.EXTENDS, PsiKeyword.SUPER)) {
|
||||
if (keyword.startsWith(result.getPrefixMatcher().getPrefix())) {
|
||||
if (myKeywordMatcher.isStartMatch(keyword)) {
|
||||
LookupElement item = BasicExpressionCompletionContributor.createKeywordLookupItem(position, keyword);
|
||||
result.addElement(new OverridableSpace(item, TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
}
|
||||
@@ -394,7 +396,7 @@ public class JavaKeywordCompletion {
|
||||
}
|
||||
}
|
||||
|
||||
if ((isInsideParameterList(myPosition) || isAtResourceVariableStart(myPosition) || isAtCatchVariableStart(myPosition)) &&
|
||||
if ((isInsideParameterList(myPosition) || isAtCatchOrResourceVariableStart(myPosition)) &&
|
||||
!psiElement().afterLeaf(PsiKeyword.FINAL).accepts(myPosition) &&
|
||||
!AFTER_DOT.accepts(myPosition)) {
|
||||
addKeyword(TailTypeDecorator.withTail(createKeyword(PsiKeyword.FINAL), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
@@ -730,12 +732,14 @@ public class JavaKeywordCompletion {
|
||||
info -> InheritanceUtil.isInheritor(info.getType(), CommonClassNames.JAVA_LANG_CLASS)) != null;
|
||||
}
|
||||
|
||||
private static boolean isAtResourceVariableStart(PsiElement position) {
|
||||
return psiElement().insideStarting(psiElement(PsiTypeElement.class).withParent(PsiResourceList.class)).accepts(position);
|
||||
}
|
||||
|
||||
private static boolean isAtCatchVariableStart(PsiElement position) {
|
||||
return psiElement().insideStarting(psiElement(PsiTypeElement.class).withParent(PsiCatchSection.class)).accepts(position);
|
||||
private static boolean isAtCatchOrResourceVariableStart(PsiElement position) {
|
||||
PsiElement type = PsiTreeUtil.getParentOfType(position, PsiTypeElement.class);
|
||||
if (type != null && type.getTextRange().getStartOffset() == position.getTextRange().getStartOffset()) {
|
||||
PsiElement parent = type.getParent();
|
||||
if (parent instanceof PsiVariable) parent = parent.getParent();
|
||||
return parent instanceof PsiCatchSection || parent instanceof PsiResourceList;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addBreakContinue() {
|
||||
|
||||
+5
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,10 +30,7 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.SuggestedNameInfo;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.refactoring.introduceField.InplaceIntroduceFieldPopup;
|
||||
import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
@@ -112,7 +109,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
|
||||
if (variableKind == VariableKind.PARAMETER) {
|
||||
final PsiMethod method = PsiTreeUtil.getParentOfType(var, PsiMethod.class);
|
||||
if (method != null) {
|
||||
propertyName = PropertyUtil.getPropertyName(method);
|
||||
propertyName = PropertyUtilBase.getPropertyName(method);
|
||||
}
|
||||
if (method != null && method.getName().startsWith("with")) {
|
||||
propertyName = StringUtil.decapitalize(method.getName().substring(4));
|
||||
@@ -393,7 +390,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
|
||||
if (staticContext && (modifierList != null && !modifierList.hasModifierProperty(PsiModifier.STATIC))) continue;
|
||||
|
||||
if (fieldType.equals(varType)) {
|
||||
final String getterName = PropertyUtil.suggestGetterName(field);
|
||||
final String getterName = PropertyUtilBase.suggestGetterName(field);
|
||||
if ((psiClass.findMethodsByName(getterName, true).length == 0 ||
|
||||
psiClass.findMethodBySignature(GenerateMembersUtil.generateGetterPrototype(field), true) == null)) {
|
||||
propertyHandlers.add(getterName);
|
||||
@@ -401,7 +398,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
|
||||
if (PsiType.VOID.equals(varType)) {
|
||||
final String setterName = PropertyUtil.suggestSetterName(field);
|
||||
final String setterName = PropertyUtilBase.suggestSetterName(field);
|
||||
if ((psiClass.findMethodsByName(setterName, true).length == 0 ||
|
||||
psiClass.findMethodBySignature(GenerateMembersUtil.generateSetterPrototype(field), true) == null)) {
|
||||
propertyHandlers.add(setterName);
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementWeigher;
|
||||
import com.intellij.codeInsight.lookup.TypedLookupItem;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Conditions;
|
||||
import com.intellij.openapi.util.Key;
|
||||
@@ -28,10 +29,7 @@ import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.filters.getters.MembersGetter;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.psi.util.proximity.KnownElementWeigher;
|
||||
import com.intellij.util.ThreeState;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -133,6 +131,8 @@ public class PreferByKindWeigher extends LookupElementWeigher {
|
||||
annoMethod,
|
||||
probableKeyword,
|
||||
castVariable,
|
||||
expectedTypeVariable,
|
||||
funExpr,
|
||||
variable,
|
||||
getter,
|
||||
qualifiedWithField,
|
||||
@@ -171,13 +171,17 @@ public class PreferByKindWeigher extends LookupElementWeigher {
|
||||
if (object instanceof PsiLocalVariable || object instanceof PsiParameter ||
|
||||
object instanceof PsiThisExpression ||
|
||||
object instanceof PsiField && !((PsiField)object).hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return MyResult.variable;
|
||||
return isExpectedTypeItem(item) ? MyResult.expectedTypeVariable : MyResult.variable;
|
||||
}
|
||||
|
||||
if (object instanceof String && item.getUserData(JavaCompletionUtil.SUPER_METHOD_PARAMETERS) == Boolean.TRUE) {
|
||||
return MyResult.superMethodParameters;
|
||||
}
|
||||
|
||||
if (item.getUserData(FunctionalExpressionCompletionProvider.FUNCTIONAL_EXPR_ITEM) != null) {
|
||||
return MyResult.funExpr;
|
||||
}
|
||||
|
||||
if (object instanceof PsiMethod) {
|
||||
PsiClass containingClass = ((PsiMethod)object).getContainingClass();
|
||||
if (containingClass != null && CommonClassNames.JAVA_UTIL_COLLECTIONS.equals(containingClass.getQualifiedName())) {
|
||||
@@ -248,6 +252,12 @@ public class PreferByKindWeigher extends LookupElementWeigher {
|
||||
return MyResult.normal;
|
||||
}
|
||||
|
||||
private boolean isExpectedTypeItem(@NotNull LookupElement item) {
|
||||
TypedLookupItem typed = item.as(TypedLookupItem.CLASS_CONDITION_KEY);
|
||||
PsiType itemType = typed == null ? null : typed.getType();
|
||||
return itemType != null && Arrays.stream(myExpectedTypes).anyMatch(info -> info.getType().isAssignableFrom(itemType));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ThreeState isProbableKeyword(String keyword) {
|
||||
if (PsiKeyword.RETURN.equals(keyword)) {
|
||||
@@ -315,7 +325,7 @@ public class PreferByKindWeigher extends LookupElementWeigher {
|
||||
if (!(object instanceof PsiMethod)) return false;
|
||||
|
||||
PsiMethod method = (PsiMethod)object;
|
||||
if (!PropertyUtil.hasGetterName(method)) return false;
|
||||
if (!PropertyUtilBase.hasGetterName(method)) return false;
|
||||
|
||||
return !KnownElementWeigher.isGetClass(method);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,6 +31,7 @@ import com.intellij.psi.filters.element.ExcludeSillyAssignment;
|
||||
import com.intellij.psi.impl.search.MethodDeepestSuperSearcher;
|
||||
import com.intellij.psi.scope.ElementClassFilter;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.CommonProcessors;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -170,15 +171,15 @@ class RecursionWeigher extends LookupElementWeigher {
|
||||
|
||||
@Nullable
|
||||
private String getSetterPropertyName(@Nullable PsiMethod calledMethod) {
|
||||
if (PropertyUtil.isSimplePropertySetter(calledMethod)) {
|
||||
if (PropertyUtilBase.isSimplePropertySetter(calledMethod)) {
|
||||
assert calledMethod != null;
|
||||
return PropertyUtil.getPropertyName(calledMethod);
|
||||
return PropertyUtilBase.getPropertyName(calledMethod);
|
||||
}
|
||||
PsiReferenceExpression reference = ExcludeSillyAssignment.getAssignedReference(myPosition);
|
||||
if (reference != null) {
|
||||
PsiElement target = reference.resolve();
|
||||
if (target instanceof PsiField) {
|
||||
return PropertyUtil.suggestPropertyName((PsiField)target);
|
||||
return PropertyUtilBase.suggestPropertyName((PsiField)target);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -189,12 +190,12 @@ class RecursionWeigher extends LookupElementWeigher {
|
||||
if (prop == null) return false;
|
||||
|
||||
if (lookupObject instanceof PsiField &&
|
||||
prop.equals(PropertyUtil.suggestPropertyName((PsiField)lookupObject))) {
|
||||
prop.equals(PropertyUtilBase.suggestPropertyName((PsiField)lookupObject))) {
|
||||
return true;
|
||||
}
|
||||
if (lookupObject instanceof PsiMethod &&
|
||||
PropertyUtil.isSimplePropertyGetter((PsiMethod)lookupObject) &&
|
||||
prop.equals(PropertyUtil.getPropertyName((PsiMethod)lookupObject))) {
|
||||
PropertyUtilBase.isSimplePropertyGetter((PsiMethod)lookupObject) &&
|
||||
prop.equals(PropertyUtilBase.getPropertyName((PsiMethod)lookupObject))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -125,7 +125,7 @@ class SmartCastProvider extends CompletionProvider<CompletionParameters> {
|
||||
if (info.getKind() == ExpectedTypeInfo.TYPE_OR_SUPERTYPE) {
|
||||
InheritanceUtil.processSupers(infoClass, true, superClass -> {
|
||||
if (!CommonClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) {
|
||||
result.consume(JavaPsiFacade.getElementFactory(superClass.getProject()).createType(superClass));
|
||||
result.consume(JavaPsiFacade.getElementFactory(superClass.getProject()).createType(CompletionUtil.getOriginalOrSelf(superClass)));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
+5
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -47,7 +48,7 @@ public class CreateGetterOrSetterFix implements IntentionAction, LowPriorityActi
|
||||
myCreateGetter = createGetter;
|
||||
myCreateSetter = createSetter;
|
||||
myField = field;
|
||||
myPropertyName = PropertyUtil.suggestPropertyName(field);
|
||||
myPropertyName = PropertyUtilBase.suggestPropertyName(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,13 +87,13 @@ public class CreateGetterOrSetterFix implements IntentionAction, LowPriorityActi
|
||||
}
|
||||
|
||||
if (myCreateGetter){
|
||||
if (isStaticFinal(myField) || PropertyUtil.findPropertyGetter(aClass, myPropertyName, isStatic(myField), false) != null){
|
||||
if (isStaticFinal(myField) || PropertyUtilBase.findPropertyGetter(aClass, myPropertyName, isStatic(myField), false) != null){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (myCreateSetter){
|
||||
if(isFinal(myField) || PropertyUtil.findPropertySetter(aClass, myPropertyName, isStatic(myField), false) != null){
|
||||
if(isFinal(myField) || PropertyUtilBase.findPropertySetter(aClass, myPropertyName, isStatic(myField), false) != null){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiMethodCallExpression;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
@@ -41,10 +42,10 @@ public class CreateGetterSetterPropertyFromUsageFix extends CreatePropertyFromUs
|
||||
|
||||
@Override
|
||||
protected boolean checkTargetClasses(List<PsiClass> classes, String methodName) {
|
||||
String propertyName = PropertyUtil.getPropertyName(methodName);
|
||||
String propertyName = PropertyUtilBase.getPropertyName(methodName);
|
||||
if (propertyName == null) return false;
|
||||
String getterName = PropertyUtil.suggestGetterName(propertyName, null);
|
||||
String setterName = PropertyUtil.suggestSetterName(propertyName);
|
||||
String getterName = PropertyUtilBase.suggestGetterName(propertyName, null);
|
||||
String setterName = PropertyUtilBase.suggestSetterName(propertyName);
|
||||
for (PsiClass aClass : classes) {
|
||||
if (aClass.findMethodsByName(getterName, false).length > 0 || aClass.findMethodsByName(setterName, false).length > 0) return false;
|
||||
}
|
||||
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,6 +35,7 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
@@ -84,7 +85,7 @@ public class CreatePropertyFromUsageFix extends CreateFromUsageBaseFix implement
|
||||
PsiReferenceExpression ref = myMethodCall.getMethodExpression();
|
||||
String methodName = myMethodCall.getMethodExpression().getReferenceName();
|
||||
LOG.assertTrue(methodName != null);
|
||||
String propertyName = PropertyUtil.getPropertyName(methodName);
|
||||
String propertyName = PropertyUtilBase.getPropertyName(methodName);
|
||||
if (propertyName == null || propertyName.isEmpty()) return false;
|
||||
|
||||
String getterOrSetter = null;
|
||||
@@ -321,7 +322,7 @@ public class CreatePropertyFromUsageFix extends CreateFromUsageBaseFix implement
|
||||
private static String getVariableName(PsiMethodCallExpression methodCall, boolean isStatic) {
|
||||
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(methodCall.getProject());
|
||||
String methodName = methodCall.getMethodExpression().getReferenceName();
|
||||
String propertyName = PropertyUtil.getPropertyName(methodName);
|
||||
String propertyName = PropertyUtilBase.getPropertyName(methodName);
|
||||
if (propertyName != null && !propertyName.isEmpty()) {
|
||||
VariableKind kind = isStatic ? VariableKind.STATIC_FIELD : VariableKind.FIELD;
|
||||
return codeStyleManager.propertyNameToVariableName(propertyName, kind);
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,6 +34,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PropertyMemberType;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -126,7 +127,7 @@ public class CreateFieldOrPropertyFix implements IntentionAction, LocalQuickFix
|
||||
boolean first = true;
|
||||
@NonNls final String TYPE_NAME_VAR = "TYPE_NAME_VAR";
|
||||
for (GenerationInfo prototype : prototypes) {
|
||||
final PsiTypeElement typeElement = PropertyUtil.getPropertyTypeElement(prototype.getPsiMember());
|
||||
final PsiTypeElement typeElement = PropertyUtilBase.getPropertyTypeElement(prototype.getPsiMember());
|
||||
if (first) {
|
||||
first = false;
|
||||
builder.replaceElement(typeElement, TYPE_NAME_VAR, expression, true);
|
||||
|
||||
+9
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.editorActions.smartEnter;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
|
||||
/**
|
||||
@@ -53,5 +54,13 @@ public class IfConditionFixer implements Fixer {
|
||||
doc.insertString(condition.getTextRange().getEndOffset(), ")");
|
||||
}
|
||||
}
|
||||
else if (psiElement instanceof PsiExpression && psiElement.getParent() instanceof PsiExpressionStatement) {
|
||||
PsiElement prevLeaf = PsiTreeUtil.prevVisibleLeaf(psiElement);
|
||||
if (prevLeaf != null && prevLeaf.textMatches(PsiKeyword.IF)) {
|
||||
Document doc = editor.getDocument();
|
||||
doc.insertString(psiElement.getTextRange().getEndOffset(), ")");
|
||||
doc.insertString(psiElement.getTextRange().getStartOffset(), "(");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -33,6 +33,7 @@ import com.intellij.psi.scope.processor.VariablesProcessor;
|
||||
import com.intellij.psi.scope.util.PsiScopesUtil;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -234,7 +235,7 @@ public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler
|
||||
if (targetClass instanceof PsiTypeParameter) {
|
||||
LinkedHashSet<PsiMethod> meths = new LinkedHashSet<>();
|
||||
for (PsiClass superClass : targetClass.getSupers()) {
|
||||
meths.addAll(Arrays.asList(superClass.getAllMethods()));
|
||||
ContainerUtil.addAll(meths, superClass.getAllMethods());
|
||||
}
|
||||
allMethods = meths.toArray(new PsiMethod[meths.size()]);
|
||||
}
|
||||
@@ -377,7 +378,7 @@ public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass == null || CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName())) continue;
|
||||
final PsiType returnType = method.getReturnType();
|
||||
if (returnType != null && PropertyUtil.isSimplePropertyGetter(method) && helper.isAccessible(method, aClass, aClass) &&
|
||||
if (returnType != null && PropertyUtilBase.isSimplePropertyGetter(method) && helper.isAccessible(method, aClass, aClass) &&
|
||||
returnType instanceof PsiClassType && !(PsiTreeUtil.isAncestor(method, element, false) && targetClass != aClass)) {
|
||||
result.add(new PsiMethodMember(method, TypeConversionUtil.getSuperClassSubstitutor( containingClass, aClass,PsiSubstitutor.EMPTY)));
|
||||
}
|
||||
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.util.PropertyMemberType;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -71,8 +72,8 @@ public class GenerateFieldOrPropertyHandler extends GenerateMembersHandlerBase {
|
||||
for (GenerationInfo info : infos) {
|
||||
PsiMember member = info.getPsiMember();
|
||||
if (!(member instanceof PsiMethod)) continue;
|
||||
if (myMemberType == PropertyMemberType.GETTER && PropertyUtil.isSimplePropertyGetter((PsiMethod)member) ||
|
||||
myMemberType == PropertyMemberType.SETTER && PropertyUtil.isSimplePropertySetter((PsiMethod)member)) {
|
||||
if (myMemberType == PropertyMemberType.GETTER && PropertyUtilBase.isSimplePropertyGetter((PsiMethod)member) ||
|
||||
myMemberType == PropertyMemberType.SETTER && PropertyUtilBase.isSimplePropertySetter((PsiMethod)member)) {
|
||||
targetMember = member;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -609,15 +609,15 @@ public class GenerateMembersUtil {
|
||||
|
||||
//java bean getters/setters
|
||||
public static PsiMethod generateSimpleGetterPrototype(@NotNull PsiField field) {
|
||||
return generatePrototype(field, PropertyUtil.generateGetterPrototype(field));
|
||||
return generatePrototype(field, PropertyUtilBase.generateGetterPrototype(field));
|
||||
}
|
||||
|
||||
public static PsiMethod generateSimpleSetterPrototype(@NotNull PsiField field) {
|
||||
return generatePrototype(field, PropertyUtil.generateSetterPrototype(field));
|
||||
return generatePrototype(field, PropertyUtilBase.generateSetterPrototype(field));
|
||||
}
|
||||
|
||||
public static PsiMethod generateSimpleSetterPrototype(PsiField field, PsiClass targetClass) {
|
||||
return generatePrototype(field, PropertyUtil.generateSetterPrototype(field, targetClass));
|
||||
return generatePrototype(field, PropertyUtilBase.generateSetterPrototype(field, targetClass));
|
||||
}
|
||||
|
||||
//custom getters/setters
|
||||
@@ -680,7 +680,7 @@ public class GenerateMembersUtil {
|
||||
catch (IncorrectOperationException e) {
|
||||
if (ignoreInvalidTemplate) {
|
||||
LOG.info(e);
|
||||
result = isGetter ? PropertyUtil.generateGetterPrototype(field) : PropertyUtil.generateSetterPrototype(field);
|
||||
result = isGetter ? PropertyUtilBase.generateGetterPrototype(field) : PropertyUtilBase.generateSetterPrototype(field);
|
||||
assert result != null : field.getText();
|
||||
}
|
||||
else {
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,7 @@ import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
|
||||
public abstract class GetterSetterPrototypeProvider {
|
||||
public static final ExtensionPointName<GetterSetterPrototypeProvider> EP_NAME = ExtensionPointName.create("com.intellij.getterSetterProvider");
|
||||
@@ -74,7 +75,7 @@ public abstract class GetterSetterPrototypeProvider {
|
||||
if (getterSetter != null) return getterSetter;
|
||||
}
|
||||
}
|
||||
final PsiMethod propertyGetterSetter = PropertyUtil.findPropertyGetter(aClass, propertyName, isStatic, false);
|
||||
final PsiMethod propertyGetterSetter = PropertyUtilBase.findPropertyGetter(aClass, propertyName, isStatic, false);
|
||||
if (propertyGetterSetter != null) {
|
||||
return new PsiMethod[] {propertyGetterSetter};
|
||||
}
|
||||
|
||||
+4
-1
@@ -236,7 +236,10 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
|
||||
return;
|
||||
}
|
||||
|
||||
int index = ParameterInfoUtils.getCurrentParameterIndex(o.getNode(), context.getOffset(), JavaTokenType.COMMA);
|
||||
int offset = context.getOffset();
|
||||
TextRange elRange = o.getTextRange();
|
||||
int index = offset <= elRange.getStartOffset() || offset >= elRange.getEndOffset()
|
||||
? -1 : ParameterInfoUtils.getCurrentParameterIndex(o.getNode(), offset, JavaTokenType.COMMA);
|
||||
context.setCurrentParameter(index);
|
||||
|
||||
Object[] candidates = context.getObjectsToView();
|
||||
|
||||
@@ -33,8 +33,15 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.siyeh.ig.callMatcher.CallMatcher.anyOf;
|
||||
import static com.siyeh.ig.callMatcher.CallMatcher.staticCall;
|
||||
|
||||
public class UnrollLoopAction extends PsiElementBaseIntentionAction {
|
||||
private static final CallMatcher LIST_CONSTRUCTOR = CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_ARRAYS, "asList");
|
||||
private static final CallMatcher LIST_CONSTRUCTOR = anyOf(staticCall(CommonClassNames.JAVA_UTIL_ARRAYS, "asList"),
|
||||
staticCall(CommonClassNames.JAVA_UTIL_LIST, "of"));
|
||||
private static final CallMatcher SINGLETON_CONSTRUCTOR =
|
||||
anyOf(staticCall(CommonClassNames.JAVA_UTIL_COLLECTIONS, "singleton", "singletonList").parameterCount(1),
|
||||
staticCall(CommonClassNames.JAVA_UTIL_LIST, "of").parameterTypes("E"));
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull final PsiElement element) {
|
||||
@@ -42,14 +49,17 @@ public class UnrollLoopAction extends PsiElementBaseIntentionAction {
|
||||
if (loop == null) return false;
|
||||
if (!(loop.getParent() instanceof PsiCodeBlock)) return false;
|
||||
PsiExpression iteratedValue = ExpressionUtils.resolveExpression(loop.getIteratedValue());
|
||||
PsiParameter iterationParameter = loop.getIterationParameter();
|
||||
if (extractExpressions(iteratedValue).length == 0) return false;
|
||||
PsiStatement[] statements = ControlFlowUtils.unwrapBlock(loop.getBody());
|
||||
if (statements.length == 0) return false;
|
||||
if (Arrays.stream(statements).anyMatch(PsiDeclarationStatement.class::isInstance)) return false;
|
||||
if (isBreakChain(loop)) {
|
||||
statements = Arrays.copyOfRange(statements, 0, statements.length - 1);
|
||||
}
|
||||
if (VariableAccessUtils.variableIsAssigned(iterationParameter, loop)) return false;
|
||||
//if (isBreakChain(loop)) {
|
||||
// statements = Arrays.copyOfRange(statements, 0, statements.length - 1);
|
||||
//}
|
||||
for (PsiStatement statement : statements) {
|
||||
if (isLoopBreak(statement)) continue;
|
||||
boolean acceptable = PsiTreeUtil.processElements(statement, e -> {
|
||||
if (e instanceof PsiBreakStatement && ((PsiBreakStatement)e).findExitedStatement() == loop) return false;
|
||||
if (e instanceof PsiContinueStatement && ((PsiContinueStatement)e).findContinuedStatement() == loop) return false;
|
||||
@@ -72,9 +82,15 @@ public class UnrollLoopAction extends PsiElementBaseIntentionAction {
|
||||
}
|
||||
if (expression instanceof PsiMethodCallExpression) {
|
||||
PsiMethodCallExpression call = (PsiMethodCallExpression)expression;
|
||||
if (LIST_CONSTRUCTOR.test(call) && MethodCallUtils.isVarArgCall(call)) {
|
||||
if (SINGLETON_CONSTRUCTOR.test(call)) {
|
||||
return call.getArgumentList().getExpressions();
|
||||
}
|
||||
if (LIST_CONSTRUCTOR.test(call)) {
|
||||
PsiExpression[] args = call.getArgumentList().getExpressions();
|
||||
if (args.length > 1 || MethodCallUtils.isVarArgCall(call)) {
|
||||
return args;
|
||||
}
|
||||
}
|
||||
}
|
||||
return PsiExpression.EMPTY_ARRAY;
|
||||
}
|
||||
@@ -96,7 +112,6 @@ public class UnrollLoopAction extends PsiElementBaseIntentionAction {
|
||||
PsiForeachStatement loop = PsiTreeUtil.getParentOfType(element, PsiForeachStatement.class);
|
||||
if (loop == null) return;
|
||||
if (!(loop.getParent() instanceof PsiCodeBlock)) return;
|
||||
boolean breakChain = isBreakChain(loop);
|
||||
PsiExpression iteratedValue = loop.getIteratedValue();
|
||||
PsiExpression[] expressions = extractExpressions(ExpressionUtils.resolveExpression(iteratedValue));
|
||||
if (expressions.length == 0) return;
|
||||
@@ -115,22 +130,23 @@ public class UnrollLoopAction extends PsiElementBaseIntentionAction {
|
||||
}
|
||||
PsiStatement body = copy.getBody();
|
||||
assert body != null;
|
||||
PsiElement[] children;
|
||||
if (body instanceof PsiBlockStatement) {
|
||||
PsiElement[] children = ((PsiBlockStatement)body).getCodeBlock().getChildren();
|
||||
PsiElement parent = anchor.getParent();
|
||||
PsiElement currentAnchor = anchor;
|
||||
children = ((PsiBlockStatement)body).getCodeBlock().getChildren();
|
||||
// Skip {braces}
|
||||
Arrays.stream(children, 1, children.length - 1).forEach(child -> parent.addBefore(child, currentAnchor));
|
||||
children = Arrays.copyOfRange(children, 1, children.length-1);
|
||||
} else {
|
||||
children = new PsiElement[]{body};
|
||||
}
|
||||
if (breakChain) {
|
||||
PsiStatement lastStatement = PsiTreeUtil.getPrevSiblingOfType(anchor, PsiStatement.class);
|
||||
if (lastStatement instanceof PsiIfStatement) {
|
||||
PsiIfStatement ifStatement = (PsiIfStatement)lastStatement;
|
||||
for(PsiElement child : children) {
|
||||
PsiElement added = anchor.getParent().addBefore(child, anchor);
|
||||
if (added instanceof PsiIfStatement && isLoopBreak((PsiStatement)added)) {
|
||||
PsiIfStatement ifStatement = (PsiIfStatement)added;
|
||||
PsiExpression condition = Objects.requireNonNull(ifStatement.getCondition());
|
||||
PsiStatement thenBranch = Objects.requireNonNull(ifStatement.getThenBranch());
|
||||
String negated = BoolUtils.getNegatedExpressionText(condition);
|
||||
condition.replace(factory.createExpressionFromText(negated, condition));
|
||||
PsiBlockStatement block = (PsiBlockStatement)thenBranch.replace(factory.createStatementFromText("{}", lastStatement));
|
||||
PsiBlockStatement block = (PsiBlockStatement)thenBranch.replace(factory.createStatementFromText("{}", added));
|
||||
anchor = block.getCodeBlock().getLastChild();
|
||||
}
|
||||
}
|
||||
@@ -140,19 +156,11 @@ public class UnrollLoopAction extends PsiElementBaseIntentionAction {
|
||||
ct.deleteAndRestoreComments(loop);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param loop loop to test
|
||||
* @return true if the last statement is "if(...) break"
|
||||
*/
|
||||
private static boolean isBreakChain(PsiForeachStatement loop) {
|
||||
PsiStatement lastStatement = loop.getBody();
|
||||
if (lastStatement instanceof PsiBlockStatement) {
|
||||
lastStatement = ControlFlowUtils.getLastStatementInBlock(((PsiBlockStatement)lastStatement).getCodeBlock());
|
||||
}
|
||||
if (!(lastStatement instanceof PsiIfStatement)) return false;
|
||||
PsiIfStatement ifStatement = (PsiIfStatement)lastStatement;
|
||||
return ifStatement.getElseBranch() == null &&
|
||||
ifStatement.getCondition() != null &&
|
||||
ControlFlowUtils.statementBreaksLoop(ControlFlowUtils.stripBraces(ifStatement.getThenBranch()), loop);
|
||||
private static boolean isLoopBreak(PsiStatement statement) {
|
||||
if (!(statement instanceof PsiIfStatement)) return false;
|
||||
PsiIfStatement ifStatement = (PsiIfStatement)statement;
|
||||
if (ifStatement.getElseBranch() != null || ifStatement.getCondition() == null) return false;
|
||||
PsiStatement thenBranch = ControlFlowUtils.stripBraces(ifStatement.getThenBranch());
|
||||
return thenBranch instanceof PsiBreakStatement && ((PsiBreakStatement)thenBranch).getLabelIdentifier() == null;
|
||||
}
|
||||
}
|
||||
|
||||
+16
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,8 @@
|
||||
package com.intellij.codeInsight.template.postfix.templates;
|
||||
|
||||
import com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils;
|
||||
import com.intellij.codeInspection.dataFlow.Nullness;
|
||||
import com.intellij.codeInspection.dataFlow.NullnessUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.psi.PsiPrimitiveType;
|
||||
@@ -35,23 +37,21 @@ public class OptionalPostfixTemplate extends StringBasedPostfixTemplate {
|
||||
@Override
|
||||
public String getTemplateString(@NotNull PsiElement element) {
|
||||
String className = "Optional";
|
||||
String methodName = "ofNullable";
|
||||
|
||||
if (element instanceof PsiExpression) {
|
||||
PsiType type = ((PsiExpression)element).getType();
|
||||
if (type instanceof PsiPrimitiveType) {
|
||||
if (PsiType.INT.equals(type)) {
|
||||
className = "OptionalInt";
|
||||
}
|
||||
else if (PsiType.DOUBLE.equals(type)) {
|
||||
className = "OptionalDouble";
|
||||
}
|
||||
else if (PsiType.LONG.equals(type)) {
|
||||
className = "OptionalLong";
|
||||
}
|
||||
methodName = "of";
|
||||
|
||||
PsiType type = ((PsiExpression)element).getType();
|
||||
if (type instanceof PsiPrimitiveType) {
|
||||
if (PsiType.INT.equals(type)) {
|
||||
className = "OptionalInt";
|
||||
}
|
||||
else if (PsiType.DOUBLE.equals(type)) {
|
||||
className = "OptionalDouble";
|
||||
}
|
||||
else if (PsiType.LONG.equals(type)) {
|
||||
className = "OptionalLong";
|
||||
}
|
||||
}
|
||||
|
||||
String methodName = Nullness.NOT_NULL.equals(NullnessUtil.getExpressionNullness((PsiExpression)element)) ? "of" : "ofNullable";
|
||||
return "java.util." + className + "." + methodName + "($expr$)";
|
||||
}
|
||||
}
|
||||
|
||||
+16
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,15 +16,28 @@
|
||||
package com.intellij.codeInsight.template.postfix.templates;
|
||||
|
||||
import com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorAllExpressionsWithCurrentOffset;
|
||||
|
||||
public class StreamPostfixTemplate extends StringBasedPostfixTemplate {
|
||||
private static final Condition<PsiElement> IS_SUPPORTED_ARRAY = element -> {
|
||||
if (!(element instanceof PsiExpression)) return false;
|
||||
|
||||
PsiType type = ((PsiExpression)element).getType();
|
||||
if (!(type instanceof PsiArrayType)) return false;
|
||||
|
||||
PsiType componentType = ((PsiArrayType)type).getComponentType();
|
||||
if (!(componentType instanceof PsiPrimitiveType)) return true;
|
||||
|
||||
return componentType.equals(PsiType.INT) || componentType.equals(PsiType.LONG) || componentType.equals(PsiType.DOUBLE);
|
||||
};
|
||||
|
||||
public StreamPostfixTemplate() {
|
||||
super("stream", "Arrays.stream(expr)", JavaPostfixTemplatesUtils.atLeastJava8Selector(selectorAllExpressionsWithCurrentOffset(JavaPostfixTemplatesUtils.IS_ARRAY)));
|
||||
super("stream", "Arrays.stream(expr)", JavaPostfixTemplatesUtils.atLeastJava8Selector(selectorAllExpressionsWithCurrentOffset(IS_SUPPORTED_ARRAY)));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+2
-1
@@ -42,6 +42,7 @@ import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.profile.codeInspection.ui.SingleInspectionProfilePanel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.safeDelete.SafeDeleteHandler;
|
||||
import com.intellij.ui.HyperlinkAdapter;
|
||||
@@ -520,7 +521,7 @@ public class UnusedDeclarationPresentation extends DefaultInspectionToolPresenta
|
||||
//todo store in the graph
|
||||
tool.isIgnoreAccessors()) {
|
||||
final PsiModifierListOwner listOwner = ((RefMethod)element).getElement();
|
||||
if (listOwner instanceof PsiMethod && PropertyUtil.isSimplePropertyAccessor((PsiMethod)listOwner)) {
|
||||
if (listOwner instanceof PsiMethod && PropertyUtilBase.isSimplePropertyAccessor((PsiMethod)listOwner)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -465,7 +465,7 @@ public class MagicConstantInspection extends BaseJavaLocalInspectionTool {
|
||||
if (!(initializer instanceof PsiLiteralExpression)) return null;
|
||||
Object val = ((PsiLiteralExpression)initializer).getValue();
|
||||
if (!(val instanceof String)) return null;
|
||||
PsiMethod setter = PropertyUtil.findPropertySetter(method.getContainingClass(), (String)val, false, false);
|
||||
PsiMethod setter = PropertyUtilBase.findPropertySetter(method.getContainingClass(), (String)val, false, false);
|
||||
if (setter == null) return null;
|
||||
// try the @beaninfo of the corresponding setter
|
||||
PsiElement navigationElement = setter.getNavigationElement();
|
||||
@@ -482,12 +482,12 @@ public class MagicConstantInspection extends BaseJavaLocalInspectionTool {
|
||||
|
||||
PsiClass aClass = method.getContainingClass();
|
||||
if (aClass == null) return null;
|
||||
if (PropertyUtil.isSimplePropertyGetter(method)) {
|
||||
List<PsiMethod> setters = PropertyUtil.getSetters(aClass, PropertyUtil.getPropertyNameByGetter(method));
|
||||
if (PropertyUtilBase.isSimplePropertyGetter(method)) {
|
||||
List<PsiMethod> setters = PropertyUtilBase.getSetters(aClass, PropertyUtilBase.getPropertyNameByGetter(method));
|
||||
if (setters.size() != 1) return null;
|
||||
method = setters.get(0);
|
||||
}
|
||||
if (!PropertyUtil.isSimplePropertySetter(method)) return null;
|
||||
if (!PropertyUtilBase.isSimplePropertySetter(method)) return null;
|
||||
PsiDocComment doc = method.getDocComment();
|
||||
if (doc == null) return null;
|
||||
PsiDocTag beaninfo = doc.findTagByName("beaninfo");
|
||||
|
||||
+3
-2
@@ -110,7 +110,7 @@ public class SimplifyForEachInspection extends BaseJavaBatchLocalInspectionTool
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static PsiLambdaExpression extractLambdaFromForEach(PsiMethodCallExpression call) {
|
||||
static PsiLambdaExpression extractLambdaFromForEach(@NotNull PsiMethodCallExpression call) {
|
||||
PsiExpression qualifier = call.getMethodExpression().getQualifierExpression();
|
||||
if (qualifier == null || !(STREAM_FOREACH.test(call) || isCollectionForEach(call, qualifier))) return null;
|
||||
PsiExpression arg = call.getArgumentList().getExpressions()[0];
|
||||
@@ -195,7 +195,8 @@ public class SimplifyForEachInspection extends BaseJavaBatchLocalInspectionTool
|
||||
return result;
|
||||
}
|
||||
|
||||
static SimplifyForEachContext from(PsiMethodCallExpression call) {
|
||||
static SimplifyForEachContext from(@Nullable PsiMethodCallExpression call) {
|
||||
if (call == null) return null;
|
||||
PsiLambdaExpression lambda = extractLambdaFromForEach(call);
|
||||
if (lambda == null) return null;
|
||||
PsiElement lambdaBody = lambda.getBody();
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static com.intellij.codeInspection.streamToLoop.FunctionHelper.replaceVarReference;
|
||||
@@ -106,6 +107,14 @@ abstract class SourceOperation extends Operation {
|
||||
CommonClassNames.JAVA_UTIL_ARRAYS.equals(className)) {
|
||||
return new ForEachSource(args[0]);
|
||||
}
|
||||
if (name.equals("stream") &&
|
||||
args.length == 3 &&
|
||||
CommonClassNames.JAVA_UTIL_ARRAYS.equals(className) &&
|
||||
args[0].getType() != null &&
|
||||
PsiType.INT.equals(args[1].getType()) &&
|
||||
PsiType.INT.equals(args[2].getType())) {
|
||||
return new ArraySliceSource(args[0], args[1], args[2]);
|
||||
}
|
||||
if (supportUnknownSources) {
|
||||
PsiType type = StreamApiUtil.getStreamElementType(call.getType(), false);
|
||||
if (type != null) {
|
||||
@@ -320,6 +329,54 @@ abstract class SourceOperation extends Operation {
|
||||
}
|
||||
}
|
||||
|
||||
static class ArraySliceSource extends SourceOperation {
|
||||
private @NotNull PsiExpression myArray;
|
||||
private @NotNull PsiExpression myOrigin;
|
||||
private @NotNull PsiExpression myBound;
|
||||
private @NotNull PsiType myArrayType;
|
||||
|
||||
ArraySliceSource(@NotNull PsiExpression array, @NotNull PsiExpression origin, @NotNull PsiExpression bound) {
|
||||
myOrigin = origin;
|
||||
myBound = bound;
|
||||
myArray = array;
|
||||
myArrayType = Objects.requireNonNull(myArray.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
void rename(String oldName, String newName, StreamToLoopReplacementContext context) {
|
||||
myOrigin = replaceVarReference(myOrigin, oldName, newName, context);
|
||||
myBound = replaceVarReference(myBound, oldName, newName, context);
|
||||
myArray = replaceVarReference(myArray, oldName, newName, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerReusedElements(Consumer<PsiElement> consumer) {
|
||||
consumer.accept(myOrigin);
|
||||
consumer.accept(myBound);
|
||||
consumer.accept(myArray);
|
||||
}
|
||||
|
||||
@Override
|
||||
String wrap(StreamVariable outVar, String code, StreamToLoopReplacementContext context) {
|
||||
String bound = myBound.getText();
|
||||
String array = myArray.getText();
|
||||
if (!ExpressionUtils.isSimpleExpression(context.createExpression(array))) {
|
||||
array = context.declare("array", myArrayType.getCanonicalText(), array);
|
||||
}
|
||||
if (!ExpressionUtils.isSimpleExpression(context.createExpression(bound))) {
|
||||
bound = context.declare("bound", "int", bound);
|
||||
}
|
||||
String loopVar = context.registerVarName(Arrays.asList("i", "j", "idx"));
|
||||
String element = outVar.getDeclaration(array + "[" + loopVar + "]");
|
||||
return context.getLoopLabel() +
|
||||
"for(" + "int " + loopVar + " = " + myOrigin.getText() + ";" +
|
||||
loopVar + "<" + bound + ";" +
|
||||
loopVar + "++) {\n" +
|
||||
element +
|
||||
code + "}\n";
|
||||
}
|
||||
}
|
||||
|
||||
private static class StreamIteratorSource extends SourceOperation {
|
||||
private final String myElementType;
|
||||
private PsiMethodCallExpression myCall;
|
||||
|
||||
+2
-1
@@ -25,6 +25,7 @@ import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -54,7 +55,7 @@ public class UnusedReturnValue extends GlobalJavaBatchInspectionTool{
|
||||
if (!refMethod.isReturnValueUsed()) {
|
||||
final PsiMethod psiMethod = (PsiMethod)refMethod.getElement();
|
||||
if (psiMethod == null) return null;
|
||||
if (IGNORE_BUILDER_PATTERN && PropertyUtil.isSimplePropertySetter(psiMethod)) return null;
|
||||
if (IGNORE_BUILDER_PATTERN && PropertyUtilBase.isSimplePropertySetter(psiMethod)) return null;
|
||||
|
||||
final boolean isNative = psiMethod.hasModifierProperty(PsiModifier.NATIVE);
|
||||
if (refMethod.isExternalOverride() && !isNative) return null;
|
||||
|
||||
+2
-1
@@ -24,6 +24,7 @@ import com.intellij.openapi.progress.EmptyProgressIndicator;
|
||||
import com.intellij.patterns.PsiJavaPatterns;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import com.siyeh.ig.psiutils.MethodUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -61,7 +62,7 @@ public class UnusedReturnValueLocalInspection extends BaseJavaLocalInspectionToo
|
||||
public ProblemDescriptor[] checkMethod(@NotNull PsiMethod method, @NotNull InspectionManager manager, boolean isOnTheFly) {
|
||||
if (method.isConstructor() ||
|
||||
PsiType.VOID.equals(method.getReturnType()) ||
|
||||
myGlobal.IGNORE_BUILDER_PATTERN && PropertyUtil.isSimplePropertySetter(method) ||
|
||||
myGlobal.IGNORE_BUILDER_PATTERN && PropertyUtilBase.isSimplePropertySetter(method) ||
|
||||
method.hasModifierProperty(PsiModifier.NATIVE) ||
|
||||
MethodUtils.hasSuper(method) ||
|
||||
RefUtil.isImplicitRead(method)) return null;
|
||||
|
||||
@@ -34,10 +34,7 @@ import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.search.searches.FunctionalExpressionSearch;
|
||||
import com.intellij.psi.search.searches.MethodReferencesSearch;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PsiSuperMethodUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.refactoring.util.JavaNonCodeSearchElementDescriptionProvider;
|
||||
import com.intellij.refactoring.util.NonCodeSearchDescriptionLocation;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
@@ -177,13 +174,13 @@ public class JavaFindUsagesHandler extends FindUsagesHandler{
|
||||
final String propertyName = JavaCodeStyleManager.getInstance(getProject()).variableNameToPropertyName(fieldName, VariableKind.FIELD);
|
||||
Set<PsiMethod> accessors = new THashSet<>();
|
||||
boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
|
||||
PsiMethod getter = PropertyUtil.findPropertyGetterWithType(propertyName, isStatic, field.getType(),
|
||||
ContainerUtil.iterate(containingClass.getMethods()));
|
||||
PsiMethod getter = PropertyUtilBase.findPropertyGetterWithType(propertyName, isStatic, field.getType(),
|
||||
ContainerUtil.iterate(containingClass.getMethods()));
|
||||
if (getter != null) accessors.add(getter);
|
||||
PsiMethod setter = PropertyUtil.findPropertySetterWithType(propertyName, isStatic, field.getType(),
|
||||
ContainerUtil.iterate(containingClass.getMethods()));
|
||||
PsiMethod setter = PropertyUtilBase.findPropertySetterWithType(propertyName, isStatic, field.getType(),
|
||||
ContainerUtil.iterate(containingClass.getMethods()));
|
||||
if (setter != null) accessors.add(setter);
|
||||
accessors.addAll(PropertyUtil.getAccessors(containingClass, fieldName));
|
||||
accessors.addAll(PropertyUtilBase.getAccessors(containingClass, fieldName));
|
||||
if (!accessors.isEmpty()) {
|
||||
boolean containsPhysical = ContainerUtil.find(accessors, psiMethod -> psiMethod.isPhysical()) != null;
|
||||
final boolean doSearch = !containsPhysical || askShouldSearchAccessors(fieldName);
|
||||
|
||||
@@ -16,28 +16,20 @@
|
||||
package com.intellij.openapi.projectRoots.impl;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.DataKey;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectBundle;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.projectRoots.*;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
|
||||
import com.intellij.openapi.util.EmptyRunnable;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.openapi.vfs.jrt.JrtFileSystem;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
@@ -410,7 +402,7 @@ public class JavaSdkImpl extends JavaSdk {
|
||||
addClasses(jdkHomeFile, sdkModificator, isJre);
|
||||
addSources(jdkHomeFile, sdkModificator);
|
||||
|
||||
return new MockSdk(jdkName, homePath, jdkName, roots, isJre);
|
||||
return new MockSdk(jdkName, homePath, jdkName, roots, this);
|
||||
}
|
||||
|
||||
private static void addClasses(@NotNull File file, @NotNull SdkModificator sdkModificator, boolean isJre) {
|
||||
@@ -544,182 +536,4 @@ public class JavaSdkImpl extends JavaSdk {
|
||||
type == JavadocOrderRootType.getInstance() ||
|
||||
type == AnnotationOrderRootType.getInstance();
|
||||
}
|
||||
|
||||
private class MockSdk implements Sdk, SdkModificator {
|
||||
private String myJdkName;
|
||||
private String myHomePath;
|
||||
@NotNull private String myVersionString;
|
||||
private final MultiMap<OrderRootType, VirtualFile> myRoots;
|
||||
private final boolean myIsJre;
|
||||
|
||||
MockSdk(@NotNull String jdkName,
|
||||
@NotNull String homePath,
|
||||
@NotNull String versionString,
|
||||
@NotNull MultiMap<OrderRootType, VirtualFile> roots,
|
||||
boolean isJre) {
|
||||
myJdkName = jdkName;
|
||||
myHomePath = homePath;
|
||||
myVersionString = versionString;
|
||||
myRoots = roots;
|
||||
myIsJre = isJre;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SdkTypeId getSdkType() {
|
||||
return JavaSdkImpl.this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return myJdkName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getVersionString() {
|
||||
return myVersionString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHomePath() {
|
||||
return myHomePath;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public VirtualFile getHomeDirectory() {
|
||||
return LocalFileSystem.getInstance().findFileByPath(myHomePath);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public SdkAdditionalData getSdkAdditionalData() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Sdk clone() {
|
||||
return new MockSdk(myJdkName, myHomePath, myVersionString, new MultiMap<>(myRoots), myIsJre){
|
||||
@NotNull
|
||||
@Override
|
||||
public SdkModificator getSdkModificator() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SdkModificator getSdkModificator() {
|
||||
throwReadOnly();
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public VirtualFile[] getRoots(@NotNull OrderRootType rootType) {
|
||||
return myRoots.get(rootType).toArray(VirtualFile.EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
myJdkName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHomePath(String path) {
|
||||
myHomePath = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVersionString(@NotNull String versionString) {
|
||||
myVersionString = versionString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSdkAdditionalData(SdkAdditionalData data) {
|
||||
throwReadOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRoot(@NotNull VirtualFile root, @NotNull OrderRootType rootType) {
|
||||
myRoots.putValue(rootType, root);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRoot(@NotNull VirtualFile root, @NotNull OrderRootType rootType) {
|
||||
myRoots.remove(rootType, root);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRoots(@NotNull OrderRootType rootType) {
|
||||
myRoots.remove(rootType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllRoots() {
|
||||
myRoots.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commitChanges() {
|
||||
for (Project project : ProjectManager.getInstance().getOpenProjects()) {
|
||||
WriteAction.run(() -> ((ProjectRootManagerEx)ProjectRootManager.getInstance(project)).makeRootsChange(EmptyRunnable.getInstance(), false, true));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWritable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public RootProvider getRootProvider() {
|
||||
return new RootProvider() {
|
||||
@NotNull
|
||||
@Override
|
||||
public String[] getUrls(@NotNull OrderRootType rootType) {
|
||||
return ContainerUtil.map2Array(getFiles(rootType), String.class, VirtualFile::getUrl);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VirtualFile[] getFiles(@NotNull OrderRootType rootType) {
|
||||
return getRoots(rootType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRootSetChangedListener(@NotNull RootSetChangedListener listener) { }
|
||||
|
||||
@Override
|
||||
public void addRootSetChangedListener(@NotNull RootSetChangedListener listener, @NotNull Disposable parentDisposable) { }
|
||||
|
||||
@Override
|
||||
public void removeRootSetChangedListener(@NotNull RootSetChangedListener listener) { }
|
||||
};
|
||||
}
|
||||
|
||||
private void throwReadOnly() {
|
||||
throw new IncorrectOperationException("Can't modify, MockJDK is read-only, consider calling .clone() first");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T getUserData(@NotNull Key<T> key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void putUserData(@NotNull Key<T> key, @Nullable T value) {
|
||||
throwReadOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MockSDK[" + myJdkName + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-4
@@ -24,6 +24,7 @@ import com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens;
|
||||
import com.intellij.psi.search.searches.SuperMethodsSearch;
|
||||
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.Functions;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -427,13 +428,13 @@ public class JavaArrangementVisitor extends JavaRecursiveElementVisitor {
|
||||
private void parseProperties(PsiMethod method, JavaElementArrangementEntry entry) {
|
||||
String propertyName = null;
|
||||
boolean getter = true;
|
||||
if (PropertyUtil.isSimplePropertyGetter(method)) {
|
||||
if (PropertyUtilBase.isSimplePropertyGetter(method)) {
|
||||
entry.addModifier(GETTER);
|
||||
propertyName = PropertyUtil.getPropertyNameByGetter(method);
|
||||
propertyName = PropertyUtilBase.getPropertyNameByGetter(method);
|
||||
}
|
||||
else if (PropertyUtil.isSimplePropertySetter(method)) {
|
||||
else if (PropertyUtilBase.isSimplePropertySetter(method)) {
|
||||
entry.addModifier(SETTER);
|
||||
propertyName = PropertyUtil.getPropertyNameBySetter(method);
|
||||
propertyName = PropertyUtilBase.getPropertyNameBySetter(method);
|
||||
getter = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -51,13 +52,13 @@ public class BeanProperty {
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
final String name = PropertyUtil.getPropertyName(myMethod);
|
||||
final String name = PropertyUtilBase.getPropertyName(myMethod);
|
||||
return name == null ? "" : name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiType getPropertyType() {
|
||||
PsiType type = PropertyUtil.getPropertyType(myMethod);
|
||||
PsiType type = PropertyUtilBase.getPropertyType(myMethod);
|
||||
assert type != null;
|
||||
return type;
|
||||
}
|
||||
@@ -69,29 +70,29 @@ public class BeanProperty {
|
||||
|
||||
@Nullable
|
||||
public PsiMethod getGetter() {
|
||||
if (PropertyUtil.isSimplePropertyGetter(myMethod)) {
|
||||
if (PropertyUtilBase.isSimplePropertyGetter(myMethod)) {
|
||||
return myMethod;
|
||||
}
|
||||
return PropertyUtil.findPropertyGetter(myMethod.getContainingClass(), getName(), false, true);
|
||||
return PropertyUtilBase.findPropertyGetter(myMethod.getContainingClass(), getName(), false, true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiMethod getSetter() {
|
||||
if (PropertyUtil.isSimplePropertySetter(myMethod)) {
|
||||
if (PropertyUtilBase.isSimplePropertySetter(myMethod)) {
|
||||
return myMethod;
|
||||
}
|
||||
return PropertyUtil.findPropertySetter(myMethod.getContainingClass(), getName(), false, true);
|
||||
return PropertyUtilBase.findPropertySetter(myMethod.getContainingClass(), getName(), false, true);
|
||||
}
|
||||
|
||||
public void setName(String newName) throws IncorrectOperationException {
|
||||
final PsiMethod setter = getSetter();
|
||||
final PsiMethod getter = getGetter();
|
||||
if (getter != null) {
|
||||
final String getterName = PropertyUtil.suggestGetterName(newName, getter.getReturnType());
|
||||
final String getterName = PropertyUtilBase.suggestGetterName(newName, getter.getReturnType());
|
||||
getter.setName(getterName);
|
||||
}
|
||||
if (setter != null) {
|
||||
final String setterName = PropertyUtil.suggestSetterName(newName);
|
||||
final String setterName = PropertyUtilBase.suggestSetterName(newName);
|
||||
setter.setName(setterName);
|
||||
}
|
||||
}
|
||||
@@ -103,6 +104,6 @@ public class BeanProperty {
|
||||
|
||||
@Nullable
|
||||
public static BeanProperty createBeanProperty(@NotNull PsiMethod method) {
|
||||
return PropertyUtil.isSimplePropertyAccessor(method) ? new BeanProperty(method) : null;
|
||||
return PropertyUtilBase.isSimplePropertyAccessor(method) ? new BeanProperty(method) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,6 +27,7 @@ import com.intellij.psi.meta.PsiMetaData;
|
||||
import com.intellij.psi.meta.PsiMetaOwner;
|
||||
import com.intellij.psi.meta.PsiPresentableMetaData;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -48,7 +49,7 @@ public class BeanPropertyElement extends FakePsiElement implements PsiMetaOwner,
|
||||
|
||||
@Nullable
|
||||
public PsiType getPropertyType() {
|
||||
return PropertyUtil.getPropertyType(myMethod);
|
||||
return PropertyUtilBase.getPropertyType(myMethod);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+3
-2
@@ -28,6 +28,7 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -125,7 +126,7 @@ public class CreateJavaBeanPropertyFix implements LocalQuickFix, IntentionAction
|
||||
|
||||
private void createSetter(final boolean createField) throws IncorrectOperationException {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(myPsiClass.getProject()).getElementFactory();
|
||||
final String methodName = PropertyUtil.suggestSetterName(myPropertyName);
|
||||
final String methodName = PropertyUtilBase.suggestSetterName(myPropertyName);
|
||||
final String typeName = myType.getCanonicalText();
|
||||
|
||||
@NonNls final String text;
|
||||
@@ -154,7 +155,7 @@ public class CreateJavaBeanPropertyFix implements LocalQuickFix, IntentionAction
|
||||
|
||||
private void createGetter(final boolean createField) throws IncorrectOperationException {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(myPsiClass.getProject()).getElementFactory();
|
||||
final String methodName = PropertyUtil.suggestGetterName(myPropertyName, myType);
|
||||
final String methodName = PropertyUtilBase.suggestGetterName(myPropertyName, myType);
|
||||
final String typeName = myType.getCanonicalText();
|
||||
@NonNls final String text;
|
||||
PsiClass psiClass = myPsiClass.getElement();
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package com.intellij.psi.impl.source.resolve.reference.impl.providers;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.jsp.JspSpiUtil;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PropertyUtilBase;
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
@@ -89,7 +90,7 @@ public class MethodPropertyReference extends BasicAttributeValueReference {
|
||||
|
||||
@Override
|
||||
public PsiElement handleElementRename(String _newElementName) throws IncorrectOperationException {
|
||||
String newElementName = PropertyUtil.getPropertyName(_newElementName);
|
||||
String newElementName = PropertyUtilBase.getPropertyName(_newElementName);
|
||||
if (newElementName == null) newElementName = _newElementName;
|
||||
|
||||
return super.handleElementRename(newElementName);
|
||||
|
||||
+5
-2
@@ -20,9 +20,12 @@ import com.intellij.codeInsight.daemon.JavaErrorMessages;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class PsiPackageReference extends PsiPolyVariantReferenceBase<PsiElement> implements EmptyResolveMessageProvider {
|
||||
private final PackageReferenceSet myReferenceSet;
|
||||
@@ -52,7 +55,7 @@ public class PsiPackageReference extends PsiPolyVariantReferenceBase<PsiElement>
|
||||
public Object[] getVariants() {
|
||||
Set<PsiPackage> subPackages = new HashSet<>();
|
||||
for (PsiPackage psiPackage : getContext()) {
|
||||
subPackages.addAll(Arrays.asList(psiPackage.getSubPackages(myReferenceSet.getResolveScope())));
|
||||
ContainerUtil.addAll(subPackages, psiPackage.getSubPackages(myReferenceSet.getResolveScope()));
|
||||
}
|
||||
return subPackages.toArray();
|
||||
}
|
||||
|
||||
+2
-5
@@ -35,10 +35,7 @@ import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
import com.intellij.refactoring.classMembers.MemberInfoBase;
|
||||
@@ -257,7 +254,7 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor {
|
||||
myInnerClass.add(outputField);
|
||||
field = outputField;
|
||||
} else {
|
||||
field = PropertyUtil.findPropertyField(myInnerClass, name, false);
|
||||
field = PropertyUtilBase.findPropertyField(myInnerClass, name, false);
|
||||
}
|
||||
LOG.assertTrue(field != null, "i:" + i + "; output variables: " + Arrays.toString(outputVariables) + "; parameters: " + Arrays.toString(getMethod().getParameterList().getParameters()) + "; output field: " + outputField );
|
||||
myInnerClass.add(GenerateMembersUtil.generateGetterPrototype(field));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,6 +24,7 @@ import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtil;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -33,10 +34,7 @@ import com.intellij.psi.javadoc.PsiDocTagValue;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.refactoring.MoveDestination;
|
||||
import com.intellij.refactoring.RefactorJBundle;
|
||||
import com.intellij.refactoring.extractclass.usageInfo.*;
|
||||
@@ -602,7 +600,7 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
|
||||
if (myGenerateAccessors) {
|
||||
getter = GenerateMembersUtil.suggestGetterName(field);
|
||||
} else {
|
||||
final PsiMethod fieldGetter = PropertyUtil.findPropertyGetter(sourceClass, field.getName(), false, false);
|
||||
final PsiMethod fieldGetter = PropertyUtilBase.findPropertyGetter(sourceClass, field.getName(), false, false);
|
||||
if (fieldGetter != null && isInMovedElement(fieldGetter)) {
|
||||
getter = fieldGetter.getName();
|
||||
}
|
||||
@@ -612,7 +610,7 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
|
||||
if (myGenerateAccessors) {
|
||||
setter = GenerateMembersUtil.suggestSetterName(field);
|
||||
} else {
|
||||
final PsiMethod fieldSetter = PropertyUtil.findPropertySetter(sourceClass, field.getName(), false, false);
|
||||
final PsiMethod fieldSetter = PropertyUtilBase.findPropertySetter(sourceClass, field.getName(), false, false);
|
||||
if (fieldSetter != null && isInMovedElement(fieldSetter)) {
|
||||
setter = fieldSetter.getName();
|
||||
}
|
||||
@@ -707,7 +705,7 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
|
||||
if (myMoveDestination != null) {
|
||||
directory = myMoveDestination.getTargetDirectory(containingDirectory);
|
||||
} else {
|
||||
final Module module = ModuleUtil.findModuleForPsiElement(containingFile);
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement(containingFile);
|
||||
assert module != null;
|
||||
directory = PackageUtil.findOrCreateDirectoryForPackage(module, newPackageName, containingDirectory, false, true);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user