mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
Generated
+3
-3
@@ -1,9 +1,9 @@
|
||||
<component name="libraryTable">
|
||||
<library name="cucumber-java">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/cucumber-core-1.2.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/cucumber-java-1.2.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/cucumber-java8-1.2.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/cucumber-core-1.2.4.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/cucumber-java-1.2.4.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/cucumber-java8-1.2.4.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
Generated
+1
-1
@@ -1,7 +1,7 @@
|
||||
<component name="libraryTable">
|
||||
<library name="cucumber-jvm">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/cucumber-core-1.2.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/cucumber-core-1.2.4.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/cucumber-jvm-deps-1.0.3.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/gherkin-2.12.2.jar!/" />
|
||||
</CLASSES>
|
||||
|
||||
@@ -1409,6 +1409,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public SuspendManager getSuspendManager() {
|
||||
return mySuspendManager;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,7 @@ import com.intellij.debugger.settings.NodeRendererSettings;
|
||||
import com.intellij.debugger.ui.impl.watch.*;
|
||||
import com.intellij.debugger.ui.tree.render.ClassRenderer;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.xdebugger.frame.*;
|
||||
import com.sun.jdi.Field;
|
||||
import com.sun.jdi.ReferenceType;
|
||||
@@ -50,8 +51,17 @@ public class JavaStaticGroup extends XValueGroup implements NodeDescriptorProvid
|
||||
@Nullable
|
||||
@Override
|
||||
public String getComment() {
|
||||
final ClassRenderer classRenderer = NodeRendererSettings.getInstance().getClassRenderer();
|
||||
return classRenderer.renderTypeName(myStaticDescriptor.getType().name());
|
||||
String res = NodeRendererSettings.getInstance().getClassRenderer().renderTypeName(myStaticDescriptor.getType().name());
|
||||
if (!StringUtil.isEmpty(res)) {
|
||||
return " members of " + res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getSeparator() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -111,10 +111,6 @@ public class DebuggerSession implements AbstractDebuggerSession {
|
||||
mySteppingThroughThread.set(threadProxy);
|
||||
}
|
||||
|
||||
void unsetSteppingThrough(ThreadReferenceProxyImpl threadProxy) {
|
||||
mySteppingThroughThread.compareAndSet(threadProxy, null);
|
||||
}
|
||||
|
||||
void clearSteppingThrough() {
|
||||
mySteppingThroughThread.set(null);
|
||||
}
|
||||
@@ -346,12 +342,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
|
||||
public void resume() {
|
||||
final SuspendContextImpl suspendContext = getSuspendContext();
|
||||
if(suspendContext != null) {
|
||||
if (suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_ALL) {
|
||||
clearSteppingThrough();
|
||||
}
|
||||
else {
|
||||
unsetSteppingThrough(suspendContext.getThread());
|
||||
}
|
||||
clearSteppingThrough();
|
||||
resetIgnoreStepFiltersFlag();
|
||||
resumeAction(myDebugProcess.createResumeCommand(suspendContext), Event.RESUME);
|
||||
}
|
||||
@@ -519,7 +510,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
|
||||
return;
|
||||
}
|
||||
|
||||
clearSteppingThrough();
|
||||
setSteppingThrough(suspendContext.getThread());
|
||||
|
||||
ThreadReferenceProxyImpl currentThread = suspendContext.getThread();
|
||||
final StackFrameContext positionContext;
|
||||
@@ -647,7 +638,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
|
||||
}
|
||||
final SuspendContextImpl currentSuspendContext = getContextManager().getContext().getSuspendContext();
|
||||
if (currentSuspendContext == null) {
|
||||
return true;
|
||||
return mySteppingThroughThread.get() == null;
|
||||
}
|
||||
if (enableBreakpointsDuringEvaluation()) {
|
||||
final ThreadReferenceProxyImpl currentThread = currentSuspendContext.getThread();
|
||||
@@ -658,10 +649,13 @@ public class DebuggerSession implements AbstractDebuggerSession {
|
||||
|
||||
|
||||
@Override
|
||||
public void resumed(final SuspendContextImpl suspendContext) {
|
||||
public void resumed(SuspendContextImpl suspendContext) {
|
||||
SuspendManager suspendManager = getProcess().getSuspendManager();
|
||||
SuspendContextImpl context = suspendManager.getPausedContext();
|
||||
if (context != null && suspendContext != null && isSteppingThrough(suspendContext.getThread())) {
|
||||
// single thread stepping
|
||||
if (suspendContext != null
|
||||
&& suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD
|
||||
&& isSteppingThrough(suspendContext.getThread())) {
|
||||
context = suspendManager.pushSuspendContext(suspendContext.getSuspendPolicy(), 0);
|
||||
context.setThread(suspendContext.getThread().getThreadReference());
|
||||
}
|
||||
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.roots.ui.configuration;
|
||||
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Jan 14, 2004
|
||||
*/
|
||||
public class LibrariesAlphaComparator implements Comparator<Library> {
|
||||
public static LibrariesAlphaComparator INSTANCE = new LibrariesAlphaComparator();
|
||||
|
||||
@Override
|
||||
public int compare(Library library1, Library library2) {
|
||||
String name1 = library1.getName();
|
||||
if (name1 != null && name1.length() == 0) {
|
||||
name1 = null;
|
||||
}
|
||||
String name2 = library2.getName();
|
||||
if (name2 != null && name2.length() == 0) {
|
||||
name2 = null;
|
||||
}
|
||||
if (name1 == null && name2 == null) {
|
||||
final VirtualFile[] files1 = library1.getFiles(OrderRootType.CLASSES);
|
||||
final VirtualFile[] files2 = library2.getFiles(OrderRootType.CLASSES);
|
||||
name1 = files1.length > 0? files1[0].getName() : null;
|
||||
name2 = files2.length > 0? files2[0].getName() : null;
|
||||
}
|
||||
return compareNames(name1, name2);
|
||||
}
|
||||
|
||||
public int compareNames(String name1, String name2) {
|
||||
if (name1 == null && name2 == null) {
|
||||
return 0;
|
||||
}
|
||||
else if (name1 == null) {
|
||||
return -1;
|
||||
}
|
||||
else if (name2 == null) {
|
||||
return +1;
|
||||
}
|
||||
else {
|
||||
return name1.compareToIgnoreCase(name2);
|
||||
}
|
||||
}
|
||||
}
|
||||
+35
-39
@@ -286,51 +286,47 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change
|
||||
}
|
||||
|
||||
final Ref<ConfigurationException> exceptionRef = Ref.create();
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
for (final ModuleEditor moduleEditor : myModuleEditors.values()) {
|
||||
final ModifiableRootModel model = moduleEditor.apply();
|
||||
if (model != null) {
|
||||
if (!model.isSdkInherited()) {
|
||||
// make sure the sdk is set to original SDK stored in the JDK Table
|
||||
final Sdk modelSdk = model.getSdk();
|
||||
if (modelSdk != null) {
|
||||
final Sdk original = modifiedToOriginalMap.get(modelSdk);
|
||||
if (original != null) {
|
||||
model.setSdk(original);
|
||||
}
|
||||
}
|
||||
try {
|
||||
for (final ModuleEditor moduleEditor : myModuleEditors.values()) {
|
||||
final ModifiableRootModel model = moduleEditor.apply();
|
||||
if (model != null) {
|
||||
if (!model.isSdkInherited()) {
|
||||
// make sure the sdk is set to original SDK stored in the JDK Table
|
||||
final Sdk modelSdk = model.getSdk();
|
||||
if (modelSdk != null) {
|
||||
final Sdk original = modifiedToOriginalMap.get(modelSdk);
|
||||
if (original != null) {
|
||||
model.setSdk(original);
|
||||
}
|
||||
models.add(model);
|
||||
}
|
||||
}
|
||||
myFacetsConfigurator.applyEditors();
|
||||
}
|
||||
catch (ConfigurationException e) {
|
||||
exceptionRef.set(e);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final ModifiableRootModel[] rootModels = models.toArray(new ModifiableRootModel[models.size()]);
|
||||
ModifiableModelCommitter.multiCommit(rootModels, myModuleModel);
|
||||
myModuleModelCommitted = true;
|
||||
myFacetsConfigurator.commitFacets();
|
||||
|
||||
}
|
||||
finally {
|
||||
ModuleStructureConfigurable.getInstance(myProject).getFacetEditorFacade().clearMaps(false);
|
||||
|
||||
myFacetsConfigurator = createFacetsConfigurator();
|
||||
myModuleModel = ModuleManager.getInstance(myProject).getModifiableModel();
|
||||
myModuleModelCommitted = false;
|
||||
models.add(model);
|
||||
}
|
||||
}
|
||||
});
|
||||
myFacetsConfigurator.applyEditors();
|
||||
}
|
||||
catch (ConfigurationException e) {
|
||||
exceptionRef.set(e);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final ModifiableRootModel[] rootModels = models.toArray(new ModifiableRootModel[models.size()]);
|
||||
ModifiableModelCommitter.multiCommit(rootModels, myModuleModel);
|
||||
myModuleModelCommitted = true;
|
||||
myFacetsConfigurator.commitFacets();
|
||||
|
||||
}
|
||||
finally {
|
||||
ModuleStructureConfigurable.getInstance(myProject).getFacetEditorFacade().clearMaps(false);
|
||||
|
||||
myFacetsConfigurator = createFacetsConfigurator();
|
||||
myModuleModel = ModuleManager.getInstance(myProject).getModifiableModel();
|
||||
myModuleModelCommitted = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+27
-33
@@ -25,8 +25,6 @@ import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
|
||||
import com.intellij.openapi.fileChooser.FileChooserFactory;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.DumbModePermission;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectBundle;
|
||||
import com.intellij.openapi.project.ex.ProjectEx;
|
||||
@@ -226,39 +224,35 @@ public class ProjectConfigurable extends ProjectStructureElementConfigurable<Pro
|
||||
throw new ConfigurationException("Please, specify project name!");
|
||||
}
|
||||
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// set the output path first so that handlers of RootsChanged event sent after JDK is set
|
||||
// would see the updated path
|
||||
String canonicalPath = myProjectCompilerOutput.getText();
|
||||
if (canonicalPath != null && canonicalPath.length() > 0) {
|
||||
try {
|
||||
canonicalPath = FileUtil.resolveShortWindowsName(canonicalPath);
|
||||
}
|
||||
catch (IOException e) {
|
||||
//file doesn't exist yet
|
||||
}
|
||||
canonicalPath = FileUtil.toSystemIndependentName(canonicalPath);
|
||||
compilerProjectExtension.setCompilerOutputUrl(VfsUtilCore.pathToUrl(canonicalPath));
|
||||
}
|
||||
else {
|
||||
compilerProjectExtension.setCompilerOutputPointer(null);
|
||||
}
|
||||
|
||||
LanguageLevelProjectExtension extension = LanguageLevelProjectExtension.getInstance(myProject);
|
||||
extension.setLanguageLevel(myLanguageLevelCombo.getSelectedLevel());
|
||||
extension.setDefault(myLanguageLevelCombo.isDefault());
|
||||
myProjectJdkConfigurable.apply();
|
||||
|
||||
if (myProjectName != null) {
|
||||
((ProjectEx)myProject).setProjectName(myProjectName.getText().trim());
|
||||
if (myDetailsComponent != null) myDetailsComponent.setText(getBannerSlogan());
|
||||
}
|
||||
// set the output path first so that handlers of RootsChanged event sent after JDK is set
|
||||
// would see the updated path
|
||||
String canonicalPath = myProjectCompilerOutput.getText();
|
||||
if (canonicalPath != null && canonicalPath.length() > 0) {
|
||||
try {
|
||||
canonicalPath = FileUtil.resolveShortWindowsName(canonicalPath);
|
||||
}
|
||||
});
|
||||
catch (IOException e) {
|
||||
//file doesn't exist yet
|
||||
}
|
||||
canonicalPath = FileUtil.toSystemIndependentName(canonicalPath);
|
||||
compilerProjectExtension.setCompilerOutputUrl(VfsUtilCore.pathToUrl(canonicalPath));
|
||||
}
|
||||
else {
|
||||
compilerProjectExtension.setCompilerOutputPointer(null);
|
||||
}
|
||||
|
||||
LanguageLevelProjectExtension extension = LanguageLevelProjectExtension.getInstance(myProject);
|
||||
extension.setLanguageLevel(myLanguageLevelCombo.getSelectedLevel());
|
||||
extension.setDefault(myLanguageLevelCombo.isDefault());
|
||||
myProjectJdkConfigurable.apply();
|
||||
|
||||
if (myProjectName != null) {
|
||||
((ProjectEx)myProject).setProjectName(myProjectName.getText().trim());
|
||||
if (myDetailsComponent != null) myDetailsComponent.setText(getBannerSlogan());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+1
-6
@@ -155,12 +155,7 @@ public class ProjectJdkConfigurable implements UnnamedConfigurable {
|
||||
|
||||
@Override
|
||||
public void apply() {
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ProjectRootManager.getInstance(myProject).setProjectSdk(getSelectedProjectJdk());
|
||||
}
|
||||
});
|
||||
ProjectRootManager.getInstance(myProject).setProjectSdk(getSelectedProjectJdk());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+17
-23
@@ -25,8 +25,6 @@ package com.intellij.openapi.roots.ui.configuration;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.DumbModePermission;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectBundle;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
@@ -119,29 +117,25 @@ public class ProjectJdksConfigurable extends MasterDetailsComponent {
|
||||
@Override
|
||||
public void apply() throws ConfigurationException {
|
||||
final Ref<ConfigurationException> exceptionRef = Ref.create();
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
ProjectJdksConfigurable.super.apply();
|
||||
boolean modifiedJdks = false;
|
||||
for (int i = 0; i < myRoot.getChildCount(); i++) {
|
||||
final NamedConfigurable configurable = ((MyNode)myRoot.getChildAt(i)).getConfigurable();
|
||||
if (configurable.isModified()) {
|
||||
configurable.apply();
|
||||
modifiedJdks = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (myProjectJdksModel.isModified() || modifiedJdks) {
|
||||
myProjectJdksModel.apply(ProjectJdksConfigurable.this);
|
||||
}
|
||||
myProjectJdksModel.setProjectSdk(getSelectedJdk());
|
||||
}
|
||||
catch (ConfigurationException e) {
|
||||
exceptionRef.set(e);
|
||||
try {
|
||||
ProjectJdksConfigurable.super.apply();
|
||||
boolean modifiedJdks = false;
|
||||
for (int i = 0; i < myRoot.getChildCount(); i++) {
|
||||
final NamedConfigurable configurable = ((MyNode)myRoot.getChildAt(i)).getConfigurable();
|
||||
if (configurable.isModified()) {
|
||||
configurable.apply();
|
||||
modifiedJdks = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (myProjectJdksModel.isModified() || modifiedJdks) {
|
||||
myProjectJdksModel.apply(ProjectJdksConfigurable.this);
|
||||
}
|
||||
myProjectJdksModel.setProjectSdk(getSelectedJdk());
|
||||
}
|
||||
catch (ConfigurationException e) {
|
||||
exceptionRef.set(e);
|
||||
}
|
||||
if (!exceptionRef.isNull()) {
|
||||
throw exceptionRef.get();
|
||||
}
|
||||
|
||||
+8
-13
@@ -336,21 +336,16 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se
|
||||
}
|
||||
}
|
||||
final Ref<ConfigurationException> exceptionRef = Ref.create();
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
for (Configurable each : myName2Config) {
|
||||
if (each.isModified()) {
|
||||
each.apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ConfigurationException e) {
|
||||
exceptionRef.set(e);
|
||||
try {
|
||||
for (Configurable each : myName2Config) {
|
||||
if (each.isModified()) {
|
||||
each.apply();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (ConfigurationException e) {
|
||||
exceptionRef.set(e);
|
||||
}
|
||||
|
||||
if (!exceptionRef.isNull()) {
|
||||
throw exceptionRef.get();
|
||||
|
||||
+11
-16
@@ -296,23 +296,18 @@ public class ArtifactsStructureConfigurable extends BaseStructureConfigurable {
|
||||
checkForEmptyAndDuplicatedNames("Artifact", CommonBundle.getErrorTitle(), ArtifactConfigurableBase.class);
|
||||
super.apply();
|
||||
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myPackagingEditorContext.getManifestFilesInfo().saveManifestFiles();
|
||||
final ModifiableArtifactModel modifiableModel = myPackagingEditorContext.getActualModifiableModel();
|
||||
if (modifiableModel != null) {
|
||||
new WriteAction() {
|
||||
@Override
|
||||
protected void run(@NotNull final Result result) {
|
||||
modifiableModel.commit();
|
||||
}
|
||||
}.execute();
|
||||
myPackagingEditorContext.resetModifiableModel();
|
||||
myPackagingEditorContext.getManifestFilesInfo().saveManifestFiles();
|
||||
final ModifiableArtifactModel modifiableModel = myPackagingEditorContext.getActualModifiableModel();
|
||||
if (modifiableModel != null) {
|
||||
new WriteAction() {
|
||||
@Override
|
||||
protected void run(@NotNull final Result result) {
|
||||
modifiableModel.commit();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}.execute();
|
||||
myPackagingEditorContext.resetModifiableModel();
|
||||
}
|
||||
|
||||
|
||||
reset(); // TODO: fix to not reset on apply!
|
||||
}
|
||||
|
||||
+5
@@ -820,6 +820,11 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canStartInBackground() {
|
||||
return false;
|
||||
}
|
||||
}.analyze();
|
||||
}
|
||||
|
||||
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.roots.ui.configuration.packaging;
|
||||
|
||||
import com.intellij.openapi.project.ProjectBundle;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.packaging.impl.ui.LibraryElementPresentation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class PackagingEditorUtil {
|
||||
private PackagingEditorUtil() {
|
||||
}
|
||||
|
||||
public static String getLibraryItemText(final @NotNull Library library, final boolean includeTableName) {
|
||||
String name = library.getName();
|
||||
VirtualFile[] files = library.getFiles(OrderRootType.CLASSES);
|
||||
if (name != null) {
|
||||
return name + (includeTableName ? LibraryElementPresentation.getLibraryTableComment(library) : "");
|
||||
}
|
||||
else if (files.length > 0) {
|
||||
return files[0].getName() + (includeTableName ? LibraryElementPresentation.getLibraryTableComment(library) : "");
|
||||
}
|
||||
else {
|
||||
return ProjectBundle.message("library.empty.item");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+6
-2
@@ -99,8 +99,12 @@ public class JavaPsiClassReferenceElement extends LookupItem<Object> implements
|
||||
return psiClass;
|
||||
}
|
||||
|
||||
final PsiClass retrieve = (PsiClass)((PsiAnchor)myClass).retrieve();
|
||||
assert retrieve != null : myQualifiedName;
|
||||
PsiAnchor anchor = (PsiAnchor)myClass;
|
||||
final PsiClass retrieve = (PsiClass)anchor.retrieve();
|
||||
if (retrieve == null) {
|
||||
throw new AssertionError(myQualifiedName + "; anchor=" + anchor + "; diagnostics=" +
|
||||
(anchor instanceof PsiAnchor.StubIndexReference ? ((PsiAnchor.StubIndexReference)anchor).diagnoseNull() : null));
|
||||
}
|
||||
myCache = new WeakReference<PsiClass>(retrieve);
|
||||
return retrieve;
|
||||
}
|
||||
|
||||
+18
-12
@@ -27,11 +27,11 @@ import com.intellij.patterns.PsiJavaPatterns;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.filters.ElementExtractorFilter;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
import com.intellij.psi.filters.GeneratorFilter;
|
||||
import com.intellij.psi.filters.OrFilter;
|
||||
import com.intellij.psi.filters.getters.*;
|
||||
import com.intellij.psi.filters.getters.ExpectedTypesGetter;
|
||||
import com.intellij.psi.filters.getters.InstanceOfLeftPartTypeGetter;
|
||||
import com.intellij.psi.filters.getters.JavaMembersGetter;
|
||||
import com.intellij.psi.filters.types.AssignableFromFilter;
|
||||
import com.intellij.psi.filters.types.AssignableGroupFilter;
|
||||
import com.intellij.psi.filters.types.AssignableToFilter;
|
||||
import com.intellij.psi.impl.source.PsiLabelReference;
|
||||
import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference;
|
||||
@@ -77,9 +77,6 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
psiElement().afterLeaf(
|
||||
psiElement().withText(PsiKeyword.THROW))));
|
||||
static final ElementPattern<PsiElement> AFTER_THROW_NEW = psiElement().afterLeaf(psiElement().withText(PsiKeyword.NEW).afterLeaf(PsiKeyword.THROW));
|
||||
private static final OrFilter THROWABLE_TYPE_FILTER = new OrFilter(
|
||||
new GeneratorFilter(AssignableGroupFilter.class, new ThrowsListGetter()),
|
||||
new AssignableFromFilter(CommonClassNames.JAVA_LANG_THROWABLE));
|
||||
public static final ElementPattern<PsiElement> INSIDE_EXPRESSION = or(
|
||||
psiElement().withParent(PsiExpression.class).andNot(psiElement().withParent(PsiLiteralExpression.class)).andNot(psiElement().withParent(PsiMethodReferenceExpression.class)),
|
||||
psiElement().inside(PsiClassObjectAccessExpression.class),
|
||||
@@ -113,13 +110,19 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
private static ElementFilter getReferenceFilter(PsiElement element) {
|
||||
//throw new foo
|
||||
if (AFTER_THROW_NEW.accepts(element)) {
|
||||
return new ElementExtractorFilter(THROWABLE_TYPE_FILTER);
|
||||
return THROWABLES_FILTER;
|
||||
}
|
||||
|
||||
//new xxx.yyy
|
||||
if (psiElement().afterLeaf(psiElement().withText(".")).withSuperParent(2, psiElement(PsiNewExpression.class)).accepts(element)) {
|
||||
if (((PsiNewExpression)element.getParent().getParent()).getClassReference() == element.getParent()) {
|
||||
return new GeneratorFilter(AssignableGroupFilter.class, new ExpectedTypesGetter());
|
||||
PsiType[] types = ExpectedTypesGetter.getExpectedTypes(element, false);
|
||||
return new OrFilter(ContainerUtil.map2Array(types, ElementFilter.class, new Function<PsiType, ElementFilter>() {
|
||||
@Override
|
||||
public ElementFilter fun(PsiType type) {
|
||||
return new AssignableFromFilter(type);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +180,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
final PsiElement element = parameters.getPosition();
|
||||
final PsiReference reference = element.getContainingFile().findReferenceAt(parameters.getOffset());
|
||||
if (reference != null) {
|
||||
final ElementFilter filter = getReferenceFilter(element);
|
||||
ElementFilter filter = getReferenceFilter(element);
|
||||
if (filter != null) {
|
||||
final List<ExpectedTypeInfo> infos = Arrays.asList(getExpectedTypes(parameters));
|
||||
for (final LookupElement item : completeReference(element, reference, filter, true, false, parameters, result.getPrefixMatcher())) {
|
||||
@@ -187,9 +190,12 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
}
|
||||
else if (INSIDE_TYPECAST_EXPRESSION.accepts(element)) {
|
||||
for (final LookupElement item : completeReference(element, reference, new GeneratorFilter(AssignableToFilter.class, new CastTypeGetter()), false, true, parameters,
|
||||
result.getPrefixMatcher())) {
|
||||
result.addElement(item);
|
||||
final PsiTypeCastExpression cast = PsiTreeUtil.getContextOfType(element, PsiTypeCastExpression.class, true);
|
||||
if (cast != null && cast.getCastType() != null) {
|
||||
filter = new AssignableToFilter(cast.getCastType().getType());
|
||||
for (final LookupElement item : completeReference(element, reference, filter, false, true, parameters, result.getPrefixMatcher())) {
|
||||
result.addElement(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ public class MarkerType {
|
||||
boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);
|
||||
boolean isSuperAbstract = superMethod.hasModifierProperty(PsiModifier.ABSTRACT);
|
||||
|
||||
String postfix = MessageFormat.format(" via sub-class <a href=\"#javaClass/{0}\">{0}</a>", ClassPresentationUtil.getNameForClass(subClass, false));
|
||||
String postfix = MessageFormat.format(" via sub-class <a href=\"#javaClass/{0}\">{0}</a>", ClassPresentationUtil.getNameForClass(subClass, true));
|
||||
@NonNls String pattern = DaemonBundle.message(isSuperAbstract && !isAbstract ?
|
||||
"method.implements" :
|
||||
"method.overrides") + postfix;
|
||||
|
||||
@@ -102,11 +102,11 @@ public class JavaGotoSuperHandler implements PresentableCodeInsightActionHandler
|
||||
final PsiElement containingElement = PsiTreeUtil.getParentOfType(element, PsiFunctionalExpression.class, PsiMember.class);
|
||||
if (containingElement instanceof PsiClass) {
|
||||
presentation.setText(ActionsBundle.actionText("GotoSuperClass"));
|
||||
presentation.setDescription(ActionsBundle.actionText("GotoSuperClass"));
|
||||
presentation.setDescription(ActionsBundle.actionDescription("GotoSuperClass"));
|
||||
}
|
||||
else {
|
||||
presentation.setText(ActionsBundle.actionText("GotoSuperMethod"));
|
||||
presentation.setDescription(ActionsBundle.actionText("GotoSuperMethod"));
|
||||
presentation.setDescription(ActionsBundle.actionDescription("GotoSuperMethod"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.filters;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: ik
|
||||
* Date: 20.03.2003
|
||||
* Time: 19:55:15
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public class GeneratorFilter implements ElementFilter{
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.filters.GeneratorFilter");
|
||||
private final ContextGetter myGetter;
|
||||
private final Class myFilterClass;
|
||||
|
||||
public GeneratorFilter(Class filterClass, ContextGetter getter){
|
||||
myFilterClass = filterClass;
|
||||
myGetter = getter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClassAcceptable(Class hintClass){
|
||||
final ElementFilter filter = getFilter();
|
||||
return filter == null || filter.isClassAcceptable(hintClass);
|
||||
}
|
||||
|
||||
|
||||
private SoftReference<PsiElement> myCachedElement = new SoftReference<PsiElement>(null);
|
||||
private SoftReference<ElementFilter> myCachedFilter = new SoftReference<ElementFilter>(null);
|
||||
|
||||
private ElementFilter getFilter(){
|
||||
return myCachedFilter.get();
|
||||
}
|
||||
|
||||
private ElementFilter getFilter(PsiElement context){
|
||||
ElementFilter filter = myCachedFilter.get();
|
||||
if(myCachedElement.get() != context || filter == null){
|
||||
filter = generateFilter(context);
|
||||
myCachedFilter = new SoftReference<ElementFilter>(filter);
|
||||
myCachedElement = new SoftReference<PsiElement>(context);
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAcceptable(Object element, PsiElement context){
|
||||
if(element == null) return false;
|
||||
final ElementFilter filter = getFilter(context);
|
||||
return filter != null && filter.isAcceptable(element, context);
|
||||
}
|
||||
|
||||
private ElementFilter generateFilter(PsiElement context){
|
||||
try{
|
||||
final ElementFilter elementFilter = (ElementFilter) myFilterClass.newInstance();
|
||||
final Object[] initArgument = myGetter.get(context, null);
|
||||
if(ReflectionUtil.isAssignable(InitializableFilter.class, myFilterClass) && initArgument != null){
|
||||
((InitializableFilter)elementFilter).init(initArgument);
|
||||
return elementFilter;
|
||||
}
|
||||
else{
|
||||
LOG.error("Filter initialization failed!");
|
||||
}
|
||||
}
|
||||
catch(InstantiationException e){
|
||||
LOG.error(e);
|
||||
}
|
||||
catch(IllegalAccessException e){
|
||||
LOG.error(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,7 +17,6 @@ package com.intellij.psi.filters;
|
||||
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
/**
|
||||
@@ -29,14 +28,6 @@ import org.jetbrains.annotations.NonNls;
|
||||
*/
|
||||
public class TextFilter extends PlainTextFilter {
|
||||
|
||||
public TextFilter(){
|
||||
myValue = ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
}
|
||||
|
||||
public TextFilter(@NonNls String value, boolean insensitiveFlag) {
|
||||
super(value, insensitiveFlag);
|
||||
}
|
||||
|
||||
public TextFilter(@NonNls String value){
|
||||
super(value);
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.filters.types;
|
||||
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiSubstitutor;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.filters.FalseFilter;
|
||||
import com.intellij.psi.filters.InitializableFilter;
|
||||
import com.intellij.psi.filters.OrFilter;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: ik
|
||||
* Date: 20.03.2003
|
||||
* Time: 21:27:25
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public class AssignableGroupFilter extends OrFilter implements InitializableFilter{
|
||||
|
||||
@Override
|
||||
public void init(Object[] classes){
|
||||
for (Object aClass : classes) {
|
||||
if (aClass instanceof PsiClass) {
|
||||
final PsiClass psiClass = (PsiClass)aClass;
|
||||
PsiType type = JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory().createType(psiClass, PsiSubstitutor.EMPTY);
|
||||
addFilter(new AssignableFromFilter(type));
|
||||
}
|
||||
if (aClass instanceof PsiType) {
|
||||
addFilter(new AssignableFromFilter((PsiType)aClass));
|
||||
}
|
||||
}
|
||||
addFilter(new FalseFilter());
|
||||
}
|
||||
}
|
||||
@@ -15,15 +15,13 @@
|
||||
*/
|
||||
package com.intellij.psi.filters.types;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiSubstitutor;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
import com.intellij.psi.filters.FilterUtil;
|
||||
import com.intellij.psi.filters.InitializableFilter;
|
||||
import com.intellij.psi.filters.OrFilter;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
@@ -32,36 +30,13 @@ import java.util.List;
|
||||
* Time: 20:53:38
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public class AssignableToFilter implements InitializableFilter{
|
||||
private PsiType myType = null;
|
||||
private ElementFilter myFilter = null;
|
||||
public class AssignableToFilter implements ElementFilter {
|
||||
private final PsiType myType;
|
||||
|
||||
public AssignableToFilter(PsiType type){
|
||||
public AssignableToFilter(@NotNull PsiType type){
|
||||
myType = type;
|
||||
}
|
||||
|
||||
public AssignableToFilter(){}
|
||||
|
||||
@Override
|
||||
public void init(Object[] type){
|
||||
myFilter = new OrFilter();
|
||||
final List<ElementFilter> filters = new ArrayList<ElementFilter>();
|
||||
for (final Object o : type) {
|
||||
PsiType currentType = null;
|
||||
if (o instanceof PsiType) {
|
||||
currentType = (PsiType)o;
|
||||
}
|
||||
else if (o instanceof PsiClass) {
|
||||
final PsiClass psiClass = (PsiClass)o;
|
||||
currentType = JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory().createType(psiClass);
|
||||
}
|
||||
if (currentType != null) {
|
||||
filters.add(new AssignableToFilter(currentType));
|
||||
}
|
||||
}
|
||||
myFilter = new OrFilter(filters.toArray(new ElementFilter[filters.size()]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClassAcceptable(Class hintClass){
|
||||
return true;
|
||||
@@ -69,31 +44,21 @@ public class AssignableToFilter implements InitializableFilter{
|
||||
|
||||
@Override
|
||||
public boolean isAcceptable(Object element, PsiElement context){
|
||||
if(myType != null){
|
||||
if(element == null) return false;
|
||||
if (element instanceof PsiType) return myType.isAssignableFrom((PsiType) element);
|
||||
PsiSubstitutor substitutor = null;
|
||||
if(element instanceof CandidateInfo){
|
||||
final CandidateInfo info = (CandidateInfo)element;
|
||||
substitutor = info.getSubstitutor();
|
||||
element = info.getElement();
|
||||
}
|
||||
if(element == null) return false;
|
||||
if (element instanceof PsiType) return myType.isAssignableFrom((PsiType) element);
|
||||
PsiSubstitutor substitutor = null;
|
||||
if(element instanceof CandidateInfo){
|
||||
final CandidateInfo info = (CandidateInfo)element;
|
||||
substitutor = info.getSubstitutor();
|
||||
element = info.getElement();
|
||||
}
|
||||
|
||||
PsiType typeByElement = FilterUtil.getTypeByElement((PsiElement)element, context);
|
||||
if(substitutor != null) typeByElement = substitutor.substitute(typeByElement);
|
||||
return typeByElement != null && typeByElement.isAssignableFrom(myType) && !typeByElement.equals(myType);
|
||||
}
|
||||
else if(myFilter != null){
|
||||
if(element == null) return false;
|
||||
return myFilter.isAcceptable(element, context);
|
||||
}
|
||||
else return false;
|
||||
PsiType typeByElement = FilterUtil.getTypeByElement((PsiElement)element, context);
|
||||
if(substitutor != null) typeByElement = substitutor.substitute(typeByElement);
|
||||
return typeByElement != null && typeByElement.isAssignableFrom(myType) && !typeByElement.equals(myType);
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
if(myType != null)
|
||||
return "assignable-to(" + myType + ")";
|
||||
else if(myFilter != null) return myFilter.toString();
|
||||
return "uninitialized-equals-filter";
|
||||
return "assignable-to(" + myType + ")";
|
||||
}
|
||||
}
|
||||
|
||||
+3
-4
@@ -24,22 +24,21 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
|
||||
import com.intellij.psi.formatter.java.SyntheticCodeBlock;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.psi.formatter.java.AbstractJavaBlock.*;
|
||||
import static com.intellij.psi.formatter.java.AbstractJavaBlock.newJavaBlock;
|
||||
|
||||
public class SyntheticBlockBuilder {
|
||||
public class CallChunkBlockBuilder {
|
||||
|
||||
private final CommonCodeStyleSettings mySettings;
|
||||
private final CommonCodeStyleSettings.IndentOptions myIndentSettings;
|
||||
private final JavaCodeStyleSettings myJavaSettings;
|
||||
|
||||
public SyntheticBlockBuilder(@NotNull CommonCodeStyleSettings settings, @NotNull JavaCodeStyleSettings javaSettings) {
|
||||
public CallChunkBlockBuilder(@NotNull CommonCodeStyleSettings settings, @NotNull JavaCodeStyleSettings javaSettings) {
|
||||
mySettings = settings;
|
||||
myIndentSettings = settings.getIndentOptions();
|
||||
myJavaSettings = javaSettings;
|
||||
+12
-3
@@ -21,6 +21,7 @@ import com.intellij.formatting.Indent;
|
||||
import com.intellij.formatting.Wrap;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiComment;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
@@ -74,7 +75,7 @@ class ChainMethodCallsBlockBuilder {
|
||||
|
||||
for (int i = 0; i < methodCall.size(); i++) {
|
||||
ChainedCallChunk currentCallChunk = methodCall.get(i);
|
||||
if (isMethodCall(currentCallChunk)) {
|
||||
if (isMethodCall(currentCallChunk) || isComment(currentCallChunk)) {
|
||||
if (myWrap == null)
|
||||
myWrap = createCallChunkWrap(i, methodCall);
|
||||
if (myChainedCallsAlignment == null)
|
||||
@@ -85,13 +86,21 @@ class ChainMethodCallsBlockBuilder {
|
||||
myChainedCallsAlignment = null;
|
||||
}
|
||||
|
||||
SyntheticBlockBuilder builder = new SyntheticBlockBuilder(mySettings, myJavaSettings);
|
||||
CallChunkBlockBuilder builder = new CallChunkBlockBuilder(mySettings, myJavaSettings);
|
||||
blocks.add(builder.create(currentCallChunk.nodes, myWrap, myChainedCallsAlignment));
|
||||
}
|
||||
|
||||
return blocks;
|
||||
}
|
||||
|
||||
private static boolean isComment(ChainedCallChunk chunk) {
|
||||
List<ASTNode> nodes = chunk.nodes;
|
||||
if (nodes.size() == 1) {
|
||||
return nodes.get(0).getPsi() instanceof PsiComment;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Wrap createCallChunkWrap(int chunkIndex, @NotNull List<ChainedCallChunk> methodCall) {
|
||||
if (mySettings.WRAP_FIRST_METHOD_IN_CALL_CHAIN) {
|
||||
ChainedCallChunk next = chunkIndex + 1 < methodCall.size() ? methodCall.get(chunkIndex + 1) : null;
|
||||
@@ -119,7 +128,7 @@ class ChainMethodCallsBlockBuilder {
|
||||
|
||||
List<ASTNode> current = new ArrayList<ASTNode>();
|
||||
for (ASTNode node : nodes) {
|
||||
if (node.getElementType() == JavaTokenType.DOT) {
|
||||
if (node.getElementType() == JavaTokenType.DOT || node.getPsi() instanceof PsiComment) {
|
||||
result.add(new ChainedCallChunk(current));
|
||||
current = new ArrayList<ASTNode>();
|
||||
}
|
||||
|
||||
@@ -140,7 +140,12 @@ public class SyntheticCodeBlock implements Block, JavaBlock{
|
||||
if (myChildAttributes != null) {
|
||||
return myChildAttributes;
|
||||
} else {
|
||||
return new ChildAttributes(getIndent(), null);
|
||||
Alignment alignment = null;
|
||||
if (mySubBlocks.size() > newChildIndex) {
|
||||
Block block = mySubBlocks.get(newChildIndex);
|
||||
alignment = block.getAlignment();
|
||||
}
|
||||
return new ChildAttributes(getIndent(), alignment);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -343,6 +343,12 @@ public class InlineUtil {
|
||||
PsiElement resolved = resolveResult.getElement();
|
||||
if (resolved instanceof PsiTypeParameter) {
|
||||
PsiType newType = resolveResult.getSubstitutor().putAll(substitutor).substitute((PsiTypeParameter)resolved);
|
||||
if (newType instanceof PsiCapturedWildcardType) {
|
||||
newType = ((PsiCapturedWildcardType)newType).getUpperBound();
|
||||
}
|
||||
if (newType instanceof PsiWildcardType) {
|
||||
newType = ((PsiWildcardType)newType).getBound();
|
||||
}
|
||||
if (newType == null) {
|
||||
newType = PsiType.getJavaLangObject(resolved.getManager(), resolved.getResolveScope());
|
||||
}
|
||||
|
||||
@@ -64,7 +64,8 @@ public class PsiCapturedWildcardType extends PsiType.Stub {
|
||||
}
|
||||
|
||||
final PsiCapturedWildcardType captured = (PsiCapturedWildcardType)o;
|
||||
if (!myContext.equals(captured.myContext)) {
|
||||
final PsiManager manager = myContext.getManager();
|
||||
if (!manager.areElementsEquivalent(myContext, captured.myContext)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -72,7 +73,8 @@ public class PsiCapturedWildcardType extends PsiType.Stub {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((myContext instanceof PsiReferenceExpression || myContext instanceof PsiMethodCallExpression) && !Comparing.equal(myParameter, captured.myParameter)) {
|
||||
if ((myContext instanceof PsiReferenceExpression || myContext instanceof PsiMethodCallExpression) &&
|
||||
!manager.areElementsEquivalent(myParameter, captured.myParameter)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,16 @@
|
||||
interface Pair<A extends String> {
|
||||
A get();
|
||||
}
|
||||
|
||||
class B {
|
||||
<V extends String> void f(Pair<V> p) {
|
||||
V v = p.get();
|
||||
}
|
||||
|
||||
{
|
||||
Pair<?> p = null;
|
||||
<caret>f(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
interface Pair<A extends String> {
|
||||
A get();
|
||||
}
|
||||
|
||||
class B {
|
||||
|
||||
{
|
||||
Pair<?> p = null;
|
||||
String v = p.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,13 +15,33 @@
|
||||
*/
|
||||
package com.intellij.codeInsight;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.impl.source.PsiFileImpl;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
|
||||
public class ClsGenerics18HighlightingTest extends ClsGenericsHighlightingTest {
|
||||
public void testIDEA121866() { doTest(); }
|
||||
|
||||
public void testIDEA127714() { doTest(); }
|
||||
|
||||
public void testCaptureContext() {
|
||||
String name = getTestName(false);
|
||||
addLibrary(name + ".jar", name + "-sources.jar");
|
||||
Project project = myFixture.getProject();
|
||||
PsiClass aClass = JavaPsiFacade.getInstance(project).findClass("a.Pair", GlobalSearchScope.allScope(project));
|
||||
assertNotNull(aClass);
|
||||
PsiFile containingFile = aClass.getContainingFile();
|
||||
PsiElement navigationElement = containingFile.getNavigationElement();
|
||||
assertInstanceOf(navigationElement, PsiFileImpl.class);
|
||||
myFixture.openFileInEditor(((PsiFile)navigationElement).getVirtualFile());
|
||||
myFixture.checkHighlighting();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LanguageLevel getLanguageLevel() {
|
||||
return LanguageLevel.JDK_1_8;
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.testFramework.IdeaTestCase;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
|
||||
import com.intellij.testFramework.fixtures.*;
|
||||
@@ -36,7 +37,7 @@ import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class ClsGenericsHighlightingTest extends UsefulTestCase {
|
||||
private CodeInsightTestFixture myFixture;
|
||||
protected CodeInsightTestFixture myFixture;
|
||||
private Module myModule;
|
||||
|
||||
@Override
|
||||
@@ -47,6 +48,7 @@ public abstract class ClsGenericsHighlightingTest extends UsefulTestCase {
|
||||
myFixture.setTestDataPath(PathManagerEx.getTestDataPath() + "/codeInsight/clsHighlighting");
|
||||
JavaModuleFixtureBuilder builder = projectBuilder.addModule(JavaModuleFixtureBuilder.class);
|
||||
builder.setLanguageLevel(getLanguageLevel());
|
||||
builder.addJdk(IdeaTestUtil.getMockJdk18Path().getPath());
|
||||
myFixture.setUp();
|
||||
myModule = builder.getFixture().getModule();
|
||||
}
|
||||
@@ -72,7 +74,7 @@ public abstract class ClsGenericsHighlightingTest extends UsefulTestCase {
|
||||
myFixture.checkHighlighting();
|
||||
}
|
||||
|
||||
private void addLibrary(@NotNull final String... libraryPath) {
|
||||
protected void addLibrary(@NotNull final String... libraryPath) {
|
||||
ModuleRootModificationUtil.updateModel(myModule, new Consumer<ModifiableRootModel>() {
|
||||
@Override
|
||||
public void consume(ModifiableRootModel model) {
|
||||
@@ -95,7 +97,8 @@ public abstract class ClsGenericsHighlightingTest extends UsefulTestCase {
|
||||
assertNotNull(libJarLocal);
|
||||
VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(libJarLocal);
|
||||
assertNotNull(jarRoot);
|
||||
libraryModel.addRoot(jarRoot, OrderRootType.CLASSES);
|
||||
libraryModel.addRoot(jarRoot, jarRoot.getName().contains("-sources") ? OrderRootType.SOURCES
|
||||
: OrderRootType.CLASSES);
|
||||
}
|
||||
libraryModel.commit();
|
||||
}
|
||||
|
||||
@@ -15,27 +15,39 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.daemon;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.ShowIntentionsPass;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.ide.highlighter.JavaFileType;
|
||||
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
public class GutterIntentionsTest extends LightPlatformCodeInsightFixtureTestCase {
|
||||
public class GutterIntentionsTest extends LightCodeInsightFixtureTestCase {
|
||||
public void testEmptyIntentions() throws Exception {
|
||||
myFixture.configureByText(JavaFileType.INSTANCE, "class Foo {\n" +
|
||||
" <caret> private String test() {\n" +
|
||||
" return null;\n" +
|
||||
" }");
|
||||
" }" +
|
||||
"}");
|
||||
myFixture.findAllGutters();
|
||||
List<IntentionAction> intentions = myFixture.getAvailableIntentions();
|
||||
assertEmpty(intentions);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isWriteActionRequired() {
|
||||
return false;
|
||||
public void testOptions() throws Exception {
|
||||
myFixture.configureByText(JavaFileType.INSTANCE, "public class Foo {\n" +
|
||||
" public static void <caret>main(String[] args) {}" +
|
||||
"}");
|
||||
assertEquals(1, myFixture.findGuttersAtCaret().size());
|
||||
|
||||
ShowIntentionsPass.IntentionsInfo intentions = new ShowIntentionsPass.IntentionsInfo();
|
||||
ShowIntentionsPass.getActionsToShow(getEditor(), getFile(), intentions, -1);
|
||||
assertEquals(1, intentions.guttersToShow.size());
|
||||
List<IntentionAction> options = intentions.guttersToShow.get(0).getOptions(myFixture.getElementAtCaret(), getEditor());
|
||||
assertNotNull(options);
|
||||
assertNotEmpty(options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.template
|
||||
|
||||
import com.intellij.JavaTestUtil
|
||||
import com.intellij.codeInsight.CodeInsightSettings
|
||||
import com.intellij.codeInsight.lookup.Lookup
|
||||
@@ -36,6 +37,7 @@ import com.intellij.util.ui.UIUtil
|
||||
import org.jetbrains.annotations.NotNull
|
||||
|
||||
import static com.intellij.codeInsight.template.Template.Property.USE_STATIC_IMPORT_IF_POSSIBLE
|
||||
|
||||
/**
|
||||
* @author spleaner
|
||||
*/
|
||||
@@ -288,7 +290,7 @@ class Foo {
|
||||
public void testToar() throws Throwable {
|
||||
configure();
|
||||
startTemplate("toar", "other")
|
||||
state.gotoEnd();
|
||||
state.gotoEnd(false);
|
||||
checkResult();
|
||||
}
|
||||
|
||||
@@ -954,6 +956,39 @@ class Foo {
|
||||
return calculateResult(params, context)
|
||||
}
|
||||
}
|
||||
|
||||
public void "test add new line on enter outside editing variable"() {
|
||||
myFixture.configureByText 'a.java', """
|
||||
class Foo {{
|
||||
<caret>
|
||||
}}
|
||||
"""
|
||||
myFixture.type 'soutv\tabc'
|
||||
myFixture.editor.caretModel.moveCaretRelatively(3, 0, false, false, false)
|
||||
myFixture.type '\n'
|
||||
myFixture.checkResult """
|
||||
class Foo {{
|
||||
System.out.println("true = " + abc);
|
||||
<caret>
|
||||
}}
|
||||
"""
|
||||
}
|
||||
|
||||
public void "test type tab character on tab outside editing variable"() {
|
||||
myFixture.configureByText 'a.java', """
|
||||
class Foo {{
|
||||
<caret>
|
||||
}}
|
||||
"""
|
||||
myFixture.type 'soutv\tabc'
|
||||
myFixture.editor.caretModel.moveCaretRelatively(3, 0, false, false, false)
|
||||
myFixture.type '\t'
|
||||
myFixture.checkResult """
|
||||
class Foo {{
|
||||
System.out.println("true = " + abc); <caret>
|
||||
}}
|
||||
"""
|
||||
}
|
||||
|
||||
public void "test multicaret expanding with space"() {
|
||||
myFixture.configureByText "a.java", """\
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
package com.intellij.psi.formatter.java;
|
||||
|
||||
import com.intellij.codeInsight.AbstractEnterActionTestCase;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -101,4 +103,55 @@ public class JavaEnterActionTest extends AbstractEnterActionTestCase {
|
||||
" \n" +
|
||||
"}");
|
||||
}
|
||||
|
||||
public void testEnter_BetweenChainedMethodCalls() throws IOException {
|
||||
doTextTest("java",
|
||||
"class T {\n" +
|
||||
" public void main() {\n" +
|
||||
" ActionBarPullToRefresh.from(getActivity())\n" +
|
||||
" .theseChildrenArePullable(eventsListView)\n" +
|
||||
" .listener(this)\n" +
|
||||
" .useViewDelegate(StickyListHeadersListView.class, new AbsListViewDelegate())<caret>\n" +
|
||||
" .setup(mPullToRefreshLayout);\n" +
|
||||
" }\n" +
|
||||
"}",
|
||||
"class T {\n" +
|
||||
" public void main() {\n" +
|
||||
" ActionBarPullToRefresh.from(getActivity())\n" +
|
||||
" .theseChildrenArePullable(eventsListView)\n" +
|
||||
" .listener(this)\n" +
|
||||
" .useViewDelegate(StickyListHeadersListView.class, new AbsListViewDelegate())\n" +
|
||||
" <caret>\n" +
|
||||
" .setup(mPullToRefreshLayout);\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
}
|
||||
|
||||
public void testEnter_BetweenAlignedChainedMethodCalls() throws IOException {
|
||||
CodeStyleSettings settings = getCodeStyleSettings();
|
||||
CommonCodeStyleSettings javaCommon = settings.getCommonSettings(JavaLanguage.INSTANCE);
|
||||
javaCommon.ALIGN_MULTILINE_CHAINED_METHODS = true;
|
||||
setCodeStyleSettings(settings);
|
||||
|
||||
doTextTest("java",
|
||||
"class T {\n" +
|
||||
" public void main() {\n" +
|
||||
" ActionBarPullToRefresh.from(getActivity())\n" +
|
||||
" .theseChildrenArePullable(eventsListView)\n" +
|
||||
" .listener(this)\n" +
|
||||
" .useViewDelegate(StickyListHeadersListView.class, new AbsListViewDelegate())<caret>\n" +
|
||||
" .setup(mPullToRefreshLayout);\n" +
|
||||
" }\n" +
|
||||
"}",
|
||||
"class T {\n" +
|
||||
" public void main() {\n" +
|
||||
" ActionBarPullToRefresh.from(getActivity())\n" +
|
||||
" .theseChildrenArePullable(eventsListView)\n" +
|
||||
" .listener(this)\n" +
|
||||
" .useViewDelegate(StickyListHeadersListView.class, new AbsListViewDelegate())\n" +
|
||||
" <caret>\n" +
|
||||
" .setup(mPullToRefreshLayout);\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
}
|
||||
}
|
||||
+44
@@ -768,4 +768,48 @@ public class JavaFormatterAlignmentTest extends AbstractJavaFormatterTest {
|
||||
"}\n"
|
||||
);
|
||||
}
|
||||
|
||||
public void test_AlignComments_BetweenChainedMethodCalls() {
|
||||
getSettings().ALIGN_MULTILINE_CHAINED_METHODS = true;
|
||||
doMethodTest(
|
||||
"ActionBarPullToRefresh.from(getActivity())\n" +
|
||||
" // Mark the ListView as pullable\n" +
|
||||
" .theseChildrenArePullable(eventsListView)\n" +
|
||||
" // Set the OnRefreshListener\n" +
|
||||
" .listener(this)\n" +
|
||||
" // Use the AbsListView delegate for StickyListHeadersListView\n" +
|
||||
" .useViewDelegate(StickyListHeadersListView.class, new AbsListViewDelegate())\n" +
|
||||
" // Finally commit the setup to our PullToRefreshLayout\n" +
|
||||
" .setup(mPullToRefreshLayout);",
|
||||
"ActionBarPullToRefresh.from(getActivity())\n" +
|
||||
" // Mark the ListView as pullable\n" +
|
||||
" .theseChildrenArePullable(eventsListView)\n" +
|
||||
" // Set the OnRefreshListener\n" +
|
||||
" .listener(this)\n" +
|
||||
" // Use the AbsListView delegate for StickyListHeadersListView\n" +
|
||||
" .useViewDelegate(StickyListHeadersListView.class, new AbsListViewDelegate())\n" +
|
||||
" // Finally commit the setup to our PullToRefreshLayout\n" +
|
||||
" .setup(mPullToRefreshLayout);"
|
||||
);
|
||||
}
|
||||
|
||||
public void test_AlignComments_2() {
|
||||
getSettings().ALIGN_MULTILINE_CHAINED_METHODS = true;
|
||||
doClassTest(
|
||||
"public String returnWithBuilder2() {\n" +
|
||||
" return MoreObjects\n" +
|
||||
" .toStringHelper(this)\n" +
|
||||
" .add(\"value\", value)\n" +
|
||||
" // comment\n" +
|
||||
" .toString();\n" +
|
||||
" }",
|
||||
"public String returnWithBuilder2() {\n" +
|
||||
" return MoreObjects\n" +
|
||||
" .toStringHelper(this)\n" +
|
||||
" .add(\"value\", value)\n" +
|
||||
" // comment\n" +
|
||||
" .toString();\n" +
|
||||
"}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,6 +185,10 @@ public class InlineMethodTest extends LightRefactoringTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSubstitutionForWildcards() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testParamNameConflictsWithLocalVar() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@@ -126,25 +126,22 @@ public class RootsChangedTest extends ModuleTestCase {
|
||||
|
||||
public void testEditLibraryForModuleLoadFromXml() throws IOException {
|
||||
final File tempDirectory = createTempDirectory();
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
File moduleFile =
|
||||
PathManagerEx.findFileUnderProjectHome("java/java-tests/testData/moduleRootManager/rootsChanged/emptyModule/a.iml", RootsChangedTest.this.getClass());
|
||||
Module a = loadModule(moduleFile, true);
|
||||
assertEventsCount(1);
|
||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
||||
File moduleFile =
|
||||
PathManagerEx.findFileUnderProjectHome("java/java-tests/testData/moduleRootManager/rootsChanged/emptyModule/a.iml", RootsChangedTest.this.getClass());
|
||||
Module a = loadModule(moduleFile, true);
|
||||
assertEventsCount(1);
|
||||
|
||||
final Sdk jdk = IdeaTestUtil.getMockJdk17();
|
||||
ProjectJdkTable.getInstance().addJdk(jdk);
|
||||
assertEventsCount(0);
|
||||
final Sdk jdk = IdeaTestUtil.getMockJdk17();
|
||||
ProjectJdkTable.getInstance().addJdk(jdk);
|
||||
assertEventsCount(0);
|
||||
|
||||
ModuleRootModificationUtil.setModuleSdk(a, jdk);
|
||||
assertEventsCount(1);
|
||||
ModuleRootModificationUtil.setModuleSdk(a, jdk);
|
||||
assertEventsCount(1);
|
||||
|
||||
final SdkModificator sdkModificator = jdk.getSdkModificator();
|
||||
sdkModificator.addRoot(getVirtualFile(tempDirectory), OrderRootType.CLASSES);
|
||||
sdkModificator.commitChanges();
|
||||
}
|
||||
final SdkModificator sdkModificator = jdk.getSdkModificator();
|
||||
sdkModificator.addRoot(getVirtualFile(tempDirectory), OrderRootType.CLASSES);
|
||||
sdkModificator.commitChanges();
|
||||
});
|
||||
|
||||
assertEventsCount(1);
|
||||
@@ -152,77 +149,71 @@ public class RootsChangedTest extends ModuleTestCase {
|
||||
|
||||
public void testModuleJdkEditing() throws Exception {
|
||||
final File tempDirectory = createTempDirectory();
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Module moduleA = createModule("a.iml");
|
||||
final Module moduleB = createModule("b.iml");
|
||||
assertEventsCount(2);
|
||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
||||
final Module moduleA = createModule("a.iml");
|
||||
final Module moduleB = createModule("b.iml");
|
||||
assertEventsCount(2);
|
||||
|
||||
final Sdk jdk = IdeaTestUtil.getMockJdk17();
|
||||
ProjectJdkTable.getInstance().addJdk(jdk);
|
||||
assertEventsCount(0);
|
||||
final Sdk jdk = IdeaTestUtil.getMockJdk17();
|
||||
ProjectJdkTable.getInstance().addJdk(jdk);
|
||||
assertEventsCount(0);
|
||||
|
||||
final ModifiableRootModel rootModelA = ModuleRootManager.getInstance(moduleA).getModifiableModel();
|
||||
final ModifiableRootModel rootModelB = ModuleRootManager.getInstance(moduleB).getModifiableModel();
|
||||
rootModelA.setSdk(jdk);
|
||||
rootModelB.setSdk(jdk);
|
||||
ModifiableRootModel[] rootModels = new ModifiableRootModel[]{rootModelA, rootModelB};
|
||||
ModifiableModelCommitter.multiCommit(rootModels, ModuleManager.getInstance(rootModels[0].getProject()).getModifiableModel());
|
||||
assertEventsCount(1);
|
||||
final ModifiableRootModel rootModelA = ModuleRootManager.getInstance(moduleA).getModifiableModel();
|
||||
final ModifiableRootModel rootModelB = ModuleRootManager.getInstance(moduleB).getModifiableModel();
|
||||
rootModelA.setSdk(jdk);
|
||||
rootModelB.setSdk(jdk);
|
||||
ModifiableRootModel[] rootModels = new ModifiableRootModel[]{rootModelA, rootModelB};
|
||||
ModifiableModelCommitter.multiCommit(rootModels, ModuleManager.getInstance(rootModels[0].getProject()).getModifiableModel());
|
||||
assertEventsCount(1);
|
||||
|
||||
final SdkModificator sdkModificator = jdk.getSdkModificator();
|
||||
sdkModificator.addRoot(getVirtualFile(tempDirectory), OrderRootType.CLASSES);
|
||||
sdkModificator.commitChanges();
|
||||
assertEventsCount(1);
|
||||
final SdkModificator sdkModificator = jdk.getSdkModificator();
|
||||
sdkModificator.addRoot(getVirtualFile(tempDirectory), OrderRootType.CLASSES);
|
||||
sdkModificator.commitChanges();
|
||||
assertEventsCount(1);
|
||||
|
||||
ProjectJdkTable.getInstance().removeJdk(jdk);
|
||||
assertEventsCount(1);
|
||||
}
|
||||
ProjectJdkTable.getInstance().removeJdk(jdk);
|
||||
assertEventsCount(1);
|
||||
});
|
||||
}
|
||||
|
||||
public void testInheritedJdkEditing() throws Exception {
|
||||
final File tempDirectory = createTempDirectory();
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Module moduleA = createModule("a.iml");
|
||||
final Module moduleB = createModule("b.iml");
|
||||
assertEventsCount(2);
|
||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
||||
final Module moduleA = createModule("a.iml");
|
||||
final Module moduleB = createModule("b.iml");
|
||||
assertEventsCount(2);
|
||||
|
||||
final Sdk jdk = IdeaTestUtil.getMockJdk17("AAA");
|
||||
ProjectJdkTable.getInstance().addJdk(jdk);
|
||||
assertEventsCount(0);
|
||||
final Sdk jdk = IdeaTestUtil.getMockJdk17("AAA");
|
||||
ProjectJdkTable.getInstance().addJdk(jdk);
|
||||
assertEventsCount(0);
|
||||
|
||||
final Sdk jdkBBB = IdeaTestUtil.getMockJdk17("BBB");
|
||||
ProjectJdkTable.getInstance().addJdk(jdk);
|
||||
assertEventsCount(0);
|
||||
final Sdk jdkBBB = IdeaTestUtil.getMockJdk17("BBB");
|
||||
ProjectJdkTable.getInstance().addJdk(jdk);
|
||||
assertEventsCount(0);
|
||||
|
||||
ProjectRootManager.getInstance(myProject).setProjectSdk(jdkBBB);
|
||||
assertEventsCount(0);
|
||||
ProjectRootManager.getInstance(myProject).setProjectSdk(jdkBBB);
|
||||
assertEventsCount(0);
|
||||
|
||||
final ModifiableRootModel rootModelA = ModuleRootManager.getInstance(moduleA).getModifiableModel();
|
||||
final ModifiableRootModel rootModelB = ModuleRootManager.getInstance(moduleB).getModifiableModel();
|
||||
rootModelA.inheritSdk();
|
||||
rootModelB.inheritSdk();
|
||||
ModifiableRootModel[] rootModels = new ModifiableRootModel[]{rootModelA, rootModelB};
|
||||
if (rootModels.length > 0) {
|
||||
ModifiableModelCommitter.multiCommit(rootModels, ModuleManager.getInstance(rootModels[0].getProject()).getModifiableModel());
|
||||
}
|
||||
assertEventsCount(1);
|
||||
|
||||
ProjectRootManager.getInstance(myProject).setProjectSdk(jdk);
|
||||
assertEventsCount(1);
|
||||
|
||||
final SdkModificator sdkModificator = jdk.getSdkModificator();
|
||||
sdkModificator.addRoot(getVirtualFile(tempDirectory), OrderRootType.CLASSES);
|
||||
sdkModificator.commitChanges();
|
||||
assertEventsCount(1);
|
||||
|
||||
ProjectJdkTable.getInstance().removeJdk(jdk);
|
||||
assertEventsCount(1);
|
||||
final ModifiableRootModel rootModelA = ModuleRootManager.getInstance(moduleA).getModifiableModel();
|
||||
final ModifiableRootModel rootModelB = ModuleRootManager.getInstance(moduleB).getModifiableModel();
|
||||
rootModelA.inheritSdk();
|
||||
rootModelB.inheritSdk();
|
||||
ModifiableRootModel[] rootModels = new ModifiableRootModel[]{rootModelA, rootModelB};
|
||||
if (rootModels.length > 0) {
|
||||
ModifiableModelCommitter.multiCommit(rootModels, ModuleManager.getInstance(rootModels[0].getProject()).getModifiableModel());
|
||||
}
|
||||
assertEventsCount(1);
|
||||
|
||||
ProjectRootManager.getInstance(myProject).setProjectSdk(jdk);
|
||||
assertEventsCount(1);
|
||||
|
||||
final SdkModificator sdkModificator = jdk.getSdkModificator();
|
||||
sdkModificator.addRoot(getVirtualFile(tempDirectory), OrderRootType.CLASSES);
|
||||
sdkModificator.commitChanges();
|
||||
assertEventsCount(1);
|
||||
|
||||
ProjectJdkTable.getInstance().removeJdk(jdk);
|
||||
assertEventsCount(1);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -231,102 +222,96 @@ public class RootsChangedTest extends ModuleTestCase {
|
||||
final Module moduleB = createModule("b.iml");
|
||||
assertEventsCount(2);
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Library libraryA = libraryTable.createLibrary("A");
|
||||
final Library.ModifiableModel libraryModifiableModel = libraryA.getModifiableModel();
|
||||
libraryModifiableModel.addRoot("file:///a", OrderRootType.CLASSES);
|
||||
libraryModifiableModel.commit();
|
||||
assertEventsCount(0);
|
||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
||||
final Library libraryA = libraryTable.createLibrary("A");
|
||||
final Library.ModifiableModel libraryModifiableModel = libraryA.getModifiableModel();
|
||||
libraryModifiableModel.addRoot("file:///a", OrderRootType.CLASSES);
|
||||
libraryModifiableModel.commit();
|
||||
assertEventsCount(0);
|
||||
|
||||
final ModifiableRootModel rootModelA = ModuleRootManager.getInstance(moduleA).getModifiableModel();
|
||||
final ModifiableRootModel rootModelB = ModuleRootManager.getInstance(moduleB).getModifiableModel();
|
||||
rootModelA.addLibraryEntry(libraryA);
|
||||
rootModelB.addLibraryEntry(libraryA);
|
||||
rootModelA.addInvalidLibrary("Q", libraryTable.getTableLevel());
|
||||
rootModelB.addInvalidLibrary("Q", libraryTable.getTableLevel());
|
||||
ModifiableRootModel[] rootModels = new ModifiableRootModel[]{rootModelA, rootModelB};
|
||||
if (rootModels.length > 0) {
|
||||
ModifiableModelCommitter.multiCommit(rootModels, ModuleManager.getInstance(rootModels[0].getProject()).getModifiableModel());
|
||||
}
|
||||
assertEventsCount(1);
|
||||
final ModifiableRootModel rootModelA = ModuleRootManager.getInstance(moduleA).getModifiableModel();
|
||||
final ModifiableRootModel rootModelB = ModuleRootManager.getInstance(moduleB).getModifiableModel();
|
||||
rootModelA.addLibraryEntry(libraryA);
|
||||
rootModelB.addLibraryEntry(libraryA);
|
||||
rootModelA.addInvalidLibrary("Q", libraryTable.getTableLevel());
|
||||
rootModelB.addInvalidLibrary("Q", libraryTable.getTableLevel());
|
||||
ModifiableRootModel[] rootModels = new ModifiableRootModel[]{rootModelA, rootModelB};
|
||||
if (rootModels.length > 0) {
|
||||
ModifiableModelCommitter.multiCommit(rootModels, ModuleManager.getInstance(rootModels[0].getProject()).getModifiableModel());
|
||||
}
|
||||
assertEventsCount(1);
|
||||
|
||||
final Library.ModifiableModel libraryModifiableModel2 = libraryA.getModifiableModel();
|
||||
final File tmpDir;
|
||||
try {
|
||||
tmpDir = FileUtil.createTempDirectory(getTestName(true), "");
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
final Library.ModifiableModel libraryModifiableModel2 = libraryA.getModifiableModel();
|
||||
final File tmpDir;
|
||||
try {
|
||||
tmpDir = FileUtil.createTempDirectory(getTestName(true), "");
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
try {
|
||||
final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tmpDir);
|
||||
assertNotNull(file);
|
||||
try {
|
||||
final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tmpDir);
|
||||
assertNotNull(file);
|
||||
|
||||
libraryModifiableModel2.addRoot(file.getUrl(), OrderRootType.CLASSES);
|
||||
libraryModifiableModel2.commit();
|
||||
assertEventsCount(1);
|
||||
}
|
||||
finally {
|
||||
FileUtil.delete(tmpDir);
|
||||
}
|
||||
|
||||
libraryTable.removeLibrary(libraryA);
|
||||
assertEventsCount(1);
|
||||
|
||||
final Library libraryQ = libraryTable.createLibrary("Q");
|
||||
assertEventsCount(1);
|
||||
|
||||
libraryTable.removeLibrary(libraryQ);
|
||||
libraryModifiableModel2.addRoot(file.getUrl(), OrderRootType.CLASSES);
|
||||
libraryModifiableModel2.commit();
|
||||
assertEventsCount(1);
|
||||
}
|
||||
finally {
|
||||
FileUtil.delete(tmpDir);
|
||||
}
|
||||
|
||||
libraryTable.removeLibrary(libraryA);
|
||||
assertEventsCount(1);
|
||||
|
||||
final Library libraryQ = libraryTable.createLibrary("Q");
|
||||
assertEventsCount(1);
|
||||
|
||||
libraryTable.removeLibrary(libraryQ);
|
||||
assertEventsCount(1);
|
||||
});
|
||||
}
|
||||
|
||||
private void verifyLibraryTableEditingInUncommittedModel(final LibraryTable libraryTable) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Module moduleA = createModule("a.iml");
|
||||
final Module moduleB = createModule("b.iml");
|
||||
assertEventsCount(2);
|
||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
||||
final Module moduleA = createModule("a.iml");
|
||||
final Module moduleB = createModule("b.iml");
|
||||
assertEventsCount(2);
|
||||
|
||||
final Library libraryA = libraryTable.createLibrary("A");
|
||||
final Library.ModifiableModel libraryModifiableModel = libraryA.getModifiableModel();
|
||||
libraryModifiableModel.addRoot("file:///a", OrderRootType.CLASSES);
|
||||
libraryModifiableModel.commit();
|
||||
assertEventsCount(0);
|
||||
final Library libraryA = libraryTable.createLibrary("A");
|
||||
final Library.ModifiableModel libraryModifiableModel = libraryA.getModifiableModel();
|
||||
libraryModifiableModel.addRoot("file:///a", OrderRootType.CLASSES);
|
||||
libraryModifiableModel.commit();
|
||||
assertEventsCount(0);
|
||||
|
||||
final ModifiableRootModel rootModelA = ModuleRootManager.getInstance(moduleA).getModifiableModel();
|
||||
final ModifiableRootModel rootModelB = ModuleRootManager.getInstance(moduleB).getModifiableModel();
|
||||
rootModelA.addLibraryEntry(libraryA);
|
||||
rootModelB.addLibraryEntry(libraryA);
|
||||
final Library.ModifiableModel libraryModifiableModel2 = libraryA.getModifiableModel();
|
||||
libraryModifiableModel2.addRoot("file:///b", OrderRootType.CLASSES);
|
||||
libraryModifiableModel2.commit();
|
||||
assertEventsCount(0);
|
||||
final ModifiableRootModel rootModelA = ModuleRootManager.getInstance(moduleA).getModifiableModel();
|
||||
final ModifiableRootModel rootModelB = ModuleRootManager.getInstance(moduleB).getModifiableModel();
|
||||
rootModelA.addLibraryEntry(libraryA);
|
||||
rootModelB.addLibraryEntry(libraryA);
|
||||
final Library.ModifiableModel libraryModifiableModel2 = libraryA.getModifiableModel();
|
||||
libraryModifiableModel2.addRoot("file:///b", OrderRootType.CLASSES);
|
||||
libraryModifiableModel2.commit();
|
||||
assertEventsCount(0);
|
||||
|
||||
libraryTable.removeLibrary(libraryA);
|
||||
assertEventsCount(0);
|
||||
libraryTable.removeLibrary(libraryA);
|
||||
assertEventsCount(0);
|
||||
|
||||
rootModelA.addInvalidLibrary("Q", libraryTable.getTableLevel());
|
||||
rootModelB.addInvalidLibrary("Q", libraryTable.getTableLevel());
|
||||
assertEventsCount(0);
|
||||
rootModelA.addInvalidLibrary("Q", libraryTable.getTableLevel());
|
||||
rootModelB.addInvalidLibrary("Q", libraryTable.getTableLevel());
|
||||
assertEventsCount(0);
|
||||
|
||||
final Library libraryQ = libraryTable.createLibrary("Q");
|
||||
assertEventsCount(0);
|
||||
final Library libraryQ = libraryTable.createLibrary("Q");
|
||||
assertEventsCount(0);
|
||||
|
||||
ModifiableRootModel[] rootModels = new ModifiableRootModel[]{rootModelA, rootModelB};
|
||||
if (rootModels.length > 0) {
|
||||
ModifiableModelCommitter.multiCommit(rootModels, ModuleManager.getInstance(rootModels[0].getProject()).getModifiableModel());
|
||||
}
|
||||
assertEventsCount(1);
|
||||
|
||||
libraryTable.removeLibrary(libraryQ);
|
||||
assertEventsCount(1);
|
||||
ModifiableRootModel[] rootModels = new ModifiableRootModel[]{rootModelA, rootModelB};
|
||||
if (rootModels.length > 0) {
|
||||
ModifiableModelCommitter.multiCommit(rootModels, ModuleManager.getInstance(rootModels[0].getProject()).getModifiableModel());
|
||||
}
|
||||
assertEventsCount(1);
|
||||
|
||||
libraryTable.removeLibrary(libraryQ);
|
||||
assertEventsCount(1);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
-1
@@ -51,7 +51,7 @@ public class BackwardDependenciesBuilder extends DependenciesBuilder {
|
||||
|
||||
public BackwardDependenciesBuilder(final Project project, final AnalysisScope scope, final @Nullable AnalysisScope scopeOfInterest) {
|
||||
super(project, scope, scopeOfInterest);
|
||||
myForwardScope = ApplicationManager.getApplication().runReadAction(new Computable<AnalysisScope>() {
|
||||
myForwardScope = scopeOfInterest != null ? scopeOfInterest : ApplicationManager.getApplication().runReadAction(new Computable<AnalysisScope>() {
|
||||
@Override
|
||||
public AnalysisScope compute() {
|
||||
return getScope().getNarrowedComplementaryScope(getProject());
|
||||
|
||||
@@ -285,7 +285,7 @@ public class Main {
|
||||
else {
|
||||
message.append("Internal error. Please report to https://");
|
||||
boolean studio = "AndroidStudio".equalsIgnoreCase(System.getProperty(PLATFORM_PREFIX_PROPERTY));
|
||||
message.append(studio ? "code.google.com/p/android/issues" : "youtrack.jetbrains.com");
|
||||
message.append(studio ? "code.google.com/p/android/issues" : "intellij-support.jetbrains.com/hc/en-us/requests/new");
|
||||
message.append("\n\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,7 @@ public class RunResult<T> extends Result<T> {
|
||||
catch (Throwable t) {
|
||||
myThrowable = t;
|
||||
if (!myActionRunnable.isSilentExecution()) {
|
||||
ExceptionUtil.rethrowUnchecked(t);
|
||||
throw new RuntimeException(myThrowable);
|
||||
ExceptionUtil.rethrowAllAsUnchecked(t);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
@@ -67,8 +66,7 @@ public class RunResult<T> extends Result<T> {
|
||||
@NotNull
|
||||
public RunResult<T> throwException() throws RuntimeException, Error {
|
||||
if (myThrowable != null) {
|
||||
ExceptionUtil.rethrowUnchecked(myThrowable);
|
||||
throw new RuntimeException(myThrowable);
|
||||
ExceptionUtil.rethrowAllAsUnchecked(myThrowable);
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
@@ -58,6 +58,6 @@ public class WrappedElementAnchor extends PsiAnchor {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WrappedElementAnchor(" + myBaseAnchor.toString() + ")";
|
||||
return "WrappedElementAnchor(" + myBaseAnchor + "; provider=" + myAnchorProvider + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,24 +25,13 @@ import com.intellij.psi.PsiElement;
|
||||
* Time: 19:24:33
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public class NotFilter
|
||||
implements ElementFilter{
|
||||
ElementFilter myFilter;
|
||||
|
||||
public NotFilter(){}
|
||||
public class NotFilter implements ElementFilter {
|
||||
private final ElementFilter myFilter;
|
||||
|
||||
public NotFilter(ElementFilter filter){
|
||||
myFilter = filter;
|
||||
}
|
||||
|
||||
public void setFilter(ElementFilter filter){
|
||||
myFilter = filter;
|
||||
}
|
||||
|
||||
public ElementFilter getFilter(){
|
||||
return myFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClassAcceptable(Class hintClass){
|
||||
return myFilter.isClassAcceptable(hintClass);
|
||||
@@ -55,7 +44,7 @@ public class NotFilter
|
||||
|
||||
|
||||
public String toString(){
|
||||
return "!" + getFilter();
|
||||
return "!" + myFilter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.UnknownFileType;
|
||||
import com.intellij.openapi.fileTypes.ex.FileTypeChooser;
|
||||
import com.intellij.openapi.project.DumbModePermission;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.vcs.changes.issueLinks.LinkMouseListenerBase;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.SimpleColoredComponent;
|
||||
@@ -46,11 +48,6 @@ public class UnknownFileTypeDiffRequest extends ComponentDiffRequest {
|
||||
myTitle = title;
|
||||
}
|
||||
|
||||
public UnknownFileTypeDiffRequest(@Nullable String title) {
|
||||
myFileName = null;
|
||||
myTitle = title;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JComponent getComponent(@NotNull final DiffContext context) {
|
||||
@@ -61,8 +58,13 @@ public class UnknownFileTypeDiffRequest extends ComponentDiffRequest {
|
||||
label.append("Associate", SimpleTextAttributes.LINK_ATTRIBUTES, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
FileType type = FileTypeChooser.associateFileType(myFileName);
|
||||
if (type != null) onSuccess(context);
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
FileType type = FileTypeChooser.associateFileType(myFileName);
|
||||
if (type != null) onSuccess(context);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
LinkMouseListenerBase.installSingleTagOn(label);
|
||||
|
||||
@@ -128,7 +128,7 @@ public class UISettings extends SimpleModificationTracker implements PersistentS
|
||||
public boolean SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES = true;
|
||||
public boolean NAVIGATE_TO_PREVIEW = false;
|
||||
public boolean SORT_BOOKMARKS = false;
|
||||
public boolean MERGE_EQUAL_STACKTRACES = false;
|
||||
public boolean MERGE_EQUAL_STACKTRACES = true;
|
||||
|
||||
private final EventDispatcher<UISettingsListener> myDispatcher = EventDispatcher.create(UISettingsListener.class);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,8 +16,8 @@
|
||||
package com.intellij.openapi.editor.markup;
|
||||
|
||||
public interface HighlighterLayer {
|
||||
int CARET_ROW = 1000;
|
||||
int SYNTAX = 2000;
|
||||
int SYNTAX = 1000;
|
||||
int CARET_ROW = 2000;
|
||||
int ADDITIONAL_SYNTAX = 3000;
|
||||
int GUARDED_BLOCKS = 3500;
|
||||
int WARNING = 4000;
|
||||
@@ -25,6 +25,6 @@ public interface HighlighterLayer {
|
||||
int ELEMENT_UNDER_CARET = 5500;
|
||||
int SELECTION = 6000;
|
||||
|
||||
int FIRST = CARET_ROW;
|
||||
int FIRST = SYNTAX;
|
||||
int LAST = SELECTION;
|
||||
}
|
||||
|
||||
+1
-3
@@ -1,6 +1,5 @@
|
||||
package com.intellij.openapi.externalSystem.service.project;
|
||||
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.project.*;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -60,8 +59,7 @@ public interface PlatformFacade {
|
||||
|
||||
/**
|
||||
* Creates a module of the specified type at the specified path and adds it to the project
|
||||
* to which the module manager is related. {@link #commit()} must be called to
|
||||
* bring the changes in effect.
|
||||
* to which the module manager is related.
|
||||
*
|
||||
*
|
||||
* @param project
|
||||
|
||||
+58
-4
@@ -26,6 +26,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.externalSystem.ExternalSystemAutoImportAware;
|
||||
import com.intellij.openapi.externalSystem.ExternalSystemManager;
|
||||
import com.intellij.openapi.externalSystem.model.*;
|
||||
import com.intellij.openapi.externalSystem.model.Key;
|
||||
import com.intellij.openapi.externalSystem.model.project.LibraryData;
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
@@ -39,12 +40,10 @@ import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsListen
|
||||
import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Conditions;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -446,6 +445,61 @@ public class ExternalSystemApiUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void commitChangedModels(boolean synchronous, Project project, List<Library.ModifiableModel> models) {
|
||||
final List<Library.ModifiableModel> changedModels = ContainerUtil.findAll(models, new Condition<Library.ModifiableModel>() {
|
||||
@Override
|
||||
public boolean value(Library.ModifiableModel model) {
|
||||
return model.isChanged();
|
||||
}
|
||||
});
|
||||
if (!changedModels.isEmpty()) {
|
||||
executeProjectChangeAction(synchronous, new DisposeAwareProjectChange(project) {
|
||||
@Override
|
||||
public void execute() {
|
||||
for (Library.ModifiableModel modifiableModel : changedModels) {
|
||||
modifiableModel.commit();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void disposeModels(@NotNull Collection<ModifiableRootModel> models) {
|
||||
for (ModifiableRootModel model : models) {
|
||||
if (!model.isDisposed()) {
|
||||
model.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void commitModels(boolean synchronous, Project project, List<ModifiableRootModel> models) {
|
||||
final List<ModifiableRootModel> changedModels = ContainerUtilRt.newArrayList();
|
||||
for (ModifiableRootModel modifiableRootModel : models) {
|
||||
if (modifiableRootModel.isDisposed()) {
|
||||
continue;
|
||||
}
|
||||
if (modifiableRootModel.isChanged()) {
|
||||
changedModels.add(modifiableRootModel);
|
||||
} else {
|
||||
modifiableRootModel.dispose();
|
||||
}
|
||||
}
|
||||
// Commit only if there are changes. #executeProjectChangeAction acquires a write lock
|
||||
if (!changedModels.isEmpty()) {
|
||||
executeProjectChangeAction(synchronous, new DisposeAwareProjectChange(project) {
|
||||
@Override
|
||||
public void execute() {
|
||||
for (ModifiableRootModel modifiableRootModel : changedModels) {
|
||||
// double check
|
||||
if (!modifiableRootModel.isDisposed()) {
|
||||
modifiableRootModel.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void executeProjectChangeAction(@NotNull final DisposeAwareProjectChange task) {
|
||||
executeProjectChangeAction(false, task);
|
||||
}
|
||||
|
||||
+39
-42
@@ -28,6 +28,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ExceptionUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
@@ -133,15 +134,27 @@ public abstract class AbstractDependencyDataService<E extends AbstractDependency
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeData(@NotNull final Computable<Collection<I>> toRemoveComputable,
|
||||
@NotNull final Collection<DataNode<E>> toIgnore,
|
||||
@NotNull final ProjectData projectData,
|
||||
@NotNull final Project project,
|
||||
@NotNull final PlatformFacade platformFacade,
|
||||
final boolean synchronous) {
|
||||
Map<Module, Collection<ExportableOrderEntry>> byModule = groupByModule(toRemoveComputable.compute());
|
||||
for (Map.Entry<Module, Collection<ExportableOrderEntry>> entry : byModule.entrySet()) {
|
||||
removeData(entry.getValue(), entry.getKey(), platformFacade, synchronous);
|
||||
public void removeData(@NotNull Computable<Collection<I>> toRemoveComputable,
|
||||
@NotNull Collection<DataNode<E>> toIgnore,
|
||||
@NotNull ProjectData projectData,
|
||||
@NotNull Project project,
|
||||
@NotNull PlatformFacade platformFacade,
|
||||
boolean synchronous) {
|
||||
List<ModifiableRootModel> models = ContainerUtilRt.newArrayList();
|
||||
try {
|
||||
Map<Module, Collection<ExportableOrderEntry>> byModule = groupByModule(toRemoveComputable.compute());
|
||||
for (Map.Entry<Module, Collection<ExportableOrderEntry>> entry : byModule.entrySet()) {
|
||||
Module module = entry.getKey();
|
||||
Collection<ExportableOrderEntry> depsToRemove = entry.getValue();
|
||||
ModifiableRootModel model = platformFacade.getModuleModifiableModel(module);
|
||||
removeData(depsToRemove, model);
|
||||
models.add(model);
|
||||
}
|
||||
ExternalSystemApiUtil.commitModels(synchronous, project, models);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
ExternalSystemApiUtil.disposeModels(models);
|
||||
ExceptionUtil.rethrowAllAsUnchecked(t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,41 +172,25 @@ public abstract class AbstractDependencyDataService<E extends AbstractDependency
|
||||
}
|
||||
|
||||
protected void removeData(@NotNull Collection<? extends ExportableOrderEntry> toRemove,
|
||||
@NotNull final Module module,
|
||||
@NotNull final PlatformFacade platformFacade,
|
||||
boolean synchronous) {
|
||||
if (toRemove.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (final ExportableOrderEntry dependency : toRemove) {
|
||||
ExternalSystemApiUtil.executeProjectChangeAction(synchronous, new DisposeAwareProjectChange(dependency.getOwnerModule()) {
|
||||
@Override
|
||||
public void execute() {
|
||||
final ModifiableRootModel moduleRootModel = platformFacade.getModuleModifiableModel(module);
|
||||
try {
|
||||
// The thing is that intellij created order entry objects every time new modifiable model is created,
|
||||
// that's why we can't use target dependency object as is but need to get a reference to the current
|
||||
// entry object from the model instead.
|
||||
for (OrderEntry entry : moduleRootModel.getOrderEntries()) {
|
||||
if (entry instanceof ExportableOrderEntry) {
|
||||
ExportableOrderEntry orderEntry = (ExportableOrderEntry)entry;
|
||||
if (orderEntry.getPresentableName().equals(dependency.getPresentableName()) &&
|
||||
orderEntry.getScope().equals(dependency.getScope())) {
|
||||
moduleRootModel.removeOrderEntry(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (entry.getPresentableName().equals(dependency.getPresentableName())) {
|
||||
moduleRootModel.removeOrderEntry(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
moduleRootModel.commit();
|
||||
@NotNull ModifiableRootModel moduleRootModel) {
|
||||
for (ExportableOrderEntry dependency : toRemove) {
|
||||
// The thing is that intellij created order entry objects every time new modifiable model is created,
|
||||
// that's why we can't use target dependency object as is but need to get a reference to the current
|
||||
// entry object from the model instead.
|
||||
for (OrderEntry entry : moduleRootModel.getOrderEntries()) {
|
||||
if (entry instanceof ExportableOrderEntry) {
|
||||
ExportableOrderEntry orderEntry = (ExportableOrderEntry)entry;
|
||||
if (orderEntry.getPresentableName().equals(dependency.getPresentableName()) &&
|
||||
orderEntry.getScope().equals(dependency.getScope())) {
|
||||
moduleRootModel.removeOrderEntry(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
else if (entry.getPresentableName().equals(dependency.getPresentableName())) {
|
||||
moduleRootModel.removeOrderEntry(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+78
-79
@@ -28,7 +28,6 @@ import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.project.PlatformFacade;
|
||||
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
|
||||
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
|
||||
import com.intellij.openapi.externalSystem.util.DisposeAwareProjectChange;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
|
||||
import com.intellij.openapi.externalSystem.util.Order;
|
||||
@@ -36,7 +35,6 @@ import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ContentEntry;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
||||
import com.intellij.openapi.roots.SourceFolder;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -44,7 +42,7 @@ import com.intellij.openapi.vcs.changes.ChangeListManager;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ExceptionUtil;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -78,94 +76,95 @@ public class ContentRootDataService extends AbstractProjectDataService<ContentRo
|
||||
}
|
||||
|
||||
@Override
|
||||
public void importData(@NotNull final Collection<DataNode<ContentRootData>> toImport,
|
||||
public void importData(@NotNull Collection<DataNode<ContentRootData>> toImport,
|
||||
@Nullable ProjectData projectData,
|
||||
@NotNull final Project project,
|
||||
@NotNull final PlatformFacade platformFacade,
|
||||
final boolean synchronous) {
|
||||
@NotNull Project project,
|
||||
@NotNull PlatformFacade platformFacade,
|
||||
boolean synchronous) {
|
||||
if (toImport.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MultiMap<DataNode<ModuleData>, DataNode<ContentRootData>> byModule = ExternalSystemApiUtil.groupBy(toImport, ProjectKeys.MODULE);
|
||||
for (Map.Entry<DataNode<ModuleData>, Collection<DataNode<ContentRootData>>> entry : byModule.entrySet()) {
|
||||
final Module module = platformFacade.findIdeModule(entry.getKey().getData(), project);
|
||||
if (module == null) {
|
||||
LOG.warn(String.format(
|
||||
"Can't import content roots. Reason: target module (%s) is not found at the ide. Content roots: %s",
|
||||
entry.getKey(), entry.getValue()
|
||||
));
|
||||
continue;
|
||||
List<ModifiableRootModel> models = ContainerUtilRt.newArrayList();
|
||||
try {
|
||||
MultiMap<DataNode<ModuleData>, DataNode<ContentRootData>> byModule = ExternalSystemApiUtil.groupBy(toImport, ProjectKeys.MODULE);
|
||||
for (Map.Entry<DataNode<ModuleData>, Collection<DataNode<ContentRootData>>> entry : byModule.entrySet()) {
|
||||
Module module = platformFacade.findIdeModule(entry.getKey().getData(), project);
|
||||
if (module == null) {
|
||||
LOG.warn(String.format(
|
||||
"Can't import content roots. Reason: target module (%s) is not found at the ide. Content roots: %s",
|
||||
entry.getKey(), entry.getValue()
|
||||
));
|
||||
continue;
|
||||
}
|
||||
models.add(importData(entry.getValue(), module, platformFacade));
|
||||
}
|
||||
importData(entry.getValue(), module, synchronous);
|
||||
ExternalSystemApiUtil.commitModels(synchronous, project, models);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
ExternalSystemApiUtil.disposeModels(models);
|
||||
ExceptionUtil.rethrowAllAsUnchecked(t);
|
||||
}
|
||||
}
|
||||
|
||||
private static void importData(@NotNull final Collection<DataNode<ContentRootData>> data,
|
||||
@NotNull final Module module,
|
||||
boolean synchronous) {
|
||||
ExternalSystemApiUtil.executeProjectChangeAction(synchronous, new DisposeAwareProjectChange(module) {
|
||||
@Override
|
||||
public void execute() {
|
||||
ModuleRootModificationUtil.updateModel(module, new Consumer<ModifiableRootModel>() {
|
||||
@Override
|
||||
public void consume(ModifiableRootModel model) {
|
||||
final ContentEntry[] contentEntries = model.getContentEntries();
|
||||
final Map<String, ContentEntry> contentEntriesMap = ContainerUtilRt.newHashMap();
|
||||
for(ContentEntry contentEntry : contentEntries) {
|
||||
contentEntriesMap.put(contentEntry.getUrl(), contentEntry);
|
||||
}
|
||||
@NotNull
|
||||
private static ModifiableRootModel importData(@NotNull Collection<DataNode<ContentRootData>> data,
|
||||
@NotNull Module module,
|
||||
@NotNull PlatformFacade platformFacade) {
|
||||
ModifiableRootModel model = platformFacade.getModuleModifiableModel(module);
|
||||
ContentEntry[] contentEntries = model.getContentEntries();
|
||||
Map<String, ContentEntry> contentEntriesMap = ContainerUtilRt.newHashMap();
|
||||
for(ContentEntry contentEntry : contentEntries) {
|
||||
contentEntriesMap.put(contentEntry.getUrl(), contentEntry);
|
||||
}
|
||||
|
||||
boolean createEmptyContentRootDirectories = false;
|
||||
if (!data.isEmpty()) {
|
||||
ProjectSystemId projectSystemId = data.iterator().next().getData().getOwner();
|
||||
AbstractExternalSystemSettings externalSystemSettings =
|
||||
ExternalSystemApiUtil.getSettings(module.getProject(), projectSystemId);
|
||||
boolean createEmptyContentRootDirectories = false;
|
||||
if (!data.isEmpty()) {
|
||||
ProjectSystemId projectSystemId = data.iterator().next().getData().getOwner();
|
||||
AbstractExternalSystemSettings externalSystemSettings =
|
||||
ExternalSystemApiUtil.getSettings(module.getProject(), projectSystemId);
|
||||
|
||||
String path = module.getOptionValue(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY);
|
||||
if (path != null) {
|
||||
ExternalProjectSettings projectSettings = externalSystemSettings.getLinkedProjectSettings(path);
|
||||
createEmptyContentRootDirectories = projectSettings != null && projectSettings.isCreateEmptyContentRootDirectories();
|
||||
}
|
||||
}
|
||||
|
||||
for (final DataNode<ContentRootData> node : data) {
|
||||
final ContentRootData contentRoot = node.getData();
|
||||
|
||||
final ContentEntry contentEntry = findOrCreateContentRoot(model, contentRoot.getRootPath());
|
||||
contentEntry.clearExcludeFolders();
|
||||
contentEntry.clearSourceFolders();
|
||||
LOG.debug(String.format("Importing content root '%s' for module '%s'", contentRoot.getRootPath(), module.getName()));
|
||||
for (SourceRoot path : contentRoot.getPaths(ExternalSystemSourceType.SOURCE)) {
|
||||
createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaSourceRootType.SOURCE, false, createEmptyContentRootDirectories);
|
||||
}
|
||||
for (SourceRoot path : contentRoot.getPaths(ExternalSystemSourceType.TEST)) {
|
||||
createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaSourceRootType.TEST_SOURCE, false, createEmptyContentRootDirectories);
|
||||
}
|
||||
for (SourceRoot path : contentRoot.getPaths(ExternalSystemSourceType.RESOURCE)) {
|
||||
createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaResourceRootType.RESOURCE, false, createEmptyContentRootDirectories);
|
||||
}
|
||||
for (SourceRoot path : contentRoot.getPaths(ExternalSystemSourceType.TEST_RESOURCE)) {
|
||||
createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaResourceRootType.TEST_RESOURCE, false, createEmptyContentRootDirectories);
|
||||
}
|
||||
for (SourceRoot path : contentRoot.getPaths(ExternalSystemSourceType.SOURCE_GENERATED)) {
|
||||
createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaSourceRootType.SOURCE, true, createEmptyContentRootDirectories);
|
||||
}
|
||||
for (SourceRoot path : contentRoot.getPaths(ExternalSystemSourceType.TEST_GENERATED)) {
|
||||
createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaSourceRootType.TEST_SOURCE, true, createEmptyContentRootDirectories);
|
||||
}
|
||||
for (SourceRoot path : contentRoot.getPaths(ExternalSystemSourceType.EXCLUDED)) {
|
||||
createExcludedRootIfAbsent(contentEntry, path, module.getName(), module.getProject());
|
||||
}
|
||||
contentEntriesMap.remove(contentEntry.getUrl());
|
||||
}
|
||||
for(ContentEntry contentEntry : contentEntriesMap.values()) {
|
||||
model.removeContentEntry(contentEntry);
|
||||
}
|
||||
}
|
||||
});
|
||||
String path = module.getOptionValue(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY);
|
||||
if (path != null) {
|
||||
ExternalProjectSettings projectSettings = externalSystemSettings.getLinkedProjectSettings(path);
|
||||
createEmptyContentRootDirectories = projectSettings != null && projectSettings.isCreateEmptyContentRootDirectories();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (DataNode<ContentRootData> node : data) {
|
||||
ContentRootData contentRoot = node.getData();
|
||||
|
||||
ContentEntry contentEntry = findOrCreateContentRoot(model, contentRoot.getRootPath());
|
||||
contentEntry.clearExcludeFolders();
|
||||
contentEntry.clearSourceFolders();
|
||||
LOG.debug(String.format("Importing content root '%s' for module '%s'", contentRoot.getRootPath(), module.getName()));
|
||||
for (SourceRoot path : contentRoot.getPaths(ExternalSystemSourceType.SOURCE)) {
|
||||
createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaSourceRootType.SOURCE, false, createEmptyContentRootDirectories);
|
||||
}
|
||||
for (SourceRoot path : contentRoot.getPaths(ExternalSystemSourceType.TEST)) {
|
||||
createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaSourceRootType.TEST_SOURCE, false, createEmptyContentRootDirectories);
|
||||
}
|
||||
for (SourceRoot path : contentRoot.getPaths(ExternalSystemSourceType.RESOURCE)) {
|
||||
createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaResourceRootType.RESOURCE, false, createEmptyContentRootDirectories);
|
||||
}
|
||||
for (SourceRoot path : contentRoot.getPaths(ExternalSystemSourceType.TEST_RESOURCE)) {
|
||||
createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaResourceRootType.TEST_RESOURCE, false, createEmptyContentRootDirectories);
|
||||
}
|
||||
for (SourceRoot path : contentRoot.getPaths(ExternalSystemSourceType.SOURCE_GENERATED)) {
|
||||
createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaSourceRootType.SOURCE, true, createEmptyContentRootDirectories);
|
||||
}
|
||||
for (SourceRoot path : contentRoot.getPaths(ExternalSystemSourceType.TEST_GENERATED)) {
|
||||
createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaSourceRootType.TEST_SOURCE, true, createEmptyContentRootDirectories);
|
||||
}
|
||||
for (SourceRoot path : contentRoot.getPaths(ExternalSystemSourceType.EXCLUDED)) {
|
||||
createExcludedRootIfAbsent(contentEntry, path, module.getName(), module.getProject());
|
||||
}
|
||||
contentEntriesMap.remove(contentEntry.getUrl());
|
||||
}
|
||||
for(ContentEntry contentEntry : contentEntriesMap.values()) {
|
||||
model.removeContentEntry(contentEntry);
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+57
-65
@@ -1,14 +1,12 @@
|
||||
package com.intellij.openapi.externalSystem.service.project.manage;
|
||||
|
||||
import com.intellij.ide.highlighter.ArchiveFileType;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.externalSystem.model.DataNode;
|
||||
import com.intellij.openapi.externalSystem.model.Key;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectKeys;
|
||||
import com.intellij.openapi.externalSystem.model.project.LibraryData;
|
||||
import com.intellij.openapi.externalSystem.model.project.LibraryPathType;
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.project.ExternalLibraryPathTypeMapper;
|
||||
import com.intellij.openapi.externalSystem.service.project.PlatformFacade;
|
||||
@@ -68,18 +66,23 @@ public class LibraryDataService extends AbstractProjectDataService<LibraryData,
|
||||
|
||||
@Override
|
||||
public void importData(@NotNull final Collection<DataNode<LibraryData>> toImport,
|
||||
@Nullable final ProjectData projectData,
|
||||
@Nullable ProjectData projectData,
|
||||
@NotNull final Project project,
|
||||
@NotNull final PlatformFacade platformFacade,
|
||||
final boolean synchronous) {
|
||||
for (DataNode<LibraryData> dataNode : toImport) {
|
||||
importLibrary(dataNode.getData(), project, platformFacade, synchronous);
|
||||
}
|
||||
ExternalSystemApiUtil.executeProjectChangeAction(synchronous, new DisposeAwareProjectChange(project) {
|
||||
@Override
|
||||
public void execute() {
|
||||
for (DataNode<LibraryData> dataNode : toImport) {
|
||||
importLibrary(dataNode.getData(), project, platformFacade, synchronous);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void importLibrary(@NotNull final LibraryData toImport,
|
||||
@NotNull final Project project,
|
||||
@NotNull final PlatformFacade platformFacade,
|
||||
private void importLibrary(@NotNull LibraryData toImport,
|
||||
@NotNull Project project,
|
||||
@NotNull PlatformFacade platformFacade,
|
||||
boolean synchronous) {
|
||||
Map<OrderRootType, Collection<File>> libraryFiles = prepareLibraryFiles(toImport);
|
||||
|
||||
@@ -88,14 +91,14 @@ public class LibraryDataService extends AbstractProjectDataService<LibraryData,
|
||||
syncPaths(toImport, library, project, synchronous);
|
||||
return;
|
||||
}
|
||||
importLibrary(toImport.getInternalName(), libraryFiles, project, platformFacade, synchronous);
|
||||
importLibrary(toImport.getInternalName(), libraryFiles, project, platformFacade);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Map<OrderRootType, Collection<File>> prepareLibraryFiles(@NotNull LibraryData data) {
|
||||
Map<OrderRootType, Collection<File>> result = ContainerUtilRt.newHashMap();
|
||||
for (LibraryPathType pathType : LibraryPathType.values()) {
|
||||
final Set<String> paths = data.getPaths(pathType);
|
||||
Set<String> paths = data.getPaths(pathType);
|
||||
if (paths.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
@@ -104,38 +107,32 @@ public class LibraryDataService extends AbstractProjectDataService<LibraryData,
|
||||
return result;
|
||||
}
|
||||
|
||||
private void importLibrary(@NotNull final String libraryName,
|
||||
@NotNull final Map<OrderRootType, Collection<File>> libraryFiles,
|
||||
@NotNull final Project project,
|
||||
@NotNull final PlatformFacade platformFacade,
|
||||
boolean synchronous)
|
||||
private void importLibrary(@NotNull String libraryName,
|
||||
@NotNull Map<OrderRootType, Collection<File>> libraryFiles,
|
||||
@NotNull Project project,
|
||||
@NotNull PlatformFacade platformFacade)
|
||||
{
|
||||
ExternalSystemApiUtil.executeProjectChangeAction(synchronous, new DisposeAwareProjectChange(project) {
|
||||
@Override
|
||||
public void execute() {
|
||||
// Is assumed to be called from the EDT.
|
||||
final LibraryTable libraryTable = platformFacade.getProjectLibraryTable(project);
|
||||
final LibraryTable.ModifiableModel projectLibraryModel = libraryTable.getModifiableModel();
|
||||
final Library intellijLibrary;
|
||||
try {
|
||||
intellijLibrary = projectLibraryModel.createLibrary(libraryName);
|
||||
}
|
||||
finally {
|
||||
projectLibraryModel.commit();
|
||||
}
|
||||
final Library.ModifiableModel libraryModel = intellijLibrary.getModifiableModel();
|
||||
try {
|
||||
registerPaths(libraryFiles, libraryModel, libraryName);
|
||||
}
|
||||
finally {
|
||||
libraryModel.commit();
|
||||
}
|
||||
}
|
||||
});
|
||||
// Is assumed to be called from the EDT.
|
||||
LibraryTable libraryTable = platformFacade.getProjectLibraryTable(project);
|
||||
LibraryTable.ModifiableModel projectLibraryModel = libraryTable.getModifiableModel();
|
||||
Library intellijLibrary;
|
||||
try {
|
||||
intellijLibrary = projectLibraryModel.createLibrary(libraryName);
|
||||
}
|
||||
finally {
|
||||
projectLibraryModel.commit();
|
||||
}
|
||||
Library.ModifiableModel libraryModel = intellijLibrary.getModifiableModel();
|
||||
try {
|
||||
registerPaths(libraryFiles, libraryModel, libraryName);
|
||||
}
|
||||
finally {
|
||||
libraryModel.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
public void registerPaths(@NotNull final Map<OrderRootType, Collection<File>> libraryFiles,
|
||||
public void registerPaths(@NotNull Map<OrderRootType, Collection<File>> libraryFiles,
|
||||
@NotNull Library.ModifiableModel model,
|
||||
@NotNull String libraryName)
|
||||
{
|
||||
@@ -150,14 +147,14 @@ public class LibraryDataService extends AbstractProjectDataService<LibraryData,
|
||||
}
|
||||
String url = VfsUtil.getUrlForLibraryRoot(file);
|
||||
|
||||
final String[] urls = model.getUrls(entry.getKey());
|
||||
String[] urls = model.getUrls(entry.getKey());
|
||||
if (!ArrayUtil.contains(url, urls)) {
|
||||
model.addRoot(url, entry.getKey());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (virtualFile.isDirectory()) {
|
||||
final VirtualFile[] files = model.getFiles(entry.getKey());
|
||||
VirtualFile[] files = model.getFiles(entry.getKey());
|
||||
if (!ArrayUtil.contains(virtualFile, files)) {
|
||||
model.addRoot(virtualFile, entry.getKey());
|
||||
}
|
||||
@@ -173,7 +170,7 @@ public class LibraryDataService extends AbstractProjectDataService<LibraryData,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
final VirtualFile[] files = model.getFiles(entry.getKey());
|
||||
VirtualFile[] files = model.getFiles(entry.getKey());
|
||||
if (!ArrayUtil.contains(root, files)) {
|
||||
model.addRoot(root, entry.getKey());
|
||||
}
|
||||
@@ -216,12 +213,12 @@ public class LibraryDataService extends AbstractProjectDataService<LibraryData,
|
||||
});
|
||||
}
|
||||
|
||||
public void syncPaths(@NotNull final LibraryData externalLibrary, @NotNull final Library ideLibrary, @NotNull final Project project, boolean synchronous) {
|
||||
public void syncPaths(@NotNull LibraryData externalLibrary, @NotNull Library ideLibrary, @NotNull Project project, boolean synchronous) {
|
||||
if (externalLibrary.isUnresolved()) {
|
||||
return;
|
||||
}
|
||||
final Map<OrderRootType, Set<String>> toRemove = ContainerUtilRt.newHashMap();
|
||||
final Map<OrderRootType, Set<String>> toAdd = ContainerUtilRt.newHashMap();
|
||||
Map<OrderRootType, Set<String>> toRemove = ContainerUtilRt.newHashMap();
|
||||
Map<OrderRootType, Set<String>> toAdd = ContainerUtilRt.newHashMap();
|
||||
for (LibraryPathType pathType : LibraryPathType.values()) {
|
||||
OrderRootType ideType = myLibraryPathTypeMapper.map(pathType);
|
||||
HashSet<String> toAddPerType = ContainerUtilRt.newHashSet(externalLibrary.getPaths(pathType));
|
||||
@@ -240,27 +237,22 @@ public class LibraryDataService extends AbstractProjectDataService<LibraryData,
|
||||
if (toRemove.isEmpty() && toAdd.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
ExternalSystemApiUtil.executeProjectChangeAction(synchronous, new DisposeAwareProjectChange(project) {
|
||||
@Override
|
||||
public void execute() {
|
||||
Library.ModifiableModel model = ideLibrary.getModifiableModel();
|
||||
try {
|
||||
for (Map.Entry<OrderRootType, Set<String>> entry : toRemove.entrySet()) {
|
||||
for (String path : entry.getValue()) {
|
||||
model.removeRoot(path, entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<OrderRootType, Set<String>> entry : toAdd.entrySet()) {
|
||||
Map<OrderRootType, Collection<File>> roots = ContainerUtilRt.newHashMap();
|
||||
roots.put(entry.getKey(), ContainerUtil.map(entry.getValue(), PATH_TO_FILE));
|
||||
registerPaths(roots, model, externalLibrary.getInternalName());
|
||||
}
|
||||
}
|
||||
finally {
|
||||
model.commit();
|
||||
Library.ModifiableModel model = ideLibrary.getModifiableModel();
|
||||
try {
|
||||
for (Map.Entry<OrderRootType, Set<String>> entry : toRemove.entrySet()) {
|
||||
for (String path : entry.getValue()) {
|
||||
model.removeRoot(path, entry.getKey());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for (Map.Entry<OrderRootType, Set<String>> entry : toAdd.entrySet()) {
|
||||
Map<OrderRootType, Collection<File>> roots = ContainerUtilRt.newHashMap();
|
||||
roots.put(entry.getKey(), ContainerUtil.map(entry.getValue(), PATH_TO_FILE));
|
||||
registerPaths(roots, model, externalLibrary.getInternalName());
|
||||
}
|
||||
}
|
||||
finally {
|
||||
model.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+160
-148
@@ -21,7 +21,6 @@ import com.intellij.openapi.externalSystem.model.Key;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectKeys;
|
||||
import com.intellij.openapi.externalSystem.model.project.*;
|
||||
import com.intellij.openapi.externalSystem.service.project.PlatformFacade;
|
||||
import com.intellij.openapi.externalSystem.util.DisposeAwareProjectChange;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
|
||||
import com.intellij.openapi.externalSystem.util.Order;
|
||||
@@ -35,6 +34,8 @@ import com.intellij.openapi.roots.impl.ModuleLibraryOrderEntryImpl;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ExceptionUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -42,6 +43,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -78,17 +80,28 @@ public class LibraryDependencyDataService extends AbstractDependencyDataService<
|
||||
return;
|
||||
}
|
||||
|
||||
MultiMap<DataNode<ModuleData>, DataNode<LibraryDependencyData>> byModule = ExternalSystemApiUtil.groupBy(toImport, MODULE);
|
||||
for (Map.Entry<DataNode<ModuleData>, Collection<DataNode<LibraryDependencyData>>> entry : byModule.entrySet()) {
|
||||
Module module = platformFacade.findIdeModule(entry.getKey().getData(), project);
|
||||
if (module == null) {
|
||||
LOG.warn(String.format(
|
||||
"Can't import library dependencies %s. Reason: target module (%s) is not found at the ide and can't be imported",
|
||||
entry.getValue(), entry.getKey()
|
||||
));
|
||||
continue;
|
||||
MyImporter importer = new MyImporter(platformFacade);
|
||||
try {
|
||||
MultiMap<DataNode<ModuleData>, DataNode<LibraryDependencyData>> byModule = ExternalSystemApiUtil.groupBy(toImport, MODULE);
|
||||
for (Map.Entry<DataNode<ModuleData>, Collection<DataNode<LibraryDependencyData>>> entry : byModule.entrySet()) {
|
||||
Module module = platformFacade.findIdeModule(entry.getKey().getData(), project);
|
||||
Collection<DataNode<LibraryDependencyData>> libraryDependency = entry.getValue();
|
||||
if (module == null) {
|
||||
LOG.warn(String.format(
|
||||
"Can't import library dependencies %s. Reason: target module (%s) is not found at the ide and can't be imported",
|
||||
libraryDependency, entry.getKey()
|
||||
));
|
||||
continue;
|
||||
}
|
||||
importer.importData(module, libraryDependency);
|
||||
}
|
||||
importData(entry.getValue(), module, platformFacade, synchronous);
|
||||
// change libraries first
|
||||
ExternalSystemApiUtil.commitChangedModels(synchronous, project, importer.getLibraryModels());
|
||||
ExternalSystemApiUtil.commitModels(synchronous, project, importer.getModels());
|
||||
}
|
||||
catch (Throwable t) {
|
||||
ExternalSystemApiUtil.disposeModels(importer.getModels());
|
||||
ExceptionUtil.rethrowAllAsUnchecked(t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,158 +116,157 @@ public class LibraryDependencyDataService extends AbstractDependencyDataService<
|
||||
return orderEntry.getLibraryName();
|
||||
}
|
||||
|
||||
private void importData(@NotNull final Collection<DataNode<LibraryDependencyData>> nodesToImport,
|
||||
@NotNull final Module module,
|
||||
@NotNull final PlatformFacade platformFacade,
|
||||
final boolean synchronous) {
|
||||
ExternalSystemApiUtil.executeProjectChangeAction(synchronous, new DisposeAwareProjectChange(module) {
|
||||
@Override
|
||||
public void execute() {
|
||||
// The general idea is to import all external project library dependencies and module libraries which don't present at the
|
||||
// ide side yet and remove all project library dependencies and module libraries which present at the ide but not at
|
||||
// the given collection.
|
||||
// The trick is that we should perform module settings modification inside try/finally block against target root model.
|
||||
// That means that we need to prepare all necessary data, obtain a model and modify it as necessary.
|
||||
Map<Set<String>/* library paths */, LibraryDependencyData> moduleLibrariesToImport = ContainerUtilRt.newHashMap();
|
||||
Map<String/* library name + scope */, LibraryDependencyData> projectLibrariesToImport = ContainerUtilRt.newHashMap();
|
||||
Set<LibraryDependencyData> toImport = ContainerUtilRt.newLinkedHashSet();
|
||||
private class MyImporter {
|
||||
private final PlatformFacade myPlatformFacade;
|
||||
private final List<ModifiableRootModel> myModels = ContainerUtilRt.newArrayList();
|
||||
private final List<Library.ModifiableModel> myLibraryModels = ContainerUtilRt.newArrayList();
|
||||
|
||||
boolean hasUnresolved = false;
|
||||
for (DataNode<LibraryDependencyData> dependencyNode : nodesToImport) {
|
||||
LibraryDependencyData dependencyData = dependencyNode.getData();
|
||||
LibraryData libraryData = dependencyData.getTarget();
|
||||
hasUnresolved |= libraryData.isUnresolved();
|
||||
switch (dependencyData.getLevel()) {
|
||||
case MODULE:
|
||||
if (!libraryData.isUnresolved()) {
|
||||
Set<String> paths = ContainerUtilRt.newHashSet();
|
||||
for (String path : libraryData.getPaths(LibraryPathType.BINARY)) {
|
||||
paths.add(ExternalSystemApiUtil.toCanonicalPath(path) + dependencyData.getScope().name());
|
||||
}
|
||||
moduleLibrariesToImport.put(paths, dependencyData);
|
||||
toImport.add(dependencyData);
|
||||
private MyImporter(PlatformFacade platformFacade) {
|
||||
myPlatformFacade = platformFacade;
|
||||
}
|
||||
|
||||
public List<ModifiableRootModel> getModels() {
|
||||
return ContainerUtil.newUnmodifiableList(myModels);
|
||||
}
|
||||
|
||||
public List<Library.ModifiableModel> getLibraryModels() {
|
||||
return ContainerUtil.newUnmodifiableList(myLibraryModels);
|
||||
}
|
||||
|
||||
public void importData(@NotNull Module module, @NotNull Collection<DataNode<LibraryDependencyData>> nodesToImport) {
|
||||
// The general idea is to import all external project library dependencies and module libraries which don't present at the
|
||||
// ide side yet and remove all project library dependencies and module libraries which present at the ide but not at
|
||||
// the given collection.
|
||||
// The trick is that we should perform module settings modification inside try/finally block against target root model.
|
||||
// That means that we need to prepare all necessary data, obtain a model and modify it as necessary.
|
||||
Map<Set<String>/* library paths */, LibraryDependencyData> moduleLibrariesToImport = ContainerUtilRt.newHashMap();
|
||||
Map<String/* library name + scope */, LibraryDependencyData> projectLibrariesToImport = ContainerUtilRt.newHashMap();
|
||||
Set<LibraryDependencyData> toImport = ContainerUtilRt.newLinkedHashSet();
|
||||
|
||||
boolean hasUnresolved = false;
|
||||
for (DataNode<LibraryDependencyData> dependencyNode : nodesToImport) {
|
||||
LibraryDependencyData dependencyData = dependencyNode.getData();
|
||||
LibraryData libraryData = dependencyData.getTarget();
|
||||
hasUnresolved |= libraryData.isUnresolved();
|
||||
switch (dependencyData.getLevel()) {
|
||||
case MODULE:
|
||||
if (!libraryData.isUnresolved()) {
|
||||
Set<String> paths = ContainerUtilRt.newHashSet();
|
||||
for (String path : libraryData.getPaths(LibraryPathType.BINARY)) {
|
||||
paths.add(ExternalSystemApiUtil.toCanonicalPath(path) + dependencyData.getScope().name());
|
||||
}
|
||||
break;
|
||||
case PROJECT:
|
||||
projectLibrariesToImport.put(libraryData.getInternalName() + dependencyData.getScope().name(), dependencyData);
|
||||
moduleLibrariesToImport.put(paths, dependencyData);
|
||||
toImport.add(dependencyData);
|
||||
}
|
||||
}
|
||||
|
||||
final ModifiableRootModel moduleRootModel = platformFacade.getModuleModifiableModel(module);
|
||||
LibraryTable moduleLibraryTable = moduleRootModel.getModuleLibraryTable();
|
||||
LibraryTable libraryTable = platformFacade.getProjectLibraryTable(module.getProject());
|
||||
try {
|
||||
syncExistingAndRemoveObsolete(moduleLibrariesToImport, projectLibrariesToImport, toImport, moduleRootModel, hasUnresolved);
|
||||
|
||||
// Import missing library dependencies.
|
||||
if (!toImport.isEmpty()) {
|
||||
importMissing(toImport, moduleRootModel, moduleLibraryTable, libraryTable, module);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
moduleRootModel.commit();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void importMissing(@NotNull Set<LibraryDependencyData> toImport,
|
||||
@NotNull ModifiableRootModel moduleRootModel,
|
||||
@NotNull LibraryTable moduleLibraryTable,
|
||||
@NotNull LibraryTable libraryTable,
|
||||
@NotNull Module module) {
|
||||
for (final LibraryDependencyData dependencyData : toImport) {
|
||||
final LibraryData libraryData = dependencyData.getTarget();
|
||||
final String libraryName = libraryData.getInternalName();
|
||||
switch (dependencyData.getLevel()) {
|
||||
case MODULE:
|
||||
final Library moduleLib = moduleLibraryTable.createLibrary(libraryName);
|
||||
syncExistingLibraryDependency(dependencyData, moduleLib, moduleRootModel, module);
|
||||
break;
|
||||
case PROJECT:
|
||||
final Library projectLib = libraryTable.getLibraryByName(libraryName);
|
||||
if (projectLib == null) {
|
||||
syncExistingLibraryDependency(dependencyData, moduleLibraryTable.createLibrary(libraryName), moduleRootModel, module);
|
||||
}
|
||||
break;
|
||||
case PROJECT:
|
||||
projectLibrariesToImport.put(libraryData.getInternalName() + dependencyData.getScope().name(), dependencyData);
|
||||
toImport.add(dependencyData);
|
||||
}
|
||||
}
|
||||
|
||||
ModifiableRootModel moduleRootModel = myPlatformFacade.getModuleModifiableModel(module);
|
||||
LibraryTable moduleLibraryTable = moduleRootModel.getModuleLibraryTable();
|
||||
LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(module.getProject());
|
||||
syncExistingAndRemoveObsolete(moduleLibrariesToImport, projectLibrariesToImport, toImport, moduleRootModel, hasUnresolved);
|
||||
|
||||
// Import missing library dependencies.
|
||||
if (!toImport.isEmpty()) {
|
||||
importMissing(toImport, moduleRootModel, moduleLibraryTable, libraryTable, module);
|
||||
}
|
||||
myModels.add(moduleRootModel);
|
||||
}
|
||||
|
||||
private void importMissing(@NotNull Set<LibraryDependencyData> toImport,
|
||||
@NotNull ModifiableRootModel moduleRootModel,
|
||||
@NotNull LibraryTable moduleLibraryTable,
|
||||
@NotNull LibraryTable libraryTable,
|
||||
@NotNull Module module) {
|
||||
for (LibraryDependencyData dependencyData : toImport) {
|
||||
LibraryData libraryData = dependencyData.getTarget();
|
||||
String libraryName = libraryData.getInternalName();
|
||||
switch (dependencyData.getLevel()) {
|
||||
case MODULE:
|
||||
Library moduleLib = moduleLibraryTable.createLibrary(libraryName);
|
||||
syncExistingLibraryDependency(dependencyData, moduleLib, moduleRootModel, module);
|
||||
break;
|
||||
case PROJECT:
|
||||
Library projectLib = libraryTable.getLibraryByName(libraryName);
|
||||
if (projectLib == null) {
|
||||
syncExistingLibraryDependency(dependencyData, moduleLibraryTable.createLibrary(libraryName), moduleRootModel, module);
|
||||
break;
|
||||
}
|
||||
LibraryOrderEntry orderEntry = moduleRootModel.addLibraryEntry(projectLib);
|
||||
setLibraryScope(orderEntry, projectLib, module, dependencyData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setLibraryScope(@NotNull LibraryOrderEntry orderEntry,
|
||||
@NotNull Library lib,
|
||||
@NotNull Module module,
|
||||
@NotNull LibraryDependencyData dependencyData) {
|
||||
LOG.debug(String.format("Adding library dependency '%s' to module '%s'", lib.getName(), module.getName()));
|
||||
orderEntry.setExported(dependencyData.isExported());
|
||||
orderEntry.setScope(dependencyData.getScope());
|
||||
LOG.debug(String.format("Configuring library dependency '%s' of module '%s' to be%s exported and have scope %s", lib.getName(), module.getName(), dependencyData.isExported() ? " not" : "", dependencyData.getScope()));
|
||||
}
|
||||
|
||||
private void syncExistingAndRemoveObsolete(@NotNull Map<Set<String>, LibraryDependencyData> moduleLibrariesToImport,
|
||||
@NotNull Map<String, LibraryDependencyData> projectLibrariesToImport,
|
||||
@NotNull Set<LibraryDependencyData> toImport,
|
||||
@NotNull ModifiableRootModel moduleRootModel,
|
||||
boolean hasUnresolvedLibraries) {
|
||||
Set<String> moduleLibraryKey = ContainerUtilRt.newHashSet();
|
||||
for (OrderEntry entry : moduleRootModel.getOrderEntries()) {
|
||||
if (entry instanceof ModuleLibraryOrderEntryImpl) {
|
||||
ModuleLibraryOrderEntryImpl moduleLibraryOrderEntry = (ModuleLibraryOrderEntryImpl)entry;
|
||||
Library library = moduleLibraryOrderEntry.getLibrary();
|
||||
if (library == null) {
|
||||
LOG.warn("Skipping module-level library entry because it doesn't have backing Library object. Entry: " + entry);
|
||||
continue;
|
||||
}
|
||||
moduleLibraryKey.clear();
|
||||
for (VirtualFile file : library.getFiles(OrderRootType.CLASSES)) {
|
||||
moduleLibraryKey.add(ExternalSystemApiUtil.getLocalFileSystemPath(file) + moduleLibraryOrderEntry.getScope().name());
|
||||
}
|
||||
LibraryDependencyData existing = moduleLibrariesToImport.remove(moduleLibraryKey);
|
||||
if (existing == null) {
|
||||
moduleRootModel.removeOrderEntry(entry);
|
||||
}
|
||||
else {
|
||||
syncExistingLibraryDependency(existing, library, moduleRootModel, moduleLibraryOrderEntry.getOwnerModule());
|
||||
toImport.remove(existing);
|
||||
}
|
||||
LibraryOrderEntry orderEntry = moduleRootModel.addLibraryEntry(projectLib);
|
||||
setLibraryScope(orderEntry, projectLib, module, dependencyData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void setLibraryScope(@NotNull LibraryOrderEntry orderEntry,
|
||||
@NotNull Library lib,
|
||||
@NotNull Module module,
|
||||
@NotNull LibraryDependencyData dependencyData) {
|
||||
LOG.debug(String.format("Adding library dependency '%s' to module '%s'", lib.getName(), module.getName()));
|
||||
orderEntry.setExported(dependencyData.isExported());
|
||||
orderEntry.setScope(dependencyData.getScope());
|
||||
LOG.debug(String.format(
|
||||
"Configuring library dependency '%s' of module '%s' to be%s exported and have scope %s",
|
||||
lib.getName(), module.getName(), dependencyData.isExported() ? " not" : "", dependencyData.getScope()
|
||||
));
|
||||
}
|
||||
|
||||
private void syncExistingAndRemoveObsolete(@NotNull Map<Set<String>, LibraryDependencyData> moduleLibrariesToImport,
|
||||
@NotNull Map<String, LibraryDependencyData> projectLibrariesToImport,
|
||||
@NotNull Set<LibraryDependencyData> toImport,
|
||||
@NotNull ModifiableRootModel moduleRootModel,
|
||||
boolean hasUnresolvedLibraries) {
|
||||
Set<String> moduleLibraryKey = ContainerUtilRt.newHashSet();
|
||||
for (OrderEntry entry : moduleRootModel.getOrderEntries()) {
|
||||
if (entry instanceof ModuleLibraryOrderEntryImpl) {
|
||||
ModuleLibraryOrderEntryImpl moduleLibraryOrderEntry = (ModuleLibraryOrderEntryImpl)entry;
|
||||
Library library = moduleLibraryOrderEntry.getLibrary();
|
||||
if (library == null) {
|
||||
LOG.warn("Skipping module-level library entry because it doesn't have backing Library object. Entry: " + entry);
|
||||
continue;
|
||||
}
|
||||
moduleLibraryKey.clear();
|
||||
for (VirtualFile file : library.getFiles(OrderRootType.CLASSES)) {
|
||||
moduleLibraryKey.add(ExternalSystemApiUtil.getLocalFileSystemPath(file) + moduleLibraryOrderEntry.getScope().name());
|
||||
}
|
||||
LibraryDependencyData existing = moduleLibrariesToImport.remove(moduleLibraryKey);
|
||||
if (existing == null) {
|
||||
moduleRootModel.removeOrderEntry(entry);
|
||||
}
|
||||
else {
|
||||
syncExistingLibraryDependency(existing, library, moduleRootModel, moduleLibraryOrderEntry.getOwnerModule());
|
||||
toImport.remove(existing);
|
||||
}
|
||||
}
|
||||
else if (entry instanceof LibraryOrderEntry) {
|
||||
final LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)entry;
|
||||
final String libraryName = libraryOrderEntry.getLibraryName();
|
||||
final LibraryDependencyData existing = projectLibrariesToImport.remove(libraryName + libraryOrderEntry.getScope().name());
|
||||
if (existing != null) {
|
||||
toImport.remove(existing);
|
||||
}
|
||||
else if (!hasUnresolvedLibraries) {
|
||||
// There is a possible case that a project has been successfully imported from external model and after
|
||||
// that network/repo goes down. We don't want to drop existing binary mappings then.
|
||||
moduleRootModel.removeOrderEntry(entry);
|
||||
else if (entry instanceof LibraryOrderEntry) {
|
||||
LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)entry;
|
||||
String libraryName = libraryOrderEntry.getLibraryName();
|
||||
LibraryDependencyData existing = projectLibrariesToImport.remove(libraryName + libraryOrderEntry.getScope().name());
|
||||
if (existing != null) {
|
||||
toImport.remove(existing);
|
||||
}
|
||||
else if (!hasUnresolvedLibraries) {
|
||||
// There is a possible case that a project has been successfully imported from external model and after
|
||||
// that network/repo goes down. We don't want to drop existing binary mappings then.
|
||||
moduleRootModel.removeOrderEntry(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void syncExistingLibraryDependency(@NotNull LibraryDependencyData libraryDependencyData,
|
||||
@NotNull Library library,
|
||||
@NotNull ModifiableRootModel moduleRootModel,
|
||||
@NotNull Module module) {
|
||||
final Library.ModifiableModel libModel = library.getModifiableModel();
|
||||
try {
|
||||
final String libraryName = libraryDependencyData.getInternalName();
|
||||
private void syncExistingLibraryDependency(@NotNull LibraryDependencyData libraryDependencyData,
|
||||
@NotNull Library library,
|
||||
@NotNull ModifiableRootModel moduleRootModel,
|
||||
@NotNull Module module) {
|
||||
Library.ModifiableModel libModel = library.getModifiableModel();
|
||||
String libraryName = libraryDependencyData.getInternalName();
|
||||
Map<OrderRootType, Collection<File>> files = myLibraryManager.prepareLibraryFiles(libraryDependencyData.getTarget());
|
||||
myLibraryManager.registerPaths(files, libModel, libraryName);
|
||||
LibraryOrderEntry orderEntry = moduleRootModel.findLibraryOrderEntry(library);
|
||||
assert orderEntry != null;
|
||||
setLibraryScope(orderEntry, library, module, libraryDependencyData);
|
||||
}
|
||||
finally {
|
||||
libModel.commit();
|
||||
myLibraryModels.add(libModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+89
-84
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.openapi.externalSystem.service.project.manage;
|
||||
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.externalSystem.model.DataNode;
|
||||
@@ -39,6 +38,7 @@ import com.intellij.ui.CheckBoxList;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ExceptionUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -52,11 +52,10 @@ import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Encapsulates functionality of importing external system module to the intellij project.
|
||||
*
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 2/7/12 2:49 PM
|
||||
*/
|
||||
@@ -74,82 +73,72 @@ public class ModuleDataService extends AbstractProjectDataService<ModuleData, Mo
|
||||
}
|
||||
|
||||
@Override
|
||||
public void importData(@NotNull final Collection<DataNode<ModuleData>> toImport,
|
||||
public void importData(@NotNull Collection<DataNode<ModuleData>> toImport,
|
||||
@Nullable ProjectData projectData,
|
||||
@NotNull final Project project,
|
||||
@NotNull final PlatformFacade platformFacade,
|
||||
final boolean synchronous) {
|
||||
@NotNull Project project,
|
||||
@NotNull PlatformFacade platformFacade,
|
||||
boolean synchronous) {
|
||||
if (toImport.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
ExternalSystemApiUtil.executeProjectChangeAction(synchronous, new DisposeAwareProjectChange(project) {
|
||||
@Override
|
||||
public void execute() {
|
||||
final Collection<DataNode<ModuleData>> toCreate = filterExistingModules(toImport, project, platformFacade);
|
||||
if (!toCreate.isEmpty()) {
|
||||
createModules(toCreate, project, platformFacade);
|
||||
}
|
||||
for (DataNode<ModuleData> node : toImport) {
|
||||
Module module = platformFacade.findIdeModule(node.getData(), project);
|
||||
if (module != null) {
|
||||
syncPaths(module, platformFacade, node.getData());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
Collection<DataNode<ModuleData>> toCreate = filterExistingModules(toImport, project, platformFacade);
|
||||
if (!toCreate.isEmpty()) {
|
||||
ExternalSystemApiUtil.commitModels(synchronous, project, createModules(project, platformFacade, toCreate));
|
||||
}
|
||||
ExternalSystemApiUtil.commitModels(synchronous, project, syncModulesPaths(project, platformFacade, toImport));
|
||||
}
|
||||
|
||||
private static void createModules(@NotNull final Collection<DataNode<ModuleData>> toCreate,
|
||||
@NotNull final Project project,
|
||||
@NotNull final PlatformFacade platformFacade) {
|
||||
Application application = ApplicationManager.getApplication();
|
||||
final Map<DataNode<ModuleData>, Module> moduleMappings = ContainerUtilRt.newHashMap();
|
||||
application.runWriteAction(new Runnable() {
|
||||
@NotNull
|
||||
private static List<ModifiableRootModel> createModules(@NotNull Project project,
|
||||
@NotNull PlatformFacade platformFacade,
|
||||
Collection<DataNode<ModuleData>> toCreate) {
|
||||
List<ModifiableRootModel> models = ContainerUtilRt.newArrayList();
|
||||
try {
|
||||
for (DataNode<ModuleData> moduleData : toCreate) {
|
||||
models.add(createModule(project, platformFacade, moduleData));
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
ExternalSystemApiUtil.disposeModels(models);
|
||||
ExceptionUtil.rethrowAllAsUnchecked(t);
|
||||
}
|
||||
return models;
|
||||
}
|
||||
|
||||
private static ModifiableRootModel createModule(@NotNull Project project,
|
||||
@NotNull PlatformFacade platformFacade,
|
||||
@NotNull DataNode<ModuleData> module) {
|
||||
ModuleData data = module.getData();
|
||||
Module created = platformFacade.newModule(project, data.getModuleFilePath(), data.getModuleTypeId());
|
||||
|
||||
// Ensure that the dependencies are clear (used to be not clear when manually removing the module and importing it via gradle)
|
||||
final ModifiableRootModel moduleRootModel = platformFacade.getModuleModifiableModel(created);
|
||||
moduleRootModel.inheritSdk();
|
||||
setModuleOptions(created, module);
|
||||
|
||||
RootPolicy<Object> visitor = new RootPolicy<Object>() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (DataNode<ModuleData> module : toCreate) {
|
||||
importModule(module);
|
||||
}
|
||||
public Object visitLibraryOrderEntry(LibraryOrderEntry libraryOrderEntry, Object value) {
|
||||
moduleRootModel.removeOrderEntry(libraryOrderEntry);
|
||||
return value;
|
||||
}
|
||||
|
||||
private void importModule(@NotNull DataNode<ModuleData> module) {
|
||||
ModuleData data = module.getData();
|
||||
final Module created = platformFacade.newModule(project, data.getModuleFilePath(), data.getModuleTypeId());
|
||||
|
||||
// Ensure that the dependencies are clear (used to be not clear when manually removing the module and importing it via gradle)
|
||||
final ModifiableRootModel moduleRootModel = platformFacade.getModuleModifiableModel(created);
|
||||
moduleRootModel.inheritSdk();
|
||||
setModuleOptions(created, module);
|
||||
|
||||
RootPolicy<Object> visitor = new RootPolicy<Object>() {
|
||||
@Override
|
||||
public Object visitLibraryOrderEntry(LibraryOrderEntry libraryOrderEntry, Object value) {
|
||||
moduleRootModel.removeOrderEntry(libraryOrderEntry);
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitModuleOrderEntry(ModuleOrderEntry moduleOrderEntry, Object value) {
|
||||
moduleRootModel.removeOrderEntry(moduleOrderEntry);
|
||||
return value;
|
||||
}
|
||||
};
|
||||
try {
|
||||
for (OrderEntry orderEntry : moduleRootModel.getOrderEntries()) {
|
||||
orderEntry.accept(visitor, null);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
moduleRootModel.commit();
|
||||
}
|
||||
moduleMappings.put(module, created);
|
||||
@Override
|
||||
public Object visitModuleOrderEntry(ModuleOrderEntry moduleOrderEntry, Object value) {
|
||||
moduleRootModel.removeOrderEntry(moduleOrderEntry);
|
||||
return value;
|
||||
}
|
||||
});
|
||||
};
|
||||
for (OrderEntry orderEntry : moduleRootModel.getOrderEntries()) {
|
||||
orderEntry.accept(visitor, null);
|
||||
}
|
||||
return moduleRootModel;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Collection<DataNode<ModuleData>> filterExistingModules(@NotNull Collection<DataNode<ModuleData>> modules,
|
||||
@NotNull Project project, @NotNull PlatformFacade platformFacade)
|
||||
@NotNull Project project,
|
||||
@NotNull PlatformFacade platformFacade)
|
||||
{
|
||||
Collection<DataNode<ModuleData>> result = ContainerUtilRt.newArrayList();
|
||||
for (DataNode<ModuleData> node : modules) {
|
||||
@@ -165,30 +154,46 @@ public class ModuleDataService extends AbstractProjectDataService<ModuleData, Mo
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void syncPaths(@NotNull Module module, @NotNull PlatformFacade platformFacade, @NotNull ModuleData data) {
|
||||
@NotNull
|
||||
private List<ModifiableRootModel> syncModulesPaths(@NotNull Project project,
|
||||
@NotNull PlatformFacade platformFacade,
|
||||
Collection<DataNode<ModuleData>> toCreate) {
|
||||
List<ModifiableRootModel> models = ContainerUtilRt.newArrayList();
|
||||
try {
|
||||
for (DataNode<ModuleData> moduleData : toCreate) {
|
||||
Module module = platformFacade.findIdeModule(moduleData.getData(), project);
|
||||
if (module != null) {
|
||||
models.add(syncPaths(module, platformFacade, moduleData.getData()));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
ExternalSystemApiUtil.disposeModels(models);
|
||||
ExceptionUtil.rethrowAllAsUnchecked(t);
|
||||
}
|
||||
return models;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ModifiableRootModel syncPaths(@NotNull Module module, @NotNull PlatformFacade platformFacade, @NotNull ModuleData data) {
|
||||
ModifiableRootModel modifiableModel = platformFacade.getModuleModifiableModel(module);
|
||||
CompilerModuleExtension extension = modifiableModel.getModuleExtension(CompilerModuleExtension.class);
|
||||
if (extension == null) {
|
||||
modifiableModel.dispose();
|
||||
LOG.warn(String.format("Can't sync paths for module '%s'. Reason: no compiler extension is found for it", module.getName()));
|
||||
return;
|
||||
return modifiableModel;
|
||||
}
|
||||
String compileOutputPath = data.getCompileOutputPath(ExternalSystemSourceType.SOURCE);
|
||||
if (compileOutputPath != null) {
|
||||
extension.setCompilerOutputPath(VfsUtilCore.pathToUrl(compileOutputPath));
|
||||
}
|
||||
try {
|
||||
String compileOutputPath = data.getCompileOutputPath(ExternalSystemSourceType.SOURCE);
|
||||
if (compileOutputPath != null) {
|
||||
extension.setCompilerOutputPath(VfsUtilCore.pathToUrl(compileOutputPath));
|
||||
}
|
||||
|
||||
String testCompileOutputPath = data.getCompileOutputPath(ExternalSystemSourceType.TEST);
|
||||
if (testCompileOutputPath != null) {
|
||||
extension.setCompilerOutputPathForTests(VfsUtilCore.pathToUrl(testCompileOutputPath));
|
||||
}
|
||||
String testCompileOutputPath = data.getCompileOutputPath(ExternalSystemSourceType.TEST);
|
||||
if (testCompileOutputPath != null) {
|
||||
extension.setCompilerOutputPathForTests(VfsUtilCore.pathToUrl(testCompileOutputPath));
|
||||
}
|
||||
|
||||
extension.inheritCompilerOutputPath(data.isInheritProjectCompileOutputPath());
|
||||
}
|
||||
finally {
|
||||
modifiableModel.commit();
|
||||
}
|
||||
extension.inheritCompilerOutputPath(data.isInheritProjectCompileOutputPath());
|
||||
return modifiableModel;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -340,7 +345,7 @@ public class ModuleDataService extends AbstractProjectDataService<ModuleData, Mo
|
||||
protected JComponent createCenterPanel() {
|
||||
return new JBScrollPane(content);
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
protected Action[] createActions() {
|
||||
return new Action[]{getOKAction()};
|
||||
@@ -377,7 +382,7 @@ public class ModuleDataService extends AbstractProjectDataService<ModuleData, Mo
|
||||
module.setOption(ExternalSystemConstants.EXTERNAL_SYSTEM_ID_KEY, moduleData.getOwner().toString());
|
||||
module.setOption(ExternalSystemConstants.LINKED_PROJECT_ID_KEY, moduleData.getId());
|
||||
module.setOption(ExternalSystemConstants.LINKED_PROJECT_PATH_KEY, moduleData.getLinkedExternalProjectPath());
|
||||
final ProjectData projectData = moduleDataNode.getData(ProjectKeys.PROJECT);
|
||||
ProjectData projectData = moduleDataNode.getData(ProjectKeys.PROJECT);
|
||||
module.setOption(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY, projectData != null ? projectData.getLinkedExternalProjectPath() : "");
|
||||
|
||||
if (moduleData.getGroup() != null) {
|
||||
|
||||
+64
-69
@@ -19,23 +19,18 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.externalSystem.model.DataNode;
|
||||
import com.intellij.openapi.externalSystem.model.Key;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectKeys;
|
||||
import com.intellij.openapi.externalSystem.model.project.LibraryDependencyData;
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData;
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleDependencyData;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.project.PlatformFacade;
|
||||
import com.intellij.openapi.externalSystem.util.DisposeAwareProjectChange;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
|
||||
import com.intellij.openapi.externalSystem.util.Order;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ExceptionUtil;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -68,17 +63,25 @@ public class ModuleDependencyDataService extends AbstractDependencyDataService<M
|
||||
@NotNull Project project,
|
||||
@NotNull PlatformFacade platformFacade,
|
||||
boolean synchronous) {
|
||||
MultiMap<DataNode<ModuleData>, DataNode<ModuleDependencyData>> byModule = ExternalSystemApiUtil.groupBy(toImport, MODULE);
|
||||
for (Map.Entry<DataNode<ModuleData>, Collection<DataNode<ModuleDependencyData>>> entry : byModule.entrySet()) {
|
||||
Module ideModule = platformFacade.findIdeModule(entry.getKey().getData(), project);
|
||||
if (ideModule == null) {
|
||||
LOG.warn(String.format(
|
||||
"Can't import module dependencies %s. Reason: target module (%s) is not found at the ide and can't be imported",
|
||||
entry.getValue(), entry.getKey()
|
||||
));
|
||||
continue;
|
||||
List<ModifiableRootModel> models = ContainerUtilRt.newArrayList();
|
||||
try {
|
||||
MultiMap<DataNode<ModuleData>, DataNode<ModuleDependencyData>> byModule = ExternalSystemApiUtil.groupBy(toImport, MODULE);
|
||||
for (Map.Entry<DataNode<ModuleData>, Collection<DataNode<ModuleDependencyData>>> entry : byModule.entrySet()) {
|
||||
Module ideModule = platformFacade.findIdeModule(entry.getKey().getData(), project);
|
||||
if (ideModule == null) {
|
||||
LOG.warn(String.format(
|
||||
"Can't import module dependencies %s. Reason: target module (%s) is not found at the ide and can't be imported",
|
||||
entry.getValue(), entry.getKey()
|
||||
));
|
||||
continue;
|
||||
}
|
||||
models.add(importData(entry.getValue(), ideModule, platformFacade));
|
||||
}
|
||||
importData(entry.getValue(), ideModule, platformFacade, synchronous);
|
||||
ExternalSystemApiUtil.commitModels(synchronous, project, models);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
ExternalSystemApiUtil.disposeModels(models);
|
||||
ExceptionUtil.rethrowAllAsUnchecked(t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,62 +96,54 @@ public class ModuleDependencyDataService extends AbstractDependencyDataService<M
|
||||
return orderEntry.getModuleName();
|
||||
}
|
||||
|
||||
private void importData(@NotNull final Collection<DataNode<ModuleDependencyData>> toImport,
|
||||
@NotNull final Module module,
|
||||
@NotNull final PlatformFacade platformFacade,
|
||||
final boolean synchronous)
|
||||
@NotNull
|
||||
private ModifiableRootModel importData(@NotNull Collection<DataNode<ModuleDependencyData>> toImport,
|
||||
@NotNull Module module,
|
||||
@NotNull PlatformFacade platformFacade)
|
||||
{
|
||||
ExternalSystemApiUtil.executeProjectChangeAction(synchronous, new DisposeAwareProjectChange(module) {
|
||||
@Override
|
||||
public void execute() {
|
||||
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
|
||||
Map<Pair<String /* dependency module internal name */, /* dependency module scope */DependencyScope> , ModuleOrderEntry> toRemove = ContainerUtilRt.newHashMap();
|
||||
for (OrderEntry entry : moduleRootManager.getOrderEntries()) {
|
||||
if (entry instanceof ModuleOrderEntry) {
|
||||
ModuleOrderEntry e = (ModuleOrderEntry)entry;
|
||||
toRemove.put(Pair.create(e.getModuleName(), e.getScope()), e);
|
||||
}
|
||||
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
|
||||
Map<Pair<String /* dependency module internal name */, /* dependency module scope */DependencyScope>, ModuleOrderEntry> toRemove =
|
||||
ContainerUtilRt.newHashMap();
|
||||
for (OrderEntry entry : moduleRootManager.getOrderEntries()) {
|
||||
if (entry instanceof ModuleOrderEntry) {
|
||||
ModuleOrderEntry e = (ModuleOrderEntry)entry;
|
||||
toRemove.put(Pair.create(e.getModuleName(), e.getScope()), e);
|
||||
}
|
||||
}
|
||||
|
||||
ModifiableRootModel moduleRootModel = platformFacade.getModuleModifiableModel(module);
|
||||
for (DataNode<ModuleDependencyData> dependencyNode : toImport) {
|
||||
ModuleDependencyData dependencyData = dependencyNode.getData();
|
||||
toRemove.remove(Pair.create(dependencyData.getInternalName(), dependencyData.getScope()));
|
||||
String moduleName = dependencyData.getInternalName();
|
||||
Module ideDependencyModule = platformFacade.findIdeModule(moduleName, module.getProject());
|
||||
|
||||
ModuleOrderEntry orderEntry;
|
||||
if (module.equals(ideDependencyModule)) {
|
||||
// skip recursive module dependency check
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
if (ideDependencyModule == null) {
|
||||
LOG.warn(String.format("Can't import module dependency for '%s' module. Reason: target module (%s) is not found at the ide",
|
||||
module.getName(), dependencyData));
|
||||
}
|
||||
|
||||
final ModifiableRootModel moduleRootModel = platformFacade.getModuleModifiableModel(module);
|
||||
try {
|
||||
for (DataNode<ModuleDependencyData> dependencyNode : toImport) {
|
||||
final ModuleDependencyData dependencyData = dependencyNode.getData();
|
||||
toRemove.remove(Pair.create(dependencyData.getInternalName(), dependencyData.getScope()));
|
||||
final String moduleName = dependencyData.getInternalName();
|
||||
Module ideDependencyModule = platformFacade.findIdeModule(moduleName, module.getProject());
|
||||
|
||||
ModuleOrderEntry orderEntry;
|
||||
if (module.equals(ideDependencyModule)) {
|
||||
// skip recursive module dependency check
|
||||
continue;
|
||||
} else {
|
||||
if(ideDependencyModule == null) {
|
||||
LOG.warn(String.format(
|
||||
"Can't import module dependency for '%s' module. Reason: target module (%s) is not found at the ide",
|
||||
module.getName(), dependencyData
|
||||
));
|
||||
}
|
||||
orderEntry = platformFacade.findIdeModuleDependency(dependencyData, moduleRootModel);
|
||||
if (orderEntry == null) {
|
||||
orderEntry = ideDependencyModule == null
|
||||
? moduleRootModel.addInvalidModuleEntry(moduleName)
|
||||
: moduleRootModel.addModuleOrderEntry(ideDependencyModule);
|
||||
}
|
||||
}
|
||||
|
||||
orderEntry.setScope(dependencyData.getScope());
|
||||
orderEntry.setExported(dependencyData.isExported());
|
||||
}
|
||||
}
|
||||
finally {
|
||||
moduleRootModel.commit();
|
||||
}
|
||||
|
||||
if (!toRemove.isEmpty()) {
|
||||
removeData(toRemove.values(), module, platformFacade, synchronous);
|
||||
orderEntry = platformFacade.findIdeModuleDependency(dependencyData, moduleRootModel);
|
||||
if (orderEntry == null) {
|
||||
orderEntry = ideDependencyModule == null
|
||||
? moduleRootModel.addInvalidModuleEntry(moduleName)
|
||||
: moduleRootModel.addModuleOrderEntry(ideDependencyModule);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
orderEntry.setScope(dependencyData.getScope());
|
||||
orderEntry.setExported(dependencyData.isExported());
|
||||
}
|
||||
|
||||
if (!toRemove.isEmpty()) {
|
||||
removeData(toRemove.values(), moduleRootModel);
|
||||
}
|
||||
|
||||
return moduleRootModel;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-13
@@ -18,8 +18,7 @@ package com.intellij.openapi.module.impl.scopes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.openapi.roots.libraries.LibraryUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -27,26 +26,18 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public class LibraryScope extends LibraryScopeBase {
|
||||
private final Library myLibrary;
|
||||
private final String myLibraryName;
|
||||
|
||||
public LibraryScope(Project project, Library library) {
|
||||
super(project, library.getFiles(OrderRootType.CLASSES), library.getFiles(OrderRootType.SOURCES));
|
||||
myLibraryName = LibraryUtil.getPresentableName(library);
|
||||
myLibrary = library;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
String name = myLibrary.getName();
|
||||
if (name == null) {
|
||||
String[] urls = myLibrary.getUrls(OrderRootType.CLASSES);
|
||||
if (urls.length > 0) {
|
||||
name = PathUtil.getFileName(VfsUtilCore.urlToPath(urls[0]));
|
||||
}
|
||||
else {
|
||||
name = "empty";
|
||||
}
|
||||
}
|
||||
return "Library '" + name + "'";
|
||||
return "Library '" + myLibraryName + "'";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -32,26 +32,25 @@ public interface LineMarkerProvider {
|
||||
* Get line markers for this PsiElement.
|
||||
* <p/>
|
||||
* NOTE for implementers:
|
||||
* Please return line marker info for exact element you were asked for.
|
||||
* For example, do not return class marker info if getLineMarkerInfo() was called for a method.
|
||||
* Please return relevant line marker info for as small element as possible.
|
||||
* For example, do not return method marker for PsiMethod. Instead, return it for the PsiIdentifier which is a name of this method.
|
||||
* Please return line marker info for the exact element you were asked for, which is as small as possible.
|
||||
* For example, instead of returning method marker for PsiMethod,
|
||||
* return it for the PsiIdentifier which is a name of this method.
|
||||
* <p/>
|
||||
* More technical details:
|
||||
* Inspection (specifically, LineMarkersPass) for performance reasons queries all LineMarkerProviders in two passes:
|
||||
* More technical details:<p>
|
||||
* IDEA highlighting (specifically, LineMarkersPass) queries all LineMarkerProviders in two passes (for performance reasons):
|
||||
* <ul>
|
||||
* <li>first pass for all elements in visible area</li>
|
||||
* <li>second pass for all the rest elements</li>
|
||||
* </ul>
|
||||
* If providers return nothing for either area, its line markers are cleared.
|
||||
* If providers returned nothing for both areas, its line markers are cleared.
|
||||
* <p/>
|
||||
* So if, for example a method, is half-visible (e.g. its name is visible but a part of its body isn't) and
|
||||
* some poorly written LineMarkerProvider returns info for the PsiMethod instead of PsiIdentifier then following happens:
|
||||
* So if, for example, a method is half-visible (e.g. its name is visible but a part of its body isn't) and
|
||||
* some poorly written LineMarkerProvider returned info for the PsiMethod instead of PsiIdentifier then following would happen:
|
||||
* <ul>
|
||||
* <li>the first pass removes line marker info because whole PsiMethod is not visible</li>
|
||||
* <li>the second pass tries to add line marker info back because LineMarkerProvider is called for the PsiMethod at last</li>
|
||||
* <li>the first pass would remove line marker info because the whole PsiMethod isn't visible</li>
|
||||
* <li>the second pass would try to add line marker info back because LineMarkerProvider was called for the PsiMethod at last</li>
|
||||
* </ul>
|
||||
* As a result, line marker icon blinks annoyingly.
|
||||
* As a result, line marker icon would blink annoyingly.
|
||||
*/
|
||||
@Nullable
|
||||
LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element);
|
||||
|
||||
+35
-8
@@ -26,30 +26,36 @@ import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IconUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
class GutterIntentionAction extends AbstractIntentionAction implements Comparable<IntentionAction> {
|
||||
class GutterIntentionAction extends AbstractIntentionAction implements Comparable<IntentionAction>, Iconable {
|
||||
private final AnAction myAction;
|
||||
private final int myOrder;
|
||||
private final Icon myIcon;
|
||||
private String myText;
|
||||
|
||||
private GutterIntentionAction(AnAction action, int order) {
|
||||
private GutterIntentionAction(AnAction action, int order, Icon icon) {
|
||||
myAction = action;
|
||||
myOrder = order;
|
||||
myIcon = icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -96,10 +102,26 @@ class GutterIntentionAction extends AbstractIntentionAction implements Comparabl
|
||||
if (renderer == null || DumbService.isDumb(project) && !DumbService.isDumbAware(renderer)) {
|
||||
return;
|
||||
}
|
||||
addActions(project, editor, psiFile, renderer.getClickAction(), descriptors, renderer, 0);
|
||||
addActions(project, editor, psiFile, renderer.getMiddleButtonClickAction(), descriptors, renderer, 0);
|
||||
addActions(project, editor, psiFile, renderer.getRightButtonClickAction(), descriptors, renderer, 0);
|
||||
addActions(project, editor, psiFile, renderer.getPopupMenuActions(), descriptors, renderer, 0);
|
||||
List<HighlightInfo.IntentionActionDescriptor> list = new ArrayList<HighlightInfo.IntentionActionDescriptor>();
|
||||
addActions(project, editor, psiFile, renderer.getClickAction(), list, renderer, 0);
|
||||
addActions(project, editor, psiFile, renderer.getMiddleButtonClickAction(), list, renderer, 0);
|
||||
addActions(project, editor, psiFile, renderer.getRightButtonClickAction(), list, renderer, 0);
|
||||
addActions(project, editor, psiFile, renderer.getPopupMenuActions(), list, renderer, 0);
|
||||
if (list.isEmpty()) return;
|
||||
if (list.size() == 1) {
|
||||
descriptors.addAll(list);
|
||||
}
|
||||
else {
|
||||
HighlightInfo.IntentionActionDescriptor first = list.get(0);
|
||||
List<IntentionAction> options = ContainerUtil.map(list.subList(1, list.size()),
|
||||
new Function<HighlightInfo.IntentionActionDescriptor, IntentionAction>() {
|
||||
@Override
|
||||
public IntentionAction fun(HighlightInfo.IntentionActionDescriptor descriptor) {
|
||||
return descriptor.getAction();
|
||||
}
|
||||
});
|
||||
descriptors.add(new HighlightInfo.IntentionActionDescriptor(first.getAction(), options, first.getDisplayName(), first.getIcon()));
|
||||
}
|
||||
}
|
||||
|
||||
private static void addActions(@NotNull Project project,
|
||||
@@ -119,11 +141,11 @@ class GutterIntentionAction extends AbstractIntentionAction implements Comparabl
|
||||
addActions(project, editor, psiFile, child, descriptors, renderer, i + order);
|
||||
}
|
||||
}
|
||||
final IntentionAction gutterAction = new GutterIntentionAction(action, order);
|
||||
if (!gutterAction.isAvailable(project, editor, psiFile)) return;
|
||||
Icon icon = action.getTemplatePresentation().getIcon();
|
||||
if (icon == null) icon = renderer.getIcon();
|
||||
if (icon.getIconWidth() < 16) icon = IconUtil.toSize(icon, 16, 16);
|
||||
final IntentionAction gutterAction = new GutterIntentionAction(action, order, icon);
|
||||
if (!gutterAction.isAvailable(project, editor, psiFile)) return;
|
||||
HighlightInfo.IntentionActionDescriptor descriptor =
|
||||
new HighlightInfo.IntentionActionDescriptor(gutterAction, Collections.<IntentionAction>emptyList(), null, icon) {
|
||||
@Nullable
|
||||
@@ -143,4 +165,9 @@ class GutterIntentionAction extends AbstractIntentionAction implements Comparabl
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIcon(@IconFlags int flags) {
|
||||
return myIcon;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-5
@@ -48,9 +48,7 @@ import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
public class InjectedGeneralHighlightingPass extends GeneralHighlightingPass implements DumbAware {
|
||||
private static final String PRESENTABLE_NAME = "Injected fragments";
|
||||
@@ -421,9 +419,8 @@ public class InjectedGeneralHighlightingPass extends GeneralHighlightingPass imp
|
||||
TextAttributes.ERASE_MARKER).createUnconditionally();
|
||||
holder.add(info);
|
||||
|
||||
Color back = attributes.getBackgroundColor() == null ? myGlobalScheme.getDefaultBackground() : attributes.getBackgroundColor();
|
||||
Color fore = attributes.getForegroundColor() == null ? myGlobalScheme.getDefaultForeground() : attributes.getForegroundColor();
|
||||
forcedAttributes = new TextAttributes(fore, back, attributes.getEffectColor(), attributes.getEffectType(), attributes.getFontType());
|
||||
forcedAttributes = new TextAttributes(attributes.getForegroundColor(), attributes.getBackgroundColor(),
|
||||
attributes.getEffectColor(), attributes.getEffectType(), attributes.getFontType());
|
||||
}
|
||||
|
||||
HighlightInfo info =
|
||||
|
||||
+5
-2
@@ -104,8 +104,7 @@ public abstract class DockablePopupManager<T extends JComponent & Disposable> {
|
||||
myToolWindow.setAvailable(true, null);
|
||||
myToolWindow.setToHideOnEmptyContent(false);
|
||||
|
||||
final Rectangle rectangle = WindowManager.getInstance().getIdeFrame(myProject).suggestChildFrameBounds();
|
||||
myToolWindow.setDefaultState(ToolWindowAnchor.RIGHT, ToolWindowType.FLOATING, rectangle);
|
||||
setToolwindowDefaultState();
|
||||
|
||||
((ToolWindowEx)myToolWindow).setTitleActions(createRestorePopupAction());
|
||||
|
||||
@@ -139,6 +138,10 @@ public abstract class DockablePopupManager<T extends JComponent & Disposable> {
|
||||
doUpdateComponent(element, originalElement, component);
|
||||
}
|
||||
|
||||
protected void setToolwindowDefaultState() {
|
||||
final Rectangle rectangle = WindowManager.getInstance().getIdeFrame(myProject).suggestChildFrameBounds();
|
||||
myToolWindow.setDefaultState(ToolWindowAnchor.RIGHT, ToolWindowType.FLOATING, rectangle);
|
||||
}
|
||||
|
||||
protected AnAction[] createActions() {
|
||||
ToggleAction toggleAutoUpdateAction = new ToggleAction(getAutoUpdateTitle(), getAutoUpdateDescription(),
|
||||
|
||||
@@ -118,12 +118,7 @@ public class TemplateState implements Disposable {
|
||||
|
||||
@Override
|
||||
public void commandStarted(CommandEvent event) {
|
||||
if (myEditor != null) {
|
||||
final int offset = myEditor.getCaretModel().getOffset();
|
||||
myDocumentChangesTerminateTemplate = myCurrentSegmentNumber >= 0 &&
|
||||
(offset < mySegments.getSegmentStart(myCurrentSegmentNumber) ||
|
||||
offset > mySegments.getSegmentEnd(myCurrentSegmentNumber));
|
||||
}
|
||||
myDocumentChangesTerminateTemplate = isCaretOutsideCurrentSegment();
|
||||
started = true;
|
||||
}
|
||||
|
||||
@@ -170,6 +165,14 @@ public class TemplateState implements Disposable {
|
||||
CommandProcessor.getInstance().addCommandListener(myCommandListener, this);
|
||||
}
|
||||
|
||||
private boolean isCaretOutsideCurrentSegment() {
|
||||
if (myEditor != null) {
|
||||
final int offset = myEditor.getCaretModel().getOffset();
|
||||
return offset < mySegments.getSegmentStart(myCurrentSegmentNumber) || offset > mySegments.getSegmentEnd(myCurrentSegmentNumber);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isMultiCaretMode() {
|
||||
return myEditor != null && myEditor.getCaretModel().getCaretCount() > 1;
|
||||
}
|
||||
@@ -188,6 +191,9 @@ public class TemplateState implements Disposable {
|
||||
}
|
||||
|
||||
public boolean isToProcessTab() {
|
||||
if (isCaretOutsideCurrentSegment()) {
|
||||
return false;
|
||||
}
|
||||
if (ourLookupShown) {
|
||||
final LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
|
||||
if (lookup != null && !lookup.isFocused()) {
|
||||
|
||||
@@ -1212,9 +1212,9 @@ public class FindDialog extends DialogWrapper {
|
||||
|
||||
|
||||
ButtonGroup bgScope = new ButtonGroup();
|
||||
bgScope.add(myRbDirectory);
|
||||
bgScope.add(myRbProject);
|
||||
bgScope.add(myRbModule);
|
||||
bgScope.add(myRbDirectory);
|
||||
bgScope.add(myRbCustomScope);
|
||||
|
||||
ActionListener validateAll = new ActionListener() {
|
||||
|
||||
@@ -1652,6 +1652,7 @@ public class FormatProcessor {
|
||||
if (space.containsLineFeeds()) {
|
||||
myCurrentBlock = (LeafBlockWrapper)block;
|
||||
adjustIndent();
|
||||
adjustAlignmentsAfterCurrentBlock();
|
||||
}
|
||||
}
|
||||
else if (block instanceof CompositeBlockWrapper) {
|
||||
@@ -1662,6 +1663,20 @@ public class FormatProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
private void adjustAlignmentsAfterCurrentBlock() {
|
||||
LeafBlockWrapper current = myCurrentBlock.getNextBlock();
|
||||
while (current != null && !current.getWhiteSpace().containsLineFeeds()) {
|
||||
if (current.getAlignment() != null) {
|
||||
myCurrentBlock = current;
|
||||
WhiteSpace currentWhiteSpace = myCurrentBlock.getWhiteSpace();
|
||||
SpacingImpl currentSpaceProperty = myCurrentBlock.getSpaceProperty();
|
||||
currentWhiteSpace.arrangeSpaces(currentSpaceProperty);
|
||||
adjustIndent();
|
||||
}
|
||||
current = current.getNextBlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void prepare() {
|
||||
}
|
||||
|
||||
+10
-3
@@ -22,6 +22,8 @@ import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.DumbModePermission;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.roots.impl.DirectoryIndex;
|
||||
@@ -60,11 +62,16 @@ public abstract class MarkRootActionBase extends DumbAwareAction {
|
||||
modifyRoots(file, entry);
|
||||
}
|
||||
}
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
model.commit();
|
||||
module.getProject().save();
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
model.commit();
|
||||
module.getProject().save();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+7
-2
@@ -30,12 +30,17 @@ import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PsiAwareTextEditorImpl extends TextEditorImpl {
|
||||
private TextEditorBackgroundHighlighter myBackgroundHighlighter;
|
||||
|
||||
public PsiAwareTextEditorImpl(@NotNull final Project project, @NotNull final VirtualFile file, final TextEditorProvider provider) {
|
||||
super(project, file, provider);
|
||||
public PsiAwareTextEditorImpl(@NotNull Project project, @NotNull VirtualFile file, TextEditorProvider provider) {
|
||||
this(project, file, provider, null);
|
||||
}
|
||||
|
||||
PsiAwareTextEditorImpl(@NotNull Project project, @NotNull VirtualFile file, TextEditorProvider provider, @Nullable String name) {
|
||||
super(project, file, provider, name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ public class PsiAwareTextEditorProvider extends TextEditorProvider implements As
|
||||
return new Builder() {
|
||||
@Override
|
||||
public FileEditor build() {
|
||||
final PsiAwareTextEditorImpl editor = new PsiAwareTextEditorImpl(project, file, PsiAwareTextEditorProvider.this);
|
||||
PsiAwareTextEditorImpl editor = new PsiAwareTextEditorImpl(project, file, PsiAwareTextEditorProvider.this, getFileEditorName());
|
||||
if (finalState != null) {
|
||||
finalState.setToEditor(editor.getEditor());
|
||||
}
|
||||
|
||||
+9
-14
@@ -117,23 +117,18 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable
|
||||
}
|
||||
myOriginalToEditedMap.clear();
|
||||
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!myManager.isIgnoredFilesListEqualToCurrent(myFileTypePanel.myIgnoreFilesField.getText())) {
|
||||
myManager.setIgnoredFilesList(myFileTypePanel.myIgnoreFilesField.getText());
|
||||
}
|
||||
myManager.setPatternsTable(myTempFileTypes, myTempPatternsTable);
|
||||
for (FileNameMatcher matcher : myReassigned.keySet()) {
|
||||
myManager.getRemovedMappings().put(matcher, Pair.create(myReassigned.get(matcher), true));
|
||||
}
|
||||
if (!myManager.isIgnoredFilesListEqualToCurrent(myFileTypePanel.myIgnoreFilesField.getText())) {
|
||||
myManager.setIgnoredFilesList(myFileTypePanel.myIgnoreFilesField.getText());
|
||||
}
|
||||
myManager.setPatternsTable(myTempFileTypes, myTempPatternsTable);
|
||||
for (FileNameMatcher matcher : myReassigned.keySet()) {
|
||||
myManager.getRemovedMappings().put(matcher, Pair.create(myReassigned.get(matcher), true));
|
||||
}
|
||||
|
||||
TemplateDataLanguagePatterns.getInstance().setAssocTable(myTempTemplateDataLanguages);
|
||||
}
|
||||
});
|
||||
TemplateDataLanguagePatterns.getInstance().setAssocTable(myTempTemplateDataLanguages);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+2
-22
@@ -23,6 +23,7 @@ import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.wm.ToolWindowId;
|
||||
import com.intellij.packageDependencies.BackwardDependenciesBuilder;
|
||||
import com.intellij.packageDependencies.DependenciesBuilder;
|
||||
import com.intellij.packageDependencies.ForwardDependenciesBuilder;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -72,27 +73,6 @@ public class AnalyzeDependenciesOnSpecifiedTargetHandler extends DependenciesHan
|
||||
|
||||
@Override
|
||||
protected DependenciesBuilder createDependenciesBuilder(AnalysisScope scope) {
|
||||
return new ForwardDependenciesBuilder(myProject, scope) {
|
||||
@Override
|
||||
public void analyze() {
|
||||
super.analyze();
|
||||
final Map<PsiFile,Set<PsiFile>> dependencies = getDependencies();
|
||||
for (Iterator<PsiFile> leftTreeIterator = dependencies.keySet().iterator(); leftTreeIterator.hasNext(); ) {
|
||||
final PsiFile leftTreeFile = leftTreeIterator.next();
|
||||
final Set<PsiFile> files = dependencies.get(leftTreeFile);
|
||||
final Iterator<PsiFile> iterator = files.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
PsiFile next = iterator.next();
|
||||
final VirtualFile virtualFile = next.getVirtualFile();
|
||||
if (virtualFile == null || !myTargetScope.contains(virtualFile)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
if (files.isEmpty()) {
|
||||
leftTreeIterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return new BackwardDependenciesBuilder(myProject, new AnalysisScope(myTargetScope, myProject), scope);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,13 +18,12 @@ package com.intellij.psi.filters;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class PlainTextFilter implements ElementFilter, InitializableFilter {
|
||||
protected String[] myValue;
|
||||
public class PlainTextFilter implements ElementFilter {
|
||||
protected final String[] myValue;
|
||||
protected boolean myCaseInsensitiveFlag = false;
|
||||
|
||||
public PlainTextFilter(final String value, final boolean insensitiveFlag) {
|
||||
@@ -80,17 +79,6 @@ public class PlainTextFilter implements ElementFilter, InitializableFilter {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Object[] fromGetter){
|
||||
try{
|
||||
myValue = new String[fromGetter.length];
|
||||
System.arraycopy(fromGetter, 0, myValue, 0, fromGetter.length);
|
||||
}
|
||||
catch(ClassCastException cce){
|
||||
myValue = ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
}
|
||||
}
|
||||
|
||||
protected String getTextByElement(Object element){
|
||||
String elementValue = null;
|
||||
if(element instanceof PsiNamedElement){
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
* User: spLeaner
|
||||
*/
|
||||
public class AfterElement extends PositionElementFilter {
|
||||
public AfterElement(){}
|
||||
|
||||
public AfterElement(ElementFilter filter){
|
||||
setFilter(filter);
|
||||
|
||||
@@ -28,7 +28,6 @@ import com.intellij.psi.filters.FilterPositionUtil;
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public class LeftNeighbour extends PositionElementFilter{
|
||||
public LeftNeighbour(){}
|
||||
|
||||
public LeftNeighbour(ElementFilter filter){
|
||||
setFilter(filter);
|
||||
|
||||
@@ -31,8 +31,6 @@ public class SuperParentFilter extends PositionElementFilter{
|
||||
setFilter(filter);
|
||||
}
|
||||
|
||||
public SuperParentFilter(){}
|
||||
|
||||
@Override
|
||||
public boolean isAcceptable(Object element, PsiElement scope){
|
||||
if (!(element instanceof PsiElement)) return false;
|
||||
|
||||
@@ -97,12 +97,7 @@ public abstract class LanguagePerFileConfigurable<T> implements SearchableConfig
|
||||
|
||||
@Override
|
||||
public void apply() throws ConfigurationException {
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myMappings.setMappings(myTreeView.getValues());
|
||||
}
|
||||
});
|
||||
myMappings.setMappings(myTreeView.getValues());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+12
-72
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,22 +16,17 @@
|
||||
package com.intellij.execution.configurations;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.vfs.encoding.EncodingManager;
|
||||
import com.intellij.openapi.vfs.encoding.EncodingProjectManager;
|
||||
import com.intellij.util.EnvironmentUtil;
|
||||
import com.intellij.util.PlatformUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class EncodingEnvironmentUtil {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(EncodingEnvironmentUtil.class);
|
||||
|
||||
private static final String LC_ALL = "LC_ALL";
|
||||
private static final String LC_CTYPE = "LC_CTYPE";
|
||||
private static final String LANG = "LANG";
|
||||
@@ -43,7 +38,7 @@ public class EncodingEnvironmentUtil {
|
||||
* <p/>
|
||||
* Unfortunately, Mac OSX has a special behavior:<br/>
|
||||
* These environment variables aren't passed to an IDE, if the IDE is launched from Spotlight.<br/>
|
||||
* Unfortunately, even {@link com.intellij.util.EnvironmentUtil#getEnvironment()} doesn't have these variables.<p/>
|
||||
* Unfortunately, even {@link EnvironmentUtil#getEnvironment()} doesn't have these variables.<p/>
|
||||
* As a result, no encoding environment variables are passed to Ruby/Node.js/Python/other processes that are launched from IDE.
|
||||
* Thus, these processes wrongly assume that the default encoding is US-ASCII.
|
||||
* <p/>
|
||||
@@ -54,22 +49,17 @@ public class EncodingEnvironmentUtil {
|
||||
* @param commandLine GeneralCommandLine instance
|
||||
*/
|
||||
public static void setLocaleEnvironmentIfMac(@NotNull GeneralCommandLine commandLine) {
|
||||
if (SystemInfo.isMac) {
|
||||
if (!isLocaleDefined(commandLine)) {
|
||||
setLocaleEnvironment(commandLine.getEnvironment(), commandLine.getCharset());
|
||||
}
|
||||
if (SystemInfo.isMac && !isLocaleDefined(commandLine)) {
|
||||
setLocaleEnvironment(commandLine.getEnvironment(), commandLine.getCharset());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setLocaleEnvironmentIfMac(GeneralCommandLine)} instead. To be removed in IDEA 15.
|
||||
* Sets default encoding on Mac if it's undefined. <br/>
|
||||
*/
|
||||
@Deprecated
|
||||
public static void fixDefaultEncodingIfMac(@NotNull GeneralCommandLine commandLine, @Nullable Project project) {
|
||||
if (SystemInfo.isMac) {
|
||||
if (!isLocaleDefined(commandLine)) {
|
||||
setLocaleEnvironment(commandLine.getEnvironment(), getCharset(project));
|
||||
}
|
||||
public static void setLocaleEnvironmentIfMac(@NotNull Map<String, String> env, @NotNull Charset charset) {
|
||||
if (SystemInfo.isMac && !isLocaleDefined(env)) {
|
||||
setLocaleEnvironment(env, charset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,65 +75,15 @@ public class EncodingEnvironmentUtil {
|
||||
Locale locale = Locale.getDefault();
|
||||
String language = locale.getLanguage();
|
||||
String country = locale.getCountry();
|
||||
if (language.isEmpty() || country.isEmpty()) {
|
||||
return "en_US." + charset.name();
|
||||
}
|
||||
return language + "_" + country + "." + charset.name();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets default encoding on Mac if it's undefined. <br/>
|
||||
* @deprecated Use {@link #setLocaleEnvironmentIfMac(java.util.Map, java.nio.charset.Charset)} instead. To be removed in IDEA 15.
|
||||
*/
|
||||
@Deprecated
|
||||
public static void fixDefaultEncodingIfMac(@NotNull Map<String, String> env, @Nullable Project project) {
|
||||
if (SystemInfo.isMac) {
|
||||
if (!isLocaleDefined(env)) {
|
||||
setLocaleEnvironment(env, getCharset(project));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets default encoding on Mac if it's undefined. <br/>
|
||||
*/
|
||||
public static void setLocaleEnvironmentIfMac(@NotNull Map<String, String> env, @NotNull Charset charset) {
|
||||
if (SystemInfo.isMac) {
|
||||
if (!isLocaleDefined(env)) {
|
||||
setLocaleEnvironment(env, charset);
|
||||
}
|
||||
}
|
||||
return (language.isEmpty() || country.isEmpty() ? "en_US" : language + "_" + country) + "." + charset.name();
|
||||
}
|
||||
|
||||
private static boolean isLocaleDefined(@NotNull GeneralCommandLine commandLine) {
|
||||
Map<String, String> env = commandLine.getEnvironment();
|
||||
if (isLocaleDefined(env)) {
|
||||
return true;
|
||||
}
|
||||
if (commandLine.isPassParentEnvironment()) {
|
||||
// 'parentEnv' calculation logic should be kept in sync with GeneralCommandLine.setupEnvironment
|
||||
Map<String, String> parentEnv = PlatformUtils.isAppCode() ? System.getenv() // Temporarily fix for OC-8606
|
||||
: EnvironmentUtil.getEnvironmentMap();
|
||||
if (isLocaleDefined(parentEnv)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return isLocaleDefined(commandLine.getEnvironment()) ||
|
||||
commandLine.isPassParentEnvironment() && isLocaleDefined(commandLine.getParentEnvironment());
|
||||
}
|
||||
|
||||
private static boolean isLocaleDefined(@NotNull Map<String, String> env) {
|
||||
return env.containsKey(LC_ALL) || env.containsKey(LC_CTYPE) || env.containsKey(LANG);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Charset getCharset(@Nullable Project project) {
|
||||
Charset charset;
|
||||
if (project == null) {
|
||||
charset = EncodingManager.getInstance().getDefaultCharset();
|
||||
}
|
||||
else {
|
||||
charset = EncodingProjectManager.getInstance(project).getDefaultCharset();
|
||||
}
|
||||
return charset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
package com.intellij.ui;
|
||||
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.fileChooser.FileChooser;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
|
||||
@@ -366,25 +366,8 @@ public class GuiUtils {
|
||||
return s;
|
||||
}
|
||||
|
||||
public static void invokeAndWait(@NotNull Runnable runnable) throws InvocationTargetException, InterruptedException {
|
||||
Application application = ApplicationManager.getApplication();
|
||||
assert !application.isDispatchThread() : "Must not be invoked from AWT dispatch thread";
|
||||
if (application.isReadAccessAllowed()) {
|
||||
// make ApplicationImpl catch deadlock situation with readLock held
|
||||
application.invokeAndWait(runnable, application.getDefaultModalityState());
|
||||
return;
|
||||
}
|
||||
SwingUtilities.invokeAndWait(runnable);
|
||||
}
|
||||
|
||||
public static void runOrInvokeAndWait(@NotNull Runnable runnable) throws InvocationTargetException, InterruptedException {
|
||||
Application application = ApplicationManager.getApplication();
|
||||
if (application.isDispatchThread()) {
|
||||
runnable.run();
|
||||
}
|
||||
else {
|
||||
invokeAndWait(runnable);
|
||||
}
|
||||
ApplicationManager.getApplication().invokeAndWait(runnable, ModalityState.defaultModalityState());
|
||||
}
|
||||
|
||||
public static JTextField createUndoableTextField() {
|
||||
|
||||
@@ -1090,9 +1090,6 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
|
||||
@Override
|
||||
public void propertyChange(@NotNull PropertyChangeEvent evt) {
|
||||
final JBList list = getSelectedList();
|
||||
final Object value = list.getSelectedValue();
|
||||
|
||||
if (project.isDisposed()) {
|
||||
myPopup.cancel();
|
||||
return;
|
||||
@@ -1107,11 +1104,6 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
files.getEmptyText().setText(StatusText.DEFAULT_EMPTY_TEXT);
|
||||
toolWindows.getEmptyText().setText(StatusText.DEFAULT_EMPTY_TEXT);
|
||||
}
|
||||
files.repaint();
|
||||
toolWindows.repaint();
|
||||
if (value != null) {
|
||||
ScrollingUtil.ensureSelectionExists(getSelectedList(list));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,6 @@ import java.awt.image.BufferedImage;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.text.AttributedString;
|
||||
import java.text.CharacterIterator;
|
||||
@@ -5726,31 +5725,17 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
|
||||
private static <T> T execute(final Computable<T> computable) {
|
||||
if (ApplicationManager.getApplication().isDispatchThread()) {
|
||||
return computable.compute();
|
||||
}
|
||||
else {
|
||||
final Ref<T> ref = Ref.create();
|
||||
try {
|
||||
GuiUtils.invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ref.set(computable.compute());
|
||||
}
|
||||
});
|
||||
final Ref<T> ref = Ref.create();
|
||||
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ref.set(computable.compute());
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
return ref.get();
|
||||
}
|
||||
}, ModalityState.defaultModalityState());
|
||||
return ref.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class MyInputMethodHandler implements InputMethodRequests {
|
||||
private String composedText;
|
||||
private ProperTextRange composedTextRange;
|
||||
|
||||
@@ -455,14 +455,9 @@ public final class IterationState {
|
||||
}
|
||||
}
|
||||
|
||||
if (syntax != null && highlighter.getLayer() < HighlighterLayer.SYNTAX) {
|
||||
if (fold != null) {
|
||||
cachedAttributes.add(fold);
|
||||
fold = null;
|
||||
}
|
||||
|
||||
cachedAttributes.add(syntax);
|
||||
syntax = null;
|
||||
if (fold != null && highlighter.getLayer() < HighlighterLayer.GUARDED_BLOCKS) {
|
||||
cachedAttributes.add(fold);
|
||||
fold = null;
|
||||
}
|
||||
|
||||
if (guard != null && highlighter.getLayer() < HighlighterLayer.GUARDED_BLOCKS) {
|
||||
@@ -475,6 +470,11 @@ public final class IterationState {
|
||||
caret = null;
|
||||
}
|
||||
|
||||
if (syntax != null && highlighter.getLayer() < HighlighterLayer.SYNTAX) {
|
||||
cachedAttributes.add(syntax);
|
||||
syntax = null;
|
||||
}
|
||||
|
||||
TextAttributes textAttributes = highlighter.getTextAttributes();
|
||||
if (textAttributes != null && textAttributes != TextAttributes.ERASE_MARKER) {
|
||||
cachedAttributes.add(textAttributes);
|
||||
|
||||
+8
-8
@@ -507,14 +507,9 @@ public class IterationState {
|
||||
}
|
||||
}
|
||||
|
||||
if (syntax != null && highlighter.getLayer() < HighlighterLayer.SYNTAX) {
|
||||
if (fold != null) {
|
||||
cachedAttributes.add(fold);
|
||||
fold = null;
|
||||
}
|
||||
|
||||
cachedAttributes.add(syntax);
|
||||
syntax = null;
|
||||
if (fold != null && highlighter.getLayer() < HighlighterLayer.GUARDED_BLOCKS) {
|
||||
cachedAttributes.add(fold);
|
||||
fold = null;
|
||||
}
|
||||
|
||||
if (guard != null && highlighter.getLayer() < HighlighterLayer.GUARDED_BLOCKS) {
|
||||
@@ -527,6 +522,11 @@ public class IterationState {
|
||||
caret = null;
|
||||
}
|
||||
|
||||
if (syntax != null && highlighter.getLayer() < HighlighterLayer.SYNTAX) {
|
||||
cachedAttributes.add(syntax);
|
||||
syntax = null;
|
||||
}
|
||||
|
||||
TextAttributes textAttributes = highlighter.getTextAttributes();
|
||||
if (textAttributes != null && textAttributes != TextAttributes.ERASE_MARKER) {
|
||||
cachedAttributes.add(textAttributes);
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ public final class FileEditorProviderManagerImpl extends FileEditorProviderManag
|
||||
ContainerUtil.retainAll(sharedProviders, new Condition<FileEditorProvider>() {
|
||||
@Override
|
||||
public boolean value(FileEditorProvider provider) {
|
||||
return !(provider instanceof TextEditorProvider);
|
||||
return !(provider instanceof TextEditorProvider) || !((TextEditorProvider)provider).isDefaultFileEditorProvider();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+8
-2
@@ -24,7 +24,9 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.beans.PropertyChangeListener;
|
||||
@@ -34,16 +36,20 @@ import java.beans.PropertyChangeSupport;
|
||||
* @author Vladimir Kondratyev
|
||||
*/
|
||||
public class TextEditorImpl extends UserDataHolderBase implements TextEditor {
|
||||
public static final String DEFAULT_NAME = "Text";
|
||||
|
||||
protected final Project myProject;
|
||||
private final PropertyChangeSupport myChangeSupport;
|
||||
@NotNull private final TextEditorComponent myComponent;
|
||||
private final TextEditorProvider myProvider;
|
||||
private final String myName;
|
||||
|
||||
TextEditorImpl(@NotNull final Project project, @NotNull final VirtualFile file, final TextEditorProvider provider) {
|
||||
TextEditorImpl(@NotNull final Project project, @NotNull final VirtualFile file, final TextEditorProvider provider, @Nullable String name) {
|
||||
myProject = project;
|
||||
myProvider = provider;
|
||||
myChangeSupport = new PropertyChangeSupport(this);
|
||||
myComponent = createEditorComponent(project, file);
|
||||
myName = ObjectUtils.notNull(name, DEFAULT_NAME);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -84,7 +90,7 @@ public class TextEditorImpl extends UserDataHolderBase implements TextEditor {
|
||||
@Override
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return "Text";
|
||||
return myName;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+12
-3
@@ -75,9 +75,9 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public FileEditor createEditor(@NotNull Project project, @NotNull final VirtualFile file) {
|
||||
public FileEditor createEditor(@NotNull Project project, @NotNull VirtualFile file) {
|
||||
LOG.assertTrue(accept(project, file));
|
||||
return new TextEditorImpl(project, file, this);
|
||||
return new TextEditorImpl(project, file, this, getFileEditorName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -304,6 +304,15 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isDefaultFileEditorProvider() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getFileEditorName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected class EditorWrapper extends UserDataHolderBase implements TextEditor {
|
||||
private final Editor myEditor;
|
||||
|
||||
@@ -331,7 +340,7 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
|
||||
@Override
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return "Text";
|
||||
return TextEditorImpl.DEFAULT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-6
@@ -500,7 +500,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
|
||||
boolean wasDetectedAsBinary = BitUtil.isSet(flags, AUTO_DETECTED_AS_BINARY_MASK);
|
||||
boolean wasAutoDetectRun = BitUtil.isSet(flags, AUTO_DETECT_WAS_RUN_MASK);
|
||||
if (wasAutoDetectRun && (wasDetectedAsText || wasDetectedAsBinary)) {
|
||||
return wasDetectedAsText ? FileTypes.PLAIN_TEXT : UnknownFileType.INSTANCE;
|
||||
return wasDetectedAsText ? PlainTextFileType.INSTANCE : UnknownFileType.INSTANCE;
|
||||
}
|
||||
}
|
||||
FileType fileType = file.getUserData(DETECTED_FROM_CONTENT_FILE_TYPE_KEY);
|
||||
@@ -568,9 +568,9 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
|
||||
@NotNull
|
||||
private FileType getAutoDetectedType(@NotNull VirtualFile file, int id) {
|
||||
long flags = packedFlags.get(id);
|
||||
return BitUtil.isSet(flags, AUTO_DETECTED_AS_TEXT_MASK) ? FileTypes.PLAIN_TEXT :
|
||||
return BitUtil.isSet(flags, AUTO_DETECTED_AS_TEXT_MASK) ? PlainTextFileType.INSTANCE :
|
||||
BitUtil.isSet(flags, AUTO_DETECTED_AS_BINARY_MASK) ? UnknownFileType.INSTANCE :
|
||||
ObjectUtils.notNull(file.getUserData(DETECTED_FROM_CONTENT_FILE_TYPE_KEY), FileTypes.PLAIN_TEXT);
|
||||
ObjectUtils.notNull(file.getUserData(DETECTED_FROM_CONTENT_FILE_TYPE_KEY), PlainTextFileType.INSTANCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -581,8 +581,8 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
|
||||
}
|
||||
|
||||
private void cacheAutoDetectedFileType(@NotNull VirtualFile file, @NotNull FileType fileType) {
|
||||
boolean wasAutodetectedAsText = fileType == FileTypes.PLAIN_TEXT;
|
||||
boolean wasAutodetectedAsBinary = fileType == FileTypes.UNKNOWN;
|
||||
boolean wasAutodetectedAsText = fileType == PlainTextFileType.INSTANCE;
|
||||
boolean wasAutodetectedAsBinary = fileType == UnknownFileType.INSTANCE;
|
||||
|
||||
int flags = BitUtil.set(0, AUTO_DETECTED_AS_TEXT_MASK, wasAutodetectedAsText);
|
||||
flags = BitUtil.set(flags, AUTO_DETECTED_AS_BINARY_MASK, wasAutodetectedAsBinary);
|
||||
@@ -1263,7 +1263,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
|
||||
}
|
||||
|
||||
private static boolean shouldSave(@NotNull FileType fileType) {
|
||||
return fileType != FileTypes.UNKNOWN && !fileType.isReadOnly();
|
||||
return fileType != UnknownFileType.INSTANCE && !fileType.isReadOnly();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
+46
-33
@@ -24,6 +24,8 @@ import com.intellij.openapi.help.HelpManager;
|
||||
import com.intellij.openapi.options.BaseConfigurable;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.DumbModePermission;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
@@ -171,24 +173,30 @@ public class SingleConfigurableEditor extends DialogWrapper {
|
||||
|
||||
@Override
|
||||
protected void doOKAction() {
|
||||
try {
|
||||
if (myConfigurable.isModified()) {
|
||||
myConfigurable.apply();
|
||||
mySaveAllOnClose = true;
|
||||
}
|
||||
}
|
||||
catch (ConfigurationException e) {
|
||||
if (e.getMessage() != null) {
|
||||
if (myProject != null) {
|
||||
Messages.showMessageDialog(myProject, e.getMessage(), e.getTitle(), Messages.getErrorIcon());
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (myConfigurable.isModified()) {
|
||||
myConfigurable.apply();
|
||||
mySaveAllOnClose = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Messages.showMessageDialog(getRootPane(), e.getMessage(), e.getTitle(), Messages.getErrorIcon());
|
||||
catch (ConfigurationException e) {
|
||||
if (e.getMessage() != null) {
|
||||
if (myProject != null) {
|
||||
Messages.showMessageDialog(myProject, e.getMessage(), e.getTitle(), Messages.getErrorIcon());
|
||||
}
|
||||
else {
|
||||
Messages.showMessageDialog(getRootPane(), e.getMessage(), e.getTitle(), Messages.getErrorIcon());
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
SingleConfigurableEditor.super.doOKAction();
|
||||
}
|
||||
return;
|
||||
}
|
||||
super.doOKAction();
|
||||
});
|
||||
}
|
||||
|
||||
protected static String createDimensionKey(Configurable configurable) {
|
||||
@@ -231,25 +239,30 @@ public class SingleConfigurableEditor extends DialogWrapper {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
if (myPerformAction) return;
|
||||
try {
|
||||
myPerformAction = true;
|
||||
if (myConfigurable.isModified()) {
|
||||
myConfigurable.apply();
|
||||
mySaveAllOnClose = true;
|
||||
setCancelButtonText(CommonBundle.getCloseButtonText());
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myPerformAction = true;
|
||||
if (myConfigurable.isModified()) {
|
||||
myConfigurable.apply();
|
||||
mySaveAllOnClose = true;
|
||||
setCancelButtonText(CommonBundle.getCloseButtonText());
|
||||
}
|
||||
}
|
||||
catch (ConfigurationException e) {
|
||||
if (myProject != null) {
|
||||
Messages.showMessageDialog(myProject, e.getMessage(), e.getTitle(), Messages.getErrorIcon());
|
||||
}
|
||||
else {
|
||||
Messages.showMessageDialog(getRootPane(), e.getMessage(), e.getTitle(),
|
||||
Messages.getErrorIcon());
|
||||
}
|
||||
} finally {
|
||||
myPerformAction = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ConfigurationException e) {
|
||||
if (myProject != null) {
|
||||
Messages.showMessageDialog(myProject, e.getMessage(), e.getTitle(), Messages.getErrorIcon());
|
||||
}
|
||||
else {
|
||||
Messages.showMessageDialog(getRootPane(), e.getMessage(), e.getTitle(),
|
||||
Messages.getErrorIcon());
|
||||
}
|
||||
} finally {
|
||||
myPerformAction = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-1
@@ -31,6 +31,8 @@ import com.intellij.openapi.options.ShowSettingsUtil;
|
||||
import com.intellij.openapi.options.ex.ConfigurableCardPanel;
|
||||
import com.intellij.openapi.options.ex.ConfigurableExtensionPointUtil;
|
||||
import com.intellij.openapi.options.ex.ConfigurableVisitor;
|
||||
import com.intellij.openapi.project.DumbModePermission;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
@@ -73,7 +75,12 @@ class ConfigurableEditor extends AbstractEditor implements AnActionListener, AWT
|
||||
private final AbstractAction myApplyAction = new AbstractAction(CommonBundle.getApplyButtonText()) {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
apply();
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
apply();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
private final AbstractAction myResetAction = new AbstractAction(RESET_NAME) {
|
||||
|
||||
+19
-8
@@ -25,6 +25,8 @@ import com.intellij.openapi.options.ConfigurableGroup;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.options.SearchableConfigurable;
|
||||
import com.intellij.openapi.options.ex.ConfigurableVisitor;
|
||||
import com.intellij.openapi.project.DumbModePermission;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
@@ -197,16 +199,20 @@ public class IdeSettingsDialog extends DialogWrapper implements DataProvider {
|
||||
public void doOKAction() {
|
||||
myEditor.flushModifications();
|
||||
|
||||
if (myEditor.canApply()) {
|
||||
myEditor.apply();
|
||||
if (!updateStatus()) return;
|
||||
}
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
public void run() {
|
||||
if (myEditor.canApply()) {
|
||||
myEditor.apply();
|
||||
if (!updateStatus()) return;
|
||||
}
|
||||
|
||||
saveCurrentConfigurable();
|
||||
saveCurrentConfigurable();
|
||||
|
||||
ApplicationManager.getApplication().saveAll();
|
||||
ApplicationManager.getApplication().saveAll();
|
||||
|
||||
super.doOKAction();
|
||||
IdeSettingsDialog.super.doOKAction();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -284,7 +290,12 @@ public class IdeSettingsDialog extends DialogWrapper implements DataProvider {
|
||||
}
|
||||
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
myEditor.apply();
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myEditor.apply();
|
||||
}
|
||||
});
|
||||
myEditor.revalidate();
|
||||
myEditor.repaint();
|
||||
updateStatus();
|
||||
|
||||
+19
-8
@@ -26,6 +26,8 @@ import com.intellij.openapi.options.ConfigurableGroup;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.options.SearchableConfigurable;
|
||||
import com.intellij.openapi.options.ex.Settings;
|
||||
import com.intellij.openapi.project.DumbModePermission;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
@@ -170,16 +172,20 @@ public class OptionsEditorDialog extends DialogWrapper implements DataProvider{
|
||||
protected void doOKAction() {
|
||||
myEditor.flushModifications();
|
||||
|
||||
if (myEditor.canApply()) {
|
||||
myEditor.apply();
|
||||
if (!updateStatus()) return;
|
||||
}
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
public void run() {
|
||||
if (myEditor.canApply()) {
|
||||
myEditor.apply();
|
||||
if (!updateStatus()) return;
|
||||
}
|
||||
|
||||
saveCurrentConfigurable();
|
||||
saveCurrentConfigurable();
|
||||
|
||||
ApplicationManager.getApplication().saveAll();
|
||||
ApplicationManager.getApplication().saveAll();
|
||||
|
||||
super.doOKAction();
|
||||
OptionsEditorDialog.super.doOKAction();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -295,7 +301,12 @@ public class OptionsEditorDialog extends DialogWrapper implements DataProvider{
|
||||
}
|
||||
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
myEditor.apply();
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myEditor.apply();
|
||||
}
|
||||
});
|
||||
myEditor.revalidate();
|
||||
myEditor.repaint();
|
||||
}
|
||||
|
||||
+11
-4
@@ -21,6 +21,8 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.help.HelpManager;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ConfigurableGroup;
|
||||
import com.intellij.openapi.project.DumbModePermission;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -140,10 +142,15 @@ public class SettingsDialog extends DialogWrapper implements DataProvider {
|
||||
|
||||
@Override
|
||||
public void doOKAction() {
|
||||
if (myEditor.apply()) {
|
||||
ApplicationManager.getApplication().saveAll();
|
||||
super.doOKAction();
|
||||
}
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (myEditor.apply()) {
|
||||
ApplicationManager.getApplication().saveAll();
|
||||
SettingsDialog.super.doOKAction();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -110,7 +110,7 @@ public class ProjectImpl extends PlatformComponentManagerImpl implements Project
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
boolean isLight() {
|
||||
public boolean isLight() {
|
||||
return myLight;
|
||||
}
|
||||
|
||||
|
||||
@@ -144,8 +144,14 @@ public class VfsData {
|
||||
if (segment != null || !create) return segment;
|
||||
return ourSegments.cacheOrGet(key, new Segment());
|
||||
}
|
||||
|
||||
public static class FileAlreadyCreatedException extends Exception {
|
||||
private FileAlreadyCreatedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void initFile(int id, Segment segment, int nameId, @NotNull Object data) {
|
||||
public static void initFile(int id, Segment segment, int nameId, @NotNull Object data) throws FileAlreadyCreatedException {
|
||||
assert id > 0;
|
||||
int offset = getOffset(id);
|
||||
|
||||
@@ -154,12 +160,12 @@ public class VfsData {
|
||||
Object existingData = segment.myObjectArray.get(offset);
|
||||
if (existingData != null) {
|
||||
int parent = FSRecords.getParent(id);
|
||||
String msg = "File already created: " + existingData + "; parentId=" + parent;
|
||||
String msg = "File already created: " + nameId + ", data=" + existingData + "; parentId=" + parent;
|
||||
if (parent > 0) {
|
||||
msg += "; parent.name=" + FSRecords.getName(parent);
|
||||
msg += "; parent.children=" + Arrays.toString(FSRecords.listAll(id));
|
||||
}
|
||||
throw new AssertionError(msg);
|
||||
throw new FileAlreadyCreatedException(msg);
|
||||
}
|
||||
segment.myObjectArray.set(offset, data);
|
||||
}
|
||||
|
||||
@@ -114,6 +114,13 @@ public class VfsRootAccess {
|
||||
final Set<String> allowed = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
|
||||
allowed.add(FileUtil.toSystemIndependentName(PathManager.getHomePath()));
|
||||
|
||||
// In plugin development environment PathManager.getHomePath() returns path like "~/.IntelliJIdea/system/plugins-sandbox/test" when running tests
|
||||
// The following is to avoid errors in tests like "File accessed outside allowed roots: file://C:/Program Files/idea/lib/idea.jar"
|
||||
final String homePath2 = PathManager.getHomePathFor(Application.class);
|
||||
if (homePath2 != null) {
|
||||
allowed.add(FileUtil.toSystemIndependentName(homePath2));
|
||||
}
|
||||
|
||||
try {
|
||||
URL outUrl = Application.class.getResource("/");
|
||||
if (outUrl != null) {
|
||||
|
||||
+7
-2
@@ -216,8 +216,13 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
|
||||
private VirtualFileSystemEntry createChild(int nameId, int id, @NotNull NewVirtualFileSystem delegate) {
|
||||
final int attributes = ourPersistence.getFileAttributes(id);
|
||||
VfsData.Segment segment = VfsData.getSegment(id, true);
|
||||
VfsData.initFile(id, segment, nameId,
|
||||
PersistentFS.isDirectory(attributes) ? new VfsData.DirectoryData() : KeyFMap.EMPTY_MAP);
|
||||
try {
|
||||
VfsData.initFile(id, segment, nameId,
|
||||
PersistentFS.isDirectory(attributes) ? new VfsData.DirectoryData() : KeyFMap.EMPTY_MAP);
|
||||
}
|
||||
catch (VfsData.FileAlreadyCreatedException e) {
|
||||
throw new RuntimeException("dir=" + myId + "; dir.children=" + Arrays.toString(FSRecords.listAll(myId)), e);
|
||||
}
|
||||
LOG.assertTrue(!(getFileSystem() instanceof Win32LocalFileSystem));
|
||||
|
||||
VirtualFileSystemEntry child = VfsData.getFileById(id, this);
|
||||
|
||||
+2
-2
@@ -908,14 +908,14 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
|
||||
try {
|
||||
VfsData.initFile(rootId, segment, -1, directoryData);
|
||||
}
|
||||
catch (AssertionError e) {
|
||||
catch (VfsData.FileAlreadyCreatedException e) {
|
||||
for (Map.Entry<String, VirtualFileSystemEntry> entry : myRoots.entrySet()) {
|
||||
final VirtualFileSystemEntry existingRoot = entry.getValue();
|
||||
if (Math.abs(existingRoot.getId()) == rootId) {
|
||||
throw new RuntimeException("Duplicate FS roots: " + rootUrl + " and " + entry.getKey() + ", id=" + rootId + ", valid=" + existingRoot.isValid(), e);
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No root duplication, roots" + Arrays.toString(FSRecords.listAll(1)), e);
|
||||
throw new RuntimeException("No root duplication, roots=" + Arrays.toString(FSRecords.listAll(1)), e);
|
||||
}
|
||||
incStructuralModificationCount();
|
||||
mark = writeAttributesToRecord(rootId, 0, newRoot, fs, attributes);
|
||||
|
||||
@@ -37,10 +37,7 @@ import com.intellij.openapi.application.ex.ApplicationManagerEx;
|
||||
import com.intellij.openapi.project.DumbAwareRunnable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.IdeFrame;
|
||||
import com.intellij.openapi.wm.IdeRootPaneNorthExtension;
|
||||
@@ -53,6 +50,7 @@ import com.intellij.openapi.wm.impl.status.*;
|
||||
import com.intellij.openapi.wm.impl.welcomeScreen.WelcomeFrame;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.ui.mac.MacMainFrameDecorator;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -136,6 +134,25 @@ public class IdeFrameImpl extends JFrame implements IdeFrameEx, DataProvider {
|
||||
}
|
||||
};
|
||||
Toolkit.getDefaultToolkit().addPropertyChangeListener("win.xpstyle.themeActive", myWindowsBorderUpdater);
|
||||
if (!SystemInfo.isJavaVersionAtLeast("1.8")) {
|
||||
final Ref<Dimension> myDimensionRef = new Ref<Dimension>(new Dimension());
|
||||
final Alarm alarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
|
||||
final Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isDisplayable() && !getSize().equals(myDimensionRef.get())) {
|
||||
Rectangle bounds = getBounds();
|
||||
bounds.width--;
|
||||
setBounds(bounds);
|
||||
bounds.width++;
|
||||
setBounds(bounds);
|
||||
myDimensionRef.set(getSize());
|
||||
}
|
||||
alarm.addRequest(this, 50);
|
||||
}
|
||||
};
|
||||
alarm.addRequest(runnable, 50);
|
||||
}
|
||||
}
|
||||
|
||||
IdeMenuBar.installAppMenuIfNeeded(this);
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.editor.colors.EditorColors;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.colors.impl.DelegateColorScheme;
|
||||
import com.intellij.openapi.editor.event.DocumentListener;
|
||||
import com.intellij.openapi.editor.ex.*;
|
||||
@@ -76,13 +77,23 @@ public abstract class EditorTextFieldCellRenderer implements TableCellRenderer,
|
||||
|
||||
protected abstract String getText(JTable table, Object value, int row, int column);
|
||||
|
||||
@Nullable
|
||||
protected TextAttributes getTextAttributes(JTable table, Object value, int row, int column) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected EditorColorsScheme getColorScheme(final JTable table) {
|
||||
return getEditorPanel(table).getEditor().getColorsScheme();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean selected, boolean focused, int row, int column) {
|
||||
RendererComponent panel = getEditorPanel(table);
|
||||
EditorEx editor = panel.getEditor();
|
||||
editor.getColorsScheme().setEditorFontSize(table.getFont().getSize());
|
||||
String text = getText(table, value, row, column);
|
||||
panel.setText(text, null, selected);
|
||||
panel.setText(text, getTextAttributes(table, value, row, column), selected);
|
||||
|
||||
editor.getColorsScheme().setColor(EditorColors.SELECTION_BACKGROUND_COLOR, table.getSelectionBackground());
|
||||
editor.getColorsScheme().setColor(EditorColors.SELECTION_FOREGROUND_COLOR, table.getSelectionForeground());
|
||||
|
||||
+12
@@ -16,6 +16,7 @@
|
||||
package com.intellij.util.ui.table;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.ui.EditorTextFieldCellRenderer;
|
||||
@@ -39,5 +40,16 @@ public abstract class EditorTextFieldJBTableRowRenderer extends EditorTextFieldC
|
||||
return getText(table, row);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected final TextAttributes getTextAttributes(JTable table, Object value, int row, int column) {
|
||||
return getTextAttributes(table, row);
|
||||
}
|
||||
|
||||
protected abstract String getText(JTable table, int row);
|
||||
|
||||
@Nullable
|
||||
protected TextAttributes getTextAttributes(JTable table, int row) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user