Merge branch 'amakeev/gradle'
# Conflicts: # community/plugins/gradle/java/src/service/project/wizard/GradleModuleBuilder.java GitOrigin-RevId: 7677c496440e29d49839174420972762c8ecc089
1
.idea/modules.xml
generated
@@ -626,6 +626,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/usageView/intellij.platform.usageView.iml" filepath="$PROJECT_DIR$/platform/usageView/intellij.platform.usageView.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/util/intellij.platform.util.iml" filepath="$PROJECT_DIR$/platform/util/intellij.platform.util.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/util-class-loader/intellij.platform.util.classLoader.iml" filepath="$PROJECT_DIR$/platform/util-class-loader/intellij.platform.util.classLoader.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/util/intellij.platform.util.concurrency.iml" filepath="$PROJECT_DIR$/platform/util/intellij.platform.util.concurrency.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/util-ex/intellij.platform.util.ex.iml" filepath="$PROJECT_DIR$/platform/util-ex/intellij.platform.util.ex.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/util-rt/intellij.platform.util.rt.iml" filepath="$PROJECT_DIR$/platform/util-rt/intellij.platform.util.rt.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/util/testSrc/intellij.platform.util.tests.iml" filepath="$PROJECT_DIR$/platform/util/testSrc/intellij.platform.util.tests.iml" />
|
||||
|
||||
@@ -41,11 +41,19 @@ public class RegExpCompletionTest extends CodeInsightFixtureTestCase {
|
||||
myFixture.configureByText(RegExpFileType.INSTANCE, "\\N{SMILE<caret>}");
|
||||
final LookupElement[] elements = myFixture.completeBasic();
|
||||
final List<String> strings = ContainerUtil.map(elements, LookupElement::getLookupString);
|
||||
assertEquals(Arrays.asList("SMILE", "SMILING FACE WITH SMILING EYES", "SMILING FACE WITH HEART-SHAPED EYES",
|
||||
"SMILING CAT FACE WITH HEART-SHAPED EYES", "SMILING FACE WITH OPEN MOUTH AND SMILING EYES",
|
||||
"SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES", "CAT FACE WITH WRY SMILE",
|
||||
"GRINNING CAT FACE WITH SMILING EYES", "GRINNING FACE WITH SMILING EYES",
|
||||
"KISSING FACE WITH SMILING EYES"), strings);
|
||||
List<String> alwaysPresent = Arrays.asList("SMILE", "SMILING FACE WITH SMILING EYES", "SMILING FACE WITH HEART-SHAPED EYES",
|
||||
"SMILING CAT FACE WITH HEART-SHAPED EYES", "SMILING FACE WITH OPEN MOUTH AND SMILING EYES",
|
||||
"SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES", "CAT FACE WITH WRY SMILE",
|
||||
"GRINNING CAT FACE WITH SMILING EYES", "GRINNING FACE WITH SMILING EYES",
|
||||
"KISSING FACE WITH SMILING EYES");
|
||||
String message = strings.toString();
|
||||
assertTrue(message, strings.containsAll(alwaysPresent));
|
||||
List<String> other = new ArrayList<>(strings);
|
||||
other.removeAll(alwaysPresent);
|
||||
// Unicode 10.0
|
||||
List<String> maybePresent = Arrays.asList("SMILING FACE WITH SMILING EYES AND HAND COVERING MOUTH", "SIGNWRITING MOUTH SMILE",
|
||||
"SIGNWRITING MOUTH SMILE OPEN", "SIGNWRITING MOUTH SMILE WRINKLED");
|
||||
assertTrue(message, maybePresent.containsAll(other));
|
||||
}
|
||||
|
||||
public void testBackSlashVariants() {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
kotlinPluginBuild=1.3.31-release-IJ2019.1-1
|
||||
jetSignBuild=42.30
|
||||
secondJreVersion=11
|
||||
secondJreBuild=11_0_3b248.2
|
||||
secondJreBuild=11_0_3b248.9
|
||||
bundledMavenVersion=3.6.0
|
||||
jdkBuild=u202b1566.2
|
||||
jdkBuild=u212b1566.4
|
||||
gradleApiVersion=5.2.1
|
||||
|
||||
@@ -52,24 +52,12 @@ class CreateGradleKotlinDslProjectWithKotlinGuiTest(private val testParameters:
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
fun data(): Collection<TestParameters> {
|
||||
return listOf(
|
||||
TestParameters(
|
||||
projectName = "gradle_k_with_jvm_explicit",
|
||||
project = kotlinProjects.getValue(Projects.GradleKProjectJvm),
|
||||
expectedFacet = defaultFacetSettings.getValue(TargetPlatform.JVM18),
|
||||
gradleModuleGroup = NewProjectDialogModel.GradleGroupModules.ExplicitModuleGroups
|
||||
),
|
||||
TestParameters(
|
||||
projectName = "gradle_k_with_jvm_qualified",
|
||||
project = kotlinProjects.getValue(Projects.GradleKProjectJvm),
|
||||
expectedFacet = defaultFacetSettings.getValue(TargetPlatform.JVM18),
|
||||
gradleModuleGroup = NewProjectDialogModel.GradleGroupModules.QualifiedNames
|
||||
),
|
||||
TestParameters(
|
||||
projectName = "gradle_k_with_js_explicit",
|
||||
project = kotlinProjects.getValue(Projects.GradleKProjectJs),
|
||||
expectedFacet = defaultFacetSettings.getValue(TargetPlatform.JavaScript),
|
||||
gradleModuleGroup = NewProjectDialogModel.GradleGroupModules.ExplicitModuleGroups
|
||||
),
|
||||
TestParameters(
|
||||
projectName = "gradle_k_with_js_qualified",
|
||||
project = kotlinProjects.getValue(Projects.GradleKProjectJs),
|
||||
|
||||
@@ -52,24 +52,12 @@ class CreateGradleProjectWithKotlinGuiTest(private val testParameters: TestParam
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
fun data(): Collection<TestParameters> {
|
||||
return listOf(
|
||||
TestParameters(
|
||||
projectName = "gradle_with_jvm_explicit",
|
||||
project = kotlinProjects.getValue(Projects.GradleGProjectJvm),
|
||||
expectedFacet = defaultFacetSettings.getValue(TargetPlatform.JVM18),
|
||||
gradleModuleGroup = NewProjectDialogModel.GradleGroupModules.ExplicitModuleGroups
|
||||
),
|
||||
TestParameters(
|
||||
projectName = "gradle_with_jvm_qualified",
|
||||
project = kotlinProjects.getValue(Projects.GradleGProjectJvm),
|
||||
expectedFacet = defaultFacetSettings.getValue(TargetPlatform.JVM18),
|
||||
gradleModuleGroup = NewProjectDialogModel.GradleGroupModules.QualifiedNames
|
||||
),
|
||||
TestParameters(
|
||||
projectName = "gradle_with_js_explicit",
|
||||
project = kotlinProjects.getValue(Projects.GradleGProjectJs),
|
||||
expectedFacet = defaultFacetSettings.getValue(TargetPlatform.JavaScript),
|
||||
gradleModuleGroup = NewProjectDialogModel.GradleGroupModules.ExplicitModuleGroups
|
||||
),
|
||||
TestParameters(
|
||||
projectName = "gradle_with_js_qualified",
|
||||
project = kotlinProjects.getValue(Projects.GradleGProjectJs),
|
||||
|
||||
@@ -95,7 +95,6 @@ final class ImageEditorUI extends JPanel implements DataProvider, CopyProvider,
|
||||
private final JPanel contentPanel;
|
||||
private final JLabel infoLabel;
|
||||
|
||||
private final PropertyChangeListener optionsChangeListener = new OptionsChangeListener();
|
||||
private final JScrollPane myScrollPane;
|
||||
|
||||
ImageEditorUI(@Nullable ImageEditor editor) {
|
||||
@@ -104,7 +103,7 @@ final class ImageEditorUI extends JPanel implements DataProvider, CopyProvider,
|
||||
imageComponent.addPropertyChangeListener(ZOOM_FACTOR_PROP, e -> imageComponent.setZoomFactor(getZoomModel().getZoomFactor()));
|
||||
Options options = OptionsManager.getInstance().getOptions();
|
||||
EditorOptions editorOptions = options.getEditorOptions();
|
||||
options.addPropertyChangeListener(optionsChangeListener);
|
||||
options.addPropertyChangeListener(new OptionsChangeListener(), this);
|
||||
|
||||
copyPasteSupport = editor != null ? new CopyPasteDelegator(editor.getProject(), this) : null;
|
||||
deleteProvider = new DeleteHandler.DefaultDeleteProvider();
|
||||
@@ -215,9 +214,6 @@ final class ImageEditorUI extends JPanel implements DataProvider, CopyProvider,
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
Options options = OptionsManager.getInstance().getOptions();
|
||||
options.removePropertyChangeListener(optionsChangeListener);
|
||||
|
||||
imageComponent.removeMouseWheelListener(wheelAdapter);
|
||||
imageComponent.getDocument().removeChangeListener(changeListener);
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package org.intellij.images.options;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
/**
|
||||
@@ -23,8 +26,10 @@ import java.beans.PropertyChangeListener;
|
||||
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
|
||||
*/
|
||||
public interface Options extends Cloneable {
|
||||
@NotNull
|
||||
EditorOptions getEditorOptions();
|
||||
|
||||
@NotNull
|
||||
ExternalEditorOptions getExternalEditorOptions();
|
||||
|
||||
/**
|
||||
@@ -32,15 +37,9 @@ public interface Options extends Cloneable {
|
||||
*
|
||||
* @param options Other options
|
||||
*/
|
||||
void inject(Options options);
|
||||
void inject(@NotNull Options options);
|
||||
|
||||
void addPropertyChangeListener(PropertyChangeListener listener);
|
||||
|
||||
void addPropertyChangeListener(String propertyName, PropertyChangeListener listener);
|
||||
|
||||
void removePropertyChangeListener(PropertyChangeListener listener);
|
||||
|
||||
void removePropertyChangeListener(String propertyName, PropertyChangeListener listener);
|
||||
void addPropertyChangeListener(@NotNull PropertyChangeListener listener, @NotNull Disposable parent);
|
||||
|
||||
/**
|
||||
* Set option by string representation.
|
||||
@@ -49,5 +48,5 @@ public interface Options extends Cloneable {
|
||||
* @param value Value
|
||||
* @return {@code true} if option is matched and setted.
|
||||
*/
|
||||
boolean setOption(String name, Object value);
|
||||
boolean setOption(@NotNull String name, Object value);
|
||||
}
|
||||
|
||||
@@ -15,10 +15,12 @@
|
||||
*/
|
||||
package org.intellij.images.options.impl;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.options.BaseConfigurableWithChangeSupport;
|
||||
import com.intellij.openapi.options.SearchableConfigurable;
|
||||
import com.intellij.openapi.options.ShowSettingsUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import org.intellij.images.ImagesBundle;
|
||||
import org.intellij.images.options.Options;
|
||||
import org.intellij.images.options.OptionsManager;
|
||||
@@ -37,6 +39,7 @@ import java.beans.PropertyChangeListener;
|
||||
public final class ImagesConfigurable extends BaseConfigurableWithChangeSupport implements SearchableConfigurable, PropertyChangeListener {
|
||||
private static final String DISPLAY_NAME = ImagesBundle.message("settings.page.name");
|
||||
private ImagesOptionsComponent myComponent;
|
||||
private final Disposable myUIResourcesDisposable = Disposer.newDisposable();
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
@@ -53,10 +56,10 @@ public final class ImagesConfigurable extends BaseConfigurableWithChangeSupport
|
||||
if (myComponent == null) {
|
||||
myComponent = new ImagesOptionsComponent();
|
||||
Options options = OptionsManager.getInstance().getOptions();
|
||||
options.addPropertyChangeListener(this);
|
||||
options.addPropertyChangeListener(this, myUIResourcesDisposable);
|
||||
myComponent.getOptions().inject(options);
|
||||
myComponent.updateUI();
|
||||
myComponent.getOptions().addPropertyChangeListener(this);
|
||||
myComponent.getOptions().addPropertyChangeListener(this, myUIResourcesDisposable);
|
||||
setModified(false);
|
||||
}
|
||||
return myComponent.getContentPane();
|
||||
@@ -81,12 +84,8 @@ public final class ImagesConfigurable extends BaseConfigurableWithChangeSupport
|
||||
|
||||
@Override
|
||||
public void disposeUIResources() {
|
||||
if (myComponent != null) {
|
||||
Options options = OptionsManager.getInstance().getOptions();
|
||||
options.removePropertyChangeListener(this);
|
||||
myComponent.getOptions().removePropertyChangeListener(this);
|
||||
myComponent = null;
|
||||
}
|
||||
Disposer.dispose(myUIResourcesDisposable);
|
||||
myComponent = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -150,6 +150,7 @@ final class ImagesOptionsComponent {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Options getOptions() {
|
||||
return options;
|
||||
}
|
||||
@@ -179,9 +180,10 @@ final class ImagesOptionsComponent {
|
||||
}
|
||||
|
||||
private final class CheckboxOptionsListener implements ItemListener {
|
||||
@NotNull
|
||||
private final String name;
|
||||
|
||||
private CheckboxOptionsListener(String name) {
|
||||
private CheckboxOptionsListener(@NotNull String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.intellij.images.options.impl;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.JDOMExternalizable;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
@@ -22,6 +24,7 @@ import org.intellij.images.options.EditorOptions;
|
||||
import org.intellij.images.options.ExternalEditorOptions;
|
||||
import org.intellij.images.options.Options;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
@@ -32,91 +35,73 @@ import java.beans.PropertyChangeSupport;
|
||||
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
|
||||
*/
|
||||
final class OptionsImpl implements Options, JDOMExternalizable {
|
||||
/**
|
||||
* Property change support (from injection)
|
||||
*/
|
||||
private final PropertyChangeSupport propertyChangeSupport;
|
||||
/**
|
||||
* Property change support (from injection)
|
||||
*/
|
||||
private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
|
||||
private final EditorOptions editorOptions;
|
||||
private final ExternalEditorOptions externalEditorOptions;
|
||||
private final EditorOptions editorOptions = new EditorOptionsImpl(propertyChangeSupport);
|
||||
private final ExternalEditorOptions externalEditorOptions = new ExternalEditorOptionsImpl(propertyChangeSupport);
|
||||
|
||||
OptionsImpl() {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
editorOptions = new EditorOptionsImpl(propertyChangeSupport);
|
||||
externalEditorOptions = new ExternalEditorOptionsImpl(propertyChangeSupport);
|
||||
@NotNull
|
||||
@Override
|
||||
public EditorOptions getEditorOptions() {
|
||||
return editorOptions;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ExternalEditorOptions getExternalEditorOptions() {
|
||||
return externalEditorOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject(@NotNull Options options) {
|
||||
editorOptions.inject(options.getEditorOptions());
|
||||
externalEditorOptions.inject(options.getExternalEditorOptions());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(@NotNull PropertyChangeListener listener, @NotNull Disposable parent) {
|
||||
propertyChangeSupport.addPropertyChangeListener(listener);
|
||||
Disposer.register(parent, () -> propertyChangeSupport.removePropertyChangeListener(listener));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setOption(@NotNull String name, Object value) {
|
||||
return editorOptions.setOption(name, value) || externalEditorOptions.setOption(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readExternal(Element element) throws InvalidDataException {
|
||||
((JDOMExternalizable)editorOptions).readExternal(element);
|
||||
((JDOMExternalizable)externalEditorOptions).readExternal(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeExternal(Element element) throws WriteExternalException {
|
||||
((JDOMExternalizable)editorOptions).writeExternal(element);
|
||||
((JDOMExternalizable)externalEditorOptions).writeExternal(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EditorOptions getEditorOptions() {
|
||||
return editorOptions;
|
||||
if (!(obj instanceof Options)) {
|
||||
return false;
|
||||
}
|
||||
Options otherOptions = (Options)obj;
|
||||
EditorOptions editorOptions = otherOptions.getEditorOptions();
|
||||
ExternalEditorOptions externalEditorOptions = otherOptions.getExternalEditorOptions();
|
||||
return editorOptions.equals(getEditorOptions()) && externalEditorOptions.equals(getExternalEditorOptions());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExternalEditorOptions getExternalEditorOptions() {
|
||||
return externalEditorOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject(Options options) {
|
||||
editorOptions.inject(options.getEditorOptions());
|
||||
externalEditorOptions.inject(options.getExternalEditorOptions());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(PropertyChangeListener listener) {
|
||||
propertyChangeSupport.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
|
||||
propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(PropertyChangeListener listener) {
|
||||
propertyChangeSupport.removePropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
|
||||
propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setOption(String name, Object value) {
|
||||
return editorOptions.setOption(name, value) || externalEditorOptions.setOption(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readExternal(Element element) throws InvalidDataException {
|
||||
((JDOMExternalizable)editorOptions).readExternal(element);
|
||||
((JDOMExternalizable)externalEditorOptions).readExternal(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeExternal(Element element) throws WriteExternalException {
|
||||
((JDOMExternalizable)editorOptions).writeExternal(element);
|
||||
((JDOMExternalizable)externalEditorOptions).writeExternal(element);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof Options)) {
|
||||
return false;
|
||||
}
|
||||
Options otherOptions = (Options)obj;
|
||||
EditorOptions editorOptions = otherOptions.getEditorOptions();
|
||||
ExternalEditorOptions externalEditorOptions = otherOptions.getExternalEditorOptions();
|
||||
return editorOptions != null && editorOptions.equals(getEditorOptions()) &&
|
||||
externalEditorOptions != null && externalEditorOptions.equals(getExternalEditorOptions());
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result;
|
||||
result = (editorOptions != null ? editorOptions.hashCode() : 0);
|
||||
result = 29 * result + (externalEditorOptions != null ? externalEditorOptions.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = editorOptions.hashCode();
|
||||
result = 29 * result + externalEditorOptions.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,6 @@ import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
final class ThumbnailViewUI extends JPanel implements DataProvider, Disposable {
|
||||
private final OptionsChangeListener optionsListener = new OptionsChangeListener();
|
||||
|
||||
private static final Navigatable[] EMPTY_NAVIGATABLE_ARRAY = new Navigatable[]{};
|
||||
|
||||
@@ -119,7 +118,7 @@ final class ThumbnailViewUI extends JPanel implements DataProvider, Disposable {
|
||||
imageComponent.setFileNameVisible(editorOptions.isFileNameVisible());
|
||||
imageComponent.setFileSizeVisible(editorOptions.isFileSizeVisible());
|
||||
|
||||
options.addPropertyChangeListener(optionsListener);
|
||||
options.addPropertyChangeListener(new OptionsChangeListener(), this);
|
||||
|
||||
list = new JBList();
|
||||
list.setModel(new DefaultListModel());
|
||||
@@ -620,9 +619,6 @@ final class ThumbnailViewUI extends JPanel implements DataProvider, Disposable {
|
||||
public void dispose() {
|
||||
removeAll();
|
||||
|
||||
Options options = OptionsManager.getInstance().getOptions();
|
||||
options.removePropertyChangeListener(optionsListener);
|
||||
|
||||
list = null;
|
||||
cellRenderer = null;
|
||||
tagsPanel = null;
|
||||
|
||||
@@ -38,7 +38,7 @@ public class TestFilesIndex extends MapReduceIndex<Integer, Void, UsedSources> {
|
||||
@Nullable
|
||||
Collection<Integer> getTestDataFor(int testId) throws IOException {
|
||||
ForwardIndex forwardIndex = getForwardIndexMap();
|
||||
KeyCollectionForwardIndexAccessor<Integer, Void, UsedSources> forwardIndexAccessor = (KeyCollectionForwardIndexAccessor<Integer, Void, UsedSources>)getForwardIndexAccessor();
|
||||
KeyCollectionForwardIndexAccessor<Integer, Void> forwardIndexAccessor = (KeyCollectionForwardIndexAccessor<Integer, Void>)getForwardIndexAccessor();
|
||||
return forwardIndexAccessor.deserializeData(forwardIndex.get(testId));
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.projectImport.DeprecatedProjectBuilderForImport;
|
||||
import com.intellij.projectImport.ProjectImportProvider;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -85,8 +86,12 @@ public class ImportModuleAction extends AnAction implements NewProjectOrModuleAc
|
||||
if (wizard == null || wizard.getStepCount() > 0 && !wizard.showAndGet()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return createFromWizard(project, wizard);
|
||||
try {
|
||||
return createFromWizard(project, wizard);
|
||||
}
|
||||
finally {
|
||||
wizard.disposeIfNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Module> createFromWizard(@Nullable Project project, AbstractProjectWizard wizard) {
|
||||
@@ -96,12 +101,19 @@ public class ImportModuleAction extends AnAction implements NewProjectOrModuleAc
|
||||
}
|
||||
|
||||
private static List<Module> doCreateFromWizard(@Nullable Project project, AbstractProjectWizard wizard) {
|
||||
final ProjectBuilder projectBuilder = wizard.getProjectBuilder();
|
||||
if (project == null) {
|
||||
Project newProject = NewProjectUtil.createFromWizard(wizard, null);
|
||||
Project newProject;
|
||||
if (projectBuilder instanceof DeprecatedProjectBuilderForImport) {
|
||||
// The path to remove import action
|
||||
newProject = ProjectUtil.openOrImport(wizard.getNewProjectFilePath(), null, false);
|
||||
}
|
||||
else {
|
||||
newProject = NewProjectUtil.createFromWizard(wizard, null);
|
||||
}
|
||||
return newProject == null ? Collections.emptyList() : Arrays.asList(ModuleManager.getInstance(newProject).getModules());
|
||||
}
|
||||
|
||||
final ProjectBuilder projectBuilder = wizard.getProjectBuilder();
|
||||
try {
|
||||
if (wizard.getStepCount() > 0) {
|
||||
Module module = new NewModuleAction().createModuleFromWizard(project, null, wizard);
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.projectImport
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
/**
|
||||
* Marker interface of deprecated project builder.
|
||||
* Import action with {@link ProjectBuilder} marked by this
|
||||
* interface will be replaced on open action if possible.
|
||||
*
|
||||
* Needed to remove the redundant import action.
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
interface DeprecatedProjectBuilderForImport
|
||||
@@ -1346,6 +1346,11 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
myRefCountHolder.registerReference(expression, result);
|
||||
}
|
||||
final PsiElement method = result.getElement();
|
||||
if (method instanceof PsiMethod && myRefCountHolder != null) {
|
||||
for (PsiParameter parameter : ((PsiMethod)method).getParameterList().getParameters()) {
|
||||
myRefCountHolder.registerLocallyReferenced(parameter);
|
||||
}
|
||||
}
|
||||
if (method != null && !result.isAccessible()) {
|
||||
String accessProblem = HighlightUtil.accessProblemDescription(expression, method, result);
|
||||
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(accessProblem).create();
|
||||
|
||||
@@ -23,17 +23,16 @@ import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
|
||||
private final List<MemoryStateChange> myHistory;
|
||||
private MemoryStateChange myHistory;
|
||||
|
||||
protected TrackingDfaMemoryState(DfaValueFactory factory) {
|
||||
super(factory);
|
||||
myHistory = new ArrayList<>(1);
|
||||
myHistory.add(null);
|
||||
myHistory = null;
|
||||
}
|
||||
|
||||
protected TrackingDfaMemoryState(TrackingDfaMemoryState toCopy) {
|
||||
super(toCopy);
|
||||
myHistory = new ArrayList<>(toCopy.myHistory);
|
||||
myHistory = toCopy.myHistory;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -46,23 +45,7 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
|
||||
protected void afterMerge(DfaMemoryStateImpl other) {
|
||||
super.afterMerge(other);
|
||||
assert other instanceof TrackingDfaMemoryState;
|
||||
for (MemoryStateChange change : ((TrackingDfaMemoryState)other).myHistory) {
|
||||
if (!tryMerge(change)) {
|
||||
myHistory.add(change);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean tryMerge(MemoryStateChange change) {
|
||||
for (ListIterator<MemoryStateChange> iterator = myHistory.listIterator(); iterator.hasNext(); ) {
|
||||
MemoryStateChange myChange = iterator.next();
|
||||
MemoryStateChange merge = myChange.tryMerge(change);
|
||||
if (merge != null) {
|
||||
iterator.set(merge);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
myHistory = myHistory.merge(((TrackingDfaMemoryState)other).myHistory);
|
||||
}
|
||||
|
||||
private Map<DfaVariableValue, Set<Relation>> getRelations() {
|
||||
@@ -118,7 +101,7 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
|
||||
void recordChange(Instruction instruction, TrackingDfaMemoryState previous) {
|
||||
Map<DfaVariableValue, Change> result = getChangeMap(previous);
|
||||
DfaValue value = isEmptyStack() ? DfaUnknownValue.getInstance() : peek();
|
||||
myHistory.replaceAll(prev -> MemoryStateChange.create(prev, instruction, result, value));
|
||||
myHistory = MemoryStateChange.create(myHistory, instruction, result, value);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -168,7 +151,7 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
|
||||
return changeMap;
|
||||
}
|
||||
|
||||
List<MemoryStateChange> getHistory() {
|
||||
MemoryStateChange getHistory() {
|
||||
return myHistory;
|
||||
}
|
||||
|
||||
@@ -211,8 +194,7 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
|
||||
}
|
||||
}
|
||||
if (changeMap != null && !changeMap.isEmpty()) {
|
||||
Map<DfaVariableValue, Change> finalChangeMap = changeMap;
|
||||
myHistory.replaceAll(s -> s.withBridge(instruction, finalChangeMap));
|
||||
myHistory = myHistory.withBridge(instruction, changeMap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,13 +273,14 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
|
||||
}
|
||||
|
||||
static final class MemoryStateChange {
|
||||
final @Nullable MemoryStateChange myPrevious;
|
||||
private final @NotNull List<MemoryStateChange> myPrevious;
|
||||
final @NotNull Instruction myInstruction;
|
||||
final @NotNull Map<DfaVariableValue, Change> myChanges;
|
||||
final @NotNull DfaValue myTopOfStack;
|
||||
final @NotNull Map<DfaVariableValue, Change> myBridgeChanges;
|
||||
int myCursor = 0;
|
||||
|
||||
private MemoryStateChange(@Nullable MemoryStateChange previous,
|
||||
private MemoryStateChange(@NotNull List<MemoryStateChange> previous,
|
||||
@NotNull Instruction instruction,
|
||||
@NotNull Map<DfaVariableValue, Change> changes,
|
||||
@NotNull DfaValue topOfStack,
|
||||
@@ -308,6 +291,23 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
|
||||
myTopOfStack = topOfStack;
|
||||
myBridgeChanges = bridgeChanges;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
for (MemoryStateChange change = this; change != null; change = change.getPrevious()) {
|
||||
change.myCursor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
boolean advance() {
|
||||
if (myCursor < myPrevious.size() && !myPrevious.get(myCursor).advance()) {
|
||||
myCursor++;
|
||||
MemoryStateChange previous = getPrevious();
|
||||
if (previous != null) {
|
||||
previous.reset();
|
||||
}
|
||||
}
|
||||
return myCursor < myPrevious.size();
|
||||
}
|
||||
|
||||
@Contract("null -> null")
|
||||
@Nullable
|
||||
@@ -343,13 +343,13 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
|
||||
@NotNull
|
||||
<T> FactDefinition<T> findFact(DfaValue value, DfaFactType<T> type) {
|
||||
if (value instanceof DfaVariableValue) {
|
||||
for (MemoryStateChange change = this; change != null; change = change.myPrevious) {
|
||||
for (MemoryStateChange change = this; change != null; change = change.getPrevious()) {
|
||||
FactDefinition<T> factPair = factFromChange(type, change, change.myChanges.get(value));
|
||||
if (factPair != null) return factPair;
|
||||
factPair = factFromChange(type, change, change.myBridgeChanges.get(value));
|
||||
if (factPair != null) return factPair;
|
||||
if (change.myInstruction instanceof AssignInstruction && change.myTopOfStack == value && change.myPrevious != null) {
|
||||
FactDefinition<T> fact = change.myPrevious.findFact(value, type);
|
||||
if (change.myInstruction instanceof AssignInstruction && change.myTopOfStack == value && change.getPrevious() != null) {
|
||||
FactDefinition<T> fact = change.getPrevious().findFact(value, type);
|
||||
return new FactDefinition<>(change, fact.myFact);
|
||||
}
|
||||
}
|
||||
@@ -358,6 +358,17 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
|
||||
return new FactDefinition<>(null, type.fromDfaValue(value));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
MemoryStateChange getPrevious() {
|
||||
return myCursor == myPrevious.size() ? null : myPrevious.get(myCursor);
|
||||
}
|
||||
|
||||
public MemoryStateChange getNonMerge() {
|
||||
MemoryStateChange change = myInstruction instanceof MergeInstruction ? getPrevious() : this;
|
||||
assert change == null || !(change.myInstruction instanceof MergeInstruction);
|
||||
return change;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static <T> FactDefinition<T> factFromChange(DfaFactType<T> type, MemoryStateChange change, Change varChange) {
|
||||
if (varChange != null) {
|
||||
@@ -374,7 +385,7 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
|
||||
|
||||
@Nullable
|
||||
private MemoryStateChange findChange(@NotNull Predicate<MemoryStateChange> predicate, boolean startFromSelf) {
|
||||
for (MemoryStateChange change = startFromSelf ? this : myPrevious; change != null; change = change.myPrevious) {
|
||||
for (MemoryStateChange change = startFromSelf ? this : getPrevious(); change != null; change = change.getPrevious()) {
|
||||
if (predicate.test(change)) {
|
||||
return change;
|
||||
}
|
||||
@@ -394,66 +405,25 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
MemoryStateChange change = (MemoryStateChange)o;
|
||||
return myInstruction.equals(change.myInstruction) &&
|
||||
myTopOfStack.equals(change.myTopOfStack) &&
|
||||
myChanges.equals(change.myChanges) &&
|
||||
myBridgeChanges.equals(change.myBridgeChanges) &&
|
||||
Objects.equals(myPrevious, change.myPrevious);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(myPrevious, myInstruction, myChanges, myBridgeChanges, myTopOfStack);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MemoryStateChange tryMerge(MemoryStateChange change) {
|
||||
MemoryStateChange[] thisFlat = flatten();
|
||||
MemoryStateChange[] thatFlat = change.flatten();
|
||||
MemoryStateChange result = null;
|
||||
int thisIndex = 0, thatIndex = 0;
|
||||
while (true) {
|
||||
int curThis = thisIndex;
|
||||
if (thisIndex == thisFlat.length && thatIndex == thatFlat.length) {
|
||||
return result;
|
||||
}
|
||||
if (thisIndex == thisFlat.length || thatIndex == thatFlat.length) return null;
|
||||
while (thisIndex < thisFlat.length) {
|
||||
MemoryStateChange thisChange = thisFlat[thisIndex];
|
||||
if (thisChange.myInstruction == thatFlat[thatIndex].myInstruction) break;
|
||||
if (!thisChange.myChanges.isEmpty()) {
|
||||
thisIndex = thisFlat.length;
|
||||
break;
|
||||
}
|
||||
thisIndex++;
|
||||
}
|
||||
if (thisIndex == thisFlat.length) {
|
||||
thisIndex = curThis;
|
||||
while (thatIndex < thatFlat.length) {
|
||||
MemoryStateChange thatChange = thatFlat[thatIndex];
|
||||
if (thatChange.myInstruction == thisFlat[thisIndex].myInstruction) break;
|
||||
if (!thatChange.myChanges.isEmpty()) return null;
|
||||
thatIndex++;
|
||||
}
|
||||
if (thatIndex == thatFlat.length) return null;
|
||||
}
|
||||
MemoryStateChange thisChange = thisFlat[thisIndex];
|
||||
MemoryStateChange thatChange = thatFlat[thatIndex];
|
||||
if (thisChange == thatChange) {
|
||||
result = thisChange;
|
||||
} else {
|
||||
assert thisChange.myInstruction == thatChange.myInstruction;
|
||||
if (!thisChange.myChanges.equals(thatChange.myChanges)) return null;
|
||||
result = create(result, thisChange.myInstruction, thisChange.myChanges, thisChange.myTopOfStack.unite(thatChange.myTopOfStack));
|
||||
}
|
||||
thisIndex++;
|
||||
thatIndex++;
|
||||
@NotNull
|
||||
public MemoryStateChange merge(MemoryStateChange change) {
|
||||
if (change == this) return this;
|
||||
Set<MemoryStateChange> previous = new LinkedHashSet<>();
|
||||
if (myInstruction instanceof MergeInstruction) {
|
||||
previous.addAll(myPrevious);
|
||||
} else {
|
||||
previous.add(this);
|
||||
}
|
||||
if (change.myInstruction instanceof MergeInstruction) {
|
||||
previous.addAll(change.myPrevious);
|
||||
} else {
|
||||
previous.add(change);
|
||||
}
|
||||
if (previous.size() == 1) {
|
||||
return previous.iterator().next();
|
||||
}
|
||||
return new MemoryStateChange(new ArrayList<>(previous), new MergeInstruction(), Collections.emptyMap(), DfaUnknownValue.getInstance(),
|
||||
Collections.emptyMap());
|
||||
}
|
||||
|
||||
MemoryStateChange withBridge(@NotNull Instruction instruction, @NotNull Map<DfaVariableValue, Change> bridge) {
|
||||
@@ -462,7 +432,8 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
|
||||
getExpression() == ((ConditionalGotoInstruction)instruction).getPsiAnchor()) {
|
||||
instruction = myInstruction;
|
||||
} else {
|
||||
return new MemoryStateChange(this, instruction, Collections.emptyMap(), DfaUnknownValue.getInstance(), bridge);
|
||||
return new MemoryStateChange(
|
||||
Collections.singletonList(this), instruction, Collections.emptyMap(), DfaUnknownValue.getInstance(), bridge);
|
||||
}
|
||||
}
|
||||
assert myBridgeChanges.isEmpty();
|
||||
@@ -477,11 +448,11 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
|
||||
if (result.isEmpty() && value == DfaUnknownValue.getInstance()) {
|
||||
return previous;
|
||||
}
|
||||
return new MemoryStateChange(previous, instruction, result, value, Collections.emptyMap());
|
||||
return new MemoryStateChange(ContainerUtil.createMaybeSingletonList(previous), instruction, result, value, Collections.emptyMap());
|
||||
}
|
||||
|
||||
MemoryStateChange[] flatten() {
|
||||
List<MemoryStateChange> changes = StreamEx.iterate(this, Objects::nonNull, change -> change.myPrevious).toList();
|
||||
List<MemoryStateChange> changes = StreamEx.iterate(this, Objects::nonNull, change -> change.getPrevious()).toList();
|
||||
Collections.reverse(changes);
|
||||
return changes.toArray(new MemoryStateChange[0]);
|
||||
}
|
||||
@@ -500,6 +471,18 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
|
||||
}
|
||||
}
|
||||
|
||||
private static class MergeInstruction extends Instruction {
|
||||
@Override
|
||||
public DfaInstructionState[] accept(DataFlowRunner runner, DfaMemoryState stateBefore, InstructionVisitor visitor) {
|
||||
return DfaInstructionState.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "STATE_MERGE";
|
||||
}
|
||||
}
|
||||
|
||||
static class FactDefinition<T> {
|
||||
final @Nullable MemoryStateChange myChange;
|
||||
final @Nullable T myFact;
|
||||
|
||||
@@ -41,7 +41,7 @@ import static com.intellij.codeInspection.dataFlow.DfaUtil.hasImplicitImpureSupe
|
||||
|
||||
@SuppressWarnings("SuspiciousNameCombination")
|
||||
public class TrackingRunner extends StandardDataFlowRunner {
|
||||
private final List<MemoryStateChange> myHistoryForContext = new ArrayList<>();
|
||||
private MemoryStateChange myHistoryForContext = null;
|
||||
private final PsiExpression myExpression;
|
||||
private final List<DfaInstructionState> afterStates = new ArrayList<>();
|
||||
private final List<TrackingDfaMemoryState> killedStates = new ArrayList<>();
|
||||
@@ -98,7 +98,8 @@ public class TrackingRunner extends StandardDataFlowRunner {
|
||||
ExpressionPushingInstruction pushing = (ExpressionPushingInstruction)instruction;
|
||||
if (pushing.getExpression() == myExpression && pushing.getExpressionRange() == null) {
|
||||
for (DfaInstructionState state : states) {
|
||||
myHistoryForContext.addAll(((TrackingDfaMemoryState)state.getMemoryState()).getHistory());
|
||||
MemoryStateChange history = ((TrackingDfaMemoryState)state.getMemoryState()).getHistory();
|
||||
myHistoryForContext = myHistoryForContext == null ? history : myHistoryForContext.merge(history);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -171,19 +172,23 @@ public class TrackingRunner extends StandardDataFlowRunner {
|
||||
*/
|
||||
@Nullable
|
||||
private CauseItem findProblemCause(PsiExpression expression, DfaProblemType type) {
|
||||
if (myHistoryForContext == null) return null;
|
||||
CauseItem cause = null;
|
||||
for (MemoryStateChange history : myHistoryForContext) {
|
||||
do {
|
||||
CauseItem item = new CauseItem(type, expression);
|
||||
MemoryStateChange history = myHistoryForContext.getNonMerge();
|
||||
if (history.getExpression() == expression) {
|
||||
item.addChildren(type.findCauses(this, expression, history));
|
||||
}
|
||||
if (cause == null) {
|
||||
cause = item;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
cause = cause.merge(item);
|
||||
if (cause == null) return null;
|
||||
}
|
||||
}
|
||||
while (myHistoryForContext.advance());
|
||||
return cause;
|
||||
}
|
||||
|
||||
@@ -693,7 +698,7 @@ public class TrackingRunner extends StandardDataFlowRunner {
|
||||
while (explanation != null) {
|
||||
MemoryStateChange causeLocation = fact.myChange;
|
||||
if (causeLocation == null) break;
|
||||
MemoryStateChange prevHistory = causeLocation.myPrevious;
|
||||
MemoryStateChange prevHistory = causeLocation.getPrevious();
|
||||
if (prevHistory == null) break;
|
||||
fact = prevHistory.findFact(operandValue, DfaFactType.TYPE_CONSTRAINT);
|
||||
TypeConstraint prevConstraint = fact.getFact(TypeConstraint.empty());
|
||||
|
||||
@@ -156,9 +156,21 @@ public class RefJavaUtilImpl extends RefJavaUtil {
|
||||
public boolean visitCallableReferenceExpression(@NotNull UCallableReferenceExpression node) {
|
||||
visitReferenceExpression(node);
|
||||
processFunctionalExpression(node, getFunctionalInterfaceType(node));
|
||||
markParametersReferenced(node);
|
||||
return false;
|
||||
}
|
||||
|
||||
private void markParametersReferenced(@NotNull UCallableReferenceExpression node) {
|
||||
PsiElement resolved = node.resolve();
|
||||
if (resolved == null) return;
|
||||
RefElement refElement = refFrom.getRefManager().getReference(resolved);
|
||||
if (refElement instanceof RefMethod) {
|
||||
for (RefParameter parameter : ((RefMethod)refElement).getParameters()) {
|
||||
refFrom.addReference(parameter, parameter.getPsiElement(), decl, false, true, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visitObjectLiteralExpression(@NotNull UObjectLiteralExpression node) {
|
||||
visitReferenceExpression(node);
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TObjectIntHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -89,19 +90,26 @@ public class JavaCompletionSorting {
|
||||
|
||||
@Nullable
|
||||
private static LookupElementWeigher dispreferPreviousChainCalls(PsiElement position) {
|
||||
Set<PsiMethod> previousChainCalls = new HashSet<>();
|
||||
TObjectIntHashMap<PsiMethod> previousChainCalls = new TObjectIntHashMap<>();
|
||||
if (position.getParent() instanceof PsiReferenceExpression) {
|
||||
PsiMethodCallExpression qualifier = getCallQualifier((PsiReferenceExpression)position.getParent());
|
||||
while (qualifier != null) {
|
||||
ContainerUtil.addIfNotNull(previousChainCalls, qualifier.resolveMethod());
|
||||
PsiMethod method = qualifier.resolveMethod();
|
||||
if (method != null) {
|
||||
String name = method.getName();
|
||||
boolean seemsLikeExpectsMultipleCalls = name.startsWith("put") || name.startsWith("add");
|
||||
if (!seemsLikeExpectsMultipleCalls) {
|
||||
previousChainCalls.put(method, previousChainCalls.get(method) + 1);
|
||||
}
|
||||
}
|
||||
qualifier = getCallQualifier(qualifier.getMethodExpression());
|
||||
}
|
||||
}
|
||||
return previousChainCalls.isEmpty() ? null : new LookupElementWeigher("dispreferPreviousChainCalls") {
|
||||
@Override
|
||||
public Comparable weigh(@NotNull LookupElement element, @NotNull WeighingContext context) {
|
||||
//noinspection SuspiciousMethodCalls
|
||||
return previousChainCalls.contains(element.getPsiElement());
|
||||
PsiElement psi = element.getPsiElement();
|
||||
return psi instanceof PsiMethod && previousChainCalls.get((PsiMethod)psi) == 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@ import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class MethodReferenceCompletionProvider extends CompletionProvider<CompletionParameters> {
|
||||
private static final Logger LOG = Logger.getInstance(MethodReferenceCompletionProvider.class);
|
||||
|
||||
@@ -36,12 +34,11 @@ public class MethodReferenceCompletionProvider extends CompletionProvider<Comple
|
||||
if (LambdaUtil.isFunctionalType(defaultType)) {
|
||||
final PsiType functionalType = FunctionalInterfaceParameterizationUtil.getGroundTargetType(defaultType);
|
||||
final PsiType returnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalType);
|
||||
if (returnType != null) {
|
||||
if (returnType != null && functionalType != null) {
|
||||
final PsiElement position = parameters.getPosition();
|
||||
final PsiElement refPlace = position.getParent();
|
||||
final ExpectedTypeInfoImpl typeInfo =
|
||||
new ExpectedTypeInfoImpl(returnType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, returnType, TailType.UNKNOWN, null, ExpectedTypeInfoImpl.NULL);
|
||||
final Map<PsiElement, PsiType> map = LambdaUtil.getFunctionalTypeMap();
|
||||
Consumer<LookupElement> noTypeCheck = new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(final LookupElement lookupElement) {
|
||||
|
||||
@@ -68,7 +68,7 @@ class JavaSimplePropertyIndex : FileBasedIndexExtension<Int, PropertyIndexValue>
|
||||
|
||||
override fun getIndexer(): DataIndexer<Int, PropertyIndexValue, FileContent> = DataIndexer { inputData ->
|
||||
val result = HashMap<Int, PropertyIndexValue>()
|
||||
val tree = (inputData as FileContentImpl).lighterASTForPsiDependentIndex
|
||||
val tree = (inputData as PsiDependentFileContent).lighterAST
|
||||
|
||||
object : RecursiveLighterASTNodeWalkingVisitor(tree) {
|
||||
var methodIndex = 0
|
||||
|
||||
@@ -44,7 +44,7 @@ public class JavaBinaryPlusExpressionIndex extends FileBasedIndexExtension<Boole
|
||||
int[] offsets = new StringSearcher("+", true, true).findAllOccurrences(text);
|
||||
if (offsets.length == 0) return Collections.emptyMap();
|
||||
|
||||
LighterAST tree = ((FileContentImpl)inputData).getLighterASTForPsiDependentIndex();
|
||||
LighterAST tree = ((PsiDependentFileContent)inputData).getLighterAST();
|
||||
TIntArrayList result = new TIntArrayList(offsets.length);
|
||||
Map<LighterASTNode, Boolean> stringConcatenations = new HashMap<>();
|
||||
LightTreeUtil.processLeavesAtOffsets(offsets, tree, (leaf, offset) -> {
|
||||
|
||||
@@ -373,7 +373,7 @@ public class JavaFunctionalExpressionIndex extends FileBasedIndexExtension<Funct
|
||||
if (offsets.length == 0) return Collections.emptyMap();
|
||||
|
||||
Map<FunctionalExpressionKey, Map<Integer, FunExprOccurrence>> result = new HashMap<>();
|
||||
LighterAST tree = ((FileContentImpl)inputData).getLighterASTForPsiDependentIndex();
|
||||
LighterAST tree = ((PsiDependentFileContent)inputData).getLighterAST();
|
||||
FileLocalResolver resolver = new FileLocalResolver(tree);
|
||||
|
||||
LightTreeUtil.processLeavesAtOffsets(offsets, tree, (leaf, offset) -> {
|
||||
|
||||
@@ -57,7 +57,7 @@ public class JavaNullMethodArgumentIndex extends ScalarIndexExtension<JavaNullMe
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
LighterAST lighterAst = ((FileContentImpl)inputData).getLighterASTForPsiDependentIndex();
|
||||
LighterAST lighterAst = ((PsiDependentFileContent)inputData).getLighterAST();
|
||||
|
||||
CharSequence text = inputData.getContentAsText();
|
||||
Set<LighterASTNode> calls = findCallsWithNulls(lighterAst, text);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.psi;
|
||||
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface PsiFunctionalExpression extends PsiExpression, Iconable, NavigatablePsiElement {
|
||||
@@ -53,7 +54,8 @@ public interface PsiFunctionalExpression extends PsiExpression, Iconable, Naviga
|
||||
* with the type of the i'th parameter of the method.
|
||||
* If the member is a variable arity method with arity n, etc
|
||||
*/
|
||||
boolean isPotentiallyCompatible(PsiType left);
|
||||
@Contract("null -> false")
|
||||
boolean isPotentiallyCompatible(@Nullable PsiType left);
|
||||
|
||||
/**
|
||||
* JLS 9.9. Function Types:
|
||||
|
||||
@@ -52,9 +52,10 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
private PsiSubstitutor myCalcedSubstitutor;
|
||||
|
||||
private volatile String myInferenceError;
|
||||
private final ThreadLocal<String> myApplicabilityError = new ThreadLocal<>();
|
||||
private volatile boolean myApplicabilityError;
|
||||
|
||||
private final LanguageLevel myLanguageLevel;
|
||||
private volatile boolean myErased;
|
||||
|
||||
public MethodCandidateInfo(@NotNull PsiElement candidate,
|
||||
@NotNull PsiSubstitutor substitutor,
|
||||
@@ -140,13 +141,11 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
final PsiMethod method = getElement();
|
||||
|
||||
if (isToInferApplicability()) {
|
||||
if (!isOverloadCheck()) {
|
||||
//ensure applicability check is performed
|
||||
getSubstitutor(false);
|
||||
}
|
||||
//ensure applicability check is performed
|
||||
getSubstitutor(false);
|
||||
|
||||
//already performed checks, so if inference failed, error message should be saved
|
||||
if (myApplicabilityError.get() != null || isPotentiallyCompatible() != ThreeState.YES) {
|
||||
if (myApplicabilityError || isPotentiallyCompatible() != ThreeState.YES) {
|
||||
return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
}
|
||||
return isVarargs() ? ApplicabilityLevel.VARARGS : ApplicabilityLevel.FIXED_ARITY;
|
||||
@@ -210,6 +209,14 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
return myArgumentList == argumentList;
|
||||
}
|
||||
|
||||
public void setErased(boolean erased) {
|
||||
myErased = erased;
|
||||
}
|
||||
|
||||
public boolean isErased() {
|
||||
return myErased;
|
||||
}
|
||||
|
||||
private static boolean checkFunctionalInterfaceAcceptance(PsiMethod method, PsiType left, PsiType right, boolean allowUncheckedConversion) {
|
||||
PsiFunctionalExpression fun = null;
|
||||
if (right instanceof PsiLambdaExpressionType) {
|
||||
@@ -348,33 +355,16 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
if (myTypeArguments == null) {
|
||||
RecursionGuard.StackStamp stackStamp = RecursionManager.markStack();
|
||||
|
||||
myApplicabilityError.remove();
|
||||
try {
|
||||
|
||||
final PsiElement markerList = myArgumentList;
|
||||
final PsiSubstitutor inferredSubstitutor = inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE, includeReturnConstraint);
|
||||
if (!stackStamp.mayCacheNow() ||
|
||||
isOverloadCheck() ||
|
||||
!includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) ||
|
||||
markerList != null && PsiResolveHelper.ourGraphGuard.currentStack().contains(markerList.getParent())
|
||||
) {
|
||||
return inferredSubstitutor;
|
||||
}
|
||||
|
||||
myInferenceError = myApplicabilityError.get();
|
||||
myCalcedSubstitutor = substitutor = inferredSubstitutor;
|
||||
}
|
||||
finally {
|
||||
//includeReturnConstraint == true, means that it's not an applicability check and it won't be used
|
||||
//Case when clear of error is required:
|
||||
//for foo(bar()) where foo is overloaded but doesn't have type parameters, start from {bar()}.getSubstitutor()
|
||||
//1. perform overload resolution for foo : evaluate {bar()}.getType() under overload lock -
|
||||
// at least one applicability error for {bar()} candidate, when the last overloaded method leads to error but first was ok:
|
||||
//2. {bar()}.getSubstitutor() would preserve error from wrong {foo} candidate => when the error was cleared - everything ok
|
||||
if (includeReturnConstraint) {
|
||||
myApplicabilityError.remove();
|
||||
}
|
||||
final PsiSubstitutor inferredSubstitutor = inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE, includeReturnConstraint);
|
||||
if (!stackStamp.mayCacheNow() ||
|
||||
isOverloadCheck() ||
|
||||
!includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) ||
|
||||
myArgumentList != null && PsiResolveHelper.ourGraphGuard.currentStack().contains(myArgumentList.getParent())
|
||||
) {
|
||||
return inferredSubstitutor;
|
||||
}
|
||||
|
||||
myCalcedSubstitutor = substitutor = inferredSubstitutor;
|
||||
}
|
||||
else {
|
||||
PsiTypeParameter[] typeParams = method.getTypeParameters();
|
||||
@@ -504,8 +494,18 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
/**
|
||||
* Should be invoked on the top level call expression candidate only
|
||||
*/
|
||||
public void setApplicabilityError(String applicabilityError) {
|
||||
myApplicabilityError.set(applicabilityError);
|
||||
public void setApplicabilityError(@NotNull String applicabilityError) {
|
||||
boolean overloadCheck = isOverloadCheck();
|
||||
if (!overloadCheck) {
|
||||
myInferenceError = applicabilityError;
|
||||
}
|
||||
if (myArgumentList == null ? overloadCheck : isOverloadCheck(myArgumentList)) {
|
||||
markNotApplicable();
|
||||
}
|
||||
}
|
||||
|
||||
public void markNotApplicable() {
|
||||
myApplicabilityError = true;
|
||||
}
|
||||
|
||||
public String getInferenceErrorMessage() {
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.scope.PsiConflictResolver;
|
||||
@@ -187,7 +186,7 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
|
||||
|
||||
//15.9.3 Choosing the Constructor and its Arguments
|
||||
//The return type and throws clause of cj are the same as the return type and throws clause determined for mj (p15.12.2.6)
|
||||
if (errorMessage == null && InferenceSession.wasUncheckedConversionPerformed(context)) {
|
||||
if (errorMessage == null && ((MethodCandidateInfo)staticFactoryCandidateInfo).isErased()) {
|
||||
return DiamondInferenceResult.RAW_RESULT;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import java.util.*;
|
||||
|
||||
public class InferenceSession {
|
||||
private static final Logger LOG = Logger.getInstance(InferenceSession.class);
|
||||
private static final Key<Boolean> ERASED = Key.create("UNCHECKED_CONVERSION");
|
||||
private static final Function<Pair<PsiType, PsiType>, PsiType> UPPER_BOUND_FUNCTION = pair -> GenericsUtil.getGreatestLowerBound(pair.first, pair.second);
|
||||
|
||||
private static final String EQUALITY_CONSTRAINTS_PRESENTATION = "equality constraints";
|
||||
@@ -315,8 +314,11 @@ public class InferenceSession {
|
||||
}
|
||||
}
|
||||
|
||||
if (currentMethod != null && myErrorMessages != null) {
|
||||
currentMethod.setApplicabilityError(StringUtil.join(myErrorMessages, "\n"));
|
||||
if (currentMethod != null) {
|
||||
if (myErrorMessages != null) {
|
||||
currentMethod.setApplicabilityError(StringUtil.join(myErrorMessages, "\n"));
|
||||
}
|
||||
currentMethod.setErased(myErased);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -355,12 +357,12 @@ public class InferenceSession {
|
||||
if (expectedActualErrorMessage != null && myErrorMessages != null) {
|
||||
myErrorMessages.add(0, expectedActualErrorMessage);
|
||||
}
|
||||
if (isOverloadCheck()) {
|
||||
if (isPertinentToApplicabilityCheckOnContainingCall(parent)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
//proceed to B3 constraints
|
||||
else if (parameters != null && parameters.length > 0 && args != null && !isOverloadCheck()) {//todo
|
||||
else if (parameters != null && parameters.length > 0 && args != null && !isPertinentToApplicabilityCheckOnContainingCall(parent)) {
|
||||
final Set<ConstraintFormula> additionalConstraints = new LinkedHashSet<>();
|
||||
final HashSet<ConstraintFormula> ignoredConstraints = new HashSet<>();
|
||||
collectAdditionalConstraints(parameters, args, method, mySiteSubstitutor, additionalConstraints,
|
||||
@@ -373,22 +375,8 @@ public class InferenceSession {
|
||||
resolveBounds(myInferenceVariables, initialSubstitutor);
|
||||
}
|
||||
|
||||
private boolean isOverloadCheck() {
|
||||
if (myContext != null) {
|
||||
for (PsiElement o : MethodCandidateInfo.ourOverloadGuard.currentStack()) {
|
||||
//method references do not contain nested arguments anyway
|
||||
if (o instanceof PsiExpressionList) {
|
||||
final PsiExpressionList element = (PsiExpressionList)o;
|
||||
for (PsiExpression expression : element.getExpressions()) {
|
||||
if (PsiUtil.skipParenthesizedExprDown(expression) == myContext) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return MethodCandidateInfo.isOverloadCheck();
|
||||
private static boolean isPertinentToApplicabilityCheckOnContainingCall(@NotNull PsiElement parent) {
|
||||
return LambdaUtil.getFunctionalTypeMap().containsKey(parent);
|
||||
}
|
||||
|
||||
private void collectAdditionalConstraints(PsiParameter[] parameters,
|
||||
@@ -1044,8 +1032,6 @@ public class InferenceSession {
|
||||
}
|
||||
}
|
||||
|
||||
setUncheckedInContext();
|
||||
|
||||
final Map<PsiTypeParameter, PsiType> map = substitutor.getSubstitutionMap();
|
||||
for (PsiTypeParameter parameter : map.keySet()) {
|
||||
final PsiType mapping = map.get(parameter);
|
||||
@@ -1065,12 +1051,6 @@ public class InferenceSession {
|
||||
}
|
||||
}
|
||||
|
||||
public void setUncheckedInContext() {
|
||||
if (myContext != null && !MethodCandidateInfo.isOverloadCheck(getArgumentList(myContext))) {//todo
|
||||
myContext.putUserData(ERASED, myErased);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean initFreshVariables(PsiSubstitutor substitutor, List<InferenceVariable> vars, UniqueNameGenerator nameGenerator) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(getManager().getProject());
|
||||
PsiSubstitutor ySubstitutor = PsiSubstitutor.EMPTY;
|
||||
@@ -1903,11 +1883,6 @@ public class InferenceSession {
|
||||
return myIncorporationPhase.hasCaptureConstraints(Collections.singletonList(inferenceVariable));
|
||||
}
|
||||
|
||||
public static boolean wasUncheckedConversionPerformed(PsiElement call) {
|
||||
final Boolean erased = call.getUserData(ERASED);
|
||||
return erased != null && erased.booleanValue();
|
||||
}
|
||||
|
||||
public PsiElement getContext() {
|
||||
return myContext;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,11 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
|
||||
for (Pair<InferenceVariable[], PsiClassType> pair : callSession.myIncorporationPhase.getCaptures()) {
|
||||
session.myIncorporationPhase.addCapture(pair.first, pair.second);
|
||||
}
|
||||
callSession.setUncheckedInContext();
|
||||
final MethodCandidateInfo currentMethod = session.getCurrentMethod(((PsiCall)myExpression).getArgumentList());
|
||||
final JavaResolveResult resolveResult = currentMethod != null ? currentMethod : PsiDiamondType.getDiamondsAwareResolveResult((PsiCall)myExpression);
|
||||
if (resolveResult instanceof MethodCandidateInfo) {
|
||||
((MethodCandidateInfo)resolveResult).setErased(callSession.isErased());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -94,7 +95,8 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiSubstitutor inferTypeArguments(@NotNull ParameterTypeInferencePolicy policy, boolean includeReturnConstraint) {
|
||||
return inferTypeArguments(includeReturnConstraint);
|
||||
return includeReturnConstraint ? inferTypeArguments(true)
|
||||
: ObjectUtils.assertNotNull(MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(reference, false, () -> inferTypeArguments(false)));
|
||||
}
|
||||
|
||||
private PsiSubstitutor inferTypeArguments(boolean includeReturnConstraint) {
|
||||
@@ -288,7 +290,7 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
}
|
||||
|
||||
if ((varargs || functionalInterfaceParamTypes.length == parameterTypes.length) &&
|
||||
isCorrectAssignment(parameterTypes, functionalInterfaceParamTypes, interfaceMethod, varargs, referenceExpression, conflict, 0)) {
|
||||
isCorrectAssignment(parameterTypes, functionalInterfaceParamTypes, interfaceMethod, varargs, conflict, 0)) {
|
||||
//reject static interface methods called on something else but interface class
|
||||
if (psiMethod.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
PsiClass containingClass = psiMethod.getContainingClass();
|
||||
@@ -304,7 +306,7 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
|
||||
if (hasReceiver &&
|
||||
(varargs || functionalInterfaceParamTypes.length == parameterTypes.length + 1) &&
|
||||
isCorrectAssignment(parameterTypes, functionalInterfaceParamTypes, interfaceMethod, varargs, referenceExpression, conflict, 1)) {
|
||||
isCorrectAssignment(parameterTypes, functionalInterfaceParamTypes, interfaceMethod, varargs, conflict, 1)) {
|
||||
return false;
|
||||
}
|
||||
return null;
|
||||
@@ -314,7 +316,6 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
PsiType[] functionalInterfaceParamTypes,
|
||||
PsiMethod interfaceMethod,
|
||||
boolean varargs,
|
||||
PsiMethodReferenceExpression referenceExpression,
|
||||
CandidateInfo conflict,
|
||||
int offset) {
|
||||
final int min = Math.min(parameterTypes.length, functionalInterfaceParamTypes.length - offset);
|
||||
@@ -324,26 +325,21 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
if (varargs && i == parameterTypes.length - 1) {
|
||||
if (!TypeConversionUtil.isAssignable(parameterType, argType) &&
|
||||
!TypeConversionUtil.isAssignable(((PsiArrayType)parameterType).getComponentType(), argType)) {
|
||||
reportParameterConflict(referenceExpression, conflict, argType, parameterType);
|
||||
markNotApplicable(conflict);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!TypeConversionUtil.isAssignable(parameterType, argType)) {
|
||||
reportParameterConflict(referenceExpression, conflict, argType, parameterType);
|
||||
markNotApplicable(conflict);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return !varargs || parameterTypes.length - 1 <= functionalInterfaceParamTypes.length - offset;
|
||||
}
|
||||
|
||||
private static void reportParameterConflict(PsiMethodReferenceExpression referenceExpression,
|
||||
CandidateInfo conflict,
|
||||
PsiType argType,
|
||||
PsiType parameterType) {
|
||||
private static void markNotApplicable(CandidateInfo conflict) {
|
||||
if (conflict instanceof MethodCandidateInfo) {
|
||||
((MethodCandidateInfo)conflict).setApplicabilityError("Invalid " +
|
||||
(referenceExpression.isConstructor() ? "constructor" :"method") +
|
||||
" reference: " + argType.getPresentableText() + " cannot be converted to " + parameterType.getPresentableText());
|
||||
((MethodCandidateInfo)conflict).markNotApplicable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.DebugUtil;
|
||||
import com.intellij.psi.impl.PsiClassImplUtil;
|
||||
import com.intellij.psi.impl.source.resolve.JavaResolveCache;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
|
||||
import com.intellij.psi.impl.source.tree.ChildRole;
|
||||
import com.intellij.psi.impl.source.tree.ElementType;
|
||||
@@ -230,7 +229,7 @@ public class PsiMethodCallExpressionImpl extends ExpressionPsiElement implements
|
||||
return TypeConversionUtil.erasure(ret);
|
||||
}
|
||||
|
||||
if (InferenceSession.wasUncheckedConversionPerformed(call)) {
|
||||
if (result instanceof MethodCandidateInfo && ((MethodCandidateInfo)result).isErased()) {
|
||||
// 18.5.2
|
||||
// if unchecked conversion was necessary, then this substitution provides the parameter types of the invocation type,
|
||||
// while the return type and thrown types are given by the erasure of m's type (without applying theta').
|
||||
|
||||
@@ -77,7 +77,7 @@ public class PsiMethodReferenceExpressionImpl extends JavaStubPsiElement<Functio
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPotentiallyCompatible(final PsiType functionalInterfaceType) {
|
||||
public boolean isPotentiallyCompatible(@Nullable PsiType functionalInterfaceType) {
|
||||
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType);
|
||||
if (interfaceMethod == null) return false;
|
||||
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
class Test {
|
||||
{
|
||||
MyBuilder b;
|
||||
b.a().b().<caret>
|
||||
b.x().b().addInt(1).putLong(2).mayCallManyTimes().mayCallManyTimes().<caret>
|
||||
}
|
||||
}
|
||||
|
||||
interface MyBuilder {
|
||||
MyBuilder a();
|
||||
MyBuilder x();
|
||||
MyBuilder b();
|
||||
MyBuilder c();
|
||||
MyBuilder d();
|
||||
MyBuilder addInt(int a);
|
||||
MyBuilder putLong(long a);
|
||||
MyBuilder mayCallManyTimes();
|
||||
}
|
||||
@@ -14,7 +14,7 @@ class Test {
|
||||
|
||||
class Test2 {
|
||||
|
||||
static void m(Integer <warning descr="Parameter 'i' is never used">i</warning>) { }
|
||||
static void m(Integer i) { }
|
||||
|
||||
interface I1 {
|
||||
void m(int x);
|
||||
|
||||
@@ -77,7 +77,7 @@ abstract class AbstractCollection<E> implements Collection<E> {
|
||||
public boolean add(E e) {
|
||||
return true;
|
||||
}
|
||||
public boolean addAll(Collection<? extends E> <warning descr="Parameter 'c' is never used">c</warning>) {
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
boolean modified = false;
|
||||
return modified;
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ class Test {
|
||||
Test m(List<Integer> l1, List<Integer> l2);
|
||||
}
|
||||
|
||||
static Test meth(List<Integer>... <warning descr="Parameter 'lli' is never used">lli</warning>) {
|
||||
static Test meth(List<Integer>... lli) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Test(List<Integer>... <warning descr="Parameter 'lli' is never used">lli</warning>) {}
|
||||
Test(List<Integer>... lli) {}
|
||||
|
||||
{
|
||||
I <warning descr="Variable 'i1' is never used">i1</warning> = <warning descr="Unchecked generics array creation for varargs parameter">Test::meth</warning>;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class A {
|
||||
private void test5(Integer <warning descr="Parameter 'i' is never used">i</warning>, String... <warning descr="Parameter 'strings' is never used">strings</warning>) {}
|
||||
private void test5(Integer i, String... strings) {}
|
||||
private void <warning descr="Private method 'test5(java.lang.Integer, java.lang.Integer, java.lang.String...)' is never used">test5</warning>(Integer i, Integer b, String... strings) {
|
||||
System.out.println(i);
|
||||
System.out.println(b);
|
||||
|
||||
@@ -12,7 +12,7 @@ class MyTest<T> {
|
||||
|
||||
public static class Builder<E> {
|
||||
|
||||
public Builder<E> add(E <warning descr="Parameter 'element' is never used">element</warning>) {
|
||||
public Builder<E> add(E element) {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,6 @@ class Main {
|
||||
}
|
||||
|
||||
public static boolean checkForJdk(String <warning descr="Parameter 'homePath' is never used">homePath</warning>) {return false;}
|
||||
public static boolean checkForJdk(File <warning descr="Parameter 'homePath' is never used">homePath</warning>) {return false;}
|
||||
public static boolean checkForJdk(File homePath) {return false;}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems/>
|
||||
@@ -0,0 +1,15 @@
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
class A {
|
||||
{
|
||||
new JComboBox().addActionListener(this::handleActionEvent);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new A();
|
||||
}
|
||||
private void handleActionEvent(ActionEvent ignore) {
|
||||
System.out.println(123);
|
||||
}
|
||||
}
|
||||
@@ -39,21 +39,28 @@ import org.jetbrains.idea.eclipse.util.PathUtil;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ExternalAnnotationsManagerTest extends LightPlatformTestCase {
|
||||
private static final Set<String> KNOWN_EXCEPTIONS = ContainerUtil.immutableSet(
|
||||
"java.util.stream.Stream<T> generate(java.util.function.Supplier<T>)" // replaced with Supplier<? extends T> in JDK11
|
||||
);
|
||||
|
||||
private final DefaultLightProjectDescriptor myDescriptor = new DefaultLightProjectDescriptor() {
|
||||
@Override
|
||||
public Sdk getSdk() {
|
||||
Sdk jdk = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk();
|
||||
Sdk sdk = PsiTestUtil.addJdkAnnotations(jdk);
|
||||
String home = jdk.getHomeDirectory().getParent().getPath();
|
||||
VfsRootAccess.allowRootAccess(getTestRootDisposable(), home);
|
||||
String toolsPath = home + "/lib/tools.jar!/";
|
||||
VirtualFile toolsJar = JarFileSystem.getInstance().findFileByPath(toolsPath);
|
||||
assertNotNull("tools.jar not found: " + toolsPath, toolsJar);
|
||||
if (jdk.getVersionString().matches("java version \"1\\.8\\..+\"")) {
|
||||
String home = jdk.getHomeDirectory().getParent().getPath();
|
||||
VfsRootAccess.allowRootAccess(getTestRootDisposable(), home);
|
||||
String toolsPath = home + "/lib/tools.jar!/";
|
||||
VirtualFile toolsJar = JarFileSystem.getInstance().findFileByPath(toolsPath);
|
||||
assertNotNull("tools.jar not found: " + toolsPath, toolsJar);
|
||||
|
||||
Sdk plusTools = PsiTestUtil.addRootsToJdk(sdk, OrderRootType.CLASSES, toolsJar);
|
||||
sdk = PsiTestUtil.addRootsToJdk(sdk, OrderRootType.CLASSES, toolsJar);
|
||||
}
|
||||
|
||||
Collection<String> utilClassPath = PathManager.getUtilClassPath();
|
||||
VirtualFile[] files = StreamEx.of(utilClassPath)
|
||||
@@ -63,7 +70,7 @@ public class ExternalAnnotationsManagerTest extends LightPlatformTestCase {
|
||||
LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(path)))
|
||||
.toArray(VirtualFile[]::new);
|
||||
|
||||
return PsiTestUtil.addRootsToJdk(plusTools, OrderRootType.CLASSES, files);
|
||||
return PsiTestUtil.addRootsToJdk(sdk, OrderRootType.CLASSES, files);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -183,6 +190,7 @@ public class ExternalAnnotationsManagerTest extends LightPlatformTestCase {
|
||||
}
|
||||
boolean found = !methods.isEmpty();
|
||||
if (!found) {
|
||||
if (KNOWN_EXCEPTIONS.contains(methodSignature)) return;
|
||||
List<String> candidates = ContainerUtil.map(aClass.findMethodsByName(methodName, true), method ->
|
||||
XmlUtil.escape(PsiFormatUtil.getExternalName(method, false, Integer.MAX_VALUE)));
|
||||
String additionalMsg = candidates.isEmpty() ? "" : "\nMaybe you have meant one of these methods instead:\n"+StringUtil.join(candidates, "\n")+"\n";
|
||||
|
||||
@@ -872,7 +872,7 @@ class Foo {
|
||||
}
|
||||
|
||||
void testDispreferAlreadyCalledBuilderMethods() {
|
||||
checkPreferredItems 0, 'c', 'd'
|
||||
checkPreferredItems 0, 'addInt', 'c', 'd', 'mayCallManyTimes', 'putLong'
|
||||
}
|
||||
|
||||
void testPreferPrintln() {
|
||||
|
||||
@@ -254,6 +254,10 @@ public class UnusedDeclarationTest extends AbstractUnusedDeclarationTest {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testMethodParametersIfMethodReferenceUsed() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest5() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_1_5, () -> doTest());
|
||||
}
|
||||
|
||||
@@ -318,11 +318,6 @@
|
||||
<item name="java.lang.RuntimeException RuntimeException(java.lang.String) 0">
|
||||
<annotation name="org.jetbrains.annotations.NonNls" />
|
||||
</item>
|
||||
<item name="java.lang.SecurityManager void checkMemberAccess(java.lang.Class<?>, int) 1">
|
||||
<annotation name="org.intellij.lang.annotations.MagicConstant">
|
||||
<val name="valuesFromClass" val="java.lang.reflect.Member.class" />
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='java.lang.Short int intValue()'>
|
||||
<annotation name='org.jetbrains.annotations.Range'>
|
||||
<val name="from" val="java.lang.Short.MIN_VALUE"/>
|
||||
@@ -428,9 +423,6 @@
|
||||
<item name="java.lang.String String(char[]) 0">
|
||||
<annotation name="org.jetbrains.annotations.NotNull" />
|
||||
</item>
|
||||
<item name="java.lang.String String(char[], boolean) 0">
|
||||
<annotation name="org.jetbrains.annotations.NotNull" />
|
||||
</item>
|
||||
<item name="java.lang.String String(char[], int, int) 0">
|
||||
<annotation name="org.jetbrains.annotations.NotNull" />
|
||||
</item>
|
||||
@@ -564,9 +556,6 @@
|
||||
<val name="pure" val="true"/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name="java.lang.String int indexOf(char[], int, int, java.lang.String, int) 0">
|
||||
<annotation name="org.jetbrains.annotations.NotNull" />
|
||||
</item>
|
||||
<item name="java.lang.String int indexOf(java.lang.String) 0">
|
||||
<annotation name="org.jetbrains.annotations.NotNull" />
|
||||
</item>
|
||||
|
||||
@@ -242,12 +242,6 @@
|
||||
<item name='java.nio.file.Files java.util.Set<java.nio.file.attribute.PosixFilePermission> getPosixFilePermissions(java.nio.file.Path, java.nio.file.LinkOption...) 0'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='java.nio.file.Files long copy(java.io.InputStream, java.io.OutputStream) 0'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='java.nio.file.Files long copy(java.io.InputStream, java.io.OutputStream) 1'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='java.nio.file.Files long copy(java.io.InputStream, java.nio.file.Path, java.nio.file.CopyOption...) 0'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
|
||||
@@ -44,6 +44,7 @@ public class JavaSdkVersionUtil {
|
||||
JavaSdk javaSdk = JavaSdk.getInstance();
|
||||
Sdk candidate = null;
|
||||
for (Sdk sdk : ProjectJdkTable.getInstance().getSdksOfType(javaSdk)) {
|
||||
if (!javaSdk.isValidSdkHome(sdk.getHomePath())) continue;
|
||||
JavaSdkVersion v = javaSdk.getVersion(sdk);
|
||||
if (v == version) {
|
||||
return sdk; // exact match
|
||||
|
||||
@@ -423,7 +423,7 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCodeFragmentText(PsiCodeFragment fragment) {
|
||||
public String getCodeFragmentText(PsiFile fragment) {
|
||||
final List<String> imports = StringUtil.split(((JavaCodeFragment)fragment).importsToString(), ",");
|
||||
final Map<String, String> importMap =
|
||||
imports.stream().collect(Collectors.toMap(s -> s.substring(s.lastIndexOf('.') + 1), Function.identity()));
|
||||
|
||||
@@ -173,10 +173,9 @@ public class JavacMain {
|
||||
};
|
||||
|
||||
final StandardJavaFileManager fm = wrapWithCallDispatcher(fileManager);
|
||||
final JavaCompiler.CompilationTask task = compiler.getTask(
|
||||
final JavaCompiler.CompilationTask task = tryUnwrapFileManager(compiler.getTask(
|
||||
out, fm, diagnosticConsumer, _options, null, fileManager.getJavaFileObjectsFromFiles(sources)
|
||||
);
|
||||
tryUnwrapFileManager(task, fileManager);
|
||||
), fileManager);
|
||||
for (JavaCompilerToolExtension extension : JavaCompilerToolExtension.getExtensions()) {
|
||||
try {
|
||||
extension.beforeCompileTaskExecution(compilingTool, task, _options, diagnosticConsumer);
|
||||
@@ -230,7 +229,7 @@ public class JavacMain {
|
||||
// Workaround for javac bug:
|
||||
// the internal ClientCodeWrapper class may not implement some interface-declared methods
|
||||
// which throw UnsupportedOperationException instead of delegating to our JpsFileManager instance
|
||||
private static void tryUnwrapFileManager(JavaCompiler.CompilationTask task, JavaFileManager manager) {
|
||||
private static JavaCompiler.CompilationTask tryUnwrapFileManager(JavaCompiler.CompilationTask task, JavaFileManager manager) {
|
||||
try {
|
||||
final Class<? extends JavaCompiler.CompilationTask> taskClass = task.getClass();
|
||||
final Field contextField = findFieldOfType(taskClass, Class.forName("com.sun.tools.javac.util.Context", true, taskClass.getClassLoader()));
|
||||
@@ -246,6 +245,7 @@ public class JavacMain {
|
||||
}
|
||||
catch (Throwable ignored) {
|
||||
}
|
||||
return task;
|
||||
}
|
||||
|
||||
private static Field findFieldOfType(final Class<?> aClass, final Class<?> fieldType) {
|
||||
|
||||
@@ -379,6 +379,9 @@ public class JpsJavacFileManager extends ForwardingJavaFileManager<StandardJavaF
|
||||
|
||||
private boolean isFileSystemLocation(Location location) {
|
||||
try {
|
||||
if (!(location instanceof StandardLocation)) {
|
||||
return false;
|
||||
}
|
||||
final StandardLocation loc = StandardLocation.valueOf(location.getName());
|
||||
if (loc == StandardLocation.PLATFORM_CLASS_PATH) {
|
||||
return myJavacBefore9;
|
||||
|
||||
@@ -18,6 +18,8 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.TokenType;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.jetbrains.jsonSchema.extension.JsonLikeSyntaxAdapter;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -52,13 +54,19 @@ public class SuggestEnumValuesFix implements LocalQuickFix, BatchQuickFix<Common
|
||||
PsiElement element = myQuickFixAdapter.adjustValue(initialElement);
|
||||
FileEditor fileEditor = FileEditorManager.getInstance(project).getSelectedEditor(element.getContainingFile().getVirtualFile());
|
||||
boolean whitespaceBefore = false;
|
||||
if (element.getPrevSibling() instanceof PsiWhiteSpace) {
|
||||
PsiElement prevPrev = null;
|
||||
PsiElement prev = element.getPrevSibling();
|
||||
if (prev instanceof PsiWhiteSpace) {
|
||||
whitespaceBefore = true;
|
||||
prevPrev = prev.getPrevSibling();
|
||||
}
|
||||
boolean shouldAddWhitespace = myQuickFixAdapter.fixWhitespaceBefore(initialElement, element);
|
||||
WriteAction.run(() -> element.delete());
|
||||
EditorEx editor = EditorUtil.getEditorEx(fileEditor);
|
||||
assert editor != null;
|
||||
if (myQuickFixAdapter.fixWhitespaceBefore(initialElement, element) && whitespaceBefore) {
|
||||
// this is a workaround for buggy formatters such as in YAML - it removes the whitespace after ':' when deleting the value
|
||||
shouldAddWhitespace |= prevPrev != null && PsiUtilCore.getElementType(prevPrev.getNextSibling()) != TokenType.WHITE_SPACE;
|
||||
if (shouldAddWhitespace && whitespaceBefore) {
|
||||
WriteAction.run(() -> {
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
editor.getDocument().insertString(offset, " ");
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
public class Main {
|
||||
public static final int NO_GRAPHICS = 1;
|
||||
@@ -133,6 +134,14 @@ public class Main {
|
||||
}
|
||||
|
||||
t.printStackTrace(new PrintWriter(message));
|
||||
|
||||
Properties sp = System.getProperties();
|
||||
String jre = sp.getProperty("java.runtime.version", sp.getProperty("java.version", "(unknown)"));
|
||||
String vendor = sp.getProperty("java.vendor", "(unknown vendor)");
|
||||
String arch = sp.getProperty("os.arch", "(unknown arch)");
|
||||
String home = sp.getProperty("java.home", "(unknown java.home)");
|
||||
message.append("\n-----\nJRE ").append(jre).append(' ').append(arch).append(" by ").append(vendor).append('\n').append(home);
|
||||
|
||||
showMessage(title, message.toString(), true);
|
||||
}
|
||||
|
||||
|
||||
@@ -119,6 +119,8 @@ class DistributionJARsBuilder {
|
||||
withModule("intellij.platform.util")
|
||||
withModule("intellij.platform.util.rt", "util.jar")
|
||||
withModule("intellij.platform.util.classLoader", "util.jar")
|
||||
withModule("intellij.platform.util.concurrency")
|
||||
|
||||
withModule("intellij.platform.extensions")
|
||||
withModule("intellij.platform.bootstrap")
|
||||
withModule("intellij.java.guiForms.rt")
|
||||
|
||||
@@ -87,7 +87,7 @@ class LinuxDistributionBuilder extends OsSpecificDistributionBuilder {
|
||||
buildContext.ant.copy(todir: "${unixDistPath}/bin") {
|
||||
fileset(dir: "$buildContext.paths.communityHome/platform/build-scripts/resources/linux/scripts")
|
||||
|
||||
filterset(begintoken: "@@", endtoken: "@@") {
|
||||
filterset(begintoken: "__", endtoken: "__") {
|
||||
filter(token: "product_full", value: fullName)
|
||||
filter(token: "product_uc", value: buildContext.productProperties.getEnvironmentVariableBaseName(buildContext.applicationInfo))
|
||||
filter(token: "vm_options", value: vmOptionsFileName)
|
||||
|
||||
@@ -1,70 +1,72 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# ---------------------------------------------------------------------
|
||||
# @@product_full@@ startup script.
|
||||
# __product_full__ startup script.
|
||||
# ---------------------------------------------------------------------
|
||||
#
|
||||
|
||||
message()
|
||||
{
|
||||
TITLE="Cannot start @@product_full@@"
|
||||
if [ -n "`which zenity`" ]; then
|
||||
TITLE="Cannot start __product_full__"
|
||||
if [ -n "$(command -v zenity)" ]; then
|
||||
zenity --error --title="$TITLE" --text="$1" --no-wrap
|
||||
elif [ -n "`which kdialog`" ]; then
|
||||
elif [ -n "$(command -v kdialog)" ]; then
|
||||
kdialog --error "$1" --title "$TITLE"
|
||||
elif [ -n "`which notify-send`" ]; then
|
||||
elif [ -n "$(command -v notify-send)" ]; then
|
||||
notify-send "ERROR: $TITLE" "$1"
|
||||
elif [ -n "`which xmessage`" ]; then
|
||||
elif [ -n "$(command -v xmessage)" ]; then
|
||||
xmessage -center "ERROR: $TITLE: $1"
|
||||
else
|
||||
printf "ERROR: $TITLE\n$1\n"
|
||||
printf "ERROR: %s\n%s\n" "$TITLE" "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
UNAME=`which uname`
|
||||
GREP=`which egrep`
|
||||
GREP_OPTIONS=""
|
||||
CUT=`which cut`
|
||||
READLINK=`which readlink`
|
||||
XARGS=`which xargs`
|
||||
DIRNAME=`which dirname`
|
||||
MKTEMP=`which mktemp`
|
||||
RM=`which rm`
|
||||
CAT=`which cat`
|
||||
SED=`which sed`
|
||||
UNAME=$(command -v uname)
|
||||
GREP=$(command -v egrep)
|
||||
CUT=$(command -v cut)
|
||||
READLINK=$(command -v readlink)
|
||||
XARGS=$(command -v xargs)
|
||||
DIRNAME=$(command -v dirname)
|
||||
MKTEMP=$(command -v mktemp)
|
||||
RM=$(command -v rm)
|
||||
CAT=$(command -v cat)
|
||||
SED=$(command -v sed)
|
||||
|
||||
if [ -z "$UNAME" -o -z "$GREP" -o -z "$CUT" -o -z "$DIRNAME" -o -z "$MKTEMP" -o -z "$RM" -o -z "$CAT" -o -z "$SED" ]; then
|
||||
if [ -z "$UNAME" ] || [ -z "$GREP" ] || [ -z "$CUT" ] || [ -z "$DIRNAME" ] || [ -z "$MKTEMP" ] || [ -z "$RM" ] || [ -z "$CAT" ] || [ -z "$SED" ]; then
|
||||
message "Required tools are missing - check beginning of \"$0\" file for details."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OS_TYPE=`"$UNAME" -s`
|
||||
# shellcheck disable=SC2034
|
||||
GREP_OPTIONS=''
|
||||
OS_TYPE=$("$UNAME" -s)
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Ensure IDE_HOME points to the directory where the IDE is installed.
|
||||
# ---------------------------------------------------------------------
|
||||
SCRIPT_LOCATION=$0
|
||||
SCRIPT_LOCATION="$0"
|
||||
if [ -x "$READLINK" ]; then
|
||||
while [ -L "$SCRIPT_LOCATION" ]; do
|
||||
SCRIPT_LOCATION=`"$READLINK" -e "$SCRIPT_LOCATION"`
|
||||
SCRIPT_LOCATION=$("$READLINK" -e "$SCRIPT_LOCATION")
|
||||
done
|
||||
fi
|
||||
|
||||
cd $(${DIRNAME} ${SCRIPT_LOCATION})
|
||||
IDE_BIN_HOME=`pwd`
|
||||
IDE_HOME=$(${DIRNAME} ${IDE_BIN_HOME})
|
||||
cd ${OLDPWD}
|
||||
cd "$("$DIRNAME" "$SCRIPT_LOCATION")" || exit 2
|
||||
IDE_BIN_HOME=$(pwd)
|
||||
IDE_HOME=$("$DIRNAME" "$IDE_BIN_HOME")
|
||||
cd "${OLDPWD}" || exit 2
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Locate a JDK installation directory which will be used to run the IDE.
|
||||
# Try (in order): @@product_uc@@_JDK, @@vm_options@@.jdk, ./jbr, ./jre64, JDK_HOME, JAVA_HOME, "java" in PATH.
|
||||
# Locate a JDK installation directory command -v will be used to run the IDE.
|
||||
# Try (in order): __product_uc___JDK, __vm_options__.jdk, ./jbr, ./jre64, JDK_HOME, JAVA_HOME, "java" in PATH.
|
||||
# ---------------------------------------------------------------------
|
||||
if [ -n "$@@product_uc@@_JDK" -a -x "$@@product_uc@@_JDK/bin/java" ]; then
|
||||
JDK="$@@product_uc@@_JDK"
|
||||
# shellcheck disable=SC2154
|
||||
if [ -n "$__product_uc___JDK" ] && [ -x "$__product_uc___JDK/bin/java" ]; then
|
||||
JDK="$__product_uc___JDK"
|
||||
fi
|
||||
|
||||
if [ -z "$JDK" -a -s "$HOME/.@@system_selector@@/config/@@vm_options@@.jdk" ]; then
|
||||
USER_JRE=`"$CAT" $HOME/.@@system_selector@@/config/@@vm_options@@.jdk`
|
||||
if [ -z "$JDK" ] && [ -s "$HOME/.__system_selector__/config/__vm_options__.jdk" ]; then
|
||||
USER_JRE=$("$CAT" "$HOME/.__system_selector__/config/__vm_options__.jdk")
|
||||
if [ ! -d "$USER_JRE" ]; then
|
||||
USER_JRE="$IDE_HOME/$USER_JRE"
|
||||
fi
|
||||
@@ -73,7 +75,7 @@ if [ -z "$JDK" -a -s "$HOME/.@@system_selector@@/config/@@vm_options@@.jdk" ]; t
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JDK" -a "$OS_TYPE" = "Linux" ] ; then
|
||||
if [ -z "$JDK" ] && [ "$OS_TYPE" = "Linux" ] ; then
|
||||
BUNDLED_JRE="$IDE_HOME/jbr"
|
||||
if [ ! -d "$BUNDLED_JRE" ]; then
|
||||
BUNDLED_JRE="$IDE_HOME/jre64"
|
||||
@@ -86,20 +88,21 @@ if [ -z "$JDK" -a "$OS_TYPE" = "Linux" ] ; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JDK" -a -n "$JDK_HOME" -a -x "$JDK_HOME/bin/java" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
if [ -z "$JDK" ] && [ -n "$JDK_HOME" ] && [ -x "$JDK_HOME/bin/java" ]; then
|
||||
JDK="$JDK_HOME"
|
||||
fi
|
||||
|
||||
if [ -z "$JDK" -a -n "$JAVA_HOME" -a -x "$JAVA_HOME/bin/java" ]; then
|
||||
if [ -z "$JDK" ] && [ -n "$JAVA_HOME" ] && [ -x "$JAVA_HOME/bin/java" ]; then
|
||||
JDK="$JAVA_HOME"
|
||||
fi
|
||||
|
||||
if [ -z "$JDK" ]; then
|
||||
JDK_PATH=`which java`
|
||||
JDK_PATH=$(command -v java)
|
||||
|
||||
if [ -n "$JDK_PATH" ]; then
|
||||
if [ "$OS_TYPE" = "FreeBSD" -o "$OS_TYPE" = "MidnightBSD" ]; then
|
||||
JAVA_LOCATION=`JAVAVM_DRYRUN=yes java | "$GREP" '^JAVA_HOME' | "$CUT" -c11-`
|
||||
if [ "$OS_TYPE" = "FreeBSD" ] || [ "$OS_TYPE" = "MidnightBSD" ]; then
|
||||
JAVA_LOCATION=$(JAVAVM_DRYRUN=yes java | "$GREP" '^JAVA_HOME' | "$CUT" -c11-)
|
||||
if [ -x "$JAVA_LOCATION/bin/java" ]; then
|
||||
JDK="$JAVA_LOCATION"
|
||||
fi
|
||||
@@ -109,24 +112,24 @@ if [ -z "$JDK" ]; then
|
||||
JDK="$JAVA_LOCATION"
|
||||
fi
|
||||
elif [ "$OS_TYPE" = "Darwin" ]; then
|
||||
JAVA_LOCATION=`/usr/libexec/java_home`
|
||||
JAVA_LOCATION=$(/usr/libexec/java_home)
|
||||
if [ -x "$JAVA_LOCATION/bin/java" ]; then
|
||||
JDK="$JAVA_LOCATION"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JDK" -a -n "$JDK_PATH" -a -x "$READLINK" -a -x "$XARGS" ]; then
|
||||
JAVA_LOCATION=`"$READLINK" -f "$JDK_PATH"`
|
||||
if [ -z "$JDK" ] && [ -n "$JDK_PATH" ] && [ -x "$READLINK" ] && [ -x "$XARGS" ]; then
|
||||
JAVA_LOCATION=$("$READLINK" -f "$JDK_PATH")
|
||||
case "$JAVA_LOCATION" in
|
||||
*/jre/bin/java)
|
||||
JAVA_LOCATION=`echo "$JAVA_LOCATION" | "$XARGS" "$DIRNAME" | "$XARGS" "$DIRNAME" | "$XARGS" "$DIRNAME"`
|
||||
JAVA_LOCATION=$(echo "$JAVA_LOCATION" | "$XARGS" "$DIRNAME" | "$XARGS" "$DIRNAME" | "$XARGS" "$DIRNAME")
|
||||
if [ ! -d "$JAVA_LOCATION/bin" ]; then
|
||||
JAVA_LOCATION="$JAVA_LOCATION/jre"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
JAVA_LOCATION=`echo "$JAVA_LOCATION" | "$XARGS" "$DIRNAME" | "$XARGS" "$DIRNAME"`
|
||||
JAVA_LOCATION=$(echo "$JAVA_LOCATION" | "$XARGS" "$DIRNAME" | "$XARGS" "$DIRNAME")
|
||||
;;
|
||||
esac
|
||||
if [ -x "$JAVA_LOCATION/bin/java" ]; then
|
||||
@@ -136,13 +139,13 @@ if [ -z "$JDK" ]; then
|
||||
fi
|
||||
|
||||
JAVA_BIN="$JDK/bin/java"
|
||||
if [ -z "$JDK" -o ! -x "$JAVA_BIN" ]; then
|
||||
message "No JDK found. Please validate either @@product_uc@@_JDK, JDK_HOME or JAVA_HOME environment variable points to valid JDK installation."
|
||||
if [ -z "$JDK" ] || [ ! -x "$JAVA_BIN" ]; then
|
||||
message "No JDK found. Please validate either __product_uc___JDK, JDK_HOME or JAVA_HOME environment variable points to valid JDK installation."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION_LOG=`"$MKTEMP" -t java.version.log.XXXXXX`
|
||||
JAVA_TOOL_OPTIONS= "$JAVA_BIN" -version 2> "$VERSION_LOG"
|
||||
VERSION_LOG=$("$MKTEMP" -t java.version.log.XXXXXX)
|
||||
JAVA_TOOL_OPTIONS='' "$JAVA_BIN" -version 2> "$VERSION_LOG"
|
||||
"$GREP" "64-Bit|x86_64|amd64" "$VERSION_LOG" > /dev/null
|
||||
BITS=$?
|
||||
"$RM" -f "$VERSION_LOG"
|
||||
@@ -151,66 +154,70 @@ test ${BITS} -eq 0 && BITS="64" || BITS=""
|
||||
# ---------------------------------------------------------------------
|
||||
# Collect JVM options and IDE properties.
|
||||
# ---------------------------------------------------------------------
|
||||
if [ -n "$@@product_uc@@_PROPERTIES" ]; then
|
||||
IDE_PROPERTIES_PROPERTY="-Didea.properties.file=$@@product_uc@@_PROPERTIES"
|
||||
# shellcheck disable=SC2154
|
||||
if [ -n "$__product_uc___PROPERTIES" ]; then
|
||||
IDE_PROPERTIES_PROPERTY="-Didea.properties.file=$__product_uc___PROPERTIES"
|
||||
fi
|
||||
|
||||
VM_OPTIONS_FILE=""
|
||||
if [ -n "$@@product_uc@@_VM_OPTIONS" -a -r "$@@product_uc@@_VM_OPTIONS" ]; then
|
||||
# shellcheck disable=SC2154
|
||||
if [ -n "$__product_uc___VM_OPTIONS" ] && [ -r "$__product_uc___VM_OPTIONS" ]; then
|
||||
# explicit
|
||||
VM_OPTIONS_FILE="$@@product_uc@@_VM_OPTIONS"
|
||||
VM_OPTIONS_FILE="$__product_uc___VM_OPTIONS"
|
||||
elif [ -r "$IDE_HOME.vmoptions" ]; then
|
||||
# Toolbox
|
||||
VM_OPTIONS_FILE="$IDE_HOME.vmoptions"
|
||||
elif [ -r "$HOME/.@@system_selector@@/config/@@vm_options@@$BITS.vmoptions" ]; then
|
||||
elif [ -r "$HOME/.__system_selector__/config/__vm_options__$BITS.vmoptions" ]; then
|
||||
# user-overridden
|
||||
VM_OPTIONS_FILE="$HOME/.@@system_selector@@/config/@@vm_options@@$BITS.vmoptions"
|
||||
elif [ -r "$IDE_BIN_HOME/@@vm_options@@$BITS.vmoptions" ]; then
|
||||
VM_OPTIONS_FILE="$HOME/.__system_selector__/config/__vm_options__$BITS.vmoptions"
|
||||
elif [ -r "$IDE_BIN_HOME/__vm_options__$BITS.vmoptions" ]; then
|
||||
# default, standard installation
|
||||
VM_OPTIONS_FILE="$IDE_BIN_HOME/@@vm_options@@$BITS.vmoptions"
|
||||
VM_OPTIONS_FILE="$IDE_BIN_HOME/__vm_options__$BITS.vmoptions"
|
||||
else
|
||||
# default, universal package
|
||||
test "$OS_TYPE" = "Darwin" && OS_SPECIFIC="mac" || OS_SPECIFIC="linux"
|
||||
VM_OPTIONS_FILE="$IDE_BIN_HOME/$OS_SPECIFIC/@@vm_options@@$BITS.vmoptions"
|
||||
VM_OPTIONS_FILE="$IDE_BIN_HOME/$OS_SPECIFIC/__vm_options__$BITS.vmoptions"
|
||||
fi
|
||||
|
||||
VM_OPTIONS=""
|
||||
if [ -r "$VM_OPTIONS_FILE" ]; then
|
||||
VM_OPTIONS=`"$CAT" "$VM_OPTIONS_FILE" | "$GREP" -v "^#.*"`
|
||||
if { echo "$VM_OPTIONS" | "$GREP" -q "agentlib:yjpagent" - ; } then
|
||||
VM_OPTIONS=$("$CAT" "$VM_OPTIONS_FILE" | "$GREP" -v "^#.*")
|
||||
if { echo "$VM_OPTIONS" | "$GREP" -q "agentlib:yjpagent" - ; }; then
|
||||
if [ "$OS_TYPE" = "Linux" ]; then
|
||||
VM_OPTIONS=`echo "$VM_OPTIONS" | "$SED" -e "s|-agentlib:yjpagent\(-linux\)\?\([^=]*\)|-agentpath:$IDE_BIN_HOME/libyjpagent-linux\2.so|"`
|
||||
VM_OPTIONS=$(echo "$VM_OPTIONS" | "$SED" -e "s|-agentlib:yjpagent\(-linux\)\?\([^=]*\)|-agentpath:$IDE_BIN_HOME/libyjpagent-linux\2.so|")
|
||||
else
|
||||
VM_OPTIONS=`echo "$VM_OPTIONS" | "$SED" -e "s|-agentlib:yjpagent[^ ]*||"`
|
||||
VM_OPTIONS=$(echo "$VM_OPTIONS" | "$SED" -e "s|-agentlib:yjpagent[^ ]*||")
|
||||
fi
|
||||
fi
|
||||
else
|
||||
message "Cannot find VM options file"
|
||||
fi
|
||||
|
||||
@@class_path@@
|
||||
if [ -n "$@@product_uc@@_CLASSPATH" ]; then
|
||||
CLASSPATH="$CLASSPATH:$@@product_uc@@_CLASSPATH"
|
||||
__class_path__
|
||||
# shellcheck disable=SC2154
|
||||
if [ -n "$__product_uc___CLASSPATH" ]; then
|
||||
CLASSPATH="$CLASSPATH:$__product_uc___CLASSPATH"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Run the IDE.
|
||||
# ---------------------------------------------------------------------
|
||||
JAVA_ERR_LOG=`"$MKTEMP" -t java.error.log.XXXXXX`
|
||||
JAVA_ERR_LOG=$("$MKTEMP" -t java.error.log.XXXXXX)
|
||||
IFS="$(printf '\n\t')"
|
||||
# shellcheck disable=SC2086
|
||||
"$JAVA_BIN" \
|
||||
-classpath "$CLASSPATH" \
|
||||
${VM_OPTIONS} \
|
||||
"-XX:ErrorFile=$HOME/java_error_in_@@product_uc@@_%p.log" \
|
||||
"-XX:HeapDumpPath=$HOME/java_error_in_@@product_uc@@.hprof" \
|
||||
-Didea.paths.selector=@@system_selector@@ \
|
||||
"-XX:ErrorFile=$HOME/java_error_in___product_uc___%p.log" \
|
||||
"-XX:HeapDumpPath=$HOME/java_error_in___product_uc__.hprof" \
|
||||
-Didea.paths.selector=__system_selector__ \
|
||||
"-Djb.vmOptionsFile=$VM_OPTIONS_FILE" \
|
||||
${IDE_PROPERTIES_PROPERTY} \
|
||||
@@ide_jvm_args@@ \
|
||||
__ide_jvm_args__ \
|
||||
com.intellij.idea.Main \
|
||||
"$@" 2> "$JAVA_ERR_LOG"
|
||||
EC=$?
|
||||
if [ ${EC} -ne 0 -a -s "$JAVA_ERR_LOG" ]; then
|
||||
if [ ${EC} -ne 0 ] && [ -s "$JAVA_ERR_LOG" ]; then
|
||||
message "$(cat "$JAVA_ERR_LOG")"
|
||||
fi
|
||||
rm -f "$JAVA_ERR_LOG"
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.application;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.concurrency.AppExecutorUtil;
|
||||
import com.intellij.util.concurrency.NonUrgentExecutor;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.concurrency.CancellablePromise;
|
||||
@@ -20,7 +19,7 @@ import java.util.function.Consumer;
|
||||
*/
|
||||
public interface NonBlockingReadAction<T> {
|
||||
|
||||
/**
|
||||
/**
|
||||
* @return a copy of this builder that runs read actions only when index is available in the given project.
|
||||
* The operation is canceled if the project is closed before either the background computation or {@link #finishOnUiThread} runnable
|
||||
* are completed.
|
||||
@@ -64,7 +63,7 @@ public interface NonBlockingReadAction<T> {
|
||||
* Submit this computation to be performed in a non-blocking read action on background thread. The returned promise
|
||||
* is completed on the same thread (in the same read action), or on UI thread if {@link #finishOnUiThread} has been called.
|
||||
* @param backgroundThreadExecutor an executor to actually run the computation. Common examples are
|
||||
* {@link NonUrgentExecutor#getInstance()} or
|
||||
* {@link com.intellij.util.concurrency.NonUrgentExecutor#getInstance()} or
|
||||
* {@link AppExecutorUtil#getAppExecutorService()} or
|
||||
* {@link com.intellij.util.concurrency.BoundedTaskExecutor} on top of that.
|
||||
*/
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.ThrowableRunnable;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -349,6 +350,13 @@ public abstract class WriteCommandAction<T> extends BaseActionRunnable<T> {
|
||||
protected abstract void run() throws Throwable;
|
||||
}
|
||||
|
||||
/**
|
||||
* If run a write command using this method then "Undo" action always shows "Undefined" text - {@link #DEFAULT_COMMAND_NAME}.
|
||||
*
|
||||
* Please use {@link #runWriteCommandAction(Project, String, String, Runnable, PsiFile...)} instead.
|
||||
*/
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2019.3")
|
||||
@Deprecated
|
||||
public static void runWriteCommandAction(Project project, @NotNull Runnable runnable) {
|
||||
runWriteCommandAction(project, DEFAULT_COMMAND_NAME, DEFAULT_GROUP_ID, runnable);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.concurrent.ConcurrentMap;
|
||||
* A type of item with a distinct highlighting in an editor or in other views.
|
||||
*/
|
||||
public final class TextAttributesKey implements Comparable<TextAttributesKey> {
|
||||
public static final TextAttributesKey[] EMPTY_ARRAY = new TextAttributesKey[0];
|
||||
private static final Logger LOG = Logger.getInstance(TextAttributesKey.class);
|
||||
private static final String TEMP_PREFIX = "TEMP::";
|
||||
private static final TextAttributes NULL_ATTRIBUTES = new TextAttributes();
|
||||
|
||||
@@ -32,6 +32,8 @@ import java.util.List;
|
||||
* mode being suddenly on and off. To avoid executing a read action in "dumb" mode, please use {@link #runReadActionInSmartMode} or
|
||||
* {@link com.intellij.openapi.application.NonBlockingReadAction#inSmartMode}.
|
||||
*
|
||||
* More information about dumb mode could be found here: {@link IndexNotReadyException}
|
||||
*
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class DumbService {
|
||||
@@ -47,6 +49,8 @@ public abstract class DumbService {
|
||||
public abstract ModificationTracker getModificationTracker();
|
||||
|
||||
/**
|
||||
* To avoid race conditions use it only in EDT thread or inside read-action. See documentation for this class {@link DumbService}
|
||||
*
|
||||
* @return whether the IDE is in dumb mode, which means that right now indexes are updated in the background.
|
||||
* The IDE offers only limited functionality at such times, e.g., plain text file editing and version control operations.
|
||||
*/
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
package com.intellij.openapi.util;
|
||||
|
||||
import com.intellij.util.concurrency.AtomicFieldUpdater;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class AsyncValueLoaderManager<HOST, VALUE> {
|
||||
private final AtomicFieldUpdater<HOST, AsyncResult<VALUE>> fieldUpdater;
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public AsyncValueLoaderManager(@NotNull AtomicFieldUpdater<HOST, AsyncResult<VALUE>> fieldUpdater) {
|
||||
this.fieldUpdater = fieldUpdater;
|
||||
}
|
||||
|
||||
public AsyncValueLoaderManager(@NotNull Class<HOST> ownerClass) {
|
||||
//noinspection unchecked
|
||||
fieldUpdater = ((AtomicFieldUpdater)AtomicFieldUpdater.forFieldOfType(ownerClass, AsyncResult.class));
|
||||
}
|
||||
|
||||
public boolean isUpToDate(@NotNull HOST host, @NotNull VALUE value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract void load(@NotNull HOST host, @NotNull AsyncResult<VALUE> result);
|
||||
|
||||
public final void reset(HOST host) {
|
||||
fieldUpdater.set(host, null);
|
||||
}
|
||||
|
||||
public final void set(HOST host, @Nullable VALUE value) {
|
||||
if (value == null) {
|
||||
reset(host);
|
||||
}
|
||||
else {
|
||||
getOrCreateAsyncResult(host, false, false).setDone(value);
|
||||
}
|
||||
}
|
||||
|
||||
public final boolean has(HOST host) {
|
||||
AsyncResult<VALUE> result = fieldUpdater.get(host);
|
||||
return result != null && result.isDone() && result.getResult() != null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final AsyncResult<VALUE> get(HOST host) {
|
||||
return get(host, true);
|
||||
}
|
||||
|
||||
public final AsyncResult<VALUE> get(HOST host, boolean checkFreshness) {
|
||||
return getOrCreateAsyncResult(host, checkFreshness, true);
|
||||
}
|
||||
|
||||
private AsyncResult<VALUE> getOrCreateAsyncResult(HOST host, boolean checkFreshness, boolean load) {
|
||||
AsyncResult<VALUE> asyncResult = fieldUpdater.get(host);
|
||||
if (asyncResult == null) {
|
||||
if (!fieldUpdater.compareAndSet(host, null, asyncResult = new AsyncResult<>())) {
|
||||
return fieldUpdater.get(host);
|
||||
}
|
||||
}
|
||||
else if (!asyncResult.isProcessed()) {
|
||||
// if current asyncResult is not processed, so, we don't need to check cache state
|
||||
return asyncResult;
|
||||
}
|
||||
else if (asyncResult.isDone()) {
|
||||
if (!checkFreshness || isUpToDate(host, asyncResult.getResult())) {
|
||||
return asyncResult;
|
||||
}
|
||||
|
||||
if (!fieldUpdater.compareAndSet(host, asyncResult, asyncResult = new AsyncResult<>())) {
|
||||
AsyncResult<VALUE> valueFromAnotherThread = fieldUpdater.get(host);
|
||||
while (valueFromAnotherThread == null) {
|
||||
if (fieldUpdater.compareAndSet(host, null, asyncResult)) {
|
||||
if (load) {
|
||||
load(host, asyncResult);
|
||||
}
|
||||
return asyncResult;
|
||||
}
|
||||
else {
|
||||
valueFromAnotherThread = fieldUpdater.get(host);
|
||||
}
|
||||
}
|
||||
return valueFromAnotherThread;
|
||||
}
|
||||
}
|
||||
if (load) {
|
||||
load(host, asyncResult);
|
||||
}
|
||||
return asyncResult;
|
||||
}
|
||||
}
|
||||
@@ -750,7 +750,7 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw
|
||||
myDisplayName = displayName;
|
||||
final FileIndexFacade facade = FileIndexFacade.getInstance(project);
|
||||
myModule = virtualFile == null || project.isDefault() ? null : facade.getModuleForFile(virtualFile);
|
||||
mySearchOutsideContent = virtualFile != null && myModule == null && !facade.isInLibraryClasses(virtualFile) && !facade.isInLibrarySource(virtualFile);
|
||||
mySearchOutsideContent = project.isDefault() || virtualFile != null && myModule == null && !facade.isInLibraryClasses(virtualFile) && !facade.isInLibrarySource(virtualFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
* @author max
|
||||
*/
|
||||
package com.intellij.util;
|
||||
|
||||
import com.intellij.concurrency.*;
|
||||
import com.intellij.concurrency.AsyncFuture;
|
||||
import com.intellij.concurrency.AsyncFutureFactory;
|
||||
import com.intellij.concurrency.AsyncFutureResult;
|
||||
import com.intellij.concurrency.DefaultResultConsumer;
|
||||
import com.intellij.util.concurrency.SameThreadExecutor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class MergeQuery<T> extends AbstractQuery<T>{
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.util.concurrency;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
public final class SameThreadExecutor implements Executor {
|
||||
public static final Executor INSTANCE = new SameThreadExecutor();
|
||||
@Override
|
||||
public void execute(@NotNull Runnable command) {
|
||||
command.run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.util.indexing;
|
||||
|
||||
import com.intellij.lang.LighterAST;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface PsiDependentFileContent extends FileContent {
|
||||
@Override
|
||||
@NotNull
|
||||
PsiFile getPsiFile();
|
||||
|
||||
@NotNull
|
||||
LighterAST getLighterAST();
|
||||
}
|
||||
@@ -1,25 +1,8 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.concurrency;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public interface CancellablePromise<T> extends Promise<T>, Future<T> {
|
||||
void cancel();
|
||||
|
||||
/**
|
||||
* Create a promise that is resolved with the given value.
|
||||
*/
|
||||
@NotNull
|
||||
static <T> CancellablePromise<T> resolve(@Nullable T result) {
|
||||
if (result == null) {
|
||||
//noinspection unchecked
|
||||
return (CancellablePromise<T>)InternalPromiseUtil.FULFILLED_PROMISE.getValue();
|
||||
}
|
||||
else {
|
||||
return new DonePromise<>(InternalPromiseUtil.PromiseValue.createFulfilled(result));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.concurrency;
|
||||
|
||||
import com.intellij.util.Consumer;
|
||||
@@ -6,6 +6,7 @@ import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
@@ -37,12 +38,14 @@ public interface Promise<T> {
|
||||
@Deprecated
|
||||
@NotNull
|
||||
static <T> Promise<T> resolve(@Nullable T result) {
|
||||
if (result == null) {
|
||||
try {
|
||||
Method method = Promise.class.getClassLoader().loadClass("org.jetbrains.concurrency.Promises").getMethod("resolvedPromise", Object.class);
|
||||
method.setAccessible(true);
|
||||
//noinspection unchecked
|
||||
return (Promise<T>)InternalPromiseUtil.FULFILLED_PROMISE.getValue();
|
||||
return (Promise<T>)method.invoke(null, result);
|
||||
}
|
||||
else {
|
||||
return new DonePromise<>(InternalPromiseUtil.PromiseValue.createFulfilled(result));
|
||||
catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -411,12 +411,7 @@ public class FileManagerImpl implements FileManager {
|
||||
PsiDirectory psiDir = psiDirMap.get(vFile);
|
||||
if (psiDir != null) return psiDir;
|
||||
|
||||
if (Registry.is("ide.hide.excluded.files")) {
|
||||
if (myFileIndex.isExcludedFile(vFile)) return null;
|
||||
}
|
||||
else {
|
||||
if (myFileIndex.isUnderIgnored(vFile)) return null;
|
||||
}
|
||||
if (isExcludedOrIgnored(vFile)) return null;
|
||||
|
||||
VirtualFile parent = vFile.getParent();
|
||||
if (parent != null) { //?
|
||||
@@ -427,6 +422,11 @@ public class FileManagerImpl implements FileManager {
|
||||
return ConcurrencyUtil.cacheOrGet(psiDirMap, vFile, psiDir);
|
||||
}
|
||||
|
||||
private boolean isExcludedOrIgnored(@NotNull VirtualFile vFile) {
|
||||
if (myManager.getProject().isDefault()) return false;
|
||||
return Registry.is("ide.hide.excluded.files") ? myFileIndex.isExcludedFile(vFile) : myFileIndex.isUnderIgnored(vFile);
|
||||
}
|
||||
|
||||
public PsiDirectory getCachedDirectory(@NotNull VirtualFile vFile) {
|
||||
return getVFileToPsiDirMap().get(vFile);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.indexing.FileContent;
|
||||
import com.intellij.util.indexing.FileContentImpl;
|
||||
import com.intellij.util.indexing.IndexingDataKeys;
|
||||
import com.intellij.util.indexing.PsiDependentFileContent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -65,8 +66,8 @@ public class StubTreeBuilder {
|
||||
}
|
||||
else {
|
||||
CharSequence contentAsText = inputData.getContentAsText();
|
||||
FileContentImpl fileContent = (FileContentImpl)inputData;
|
||||
PsiFile psi = fileContent.getPsiFileForPsiDependentIndex();
|
||||
PsiDependentFileContent fileContent = (PsiDependentFileContent)inputData;
|
||||
PsiFile psi = fileContent.getPsiFile();
|
||||
final FileViewProvider viewProvider = psi.getViewProvider();
|
||||
psi = viewProvider.getStubBindingRoot();
|
||||
psi.putUserData(IndexingDataKeys.FILE_TEXT_CONTENT_KEY, contentAsText);
|
||||
@@ -79,7 +80,7 @@ public class StubTreeBuilder {
|
||||
if (stubFileElementType != null) {
|
||||
final StubBuilder stubBuilder = stubFileElementType.getBuilder();
|
||||
if (stubBuilder instanceof LightStubBuilder) {
|
||||
LightStubBuilder.FORCED_AST.set(fileContent.getLighterASTForPsiDependentIndex());
|
||||
LightStubBuilder.FORCED_AST.set(fileContent.getLighterAST());
|
||||
}
|
||||
data = stubBuilder.buildStubTree(psi);
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ import java.nio.charset.Charset;
|
||||
*
|
||||
* Class is not final since it is overridden in Upsource
|
||||
*/
|
||||
public class FileContentImpl extends UserDataHolderBase implements FileContent {
|
||||
public class FileContentImpl extends UserDataHolderBase implements PsiDependentFileContent {
|
||||
private final VirtualFile myFile;
|
||||
private final String myFileName;
|
||||
private final FileType myFileType;
|
||||
@@ -91,12 +91,14 @@ public class FileContentImpl extends UserDataHolderBase implements FileContent {
|
||||
|
||||
private static final Key<PsiFile> CACHED_PSI = Key.create("cached psi from content");
|
||||
|
||||
/**
|
||||
* @return psiFile associated with the content. If the file was not set on FileContentCreation, it will be created on the spot
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiFile getPsiFile() {
|
||||
return getPsiFileForPsiDependentIndex();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PsiFile getFileFromText() {
|
||||
PsiFile psi = getUserData(IndexingDataKeys.PSI_FILE);
|
||||
|
||||
if (psi == null) {
|
||||
@@ -111,8 +113,9 @@ public class FileContentImpl extends UserDataHolderBase implements FileContent {
|
||||
return psi;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public LighterAST getLighterASTForPsiDependentIndex() {
|
||||
public LighterAST getLighterAST() {
|
||||
LighterAST lighterAST = getUserData(IndexingDataKeys.LIGHTER_AST_NODE_KEY);
|
||||
if (lighterAST == null) {
|
||||
FileASTNode node = getPsiFileForPsiDependentIndex().getNode();
|
||||
@@ -266,7 +269,7 @@ public class FileContentImpl extends UserDataHolderBase implements FileContent {
|
||||
}
|
||||
}
|
||||
if (psi == null) {
|
||||
psi = getPsiFile();
|
||||
psi = getFileFromText();
|
||||
}
|
||||
return psi;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$/tests">
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests/testData" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests/testSrc" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
@@ -17,5 +18,6 @@
|
||||
<orderEntry type="library" scope="TEST" name="mockito" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="kotlin-test" level="project" />
|
||||
<orderEntry type="module" module-name="intellij.platform.vcs.impl" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.platform.tests" scope="TEST" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -3,6 +3,7 @@ package com.intellij.diff.util;
|
||||
|
||||
import com.intellij.codeInsight.folding.impl.FoldingUtil;
|
||||
import com.intellij.diff.fragments.DiffFragment;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.colors.EditorColors;
|
||||
@@ -31,6 +32,8 @@ import java.util.List;
|
||||
import static com.intellij.diff.util.DiffUtil.getLineCount;
|
||||
|
||||
public class DiffDrawUtil {
|
||||
private static final Logger LOG = Logger.getInstance(DiffDrawUtil.class);
|
||||
|
||||
public static final int STRIPE_LAYER = HighlighterLayer.ERROR - 1;
|
||||
public static final int DEFAULT_LAYER = HighlighterLayer.SELECTION - 3;
|
||||
public static final int INLINE_LAYER = HighlighterLayer.SELECTION - 2;
|
||||
@@ -165,7 +168,7 @@ public class DiffDrawUtil {
|
||||
public static int lineToY(@NotNull Editor editor, int line) {
|
||||
Document document = editor.getDocument();
|
||||
if (line >= getLineCount(document)) {
|
||||
int y = lineToY(editor, getLineCount(document) - 1);
|
||||
int y = editor.logicalPositionToXY(editor.offsetToLogicalPosition(document.getTextLength())).y;
|
||||
return y + editor.getLineHeight() * (line - getLineCount(document) + 1);
|
||||
}
|
||||
return editor.logicalPositionToXY(editor.offsetToLogicalPosition(document.getLineStartOffset(line))).y;
|
||||
@@ -237,9 +240,12 @@ public class DiffDrawUtil {
|
||||
int x2 = gutter.getWidth();
|
||||
|
||||
int y = r.y;
|
||||
if (placement == SeparatorPlacement.BOTTOM) y += editor.getLineHeight();
|
||||
if (placement == SeparatorPlacement.BOTTOM) {
|
||||
LOG.warn("BOTTOM gutter line renderers are not supported");
|
||||
y += editor.getLineHeight() - 1;
|
||||
}
|
||||
|
||||
drawChunkBorderLine(g2, x1, x2, y - 1, type.getColor(editor), doubleLine, resolved);
|
||||
drawChunkBorderLine(g2, x1, x2, y, type.getColor(editor), doubleLine, resolved);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -323,7 +329,7 @@ public class DiffDrawUtil {
|
||||
@NotNull
|
||||
public static List<RangeHighlighter> createLineMarker(@NotNull final Editor editor, int line, @NotNull final TextDiffType type) {
|
||||
if (line == 0) return Collections.emptyList();
|
||||
return new LineMarkerBuilder(editor, line - 1, SeparatorPlacement.BOTTOM)
|
||||
return new LineMarkerBuilder(editor, line, SeparatorPlacement.TOP)
|
||||
.withType(type)
|
||||
.withDefaultRenderer(false)
|
||||
.withDefaultGutterRenderer(false)
|
||||
|
||||
|
After Width: | Height: | Size: 356 B |
BIN
platform/diff-impl/tests/testData/diff/painting/emptyRange.png
Normal file
|
After Width: | Height: | Size: 295 B |
|
After Width: | Height: | Size: 183 B |
|
After Width: | Height: | Size: 343 B |
|
After Width: | Height: | Size: 235 B |
|
After Width: | Height: | Size: 259 B |
|
After Width: | Height: | Size: 303 B |
BIN
platform/diff-impl/tests/testData/diff/painting/lineMarker.png
Normal file
|
After Width: | Height: | Size: 353 B |
|
After Width: | Height: | Size: 249 B |
|
After Width: | Height: | Size: 175 B |
|
After Width: | Height: | Size: 165 B |