Merge remote-tracking branch 'origin/master'

This commit is contained in:
alexey.afanasiev
2017-09-18 15:24:40 +03:00
536 changed files with 14645 additions and 4883 deletions
+18
View File
@@ -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>
+14 -10
View File
@@ -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>
-9
View File
@@ -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>
-1
View File
@@ -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.
+6
View File
@@ -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 -1
View File
@@ -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
-1
View File
@@ -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);
@@ -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) {
@@ -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);
@@ -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){
@@ -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");
@@ -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)
}
}
@@ -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)
}
}
@@ -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
}
}
@@ -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;
}
@@ -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);
}
}
@@ -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));
@@ -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;
}
@@ -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);
@@ -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);
@@ -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
@@ -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)));
}
}
@@ -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(" ");
}
}
@@ -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
@@ -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;
}
@@ -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();
@@ -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
@@ -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;
@@ -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);
@@ -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);
});
}
}
}
@@ -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() {
@@ -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;
});
@@ -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;
}
}
@@ -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;
}
@@ -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);
@@ -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);
@@ -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)));
}
@@ -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 {
@@ -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};
}
@@ -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;
}
}
@@ -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$)";
}
}
@@ -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
@@ -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;
}
}
@@ -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");
@@ -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;
@@ -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;
@@ -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 + "]";
}
}
}
@@ -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
@@ -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();
@@ -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);
@@ -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();
}
@@ -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