Merge remote-tracking branch 'origin/master'

This commit is contained in:
Max Medvedev
2015-09-09 01:01:32 +03:00
176 changed files with 2144 additions and 1800 deletions
+3 -3
View File
@@ -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 />
+1 -1
View File
@@ -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());
}
@@ -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);
}
}
}
@@ -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;
}
}
});
@@ -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());
}
}
});
}
@@ -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
@@ -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();
}
@@ -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();
@@ -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!
}
@@ -820,6 +820,11 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel {
}
return false;
}
@Override
protected boolean canStartInBackground() {
return false;
}
}.analyze();
}
@@ -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");
}
}
}
@@ -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;
}
@@ -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 + ")";
}
}
@@ -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;
@@ -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;
}
@@ -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" +
"}");
}
}
@@ -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.
@@ -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,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
@@ -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);
}
@@ -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;
}
}
}
}
}
@@ -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
@@ -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();
}
}
}
@@ -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);
}
}
}
@@ -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) {
@@ -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;
}
}
@@ -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);
@@ -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;
}
}
@@ -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 =
@@ -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() {
}
@@ -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();
}
});
}
});
}
@@ -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
@@ -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());
}
@@ -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);
}
});
}
@@ -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
@@ -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);
@@ -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);
@@ -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();
}
});
}
@@ -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
@@ -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
@@ -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();
}
// -------------------------------------------------------------------------
@@ -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;
}
});
}
}
@@ -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) {
@@ -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();
@@ -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();
}
@@ -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) {
@@ -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);
@@ -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());
@@ -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