mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -36,11 +36,11 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.CommonClassNames;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.intellij.util.ThreeState;
|
||||
import com.intellij.xdebugger.XExpression;
|
||||
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
|
||||
@@ -347,10 +347,8 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
|
||||
|
||||
@Override
|
||||
public void contextAction(@NotNull SuspendContextImpl suspendContext) throws Exception {
|
||||
final XValueChildrenList children = new XValueChildrenList();
|
||||
final NodeRenderer renderer = myValueDescriptor.getRenderer(myEvaluationContext.getDebugProcess());
|
||||
final Ref<Integer> remainingNum = new Ref<>(0);
|
||||
renderer.buildChildren(myValueDescriptor.getValue(), new ChildrenBuilder() {
|
||||
myValueDescriptor.getRenderer(myEvaluationContext.getDebugProcess())
|
||||
.buildChildren(myValueDescriptor.getValue(), new ChildrenBuilder() {
|
||||
@Override
|
||||
public NodeDescriptorFactory getDescriptorManager() {
|
||||
return myNodeManager;
|
||||
@@ -368,7 +366,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
|
||||
|
||||
@Override
|
||||
public void setRemaining(int remaining) {
|
||||
remainingNum.set(remaining);
|
||||
node.tooManyChildren(remaining);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -379,23 +377,38 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChildren(List<DebuggerTreeNode> nodes) {
|
||||
for (DebuggerTreeNode node : nodes) {
|
||||
final NodeDescriptor descriptor = node.getDescriptor();
|
||||
if (descriptor instanceof ValueDescriptorImpl) {
|
||||
// Value is calculated already in NodeManagerImpl
|
||||
children.add(create(JavaValue.this, (ValueDescriptorImpl)descriptor, myEvaluationContext, myNodeManager, false));
|
||||
}
|
||||
else if (descriptor instanceof MessageDescriptor) {
|
||||
children.add(new JavaStackFrame.DummyMessageValueNode(descriptor.getLabel(), null));
|
||||
}
|
||||
public void addChildren(List<DebuggerTreeNode> nodes, boolean last) {
|
||||
if (nodes.isEmpty()) {
|
||||
node.addChildren(XValueChildrenList.EMPTY, last);
|
||||
}
|
||||
else {
|
||||
nodes.stream().map(DebuggerTreeNode::getDescriptor).forEach(descriptor -> {
|
||||
if (descriptor instanceof ValueDescriptorImpl) {
|
||||
// Value is calculated already in NodeManagerImpl
|
||||
node.addChildren(XValueChildrenList.singleton(
|
||||
create(JavaValue.this, (ValueDescriptorImpl)descriptor, myEvaluationContext, myNodeManager, false)), last);
|
||||
}
|
||||
else if (descriptor instanceof MessageDescriptor) {
|
||||
node.addChildren(XValueChildrenList.singleton(
|
||||
new JavaStackFrame.DummyMessageValueNode(descriptor.getLabel(), DebuggerTreeRenderer.getDescriptorIcon(descriptor))), last);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChildren(List<DebuggerTreeNode> nodes) {
|
||||
addChildren(nodes, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMessage(@NotNull String message,
|
||||
@Nullable Icon icon,
|
||||
@NotNull SimpleTextAttributes attributes,
|
||||
@Nullable XDebuggerTreeNodeHyperlink link) {
|
||||
node.setMessage(message, icon, attributes, link);
|
||||
}
|
||||
}, myEvaluationContext);
|
||||
node.addChildren(children, true);
|
||||
if (remainingNum.get() > 0) {
|
||||
node.tooManyChildren(remainingNum.get());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.debugger.ui.impl.watch.*;
|
||||
import com.intellij.debugger.ui.tree.NodeDescriptor;
|
||||
import com.intellij.debugger.ui.tree.ValueDescriptor;
|
||||
import com.intellij.debugger.ui.tree.render.EnumerationChildrenRenderer;
|
||||
import com.intellij.icons.AllIcons;
|
||||
@@ -62,7 +63,7 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Icon getDescriptorIcon(NodeDescriptorImpl descriptor) {
|
||||
public static Icon getDescriptorIcon(NodeDescriptor descriptor) {
|
||||
Icon nodeIcon = null;
|
||||
if (descriptor instanceof ThreadGroupDescriptorImpl) {
|
||||
nodeIcon = (((ThreadGroupDescriptorImpl)descriptor).isCurrent() ? AllIcons.Debugger.ThreadGroupCurrent : AllIcons.Debugger.ThreadGroup);
|
||||
|
||||
@@ -37,6 +37,7 @@ import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiElementFactory;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.sun.jdi.ArrayReference;
|
||||
import com.sun.jdi.ArrayType;
|
||||
@@ -45,8 +46,7 @@ import com.sun.jdi.Value;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* User: lex
|
||||
@@ -99,7 +99,6 @@ public class ArrayRenderer extends NodeRendererImpl{
|
||||
|
||||
public void buildChildren(Value value, ChildrenBuilder builder, EvaluationContext evaluationContext) {
|
||||
DebuggerManagerThreadImpl.assertIsManagerThread();
|
||||
List<DebuggerTreeNode> children = new ArrayList<>();
|
||||
NodeManagerImpl nodeManager = (NodeManagerImpl)builder.getNodeManager();
|
||||
NodeDescriptorFactory descriptorFactory = builder.getDescriptorManager();
|
||||
|
||||
@@ -133,7 +132,7 @@ public class ArrayRenderer extends NodeRendererImpl{
|
||||
continue;
|
||||
}
|
||||
|
||||
children.add(arrayItemNode);
|
||||
builder.addChildren(Collections.singletonList(arrayItemNode), false);
|
||||
added++;
|
||||
if (added > ENTRIES_LIMIT) {
|
||||
break;
|
||||
@@ -141,24 +140,26 @@ public class ArrayRenderer extends NodeRendererImpl{
|
||||
}
|
||||
}
|
||||
|
||||
builder.addChildren(Collections.emptyList(), true);
|
||||
|
||||
if (added == 0) {
|
||||
if (START_INDEX == 0 && array.length() - 1 <= END_INDEX) {
|
||||
children.add(nodeManager.createMessageNode(ALL_ELEMENTS_IN_RANGE_ARE_NULL));
|
||||
builder.setMessage(DebuggerBundle.message("message.node.all.elements.null"), null, SimpleTextAttributes.REGULAR_ATTRIBUTES, null);
|
||||
}
|
||||
else {
|
||||
children.add(nodeManager.createMessageNode(DebuggerBundle.message("message.node.all.array.elements.null", START_INDEX, END_INDEX)));
|
||||
builder.setMessage(DebuggerBundle.message("message.node.all.array.elements.null", START_INDEX, END_INDEX), null,
|
||||
SimpleTextAttributes.REGULAR_ATTRIBUTES, null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (hiddenNulls) {
|
||||
children.add(0, nodeManager.createMessageNode(HIDDEN_NULL_ELEMENTS));
|
||||
builder.setMessage(DebuggerBundle.message("message.node.elements.null.hidden"), null, SimpleTextAttributes.REGULAR_ATTRIBUTES, null);
|
||||
}
|
||||
if (!myForced && END_INDEX < array.length() - 1) {
|
||||
builder.setRemaining(array.length() - 1 - END_INDEX);
|
||||
}
|
||||
}
|
||||
}
|
||||
builder.setChildren(children);
|
||||
}
|
||||
|
||||
private static boolean elementIsNull(ArrayReference arrayReference, int index) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +16,12 @@
|
||||
package com.intellij.debugger.ui.tree.render;
|
||||
|
||||
import com.intellij.debugger.ui.tree.*;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.List;
|
||||
|
||||
public interface ChildrenBuilder {
|
||||
@@ -28,6 +33,16 @@ public interface ChildrenBuilder {
|
||||
|
||||
void setChildren(List<DebuggerTreeNode> children);
|
||||
|
||||
default void addChildren(List<DebuggerTreeNode> children, boolean last) {
|
||||
setChildren(children);
|
||||
}
|
||||
|
||||
default void setMessage(@NotNull String message,
|
||||
@Nullable Icon icon,
|
||||
@NotNull SimpleTextAttributes attributes,
|
||||
@Nullable XDebuggerTreeNodeHyperlink link) {
|
||||
}
|
||||
|
||||
void setRemaining(int remaining);
|
||||
|
||||
void initChildrenArrayRenderer(ArrayRenderer renderer);
|
||||
|
||||
+18
-11
@@ -127,14 +127,28 @@ public class RefJavaModuleImpl extends RefElementImpl implements RefJavaModule {
|
||||
for (PsiJavaCodeReferenceElement implementationReference : implementationList.getReferenceElements()) {
|
||||
final PsiElement implementationClass = implementationReference.resolve();
|
||||
if (implementationClass instanceof PsiClass) {
|
||||
RefElement refTargetElement = null;
|
||||
PsiElement targetElement = getProviderMethod((PsiClass)implementationClass);
|
||||
|
||||
if (targetElement == null) {
|
||||
targetElement = getDefaultConstructor((PsiClass)implementationClass);
|
||||
if (targetElement == null) {
|
||||
targetElement = implementationClass;
|
||||
final RefElement refClass = getRefManager().getReference(implementationClass);
|
||||
if (refClass instanceof RefClassImpl) {
|
||||
final RefMethod refConstructor = ((RefClassImpl)refClass).getDefaultConstructor();
|
||||
if (refConstructor != null) {
|
||||
final PsiModifierListOwner constructorElement = refConstructor.getElement();
|
||||
if (constructorElement != null && constructorElement.hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||
refTargetElement = refConstructor;
|
||||
targetElement = constructorElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
final RefElement refTargetElement = getRefManager().getReference(targetElement);
|
||||
if (targetElement == null) {
|
||||
targetElement = implementationClass;
|
||||
}
|
||||
if (refTargetElement == null) {
|
||||
refTargetElement = getRefManager().getReference(targetElement);
|
||||
}
|
||||
if (refTargetElement != null) {
|
||||
((RefJavaElementImpl)refInterface)
|
||||
.addReference(refTargetElement, targetElement, providerInterface, false, true, null);
|
||||
@@ -187,11 +201,4 @@ public class RefJavaModuleImpl extends RefElementImpl implements RefJavaModule {
|
||||
m.hasModifierProperty(PsiModifier.STATIC) &&
|
||||
m.getParameterList().getParametersCount() == 0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiMethod getDefaultConstructor(@NotNull PsiClass psiClass) {
|
||||
final PsiMethod[] constructors = psiClass.getConstructors();
|
||||
return ContainerUtil.find(constructors, m -> m.hasModifierProperty(PsiModifier.PUBLIC) &&
|
||||
m.getParameterList().getParametersCount() == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,16 +56,17 @@ class PreferMostUsedWeigher extends LookupElementWeigher {
|
||||
if (!(psi instanceof PsiMember)) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
if (OBJECT_METHOD_PATTERN.accepts(psi)) {
|
||||
return null;
|
||||
}
|
||||
if (looksLikeHelperMethodOrConst(psi)) {
|
||||
return null;
|
||||
}
|
||||
final Integer occurrenceCount = myCompilerReferenceService.getCompileTimeOccurrenceCount(psi, myConstructorSuggestion);
|
||||
return occurrenceCount == null ? null : - occurrenceCount;
|
||||
if (element.getUserData(JavaGenerateMemberCompletionContributor.GENERATE_ELEMENT) != null) {
|
||||
return null;
|
||||
}
|
||||
if (OBJECT_METHOD_PATTERN.accepts(psi)) {
|
||||
return null;
|
||||
}
|
||||
if (looksLikeHelperMethodOrConst(psi)) {
|
||||
return null;
|
||||
}
|
||||
final Integer occurrenceCount = myCompilerReferenceService.getCompileTimeOccurrenceCount(psi, myConstructorSuggestion);
|
||||
return occurrenceCount == null ? null : -occurrenceCount;
|
||||
}
|
||||
|
||||
//Objects.requireNonNull is an example
|
||||
|
||||
+19
-1
@@ -6,7 +6,16 @@
|
||||
<package>my.ext</package>
|
||||
<entry_point TYPE="class" FQNAME="my.ext.MyServiceExt" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>Class is not instantiated.</description>
|
||||
<description>Class has one instantiation but it is not reachable from entry points.</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyServiceExt.java</file>
|
||||
<line>4</line>
|
||||
<package>my.ext</package>
|
||||
<entry_point TYPE="class" FQNAME="my.ext.MyServiceExt" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>Class has one instantiation but it is not reachable from entry points.</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
@@ -17,4 +26,13 @@
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description><ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul></description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyService.java</file>
|
||||
<line>1</line>
|
||||
<package>my.api</package>
|
||||
<entry_point TYPE="class" FQNAME="my.api.MyService" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>&nbsp;Interface has an implementation but <ul><li>it is never instantiated OR</li><li>no instantiations are reachable from entry points.</li></ul></description>
|
||||
</problem>
|
||||
</problems>
|
||||
+19
-1
@@ -6,7 +6,25 @@
|
||||
<package>my.impl</package>
|
||||
<entry_point TYPE="class" FQNAME="my.impl.MyServiceImpl" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>Class is not instantiated.</description>
|
||||
<description>Class has one instantiation but it is not reachable from entry points.</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyServiceImpl.java</file>
|
||||
<line>4</line>
|
||||
<package>my.impl</package>
|
||||
<entry_point TYPE="class" FQNAME="my.impl.MyServiceImpl" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>Class has one instantiation but it is not reachable from entry points.</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyService.java</file>
|
||||
<line>1</line>
|
||||
<package>my.api</package>
|
||||
<entry_point TYPE="class" FQNAME="my.api.MyService" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>&nbsp;Interface has an implementation but <ul><li>it is never instantiated OR</li><li>no instantiations are reachable from entry points.</li></ul></description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package my.impl;
|
||||
import my.api.MyService;
|
||||
|
||||
public class MyServiceImpl implements MyService {
|
||||
public MyServiceImpl(Object... objects) {System.out.println(objects);}
|
||||
@Override
|
||||
public void foo() {}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>MyServiceImpl.java</file>
|
||||
<line>5</line>
|
||||
<package>my.impl</package>
|
||||
<entry_point TYPE="method" FQNAME="my.impl.MyServiceImpl MyServiceImpl(java.lang.Object... objects)" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>Constructor has usage(s) but they all belong to calls chain that has no members reachable from entry points.</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyServiceImpl.java</file>
|
||||
<line>4</line>
|
||||
<package>my.impl</package>
|
||||
<entry_point TYPE="class" FQNAME="my.impl.MyServiceImpl" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>Class has one instantiation but it is not reachable from entry points.</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyService.java</file>
|
||||
<line>1</line>
|
||||
<package>my.api</package>
|
||||
<entry_point TYPE="method" FQNAME="my.api.MyService void foo()" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description><ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul></description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyService.java</file>
|
||||
<line>1</line>
|
||||
<package>my.api</package>
|
||||
<entry_point TYPE="class" FQNAME="my.api.MyService" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>&nbsp;Interface has an implementation but <ul><li>it is never instantiated OR</li><li>no instantiations are reachable from entry points.</li></ul></description>
|
||||
</problem>
|
||||
</problems>
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package my.impl;
|
||||
import my.api.MyService;
|
||||
|
||||
public class MyServiceImpl implements MyService {
|
||||
public MyServiceImpl(Object... objects) {System.out.println(objects);}
|
||||
@Override
|
||||
public void foo() {}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
</problems>
|
||||
+4
@@ -48,12 +48,16 @@ class Java9UnusedServiceImplementationsTest : LightJava9ModulesCodeInsightFixtur
|
||||
|
||||
fun testProvider() = doTest()
|
||||
|
||||
fun testVarargConstructor() = doTest()
|
||||
|
||||
fun testUnusedImplementation() = doTest(false)
|
||||
|
||||
fun testUnusedConstructor() = doTest(false)
|
||||
|
||||
fun testUnusedProvider() = doTest(false)
|
||||
|
||||
fun testUnusedVarargConstructor() = doTest(false)
|
||||
|
||||
fun testExternalImplementation() = doTest(sameModule = false)
|
||||
|
||||
fun testExternalConstructor() = doTest(sameModule = false)
|
||||
|
||||
@@ -45,6 +45,8 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.chooseNotNull;
|
||||
|
||||
public class DiffRequestFactoryImpl extends DiffRequestFactory {
|
||||
private final DiffContentFactoryEx myContentFactory = DiffContentFactoryEx.getInstanceEx();
|
||||
|
||||
@@ -127,7 +129,13 @@ public class DiffRequestFactoryImpl extends DiffRequestFactory {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getTitle(@NotNull FilePath path1, @NotNull FilePath path2, @NotNull String separator) {
|
||||
public static String getTitle(@Nullable FilePath path1, @Nullable FilePath path2, @NotNull String separator) {
|
||||
assert path1 != null || path2 != null;
|
||||
|
||||
if (path1 == null || path2 == null) {
|
||||
return getContentTitle(chooseNotNull(path1, path2));
|
||||
}
|
||||
|
||||
if ((path1.isDirectory() || path2.isDirectory()) && path1.getPath().equals(path2.getPath())) {
|
||||
return path1.getPresentableUrl();
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.ide.WelcomeWizardUtil
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.*
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.util.IconLoader
|
||||
import com.intellij.openapi.util.Pair
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
@@ -264,6 +265,8 @@ class UISettings : BaseState(), PersistentStateComponent<UISettings> {
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOG = Logger.getInstance(UISettings::class.java)
|
||||
|
||||
const val ANIMATION_DURATION = 300 // Milliseconds
|
||||
|
||||
/** Not tabbed pane. */
|
||||
@@ -369,14 +372,16 @@ class UISettings : BaseState(), PersistentStateComponent<UISettings> {
|
||||
|
||||
@JvmStatic
|
||||
fun restoreFontSize(readSize: Int, readScale: Float?): Int {
|
||||
var size = readSize
|
||||
if (readScale == null || readScale <= 0) {
|
||||
// Reset font to default on switch from IDE-managed HiDPI to JRE-managed HiDPI. Doesn't affect OSX.
|
||||
if (UIUtil.isJreHiDPIEnabled() && !SystemInfo.isMac) return UIUtil.DEF_SYSTEM_FONT_SIZE.toInt()
|
||||
if (UIUtil.isJreHiDPIEnabled() && !SystemInfo.isMac) size = UIUtil.DEF_SYSTEM_FONT_SIZE.toInt()
|
||||
}
|
||||
else {
|
||||
return ((readSize.toFloat() / readScale) * normalizingScale).toInt()
|
||||
size = ((readSize.toFloat() / readScale) * normalizingScale).toInt()
|
||||
}
|
||||
return readSize
|
||||
LOG.info("Loaded: fontSize=$readSize, fontScale=$readScale; restored: fontSize=$size, fontScale=$normalizingScale")
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
|
||||
import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.externalSystem.service.project;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.externalSystem.model.DataNode;
|
||||
import com.intellij.openapi.externalSystem.model.ExternalProjectInfo;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Aggregates all {@link ProjectDataService#EP_NAME registered data services}
|
||||
* and provides entry points for project data management.
|
||||
*
|
||||
* @author Vladislav Soroka
|
||||
* @since 4/16/13 11:38 AM
|
||||
*/
|
||||
public interface ProjectDataManager {
|
||||
static ProjectDataManager getInstance() {
|
||||
return ServiceManager.getService(ProjectDataManager.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
void importData(@NotNull Collection<DataNode<?>> nodes,
|
||||
@NotNull Project project,
|
||||
@NotNull IdeModifiableModelsProvider modelsProvider,
|
||||
boolean synchronous);
|
||||
|
||||
<T> void importData(@NotNull Collection<DataNode<T>> nodes, @NotNull Project project, boolean synchronous);
|
||||
|
||||
<T> void importData(@NotNull DataNode<T> node,
|
||||
@NotNull Project project,
|
||||
@NotNull IdeModifiableModelsProvider modelsProvider,
|
||||
boolean synchronous);
|
||||
|
||||
<T> void importData(@NotNull DataNode<T> node,
|
||||
@NotNull Project project,
|
||||
boolean synchronous);
|
||||
|
||||
void ensureTheDataIsReadyToUse(@Nullable DataNode dataNode);
|
||||
|
||||
@Nullable
|
||||
ExternalProjectInfo getExternalProjectData(@NotNull Project project,
|
||||
@NotNull ProjectSystemId projectSystemId,
|
||||
@NotNull String externalProjectPath);
|
||||
|
||||
@NotNull
|
||||
Collection<ExternalProjectInfo> getExternalProjectsData(@NotNull Project project, @NotNull ProjectSystemId projectSystemId);
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.externalSystem.service.project.manage;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.externalSystem.importing.ImportSpec;
|
||||
import com.intellij.openapi.externalSystem.model.DataNode;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
* @since 10/23/2014
|
||||
*/
|
||||
public interface ExternalProjectsManager {
|
||||
|
||||
static ExternalProjectsManager getInstance(@NotNull Project project) {
|
||||
return ServiceManager.getService(project, ExternalProjectsManager.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
Project getProject();
|
||||
|
||||
void refreshProject(@NotNull String externalProjectPath, @NotNull ImportSpec importSpec);
|
||||
|
||||
void runWhenInitialized(Runnable runnable);
|
||||
|
||||
boolean isIgnored(@NotNull ProjectSystemId systemId, @NotNull String projectPath);
|
||||
|
||||
void setIgnored(@NotNull DataNode<?> dataNode, boolean isIgnored);
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.externalSystem.service.project.manage;
|
||||
|
||||
import com.intellij.util.messages.Topic;
|
||||
|
||||
/**
|
||||
* @author Vladislav Soroka
|
||||
* @since 4/13/17 11:38 AM
|
||||
*/
|
||||
public interface ProjectDataImportListener {
|
||||
Topic<ProjectDataImportListener> TOPIC = new Topic<>("project data import listener", ProjectDataImportListener.class);
|
||||
|
||||
void onImportFinished(String projectPath);
|
||||
}
|
||||
+40
-5
@@ -16,6 +16,11 @@
|
||||
package com.intellij.openapi.externalSystem.settings;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.externalSystem.ExternalSystemManager;
|
||||
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import com.intellij.util.messages.Topic;
|
||||
@@ -138,13 +143,17 @@ public abstract class AbstractExternalSystemSettings<
|
||||
}
|
||||
|
||||
public void setLinkedProjectsSettings(@NotNull Collection<PS> settings) {
|
||||
setLinkedProjectsSettings(settings, null);
|
||||
}
|
||||
|
||||
private void setLinkedProjectsSettings(@NotNull Collection<PS> settings, @Nullable ExternalSystemSettingsListener listener) {
|
||||
List<PS> added = ContainerUtilRt.newArrayList();
|
||||
Map<String, PS> removed = ContainerUtilRt.newHashMap(myLinkedProjectsSettings);
|
||||
myLinkedProjectsSettings.clear();
|
||||
for (PS current : settings) {
|
||||
myLinkedProjectsSettings.put(current.getExternalProjectPath(), current);
|
||||
}
|
||||
|
||||
|
||||
for (PS current : settings) {
|
||||
PS old = removed.remove(current.getExternalProjectPath());
|
||||
if (old == null) {
|
||||
@@ -152,15 +161,24 @@ public abstract class AbstractExternalSystemSettings<
|
||||
}
|
||||
else {
|
||||
if (current.isUseAutoImport() != old.isUseAutoImport()) {
|
||||
if (listener != null) {
|
||||
listener.onUseAutoImportChange(current.isUseAutoImport(), current.getExternalProjectPath());
|
||||
}
|
||||
getPublisher().onUseAutoImportChange(current.isUseAutoImport(), current.getExternalProjectPath());
|
||||
}
|
||||
checkSettings(old, current);
|
||||
}
|
||||
}
|
||||
if (!added.isEmpty()) {
|
||||
if (listener != null) {
|
||||
listener.onProjectsLinked(added);
|
||||
}
|
||||
getPublisher().onProjectsLinked(added);
|
||||
}
|
||||
if (!removed.isEmpty()) {
|
||||
if (listener != null) {
|
||||
listener.onProjectsUnlinked(removed.keySet());
|
||||
}
|
||||
getPublisher().onProjectsUnlinked(removed.keySet());
|
||||
}
|
||||
}
|
||||
@@ -192,10 +210,27 @@ public abstract class AbstractExternalSystemSettings<
|
||||
protected void loadState(@NotNull State<PS> state) {
|
||||
Set<PS> settings = state.getLinkedExternalProjectsSettings();
|
||||
if (settings != null) {
|
||||
myLinkedProjectsSettings.clear();
|
||||
for (PS projectSettings : settings) {
|
||||
myLinkedProjectsSettings.put(projectSettings.getExternalProjectPath(), projectSettings);
|
||||
}
|
||||
setLinkedProjectsSettings(settings, new ExternalSystemSettingsListenerAdapter() {
|
||||
@Override
|
||||
public void onProjectsLinked(@NotNull Collection linked) {
|
||||
for (Object o : linked) {
|
||||
final ExternalProjectSettings settings = (ExternalProjectSettings)o;
|
||||
for (ExternalSystemManager manager : ExternalSystemManager.EP_NAME.getExtensions()) {
|
||||
AbstractExternalSystemSettings se = (AbstractExternalSystemSettings)manager.getSettingsProvider().fun(myProject);
|
||||
ProjectSystemId externalSystemId = manager.getSystemId();
|
||||
if (settings == se.getLinkedProjectSettings(settings.getExternalProjectPath())) {
|
||||
ExternalProjectsManager.getInstance(myProject).refreshProject(
|
||||
settings.getExternalProjectPath(),
|
||||
new ImportSpecBuilder(myProject, externalSystemId)
|
||||
.useDefaultCallback()
|
||||
.use(ProgressExecutionMode.IN_BACKGROUND_ASYNC)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -16,7 +16,6 @@
|
||||
package com.intellij.openapi.externalSystem.settings;
|
||||
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.util.xmlb.annotations.AbstractCollection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -37,7 +36,7 @@ public abstract class ExternalProjectSettings implements Comparable<ExternalProj
|
||||
|
||||
@NotNull
|
||||
public Set<String> getModules() {
|
||||
return myModules == null ? Collections.<String>emptySet() : myModules;
|
||||
return myModules == null ? Collections.emptySet() : myModules;
|
||||
}
|
||||
|
||||
public void setModules(@Nullable Set<String> modules) {
|
||||
|
||||
+5
-8
@@ -18,20 +18,17 @@ package com.intellij.openapi.externalSystem.action;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.externalSystem.model.DataNode;
|
||||
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectKeys;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManagerImpl;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
|
||||
import com.intellij.openapi.externalSystem.view.ProjectNode;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.SystemInfoRt;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
@@ -87,7 +84,7 @@ public class DetachExternalProjectAction extends ExternalSystemNodeAction<Projec
|
||||
forgetExternalProjects(Collections.singleton(projectData.getLinkedExternalProjectPath()));
|
||||
ExternalSystemApiUtil.getSettings(project, projectSystemId).unlinkExternalProject(projectData.getLinkedExternalProjectPath());
|
||||
|
||||
ExternalProjectsManager.getInstance(project).forgetExternalProjectData(projectSystemId, projectData.getLinkedExternalProjectPath());
|
||||
ExternalProjectsManagerImpl.getInstance(project).forgetExternalProjectData(projectSystemId, projectData.getLinkedExternalProjectPath());
|
||||
|
||||
// Process orphan modules.
|
||||
List<Module> orphanModules = ContainerUtilRt.newArrayList();
|
||||
@@ -102,8 +99,8 @@ public class DetachExternalProjectAction extends ExternalSystemNodeAction<Projec
|
||||
|
||||
if (!orphanModules.isEmpty()) {
|
||||
projectNode.getGroup().remove(projectNode);
|
||||
ProjectDataManager.getInstance().removeData(
|
||||
ProjectKeys.MODULE, orphanModules, Collections.<DataNode<ModuleData>>emptyList(), projectData, project, false);
|
||||
ProjectDataManagerImpl.getInstance().removeData(
|
||||
ProjectKeys.MODULE, orphanModules, Collections.emptyList(), projectData, project, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ import com.intellij.openapi.externalSystem.model.ExternalProjectInfo;
|
||||
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.ui.ExternalProjectDataSelectorDialog;
|
||||
import com.intellij.openapi.externalSystem.view.ExternalSystemNode;
|
||||
import com.intellij.openapi.externalSystem.view.ProjectNode;
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.project.ExternalConfigPathAware;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
|
||||
import com.intellij.openapi.externalSystem.view.ExternalSystemNode;
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.model.task.TaskData;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemKeymapExtension;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemShortcutsManager;
|
||||
import com.intellij.openapi.externalSystem.view.ExternalSystemNode;
|
||||
@@ -55,7 +55,7 @@ public class AssignShortcutAction extends ExternalSystemNodeAction<TaskData> {
|
||||
@NotNull ProjectSystemId projectSystemId,
|
||||
@NotNull TaskData taskData,
|
||||
@NotNull AnActionEvent e) {
|
||||
final ExternalSystemShortcutsManager shortcutsManager = ExternalProjectsManager.getInstance(project).getShortcutsManager();
|
||||
final ExternalSystemShortcutsManager shortcutsManager = ExternalProjectsManagerImpl.getInstance(project).getShortcutsManager();
|
||||
final String actionId = shortcutsManager.getActionId(taskData.getLinkedExternalProjectPath(), taskData.getName());
|
||||
if (actionId != null) {
|
||||
AnAction action = ActionManager.getInstance().getAction(actionId);
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@ import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
|
||||
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
|
||||
import com.intellij.openapi.externalSystem.model.task.TaskData;
|
||||
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator;
|
||||
import com.intellij.openapi.externalSystem.view.ExternalSystemNode;
|
||||
import com.intellij.openapi.externalSystem.view.RunConfigurationNode;
|
||||
@@ -108,6 +108,6 @@ public abstract class ToggleTaskActivationAction extends ExternalSystemToggleAct
|
||||
|
||||
|
||||
private ExternalSystemTaskActivator getTaskActivator(AnActionEvent e) {
|
||||
return ExternalProjectsManager.getInstance(getProject(e)).getTaskActivator();
|
||||
return ExternalProjectsManagerImpl.getInstance(getProject(e)).getTaskActivator();
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ import com.intellij.openapi.externalSystem.ExternalSystemManager;
|
||||
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder;
|
||||
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectRenameAware;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl;
|
||||
import com.intellij.openapi.externalSystem.service.ui.ExternalToolWindowManager;
|
||||
import com.intellij.openapi.externalSystem.service.vcs.ExternalSystemVcsRegistrar;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
@@ -62,7 +62,7 @@ public class ExternalSystemStartupActivity implements StartupActivity {
|
||||
ProjectRenameAware.beAware(project);
|
||||
};
|
||||
|
||||
ExternalProjectsManager.getInstance(project).init();
|
||||
ExternalProjectsManagerImpl.getInstance(project).init();
|
||||
DumbService.getInstance(project).runWhenSmart(DisposeAwareRunnable.create(task, project));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -26,13 +26,12 @@ import com.intellij.openapi.externalSystem.model.project.ModuleData;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.model.task.TaskData;
|
||||
import com.intellij.openapi.externalSystem.service.execution.cmd.CommandLineCompletionProvider;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.TextAccessor;
|
||||
import com.intellij.util.BooleanFunction;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import groovyjarjarcommonscli.Options;
|
||||
import icons.ExternalSystemIcons;
|
||||
|
||||
+2
-3
@@ -1,6 +1,5 @@
|
||||
package com.intellij.openapi.externalSystem.service.internal;
|
||||
|
||||
import com.intellij.execution.configurations.ParametersList;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.externalSystem.ExternalSystemManager;
|
||||
import com.intellij.openapi.externalSystem.model.DataNode;
|
||||
@@ -15,7 +14,7 @@ import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskState;
|
||||
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType;
|
||||
import com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager;
|
||||
import com.intellij.openapi.externalSystem.service.notification.ExternalSystemProgressNotificationManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManagerImpl;
|
||||
import com.intellij.openapi.externalSystem.service.remote.ExternalSystemProgressNotificationManagerImpl;
|
||||
import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProjectResolver;
|
||||
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
|
||||
@@ -139,7 +138,7 @@ public class ExternalSystemResolveProjectTask extends AbstractExternalSystemTask
|
||||
final long currentTimeMillis = System.currentTimeMillis();
|
||||
projectInfo.setLastImportTimestamp(currentTimeMillis);
|
||||
projectInfo.setLastSuccessfulImportTimestamp(state == ExternalSystemTaskState.FAILED ? -1 : currentTimeMillis);
|
||||
ProjectDataManager.getInstance().updateExternalProjectData(getIdeProject(), projectInfo);
|
||||
ProjectDataManagerImpl.getInstance().updateExternalProjectData(getIdeProject(), projectInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ import com.intellij.openapi.externalSystem.ExternalSystemConfigurableAware;
|
||||
import com.intellij.openapi.externalSystem.ExternalSystemManager;
|
||||
import com.intellij.openapi.externalSystem.model.LocationAwareExternalSystemException;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
|
||||
@@ -156,7 +156,7 @@ public class ExternalSystemNotificationManager implements Disposable {
|
||||
NotificationGroup group;
|
||||
if (notificationData.getBalloonGroup() == null) {
|
||||
ExternalProjectsView externalProjectsView =
|
||||
ExternalProjectsManager.getInstance(myProject).getExternalProjectsView(externalSystemId);
|
||||
ExternalProjectsManagerImpl.getInstance(myProject).getExternalProjectsView(externalSystemId);
|
||||
group = externalProjectsView instanceof ExternalProjectsViewImpl ?
|
||||
((ExternalProjectsViewImpl)externalProjectsView).getNotificationGroup() : null;
|
||||
}
|
||||
|
||||
+12
-14
@@ -33,7 +33,7 @@ import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMo
|
||||
import com.intellij.openapi.externalSystem.service.internal.ExternalSystemProcessingManager;
|
||||
import com.intellij.openapi.externalSystem.service.notification.ExternalSystemProgressNotificationManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
|
||||
@@ -609,22 +609,20 @@ public class ExternalSystemProjectsWatcher extends ExternalSystemTaskNotificatio
|
||||
PsiFile psiFile = PsiManager.getInstance(myProject).findFile(file);
|
||||
if (psiFile != null) {
|
||||
final CRC32 crc32 = new CRC32();
|
||||
ApplicationManager.getApplication().runReadAction(() -> {
|
||||
psiFile.acceptChildren(new PsiRecursiveElementVisitor() {
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
if (element instanceof LeafElement && !(element instanceof PsiWhiteSpace) && !(element instanceof PsiComment)) {
|
||||
String text = element.getText();
|
||||
if (!text.trim().isEmpty()) {
|
||||
for (int i = 0, end = text.length(); i < end; i++) {
|
||||
crc32.update(text.charAt(i));
|
||||
}
|
||||
ApplicationManager.getApplication().runReadAction(() -> psiFile.acceptChildren(new PsiRecursiveElementVisitor() {
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
if (element instanceof LeafElement && !(element instanceof PsiWhiteSpace) && !(element instanceof PsiComment)) {
|
||||
String text = element.getText();
|
||||
if (!text.trim().isEmpty()) {
|
||||
for (int i = 0, end = text.length(); i < end; i++) {
|
||||
crc32.update(text.charAt(i));
|
||||
}
|
||||
}
|
||||
super.visitElement(element);
|
||||
}
|
||||
});
|
||||
});
|
||||
super.visitElement(element);
|
||||
}
|
||||
}));
|
||||
newCrc = crc32.getValue();
|
||||
}
|
||||
else {
|
||||
|
||||
+1
-1
@@ -176,6 +176,6 @@ public class ExternalModuleStructureExtension extends ModuleStructureExtension {
|
||||
private static void unlinkProject(@NotNull Project project, ProjectSystemId systemId, String rootProjectPath) {
|
||||
ExternalSystemApiUtil.getLocalSettings(project, systemId).forgetExternalProjects(Collections.singleton(rootProjectPath));
|
||||
ExternalSystemApiUtil.getSettings(project, systemId).unlinkExternalProject(rootProjectPath);
|
||||
ExternalProjectsManager.getInstance(project).forgetExternalProjectData(systemId, rootProjectPath);
|
||||
ExternalProjectsManagerImpl.getInstance(project).forgetExternalProjectData(systemId, rootProjectPath);
|
||||
}
|
||||
}
|
||||
|
||||
+8
-4
@@ -19,7 +19,10 @@ import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.externalSystem.ExternalSystemManager;
|
||||
import com.intellij.openapi.externalSystem.model.*;
|
||||
import com.intellij.openapi.externalSystem.model.DataNode;
|
||||
import com.intellij.openapi.externalSystem.model.ExternalProjectInfo;
|
||||
import com.intellij.openapi.externalSystem.model.Key;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo;
|
||||
import com.intellij.openapi.externalSystem.model.internal.InternalExternalProjectInfo;
|
||||
import com.intellij.openapi.externalSystem.model.project.ExternalConfigPathAware;
|
||||
@@ -35,7 +38,8 @@ import com.intellij.openapi.module.ModuleTypeId;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.xmlb.annotations.AbstractCollection;
|
||||
@@ -105,7 +109,7 @@ public class ExternalProjectsDataStorage implements SettingsSavingComponent, Per
|
||||
final DataNode<ProjectData> projectStructure = externalProjectInfo.getExternalProjectStructure();
|
||||
if (projectStructure == null) return false;
|
||||
|
||||
ProjectDataManager.getInstance().ensureTheDataIsReadyToUse(projectStructure);
|
||||
ProjectDataManagerImpl.getInstance().ensureTheDataIsReadyToUse(projectStructure);
|
||||
return externalProjectInfo.getExternalProjectPath().equals(projectStructure.getData().getLinkedExternalProjectPath());
|
||||
}
|
||||
catch (Exception e) {
|
||||
@@ -262,7 +266,7 @@ public class ExternalProjectsDataStorage implements SettingsSavingComponent, Per
|
||||
if (linkedProjectSettings != null && ContainerUtil.isEmpty(linkedProjectSettings.getModules())) {
|
||||
|
||||
final Set<String> modulePaths = ContainerUtil.map2Set(
|
||||
ExternalSystemApiUtil.findAllRecursively(externalProjectInfo.getExternalProjectStructure(), ProjectKeys.MODULE),
|
||||
ExternalSystemApiUtil.findAllRecursively(externalProjectInfo.getExternalProjectStructure(), MODULE),
|
||||
node -> node.getData().getLinkedExternalProjectPath());
|
||||
linkedProjectSettings.setModules(modulePaths);
|
||||
}
|
||||
|
||||
+21
-11
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.externalSystem.ExternalSystemManager;
|
||||
import com.intellij.openapi.externalSystem.importing.ImportSpec;
|
||||
import com.intellij.openapi.externalSystem.model.DataNode;
|
||||
import com.intellij.openapi.externalSystem.model.ExternalProjectInfo;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
@@ -54,7 +55,7 @@ import static com.intellij.openapi.externalSystem.model.ProjectKeys.TASK;
|
||||
* @since 10/23/2014
|
||||
*/
|
||||
@State(name = "ExternalProjectsManager", storages = {@Storage(StoragePathMacros.WORKSPACE_FILE)})
|
||||
public class ExternalProjectsManager implements PersistentStateComponent<ExternalProjectsState>, Disposable {
|
||||
public class ExternalProjectsManagerImpl implements ExternalProjectsManager, PersistentStateComponent<ExternalProjectsState>, Disposable {
|
||||
private static final Logger LOG = Logger.getInstance(ExternalProjectsManager.class);
|
||||
|
||||
private final AtomicBoolean isInitializationFinished = new AtomicBoolean();
|
||||
@@ -71,12 +72,7 @@ public class ExternalProjectsManager implements PersistentStateComponent<Externa
|
||||
private final List<ExternalProjectsView> myProjectsViews = new SmartList<>();
|
||||
private ExternalSystemProjectsWatcher myWatcher;
|
||||
|
||||
|
||||
public static ExternalProjectsManager getInstance(@NotNull Project project) {
|
||||
return ServiceManager.getService(project, ExternalProjectsManager.class);
|
||||
}
|
||||
|
||||
public ExternalProjectsManager(@NotNull Project project) {
|
||||
public ExternalProjectsManagerImpl(@NotNull Project project) {
|
||||
myProject = project;
|
||||
myShortcutsManager = new ExternalSystemShortcutsManager(project);
|
||||
Disposer.register(this, myShortcutsManager);
|
||||
@@ -84,7 +80,13 @@ public class ExternalProjectsManager implements PersistentStateComponent<Externa
|
||||
myRunManagerListener = new ExternalSystemRunManagerListener(this);
|
||||
}
|
||||
|
||||
public static ExternalProjectsManagerImpl getInstance(@NotNull Project project) {
|
||||
ExternalProjectsManager service = ServiceManager.getService(project, ExternalProjectsManager.class);
|
||||
return (ExternalProjectsManagerImpl)service;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Project getProject() {
|
||||
return myProject;
|
||||
}
|
||||
@@ -112,7 +114,7 @@ public class ExternalProjectsManager implements PersistentStateComponent<Externa
|
||||
@Nullable
|
||||
public ExternalProjectsView getExternalProjectsView(@NotNull ProjectSystemId systemId) {
|
||||
for (ExternalProjectsView projectsView : myProjectsViews) {
|
||||
if(projectsView.getSystemId().equals(systemId)) return projectsView;
|
||||
if (projectsView.getSystemId().equals(systemId)) return projectsView;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -155,8 +157,14 @@ public class ExternalProjectsManager implements PersistentStateComponent<Externa
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshProject(@NotNull final String externalProjectPath, @NotNull final ImportSpec importSpec) {
|
||||
ExternalSystemUtil.refreshProject(externalProjectPath, importSpec);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runWhenInitialized(Runnable runnable) {
|
||||
synchronized(isInitializationFinished) {
|
||||
synchronized (isInitializationFinished) {
|
||||
if (isInitializationFinished.get()) {
|
||||
ApplicationManager.getApplication().executeOnPooledThread(runnable);
|
||||
}
|
||||
@@ -213,7 +221,7 @@ public class ExternalProjectsManager implements PersistentStateComponent<Externa
|
||||
.collect(Collectors.toMap(o -> o.getSystemId().getId(), o -> o.getSystemId()));
|
||||
for (Map.Entry<String, ExternalProjectsState.State> systemState : myState.getExternalSystemsState().entrySet()) {
|
||||
ProjectSystemId systemId = systemIds.get(systemState.getKey());
|
||||
if(systemId == null) continue;
|
||||
if (systemId == null) continue;
|
||||
|
||||
for (Map.Entry<String, TaskActivationState> activationStateEntry : systemState.getValue().getExternalSystemsTaskActivation()
|
||||
.entrySet()) {
|
||||
@@ -243,6 +251,7 @@ public class ExternalProjectsManager implements PersistentStateComponent<Externa
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIgnored(@NotNull ProjectSystemId systemId, @NotNull String projectPath) {
|
||||
final ExternalProjectInfo projectInfo = ExternalSystemUtil.getExternalProjectInfo(myProject, systemId, projectPath);
|
||||
if (projectInfo == null) return true;
|
||||
@@ -250,6 +259,7 @@ public class ExternalProjectsManager implements PersistentStateComponent<Externa
|
||||
return ExternalProjectsDataStorage.getInstance(myProject).isIgnored(projectInfo.getExternalProjectPath(), projectPath, MODULE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIgnored(@NotNull DataNode<?> dataNode, boolean isIgnored) {
|
||||
ExternalProjectsDataStorage.getInstance(myProject).setIgnored(dataNode, isIgnored);
|
||||
ExternalSystemKeymapExtension.updateActions(myProject, ExternalSystemApiUtil.findAllRecursively(dataNode, TASK));
|
||||
@@ -264,7 +274,7 @@ public class ExternalProjectsManager implements PersistentStateComponent<Externa
|
||||
public void dispose() {
|
||||
myProjectsViews.clear();
|
||||
myRunManagerListener.detach();
|
||||
if(myWatcher != null) {
|
||||
if (myWatcher != null) {
|
||||
myWatcher.stop();
|
||||
}
|
||||
myWatcher = null;
|
||||
+4
-4
@@ -88,7 +88,7 @@ public class ExternalSystemKeymapExtension implements KeymapExtension {
|
||||
|
||||
MultiMap<ProjectSystemId, String> projectToActionsMapping = MultiMap.create();
|
||||
for (ExternalSystemManager<?, ?, ?, ?, ?> manager : ExternalSystemApiUtil.getAllManagers()) {
|
||||
projectToActionsMapping.putValues(manager.getSystemId(), ContainerUtil.<String>emptyList());
|
||||
projectToActionsMapping.putValues(manager.getSystemId(), ContainerUtil.emptyList());
|
||||
}
|
||||
|
||||
ActionManager actionManager = ActionManager.getInstance();
|
||||
@@ -194,7 +194,7 @@ public class ExternalSystemKeymapExtension implements KeymapExtension {
|
||||
|
||||
private static void createActions(Project project, Collection<DataNode<TaskData>> taskNodes) {
|
||||
ActionManager actionManager = ActionManager.getInstance();
|
||||
final ExternalSystemShortcutsManager shortcutsManager = ExternalProjectsManager.getInstance(project).getShortcutsManager();
|
||||
final ExternalSystemShortcutsManager shortcutsManager = ExternalProjectsManagerImpl.getInstance(project).getShortcutsManager();
|
||||
if (actionManager != null) {
|
||||
for (DataNode<TaskData> each : taskNodes) {
|
||||
final DataNode<ModuleData> moduleData = ExternalSystemApiUtil.findParent(each, ProjectKeys.MODULE);
|
||||
@@ -233,7 +233,7 @@ public class ExternalSystemKeymapExtension implements KeymapExtension {
|
||||
}
|
||||
|
||||
public static String getActionPrefix(@NotNull Project project, @Nullable String path) {
|
||||
return ExternalProjectsManager.getInstance(project).getShortcutsManager().getActionId(path, null);
|
||||
return ExternalProjectsManagerImpl.getInstance(project).getShortcutsManager().getActionId(path, null);
|
||||
}
|
||||
|
||||
public static void updateRunConfigurationActions(Project project, ProjectSystemId systemId) {
|
||||
@@ -251,7 +251,7 @@ public class ExternalSystemKeymapExtension implements KeymapExtension {
|
||||
Set<RunnerAndConfigurationSettings> settings = new THashSet<>(
|
||||
RunManager.getInstance(project).getConfigurationSettingsList(configurationType));
|
||||
|
||||
final ExternalSystemShortcutsManager shortcutsManager = ExternalProjectsManager.getInstance(project).getShortcutsManager();
|
||||
final ExternalSystemShortcutsManager shortcutsManager = ExternalProjectsManagerImpl.getInstance(project).getShortcutsManager();
|
||||
for (RunnerAndConfigurationSettings configurationSettings : settings) {
|
||||
ExternalSystemRunConfigurationAction runConfigurationAction =
|
||||
new ExternalSystemRunConfigurationAction(project, configurationSettings);
|
||||
|
||||
+5
-4
@@ -23,6 +23,7 @@ import com.intellij.openapi.externalSystem.ExternalSystemManager;
|
||||
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
|
||||
import com.intellij.openapi.externalSystem.service.execution.AbstractExternalSystemTaskConfigurationType;
|
||||
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl.ExternalProjectsStateProvider;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
@@ -42,11 +43,11 @@ import static com.intellij.openapi.externalSystem.service.project.manage.Externa
|
||||
*/
|
||||
class ExternalSystemRunManagerListener implements RunManagerListener {
|
||||
|
||||
private ExternalProjectsManager myManager;
|
||||
private ExternalProjectsManagerImpl myManager;
|
||||
private final Map<Integer, Pair<String, RunnerAndConfigurationSettings>> myMap;
|
||||
|
||||
public ExternalSystemRunManagerListener(ExternalProjectsManager manager) {
|
||||
myManager = manager;
|
||||
myManager = (ExternalProjectsManagerImpl)manager;
|
||||
myMap = ContainerUtil.newConcurrentMap();
|
||||
}
|
||||
|
||||
@@ -61,7 +62,7 @@ class ExternalSystemRunManagerListener implements RunManagerListener {
|
||||
final Pair<String, RunnerAndConfigurationSettings> pair = myMap.remove(System.identityHashCode(settings));
|
||||
if (pair == null) return;
|
||||
|
||||
final ExternalProjectsManager.ExternalProjectsStateProvider stateProvider = myManager.getStateProvider();
|
||||
final ExternalProjectsStateProvider stateProvider = myManager.getStateProvider();
|
||||
final ExternalSystemTaskExecutionSettings taskExecutionSettings =
|
||||
((ExternalSystemRunConfiguration)settings.getConfiguration()).getSettings();
|
||||
|
||||
@@ -87,7 +88,7 @@ class ExternalSystemRunManagerListener implements RunManagerListener {
|
||||
if (settings.getConfiguration() instanceof ExternalSystemRunConfiguration) {
|
||||
final Pair<String, RunnerAndConfigurationSettings> pair = myMap.get(System.identityHashCode(settings));
|
||||
if (pair != null) {
|
||||
final ExternalProjectsManager.ExternalProjectsStateProvider stateProvider = myManager.getStateProvider();
|
||||
final ExternalProjectsStateProvider stateProvider = myManager.getStateProvider();
|
||||
final ExternalSystemTaskExecutionSettings taskExecutionSettings =
|
||||
((ExternalSystemRunConfiguration)settings.getConfiguration()).getSettings();
|
||||
|
||||
|
||||
+9
-10
@@ -29,20 +29,18 @@ import com.intellij.openapi.externalSystem.model.task.TaskData;
|
||||
import com.intellij.openapi.externalSystem.service.execution.AbstractExternalSystemTaskConfigurationType;
|
||||
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration;
|
||||
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager.ExternalProjectsStateProvider;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl.ExternalProjectsStateProvider;
|
||||
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
|
||||
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
|
||||
import com.intellij.openapi.externalSystem.task.TaskCallback;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.concurrency.Semaphore;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.FactoryMap;
|
||||
@@ -96,7 +94,7 @@ public class ExternalSystemTaskActivator {
|
||||
public String getDescription(ProjectSystemId systemId, String projectPath, String taskName) {
|
||||
List<String> result = new ArrayList<>();
|
||||
final ExternalProjectsStateProvider stateProvider =
|
||||
ExternalProjectsManager.getInstance(myProject).getStateProvider();
|
||||
ExternalProjectsManagerImpl.getInstance(myProject).getStateProvider();
|
||||
final TaskActivationState taskActivationState = stateProvider.getTasksActivation(systemId, projectPath);
|
||||
if (taskActivationState == null) return null;
|
||||
|
||||
@@ -133,7 +131,8 @@ public class ExternalSystemTaskActivator {
|
||||
}
|
||||
|
||||
public boolean runTasks(@NotNull Collection<String> modules, @NotNull Phase... phases) {
|
||||
final ExternalProjectsStateProvider stateProvider = ExternalProjectsManager.getInstance(myProject).getStateProvider();
|
||||
final ExternalProjectsStateProvider stateProvider =
|
||||
ExternalProjectsManagerImpl.getInstance(myProject).getStateProvider();
|
||||
|
||||
final Queue<Pair<ProjectSystemId, ExternalSystemTaskExecutionSettings>> tasksQueue =
|
||||
new LinkedList<>();
|
||||
@@ -245,7 +244,7 @@ public class ExternalSystemTaskActivator {
|
||||
}
|
||||
|
||||
public boolean isTaskOfPhase(@NotNull TaskData taskData, @NotNull Phase phase) {
|
||||
final ExternalProjectsStateProvider stateProvider = ExternalProjectsManager.getInstance(myProject).getStateProvider();
|
||||
final ExternalProjectsStateProvider stateProvider = ExternalProjectsManagerImpl.getInstance(myProject).getStateProvider();
|
||||
final TaskActivationState taskActivationState =
|
||||
stateProvider.getTasksActivation(taskData.getOwner(), taskData.getLinkedExternalProjectPath());
|
||||
if (taskActivationState == null) return false;
|
||||
@@ -263,7 +262,7 @@ public class ExternalSystemTaskActivator {
|
||||
public void addTasks(@NotNull Collection<TaskActivationEntry> entries) {
|
||||
if (entries.isEmpty()) return;
|
||||
|
||||
final ExternalProjectsStateProvider stateProvider = ExternalProjectsManager.getInstance(myProject).getStateProvider();
|
||||
final ExternalProjectsStateProvider stateProvider = ExternalProjectsManagerImpl.getInstance(myProject).getStateProvider();
|
||||
for (TaskActivationEntry entry : entries) {
|
||||
final TaskActivationState taskActivationState = stateProvider.getTasksActivation(entry.systemId, entry.projectPath);
|
||||
taskActivationState.getTasks(entry.phase).add(entry.taskName);
|
||||
@@ -279,7 +278,7 @@ public class ExternalSystemTaskActivator {
|
||||
|
||||
public void removeTasks(@NotNull Collection<TaskActivationEntry> entries) {
|
||||
if (entries.isEmpty()) return;
|
||||
final ExternalProjectsStateProvider stateProvider = ExternalProjectsManager.getInstance(myProject).getStateProvider();
|
||||
final ExternalProjectsStateProvider stateProvider = ExternalProjectsManagerImpl.getInstance(myProject).getStateProvider();
|
||||
for (TaskActivationEntry activationEntry : entries) {
|
||||
final TaskActivationState taskActivationState =
|
||||
stateProvider.getTasksActivation(activationEntry.systemId, activationEntry.projectPath);
|
||||
@@ -300,7 +299,7 @@ public class ExternalSystemTaskActivator {
|
||||
public void moveTasks(@NotNull Collection<TaskActivationEntry> entries, int increment) {
|
||||
LOG.assertTrue(increment == -1 || increment == 1);
|
||||
|
||||
final ExternalProjectsStateProvider stateProvider = ExternalProjectsManager.getInstance(myProject).getStateProvider();
|
||||
final ExternalProjectsStateProvider stateProvider = ExternalProjectsManagerImpl.getInstance(myProject).getStateProvider();
|
||||
for (TaskActivationEntry activationEntry : entries) {
|
||||
final TaskActivationState taskActivationState =
|
||||
stateProvider.getTasksActivation(activationEntry.systemId, activationEntry.projectPath);
|
||||
@@ -319,7 +318,7 @@ public class ExternalSystemTaskActivator {
|
||||
int increment) {
|
||||
LOG.assertTrue(increment == -1 || increment == 1);
|
||||
|
||||
final ExternalProjectsStateProvider stateProvider = ExternalProjectsManager.getInstance(myProject).getStateProvider();
|
||||
final ExternalProjectsStateProvider stateProvider = ExternalProjectsManagerImpl.getInstance(myProject).getStateProvider();
|
||||
final Map<String, TaskActivationState> activationMap = stateProvider.getProjectsTasksActivationMap(systemId);
|
||||
final List<String> currentPaths = ContainerUtil.newArrayList(activationMap.keySet());
|
||||
if (pathsGroup != null) {
|
||||
|
||||
+44
-336
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,394 +15,102 @@
|
||||
*/
|
||||
package com.intellij.openapi.externalSystem.service.project.manage;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.externalSystem.model.*;
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData;
|
||||
import com.intellij.openapi.externalSystem.model.DataNode;
|
||||
import com.intellij.openapi.externalSystem.model.ExternalProjectInfo;
|
||||
import com.intellij.openapi.externalSystem.model.Key;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider;
|
||||
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProviderImpl;
|
||||
import com.intellij.openapi.externalSystem.util.DisposeAwareProjectChange;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.impl.ProjectImpl;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.NotNullLazyValue;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ExceptionUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.util.containers.ContainerUtil.map2Array;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Aggregates all {@link ProjectDataService#EP_NAME registered data services} and provides entry points for project data management.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 4/16/13 11:38 AM
|
||||
* @deprecated use {@link com.intellij.openapi.externalSystem.service.project.ProjectDataManager} instead
|
||||
*/
|
||||
public class ProjectDataManager {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#" + ProjectDataManager.class.getName());
|
||||
private static final com.intellij.openapi.util.Key<Boolean> DATA_READY =
|
||||
com.intellij.openapi.util.Key.create("externalSystem.data.ready");
|
||||
|
||||
@NotNull private final NotNullLazyValue<Map<Key<?>, List<ProjectDataService<?, ?>>>> myServices;
|
||||
public class ProjectDataManager extends ProjectDataManagerImpl {
|
||||
|
||||
public static ProjectDataManager getInstance() {
|
||||
return ServiceManager.getService(ProjectDataManager.class);
|
||||
return new ProjectDataManager(ProjectDataManagerImpl.getInstance());
|
||||
}
|
||||
|
||||
public ProjectDataManager() {
|
||||
myServices = new NotNullLazyValue<Map<Key<?>, List<ProjectDataService<?, ?>>>>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected Map<Key<?>, List<ProjectDataService<?, ?>>> compute() {
|
||||
Map<Key<?>, List<ProjectDataService<?, ?>>> result = ContainerUtilRt.newHashMap();
|
||||
for (ProjectDataService<?, ?> service : ProjectDataService.EP_NAME.getExtensions()) {
|
||||
List<ProjectDataService<?, ?>> services = result.get(service.getTargetDataKey());
|
||||
if (services == null) {
|
||||
result.put(service.getTargetDataKey(), services = ContainerUtilRt.newArrayList());
|
||||
}
|
||||
services.add(service);
|
||||
}
|
||||
private final ProjectDataManagerImpl delegate;
|
||||
|
||||
for (List<ProjectDataService<?, ?>> services : result.values()) {
|
||||
ExternalSystemApiUtil.orderAwareSort(services);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
public ProjectDataManager(ProjectDataManagerImpl delegate) {this.delegate = delegate;}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void importData(@NotNull Collection<DataNode<?>> nodes,
|
||||
@NotNull Project project,
|
||||
@NotNull IdeModifiableModelsProvider modelsProvider,
|
||||
boolean synchronous) {
|
||||
if (project.isDisposed()) return;
|
||||
|
||||
MultiMap<Key<?>, DataNode<?>> grouped = ExternalSystemApiUtil.recursiveGroup(nodes);
|
||||
for (Key<?> key : myServices.getValue().keySet()) {
|
||||
if (!grouped.containsKey(key)) {
|
||||
grouped.put(key, Collections.<DataNode<?>>emptyList());
|
||||
}
|
||||
}
|
||||
|
||||
final Collection<DataNode<?>> projects = grouped.get(ProjectKeys.PROJECT);
|
||||
// only one project(can be multi-module project) expected for per single import
|
||||
assert projects.size() == 1 || projects.isEmpty();
|
||||
|
||||
final DataNode<ProjectData> projectNode = (DataNode<ProjectData>)ContainerUtil.getFirstItem(projects);
|
||||
final ProjectData projectData;
|
||||
ProjectSystemId projectSystemId;
|
||||
if (projectNode != null) {
|
||||
projectData = projectNode.getData();
|
||||
projectSystemId = projectNode.getData().getOwner();
|
||||
ExternalProjectsDataStorage.getInstance(project).saveInclusionSettings(projectNode);
|
||||
}
|
||||
else {
|
||||
projectData = null;
|
||||
DataNode<ModuleData> aModuleNode = (DataNode<ModuleData>)ContainerUtil.getFirstItem(grouped.get(ProjectKeys.MODULE));
|
||||
projectSystemId = aModuleNode != null ? aModuleNode.getData().getOwner() : null;
|
||||
}
|
||||
|
||||
if (projectSystemId != null) {
|
||||
ExternalSystemUtil.scheduleExternalViewStructureUpdate(project, projectSystemId);
|
||||
}
|
||||
|
||||
List<Runnable> onSuccessImportTasks = ContainerUtil.newSmartList();
|
||||
try {
|
||||
final Set<Map.Entry<Key<?>, Collection<DataNode<?>>>> entries = grouped.entrySet();
|
||||
final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (indicator != null) {
|
||||
indicator.setIndeterminate(false);
|
||||
}
|
||||
final int size = entries.size();
|
||||
int count = 0;
|
||||
List<Runnable> postImportTasks = ContainerUtil.newSmartList();
|
||||
for (Map.Entry<Key<?>, Collection<DataNode<?>>> entry : entries) {
|
||||
if (indicator != null) {
|
||||
String message = ExternalSystemBundle.message(
|
||||
"progress.update.text", projectSystemId != null ? projectSystemId.getReadableName() : "",
|
||||
"Refresh " + getReadableText(entry.getKey()));
|
||||
indicator.setText(message);
|
||||
indicator.setFraction((double)count++ / size);
|
||||
}
|
||||
doImportData(entry.getKey(), entry.getValue(), projectData, project, modelsProvider, postImportTasks, onSuccessImportTasks);
|
||||
}
|
||||
|
||||
for (Runnable postImportTask : postImportTasks) {
|
||||
postImportTask.run();
|
||||
}
|
||||
|
||||
commit(modelsProvider, project, synchronous, "Imported data");
|
||||
if (indicator != null) {
|
||||
indicator.setIndeterminate(true);
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
dispose(modelsProvider, project, synchronous);
|
||||
ExceptionUtil.rethrowAllAsUnchecked(t);
|
||||
}
|
||||
|
||||
for (Runnable onSuccessImportTask : ContainerUtil.reverse(onSuccessImportTasks)) {
|
||||
onSuccessImportTask.run();
|
||||
}
|
||||
delegate.importData(nodes, project, modelsProvider, synchronous);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getReadableText(@NotNull Key key) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
String s = key.toString();
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char currChar = s.charAt(i);
|
||||
if (Character.isUpperCase(currChar)) {
|
||||
if (i != 0) {
|
||||
buffer.append(' ');
|
||||
}
|
||||
buffer.append(StringUtil.toLowerCase(currChar));
|
||||
}
|
||||
else {
|
||||
buffer.append(currChar);
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public <T> void importData(@NotNull Collection<DataNode<T>> nodes, @NotNull Project project, boolean synchronous) {
|
||||
Collection<DataNode<?>> dummy = ContainerUtil.newSmartList();
|
||||
for (DataNode<T> node : nodes) {
|
||||
dummy.add(node);
|
||||
}
|
||||
importData(dummy, project, new IdeModifiableModelsProviderImpl(project), synchronous);
|
||||
@Override
|
||||
public <T> void importData(@NotNull Collection<DataNode<T>> nodes,
|
||||
@NotNull Project project, boolean synchronous) {
|
||||
delegate.importData(nodes, project, synchronous);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void importData(@NotNull DataNode<T> node,
|
||||
@NotNull Project project,
|
||||
@NotNull IdeModifiableModelsProvider modelsProvider,
|
||||
boolean synchronous) {
|
||||
Collection<DataNode<?>> dummy = ContainerUtil.newSmartList();
|
||||
dummy.add(node);
|
||||
importData(dummy, project, modelsProvider, synchronous);
|
||||
delegate.importData(node, project, modelsProvider, synchronous);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void importData(@NotNull DataNode<T> node,
|
||||
@NotNull Project project,
|
||||
boolean synchronous) {
|
||||
importData(node, project, new IdeModifiableModelsProviderImpl(project), synchronous);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> void doImportData(@NotNull Key<T> key,
|
||||
@NotNull Collection<DataNode<?>> nodes,
|
||||
@Nullable final ProjectData projectData,
|
||||
@NotNull final Project project,
|
||||
@NotNull final IdeModifiableModelsProvider modelsProvider,
|
||||
@NotNull final List<Runnable> postImportTasks,
|
||||
@NotNull final List<Runnable> onSuccessImportTasks) {
|
||||
if (project.isDisposed()) return;
|
||||
if (project instanceof ProjectImpl) {
|
||||
assert ((ProjectImpl)project).isComponentsCreated();
|
||||
}
|
||||
|
||||
final List<DataNode<T>> toImport = ContainerUtil.newSmartList();
|
||||
final List<DataNode<T>> toIgnore = ContainerUtil.newSmartList();
|
||||
|
||||
for (DataNode node : nodes) {
|
||||
if (!key.equals(node.getKey())) continue;
|
||||
|
||||
if (node.isIgnored()) {
|
||||
toIgnore.add(node);
|
||||
}
|
||||
else {
|
||||
toImport.add(node);
|
||||
}
|
||||
}
|
||||
|
||||
ensureTheDataIsReadyToUse((Collection)toImport);
|
||||
|
||||
final List<ProjectDataService<?, ?>> services = myServices.getValue().get(key);
|
||||
if (services == null) {
|
||||
LOG.warn(String.format(
|
||||
"Can't import data nodes '%s'. Reason: no service is registered for key %s. Available services for %s",
|
||||
toImport, key, myServices.getValue().keySet()
|
||||
));
|
||||
}
|
||||
else {
|
||||
for (ProjectDataService<?, ?> service : services) {
|
||||
final long importStartTime = System.currentTimeMillis();
|
||||
((ProjectDataService)service).importData(toImport, projectData, project, modelsProvider);
|
||||
if(LOG.isDebugEnabled()) {
|
||||
final long importTimeInMs = (System.currentTimeMillis() - importStartTime);
|
||||
LOG.debug(String.format("Service %s imported data in %d ms", service.getClass().getSimpleName(), importTimeInMs));
|
||||
}
|
||||
|
||||
if(projectData != null) {
|
||||
ensureTheDataIsReadyToUse((Collection)toIgnore);
|
||||
final long removeStartTime = System.currentTimeMillis();
|
||||
final Computable<Collection<?>> orphanIdeDataComputable =
|
||||
((ProjectDataService)service).computeOrphanData(toImport, projectData, project, modelsProvider);
|
||||
((ProjectDataService)service).removeData(orphanIdeDataComputable, toIgnore, projectData, project, modelsProvider);
|
||||
if(LOG.isDebugEnabled()) {
|
||||
final long removeTimeInMs = (System.currentTimeMillis() - removeStartTime);
|
||||
LOG.debug(String.format("Service %s computed and removed data in %d ms", service.getClass().getSimpleName(), removeTimeInMs));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (services != null && projectData != null) {
|
||||
postImportTasks.add(() -> {
|
||||
for (ProjectDataService<?, ?> service : services) {
|
||||
if (service instanceof AbstractProjectDataService) {
|
||||
final long taskStartTime = System.currentTimeMillis();
|
||||
((AbstractProjectDataService)service).postProcess(toImport, projectData, project, modelsProvider);
|
||||
if(LOG.isDebugEnabled()) {
|
||||
final long taskTimeInMs = (System.currentTimeMillis() - taskStartTime);
|
||||
LOG.debug(String.format("Service %s run post import task in %d ms", service.getClass().getSimpleName(), taskTimeInMs));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
onSuccessImportTasks.add(() -> {
|
||||
for (ProjectDataService<?, ?> service : services) {
|
||||
if (service instanceof AbstractProjectDataService) {
|
||||
final long taskStartTime = System.currentTimeMillis();
|
||||
((AbstractProjectDataService)service).onSuccessImport(project);
|
||||
if(LOG.isDebugEnabled()) {
|
||||
final long taskTimeInMs = (System.currentTimeMillis() - taskStartTime);
|
||||
LOG.debug(String.format("Service %s run post import task in %d ms", service.getClass().getSimpleName(), taskTimeInMs));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@NotNull Project project, boolean synchronous) {
|
||||
delegate.importData(node, project, synchronous);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ensureTheDataIsReadyToUse(@Nullable DataNode dataNode) {
|
||||
if (dataNode == null) return;
|
||||
if (Boolean.TRUE.equals(dataNode.getUserData(DATA_READY))) return;
|
||||
|
||||
ExternalSystemApiUtil.visit(dataNode, dataNode1 -> {
|
||||
prepareDataToUse(dataNode1);
|
||||
dataNode1.putUserData(DATA_READY, Boolean.TRUE);
|
||||
});
|
||||
delegate.ensureTheDataIsReadyToUse(dataNode);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <E, I> void removeData(@NotNull Key<E> key,
|
||||
@NotNull Collection<I> toRemove,
|
||||
@NotNull final Collection<DataNode<E>> toIgnore,
|
||||
@NotNull final ProjectData projectData,
|
||||
@NotNull Collection<DataNode<E>> toIgnore,
|
||||
@NotNull ProjectData projectData,
|
||||
@NotNull Project project,
|
||||
@NotNull final IdeModifiableModelsProvider modelsProvider,
|
||||
@NotNull IdeModifiableModelsProvider modelsProvider,
|
||||
boolean synchronous) {
|
||||
try {
|
||||
List<ProjectDataService<?, ?>> services = myServices.getValue().get(key);
|
||||
for (ProjectDataService service : services) {
|
||||
final long removeStartTime = System.currentTimeMillis();
|
||||
service.removeData(new Computable.PredefinedValueComputable<Collection>(toRemove), toIgnore, projectData, project, modelsProvider);
|
||||
if(LOG.isDebugEnabled()) {
|
||||
final long removeTimeInMs = System.currentTimeMillis() - removeStartTime;
|
||||
LOG.debug(String.format("Service %s removed data in %d ms", service.getClass().getSimpleName(), removeTimeInMs));
|
||||
}
|
||||
}
|
||||
|
||||
commit(modelsProvider, project, synchronous, "Removed data");
|
||||
}
|
||||
catch (Throwable t) {
|
||||
dispose(modelsProvider, project, synchronous);
|
||||
ExceptionUtil.rethrowAllAsUnchecked(t);
|
||||
}
|
||||
delegate.removeData(key, toRemove, toIgnore, projectData, project, modelsProvider, synchronous);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E, I> void removeData(@NotNull Key<E> key,
|
||||
@NotNull Collection<I> toRemove,
|
||||
@NotNull final Collection<DataNode<E>> toIgnore,
|
||||
@NotNull final ProjectData projectData,
|
||||
@NotNull Project project,
|
||||
boolean synchronous) {
|
||||
removeData(key, toRemove, toIgnore, projectData, project, new IdeModifiableModelsProviderImpl(project), synchronous);
|
||||
@NotNull Collection<DataNode<E>> toIgnore,
|
||||
@NotNull ProjectData projectData,
|
||||
@NotNull Project project, boolean synchronous) {
|
||||
delegate.removeData(key, toRemove, toIgnore, projectData, project, synchronous);
|
||||
}
|
||||
|
||||
public void updateExternalProjectData(@NotNull Project project, @NotNull ExternalProjectInfo externalProjectInfo) {
|
||||
if (!project.isDisposed()) {
|
||||
ExternalProjectsManager.getInstance(project).updateExternalProjectData(externalProjectInfo);
|
||||
}
|
||||
@Override
|
||||
public void updateExternalProjectData(@NotNull Project project,
|
||||
@NotNull ExternalProjectInfo externalProjectInfo) {
|
||||
delegate.updateExternalProjectData(project, externalProjectInfo);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ExternalProjectInfo getExternalProjectData(@NotNull Project project,
|
||||
@NotNull ProjectSystemId projectSystemId,
|
||||
@NotNull String externalProjectPath) {
|
||||
return !project.isDisposed() ? ExternalProjectsDataStorage.getInstance(project).get(projectSystemId, externalProjectPath) : null;
|
||||
return delegate.getExternalProjectData(project, projectSystemId, externalProjectPath);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<ExternalProjectInfo> getExternalProjectsData(@NotNull Project project, @NotNull ProjectSystemId projectSystemId) {
|
||||
if (!project.isDisposed()) {
|
||||
return ExternalProjectsDataStorage.getInstance(project).list(projectSystemId);
|
||||
}
|
||||
else {
|
||||
return ContainerUtil.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureTheDataIsReadyToUse(@NotNull Collection<DataNode<?>> nodes) {
|
||||
for (DataNode<?> node : nodes) {
|
||||
ensureTheDataIsReadyToUse(node);
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareDataToUse(@NotNull DataNode dataNode) {
|
||||
final Map<Key<?>, List<ProjectDataService<?, ?>>> servicesByKey = myServices.getValue();
|
||||
List<ProjectDataService<?, ?>> services = servicesByKey.get(dataNode.getKey());
|
||||
if (services != null) {
|
||||
try {
|
||||
dataNode.prepareData(map2Array(services, ClassLoader.class, service -> service.getClass().getClassLoader()));
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.debug(e);
|
||||
dataNode.clear(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void commit(@NotNull final IdeModifiableModelsProvider modelsProvider,
|
||||
@NotNull Project project,
|
||||
boolean synchronous,
|
||||
@NotNull final String commitDesc) {
|
||||
ExternalSystemApiUtil.executeProjectChangeAction(synchronous, new DisposeAwareProjectChange(project) {
|
||||
@Override
|
||||
public void execute() {
|
||||
final long startTime = System.currentTimeMillis();
|
||||
modelsProvider.commit();
|
||||
final long timeInMs = System.currentTimeMillis() - startTime;
|
||||
LOG.debug(String.format("%s committed in %d ms", commitDesc, timeInMs));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void dispose(@NotNull final IdeModifiableModelsProvider modelsProvider,
|
||||
@NotNull Project project,
|
||||
boolean synchronous) {
|
||||
ExternalSystemApiUtil.executeProjectChangeAction(synchronous, new DisposeAwareProjectChange(project) {
|
||||
@Override
|
||||
public void execute() {
|
||||
modelsProvider.dispose();
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public Collection<ExternalProjectInfo> getExternalProjectsData(@NotNull Project project,
|
||||
@NotNull ProjectSystemId projectSystemId) {
|
||||
return delegate.getExternalProjectsData(project, projectSystemId);
|
||||
}
|
||||
}
|
||||
|
||||
+416
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.externalSystem.service.project.manage;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.externalSystem.model.*;
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider;
|
||||
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProviderImpl;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.util.DisposeAwareProjectChange;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.impl.ProjectImpl;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.NotNullLazyValue;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
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;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.util.containers.ContainerUtil.map2Array;
|
||||
|
||||
/**
|
||||
* Aggregates all {@link ProjectDataService#EP_NAME registered data services} and provides entry points for project data management.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 4/16/13 11:38 AM
|
||||
*/
|
||||
public class ProjectDataManagerImpl implements ProjectDataManager {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#" + ProjectDataManagerImpl.class.getName());
|
||||
private static final com.intellij.openapi.util.Key<Boolean> DATA_READY =
|
||||
com.intellij.openapi.util.Key.create("externalSystem.data.ready");
|
||||
|
||||
@NotNull private final NotNullLazyValue<Map<Key<?>, List<ProjectDataService<?, ?>>>> myServices;
|
||||
|
||||
public static ProjectDataManagerImpl getInstance() {
|
||||
ProjectDataManager service = ServiceManager.getService(ProjectDataManager.class);
|
||||
return (ProjectDataManagerImpl)service;
|
||||
}
|
||||
|
||||
public ProjectDataManagerImpl() {
|
||||
myServices = new NotNullLazyValue<Map<Key<?>, List<ProjectDataService<?, ?>>>>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected Map<Key<?>, List<ProjectDataService<?, ?>>> compute() {
|
||||
Map<Key<?>, List<ProjectDataService<?, ?>>> result = ContainerUtilRt.newHashMap();
|
||||
for (ProjectDataService<?, ?> service : ProjectDataService.EP_NAME.getExtensions()) {
|
||||
List<ProjectDataService<?, ?>> services = result.get(service.getTargetDataKey());
|
||||
if (services == null) {
|
||||
result.put(service.getTargetDataKey(), services = ContainerUtilRt.newArrayList());
|
||||
}
|
||||
services.add(service);
|
||||
}
|
||||
|
||||
for (List<ProjectDataService<?, ?>> services : result.values()) {
|
||||
ExternalSystemApiUtil.orderAwareSort(services);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void importData(@NotNull Collection<DataNode<?>> nodes,
|
||||
@NotNull Project project,
|
||||
@NotNull IdeModifiableModelsProvider modelsProvider,
|
||||
boolean synchronous) {
|
||||
if (project.isDisposed()) return;
|
||||
|
||||
MultiMap<Key<?>, DataNode<?>> grouped = ExternalSystemApiUtil.recursiveGroup(nodes);
|
||||
for (Key<?> key : myServices.getValue().keySet()) {
|
||||
if (!grouped.containsKey(key)) {
|
||||
grouped.put(key, Collections.emptyList());
|
||||
}
|
||||
}
|
||||
|
||||
final Collection<DataNode<?>> projects = grouped.get(ProjectKeys.PROJECT);
|
||||
// only one project(can be multi-module project) expected for per single import
|
||||
assert projects.size() == 1 || projects.isEmpty();
|
||||
|
||||
final DataNode<ProjectData> projectNode = (DataNode<ProjectData>)ContainerUtil.getFirstItem(projects);
|
||||
final ProjectData projectData;
|
||||
ProjectSystemId projectSystemId;
|
||||
if (projectNode != null) {
|
||||
projectData = projectNode.getData();
|
||||
projectSystemId = projectNode.getData().getOwner();
|
||||
ExternalProjectsDataStorage.getInstance(project).saveInclusionSettings(projectNode);
|
||||
}
|
||||
else {
|
||||
projectData = null;
|
||||
DataNode<ModuleData> aModuleNode = (DataNode<ModuleData>)ContainerUtil.getFirstItem(grouped.get(ProjectKeys.MODULE));
|
||||
projectSystemId = aModuleNode != null ? aModuleNode.getData().getOwner() : null;
|
||||
}
|
||||
|
||||
if (projectSystemId != null) {
|
||||
ExternalSystemUtil.scheduleExternalViewStructureUpdate(project, projectSystemId);
|
||||
}
|
||||
|
||||
List<Runnable> onSuccessImportTasks = ContainerUtil.newSmartList();
|
||||
try {
|
||||
final Set<Map.Entry<Key<?>, Collection<DataNode<?>>>> entries = grouped.entrySet();
|
||||
final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (indicator != null) {
|
||||
indicator.setIndeterminate(false);
|
||||
}
|
||||
final int size = entries.size();
|
||||
int count = 0;
|
||||
List<Runnable> postImportTasks = ContainerUtil.newSmartList();
|
||||
for (Map.Entry<Key<?>, Collection<DataNode<?>>> entry : entries) {
|
||||
if (indicator != null) {
|
||||
String message = ExternalSystemBundle.message(
|
||||
"progress.update.text", projectSystemId != null ? projectSystemId.getReadableName() : "",
|
||||
"Refresh " + getReadableText(entry.getKey()));
|
||||
indicator.setText(message);
|
||||
indicator.setFraction((double)count++ / size);
|
||||
}
|
||||
doImportData(entry.getKey(), entry.getValue(), projectData, project, modelsProvider, postImportTasks, onSuccessImportTasks);
|
||||
}
|
||||
|
||||
for (Runnable postImportTask : postImportTasks) {
|
||||
postImportTask.run();
|
||||
}
|
||||
|
||||
commit(modelsProvider, project, synchronous, "Imported data");
|
||||
if (indicator != null) {
|
||||
indicator.setIndeterminate(true);
|
||||
}
|
||||
|
||||
project.getMessageBus().syncPublisher(ProjectDataImportListener.TOPIC)
|
||||
.onImportFinished(projectData != null ? projectData.getLinkedExternalProjectPath() : null);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
dispose(modelsProvider, project, synchronous);
|
||||
ExceptionUtil.rethrowAllAsUnchecked(t);
|
||||
}
|
||||
|
||||
for (Runnable onSuccessImportTask : ContainerUtil.reverse(onSuccessImportTasks)) {
|
||||
onSuccessImportTask.run();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getReadableText(@NotNull Key key) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
String s = key.toString();
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char currChar = s.charAt(i);
|
||||
if (Character.isUpperCase(currChar)) {
|
||||
if (i != 0) {
|
||||
buffer.append(' ');
|
||||
}
|
||||
buffer.append(StringUtil.toLowerCase(currChar));
|
||||
}
|
||||
else {
|
||||
buffer.append(currChar);
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void importData(@NotNull Collection<DataNode<T>> nodes, @NotNull Project project, boolean synchronous) {
|
||||
Collection<DataNode<?>> dummy = ContainerUtil.newSmartList();
|
||||
dummy.addAll(nodes);
|
||||
importData(dummy, project, new IdeModifiableModelsProviderImpl(project), synchronous);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void importData(@NotNull DataNode<T> node,
|
||||
@NotNull Project project,
|
||||
@NotNull IdeModifiableModelsProvider modelsProvider,
|
||||
boolean synchronous) {
|
||||
Collection<DataNode<?>> dummy = ContainerUtil.newSmartList();
|
||||
dummy.add(node);
|
||||
importData(dummy, project, modelsProvider, synchronous);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void importData(@NotNull DataNode<T> node,
|
||||
@NotNull Project project,
|
||||
boolean synchronous) {
|
||||
importData(node, project, new IdeModifiableModelsProviderImpl(project), synchronous);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> void doImportData(@NotNull Key<T> key,
|
||||
@NotNull Collection<DataNode<?>> nodes,
|
||||
@Nullable final ProjectData projectData,
|
||||
@NotNull final Project project,
|
||||
@NotNull final IdeModifiableModelsProvider modelsProvider,
|
||||
@NotNull final List<Runnable> postImportTasks,
|
||||
@NotNull final List<Runnable> onSuccessImportTasks) {
|
||||
if (project.isDisposed()) return;
|
||||
if (project instanceof ProjectImpl) {
|
||||
assert ((ProjectImpl)project).isComponentsCreated();
|
||||
}
|
||||
|
||||
final List<DataNode<T>> toImport = ContainerUtil.newSmartList();
|
||||
final List<DataNode<T>> toIgnore = ContainerUtil.newSmartList();
|
||||
|
||||
for (DataNode node : nodes) {
|
||||
if (!key.equals(node.getKey())) continue;
|
||||
|
||||
if (node.isIgnored()) {
|
||||
toIgnore.add(node);
|
||||
}
|
||||
else {
|
||||
toImport.add(node);
|
||||
}
|
||||
}
|
||||
|
||||
ensureTheDataIsReadyToUse((Collection)toImport);
|
||||
|
||||
final List<ProjectDataService<?, ?>> services = myServices.getValue().get(key);
|
||||
if (services == null) {
|
||||
LOG.warn(String.format(
|
||||
"Can't import data nodes '%s'. Reason: no service is registered for key %s. Available services for %s",
|
||||
toImport, key, myServices.getValue().keySet()
|
||||
));
|
||||
}
|
||||
else {
|
||||
for (ProjectDataService<?, ?> service : services) {
|
||||
final long importStartTime = System.currentTimeMillis();
|
||||
((ProjectDataService)service).importData(toImport, projectData, project, modelsProvider);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
final long importTimeInMs = (System.currentTimeMillis() - importStartTime);
|
||||
LOG.debug(String.format("Service %s imported data in %d ms", service.getClass().getSimpleName(), importTimeInMs));
|
||||
}
|
||||
|
||||
if (projectData != null) {
|
||||
ensureTheDataIsReadyToUse((Collection)toIgnore);
|
||||
final long removeStartTime = System.currentTimeMillis();
|
||||
final Computable<Collection<?>> orphanIdeDataComputable =
|
||||
((ProjectDataService)service).computeOrphanData(toImport, projectData, project, modelsProvider);
|
||||
((ProjectDataService)service).removeData(orphanIdeDataComputable, toIgnore, projectData, project, modelsProvider);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
final long removeTimeInMs = (System.currentTimeMillis() - removeStartTime);
|
||||
LOG.debug(String.format("Service %s computed and removed data in %d ms", service.getClass().getSimpleName(), removeTimeInMs));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (services != null && projectData != null) {
|
||||
postImportTasks.add(() -> {
|
||||
for (ProjectDataService<?, ?> service : services) {
|
||||
if (service instanceof AbstractProjectDataService) {
|
||||
final long taskStartTime = System.currentTimeMillis();
|
||||
((AbstractProjectDataService)service).postProcess(toImport, projectData, project, modelsProvider);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
final long taskTimeInMs = (System.currentTimeMillis() - taskStartTime);
|
||||
LOG.debug(String.format("Service %s run post import task in %d ms", service.getClass().getSimpleName(), taskTimeInMs));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
onSuccessImportTasks.add(() -> {
|
||||
for (ProjectDataService<?, ?> service : services) {
|
||||
if (service instanceof AbstractProjectDataService) {
|
||||
final long taskStartTime = System.currentTimeMillis();
|
||||
((AbstractProjectDataService)service).onSuccessImport(project);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
final long taskTimeInMs = (System.currentTimeMillis() - taskStartTime);
|
||||
LOG.debug(String.format("Service %s run post import task in %d ms", service.getClass().getSimpleName(), taskTimeInMs));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ensureTheDataIsReadyToUse(@Nullable DataNode dataNode) {
|
||||
if (dataNode == null) return;
|
||||
if (Boolean.TRUE.equals(dataNode.getUserData(DATA_READY))) return;
|
||||
|
||||
ExternalSystemApiUtil.visit(dataNode, dataNode1 -> {
|
||||
prepareDataToUse(dataNode1);
|
||||
dataNode1.putUserData(DATA_READY, Boolean.TRUE);
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <E, I> void removeData(@NotNull Key<E> key,
|
||||
@NotNull Collection<I> toRemove,
|
||||
@NotNull final Collection<DataNode<E>> toIgnore,
|
||||
@NotNull final ProjectData projectData,
|
||||
@NotNull Project project,
|
||||
@NotNull final IdeModifiableModelsProvider modelsProvider,
|
||||
boolean synchronous) {
|
||||
try {
|
||||
List<ProjectDataService<?, ?>> services = myServices.getValue().get(key);
|
||||
for (ProjectDataService service : services) {
|
||||
final long removeStartTime = System.currentTimeMillis();
|
||||
service.removeData(new Computable.PredefinedValueComputable<Collection>(toRemove), toIgnore, projectData, project, modelsProvider);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
final long removeTimeInMs = System.currentTimeMillis() - removeStartTime;
|
||||
LOG.debug(String.format("Service %s removed data in %d ms", service.getClass().getSimpleName(), removeTimeInMs));
|
||||
}
|
||||
}
|
||||
|
||||
commit(modelsProvider, project, synchronous, "Removed data");
|
||||
}
|
||||
catch (Throwable t) {
|
||||
dispose(modelsProvider, project, synchronous);
|
||||
ExceptionUtil.rethrowAllAsUnchecked(t);
|
||||
}
|
||||
}
|
||||
|
||||
public <E, I> void removeData(@NotNull Key<E> key,
|
||||
@NotNull Collection<I> toRemove,
|
||||
@NotNull final Collection<DataNode<E>> toIgnore,
|
||||
@NotNull final ProjectData projectData,
|
||||
@NotNull Project project,
|
||||
boolean synchronous) {
|
||||
removeData(key, toRemove, toIgnore, projectData, project, new IdeModifiableModelsProviderImpl(project), synchronous);
|
||||
}
|
||||
|
||||
public void updateExternalProjectData(@NotNull Project project, @NotNull ExternalProjectInfo externalProjectInfo) {
|
||||
if (!project.isDisposed()) {
|
||||
ExternalProjectsManagerImpl.getInstance(project).updateExternalProjectData(externalProjectInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ExternalProjectInfo getExternalProjectData(@NotNull Project project,
|
||||
@NotNull ProjectSystemId projectSystemId,
|
||||
@NotNull String externalProjectPath) {
|
||||
return !project.isDisposed() ? ExternalProjectsDataStorage.getInstance(project).get(projectSystemId, externalProjectPath) : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<ExternalProjectInfo> getExternalProjectsData(@NotNull Project project, @NotNull ProjectSystemId projectSystemId) {
|
||||
if (!project.isDisposed()) {
|
||||
return ExternalProjectsDataStorage.getInstance(project).list(projectSystemId);
|
||||
}
|
||||
else {
|
||||
return ContainerUtil.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureTheDataIsReadyToUse(@NotNull Collection<DataNode<?>> nodes) {
|
||||
for (DataNode<?> node : nodes) {
|
||||
ensureTheDataIsReadyToUse(node);
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareDataToUse(@NotNull DataNode dataNode) {
|
||||
final Map<Key<?>, List<ProjectDataService<?, ?>>> servicesByKey = myServices.getValue();
|
||||
List<ProjectDataService<?, ?>> services = servicesByKey.get(dataNode.getKey());
|
||||
if (services != null) {
|
||||
try {
|
||||
dataNode.prepareData(map2Array(services, ClassLoader.class, service -> service.getClass().getClassLoader()));
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.debug(e);
|
||||
dataNode.clear(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void commit(@NotNull final IdeModifiableModelsProvider modelsProvider,
|
||||
@NotNull Project project,
|
||||
boolean synchronous,
|
||||
@NotNull final String commitDesc) {
|
||||
ExternalSystemApiUtil.executeProjectChangeAction(synchronous, new DisposeAwareProjectChange(project) {
|
||||
@Override
|
||||
public void execute() {
|
||||
final long startTime = System.currentTimeMillis();
|
||||
modelsProvider.commit();
|
||||
final long timeInMs = System.currentTimeMillis() - startTime;
|
||||
LOG.debug(String.format("%s committed in %d ms", commitDesc, timeInMs));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void dispose(@NotNull final IdeModifiableModelsProvider modelsProvider,
|
||||
@NotNull Project project,
|
||||
boolean synchronous) {
|
||||
ExternalSystemApiUtil.executeProjectChangeAction(synchronous, new DisposeAwareProjectChange(project) {
|
||||
@Override
|
||||
public void execute() {
|
||||
modelsProvider.dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+10
-5
@@ -13,11 +13,7 @@ import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.internal.InternalExternalProjectInfo;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
|
||||
import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback;
|
||||
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider;
|
||||
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProviderImpl;
|
||||
import com.intellij.openapi.externalSystem.service.project.IdeUIModifiableModelsProvider;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.*;
|
||||
import com.intellij.openapi.externalSystem.service.settings.AbstractImportFromExternalSystemControl;
|
||||
import com.intellij.openapi.externalSystem.service.ui.ExternalProjectDataSelectorDialog;
|
||||
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
|
||||
@@ -71,6 +67,15 @@ public abstract class AbstractExternalProjectImportBuilder<C extends AbstractImp
|
||||
|
||||
private DataNode<ProjectData> myExternalProjectNode;
|
||||
|
||||
/**
|
||||
* @deprecated use {@link AbstractExternalProjectImportBuilder#AbstractExternalProjectImportBuilder(ProjectDataManager, AbstractImportFromExternalSystemControl, ProjectSystemId)}
|
||||
*/
|
||||
public AbstractExternalProjectImportBuilder(@NotNull com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager projectDataManager,
|
||||
@NotNull C control,
|
||||
@NotNull ProjectSystemId externalSystemId) {
|
||||
this((ProjectDataManager)projectDataManager, control, externalSystemId);
|
||||
}
|
||||
|
||||
public AbstractExternalProjectImportBuilder(@NotNull ProjectDataManager projectDataManager,
|
||||
@NotNull C control,
|
||||
@NotNull ProjectSystemId externalSystemId)
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@
|
||||
package com.intellij.openapi.externalSystem.service.task.ui;
|
||||
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
|
||||
import com.intellij.openapi.externalSystem.view.ExternalProjectsViewImpl;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
@@ -45,7 +45,7 @@ public abstract class AbstractExternalSystemToolWindowFactory implements ToolWin
|
||||
toolWindow.setTitle(myExternalSystemId.getReadableName());
|
||||
ContentManager contentManager = toolWindow.getContentManager();
|
||||
final ExternalProjectsViewImpl projectsView = new ExternalProjectsViewImpl(project, (ToolWindowEx)toolWindow, myExternalSystemId);
|
||||
ExternalProjectsManager.getInstance(project).registerView(projectsView);
|
||||
ExternalProjectsManagerImpl.getInstance(project).registerView(projectsView);
|
||||
ContentImpl tasksContent = new ContentImpl(projectsView, ExternalSystemBundle.message("tool.window.title.projects"), true);
|
||||
contentManager.addContent(tasksContent);
|
||||
}
|
||||
|
||||
+3
-3
@@ -27,9 +27,10 @@ import com.intellij.openapi.externalSystem.model.ExternalProjectInfo;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectKeys;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl.ExternalProjectsStateProvider;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator.Phase;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.TaskActivationState;
|
||||
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
|
||||
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
|
||||
@@ -67,8 +68,7 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager.ExternalProjectsStateProvider;
|
||||
import static com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager.getInstance;
|
||||
import static com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl.getInstance;
|
||||
import static com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator.TaskActivationEntry;
|
||||
|
||||
/**
|
||||
|
||||
+3
-2
@@ -31,7 +31,8 @@ import com.intellij.openapi.externalSystem.model.project.Identifiable;
|
||||
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.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManagerImpl;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil;
|
||||
@@ -123,7 +124,7 @@ public class ExternalProjectDataSelectorDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
private void init(@NotNull ExternalProjectInfo projectInfo) {
|
||||
ProjectDataManager.getInstance().ensureTheDataIsReadyToUse(projectInfo.getExternalProjectStructure());
|
||||
ProjectDataManagerImpl.getInstance().ensureTheDataIsReadyToUse(projectInfo.getExternalProjectStructure());
|
||||
myProjectInfo = projectInfo;
|
||||
myExternalSystemUiAware = ExternalSystemUiUtil.getUiAware(myProjectInfo.getProjectSystemId());
|
||||
myTree = createTree();
|
||||
|
||||
+10
-16
@@ -37,28 +37,22 @@ public class ExternalToolWindowManager {
|
||||
settings.subscribe(new ExternalSystemSettingsListenerAdapter() {
|
||||
@Override
|
||||
public void onProjectsLinked(@NotNull Collection linked) {
|
||||
if (settings.getLinkedProjectsSettings().size() != 1) {
|
||||
return;
|
||||
}
|
||||
ToolWindow toolWindow = getToolWindow(project, manager.getSystemId());
|
||||
if (toolWindow != null) {
|
||||
toolWindow.setAvailable(true, null);
|
||||
}
|
||||
else {
|
||||
StartupManager.getInstance(project).runWhenProjectIsInitialized(new DumbAwareRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (project.isDisposed()) return;
|
||||
StartupManager.getInstance(project).runWhenProjectIsInitialized((DumbAwareRunnable)() -> {
|
||||
if (project.isDisposed()) return;
|
||||
|
||||
ExternalSystemUtil.ensureToolWindowInitialized(project, manager.getSystemId());
|
||||
ToolWindowManager.getInstance(project).invokeLater(() -> {
|
||||
if (project.isDisposed()) return;
|
||||
ToolWindow toolWindow1 = getToolWindow(project, manager.getSystemId());
|
||||
if (toolWindow1 != null) {
|
||||
toolWindow1.setAvailable(true, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
ExternalSystemUtil.ensureToolWindowInitialized(project, manager.getSystemId());
|
||||
ToolWindowManager.getInstance(project).invokeLater(() -> {
|
||||
if (project.isDisposed()) return;
|
||||
ToolWindow toolWindow1 = getToolWindow(project, manager.getSystemId());
|
||||
if (toolWindow1 != null) {
|
||||
toolWindow1.setAvailable(true, null);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+3
-4
@@ -19,8 +19,8 @@ import com.intellij.openapi.externalSystem.model.DataNode;
|
||||
import com.intellij.openapi.externalSystem.model.ExternalProjectInfo;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl;
|
||||
import com.intellij.openapi.externalSystem.view.ExternalProjectsStructure;
|
||||
import com.intellij.openapi.externalSystem.view.ExternalProjectsView;
|
||||
import com.intellij.openapi.externalSystem.view.ExternalProjectsViewAdapter;
|
||||
@@ -32,7 +32,6 @@ import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.treeStructure.SimpleNode;
|
||||
import com.intellij.ui.treeStructure.SimpleNodeVisitor;
|
||||
import com.intellij.ui.treeStructure.SimpleTree;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
@@ -81,7 +80,7 @@ public class SelectExternalSystemNodeDialog extends DialogWrapper {
|
||||
myTree = new SimpleTree();
|
||||
myTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
|
||||
|
||||
final ExternalProjectsView projectsView = ExternalProjectsManager.getInstance(project).getExternalProjectsView(systemId);
|
||||
final ExternalProjectsView projectsView = ExternalProjectsManagerImpl.getInstance(project).getExternalProjectsView(systemId);
|
||||
if(projectsView != null) {
|
||||
final ExternalProjectsStructure treeStructure = new ExternalProjectsStructure(project, myTree) {
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
+6
-5
@@ -52,10 +52,11 @@ import com.intellij.openapi.externalSystem.service.internal.ExternalSystemResolv
|
||||
import com.intellij.openapi.externalSystem.service.notification.ExternalSystemNotificationManager;
|
||||
import com.intellij.openapi.externalSystem.service.notification.NotificationSource;
|
||||
import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ContentRootDataService;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManagerImpl;
|
||||
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
|
||||
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
|
||||
import com.intellij.openapi.externalSystem.task.TaskCallback;
|
||||
@@ -405,7 +406,7 @@ public class ExternalSystemUtil {
|
||||
.clearNotifications(null, NotificationSource.PROJECT_SYNC, externalSystemId);
|
||||
}
|
||||
|
||||
final ExternalSystemTaskActivator externalSystemTaskActivator = ExternalProjectsManager.getInstance(project).getTaskActivator();
|
||||
final ExternalSystemTaskActivator externalSystemTaskActivator = ExternalProjectsManagerImpl.getInstance(project).getTaskActivator();
|
||||
if (!isPreviewMode && !externalSystemTaskActivator.runTasks(externalProjectPath, ExternalSystemTaskActivator.Phase.BEFORE_SYNC)) {
|
||||
return;
|
||||
}
|
||||
@@ -785,7 +786,7 @@ public class ExternalSystemUtil {
|
||||
}
|
||||
|
||||
public static void scheduleExternalViewStructureUpdate(@NotNull final Project project, @NotNull final ProjectSystemId systemId) {
|
||||
ExternalProjectsView externalProjectsView = ExternalProjectsManager.getInstance(project).getExternalProjectsView(systemId);
|
||||
ExternalProjectsView externalProjectsView = ExternalProjectsManagerImpl.getInstance(project).getExternalProjectsView(systemId);
|
||||
if (externalProjectsView instanceof ExternalProjectsViewImpl) {
|
||||
((ExternalProjectsViewImpl)externalProjectsView).scheduleStructureUpdate();
|
||||
}
|
||||
@@ -799,7 +800,7 @@ public class ExternalSystemUtil {
|
||||
ExternalSystemApiUtil.getSettings(project, projectSystemId).getLinkedProjectSettings(externalProjectPath);
|
||||
if (linkedProjectSettings == null) return null;
|
||||
|
||||
return ProjectDataManager.getInstance().getExternalProjectData(
|
||||
return ProjectDataManagerImpl.getInstance().getExternalProjectData(
|
||||
project, projectSystemId, linkedProjectSettings.getExternalProjectPath());
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -31,10 +31,10 @@ import com.intellij.openapi.externalSystem.model.execution.ExternalTaskExecution
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.model.task.TaskData;
|
||||
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemTaskLocation;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemShortcutsManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsListenerAdapter;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil;
|
||||
@@ -77,7 +77,7 @@ public class ExternalProjectsViewImpl extends SimpleToolWindowPanel implements D
|
||||
@NotNull
|
||||
private final Project myProject;
|
||||
@NotNull
|
||||
private final ExternalProjectsManager myProjectsManager;
|
||||
private final ExternalProjectsManagerImpl myProjectsManager;
|
||||
@NotNull
|
||||
private final ToolWindowEx myToolWindow;
|
||||
@NotNull
|
||||
@@ -101,7 +101,7 @@ public class ExternalProjectsViewImpl extends SimpleToolWindowPanel implements D
|
||||
myToolWindow = toolWindow;
|
||||
myExternalSystemId = externalSystemId;
|
||||
myUiAware = ExternalSystemUiUtil.getUiAware(externalSystemId);
|
||||
myProjectsManager = ExternalProjectsManager.getInstance(myProject);
|
||||
myProjectsManager = ExternalProjectsManagerImpl.getInstance(myProject);
|
||||
|
||||
String toolWindowId =
|
||||
toolWindow instanceof ToolWindowImpl ? ((ToolWindowImpl)toolWindow).getId() : myExternalSystemId.getReadableName();
|
||||
@@ -527,7 +527,7 @@ public class ExternalProjectsViewImpl extends SimpleToolWindowPanel implements D
|
||||
}
|
||||
|
||||
private <T extends ExternalSystemNode> List<T> getSelectedNodes(Class<T> aClass) {
|
||||
return myStructure != null ? myStructure.getSelectedNodes(myTree, aClass) : ContainerUtil.<T>emptyList();
|
||||
return myStructure != null ? myStructure.getSelectedNodes(myTree, aClass) : ContainerUtil.emptyList();
|
||||
}
|
||||
|
||||
private List<ProjectNode> getSelectedProjectNodes() {
|
||||
|
||||
+3
-4
@@ -14,19 +14,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.externalSystem.test
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.extensions.ExtensionPoint
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.externalSystem.ExternalSystemManager
|
||||
import com.intellij.openapi.externalSystem.model.DataNode
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager
|
||||
import com.intellij.openapi.externalSystem.util.DisposeAwareProjectChange
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ex.ProjectRootManagerEx
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.testFramework.PlatformTestCase
|
||||
import com.intellij.testFramework.SkipInHeadlessEnvironment
|
||||
import com.intellij.testFramework.UsefulTestCase
|
||||
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture
|
||||
@@ -37,6 +35,7 @@ import org.jetbrains.annotations.Nullable
|
||||
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Modifier
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 8/7/13 2:04 PM
|
||||
|
||||
+7
-26
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package com.intellij.openapi.externalSystem.test;
|
||||
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.ex.CompilerPathsEx;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder;
|
||||
@@ -26,7 +24,8 @@ import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
|
||||
import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManagerImpl;
|
||||
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
|
||||
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
@@ -45,14 +44,12 @@ import com.intellij.openapi.util.Couple;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.packaging.artifacts.Artifact;
|
||||
import com.intellij.packaging.artifacts.ArtifactManager;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.util.BooleanFunction;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -162,7 +159,7 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest
|
||||
List<String> actual = new ArrayList<>();
|
||||
for (ContentEntry contentRoot : contentRoots) {
|
||||
for (SourceFolder f : contentRoot.getSourceFolders(rootType)) {
|
||||
rootUrl = rootUrl == null ? VirtualFileManager.extractPath(contentRoot.getUrl()) : VirtualFileManager.extractPath(rootUrl);
|
||||
rootUrl = VirtualFileManager.extractPath(rootUrl == null ? contentRoot.getUrl() : rootUrl);
|
||||
String folderUrl = VirtualFileManager.extractPath(f.getUrl());
|
||||
if (folderUrl.startsWith(rootUrl)) {
|
||||
int length = rootUrl.length() + 1;
|
||||
@@ -215,7 +212,7 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest
|
||||
}
|
||||
|
||||
private static String getAbsolutePath(String path) {
|
||||
path = VfsUtil.urlToPath(path);
|
||||
path = VfsUtilCore.urlToPath(path);
|
||||
path = PathUtil.getCanonicalPath(path);
|
||||
return FileUtil.toSystemIndependentName(path);
|
||||
}
|
||||
@@ -364,28 +361,12 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest
|
||||
|
||||
protected void assertArtifacts(String... expectedNames) {
|
||||
final List<String> actualNames = ContainerUtil.map(
|
||||
ArtifactManager.getInstance(myProject).getAllArtifactsIncludingInvalid(), new Function<Artifact, String>() {
|
||||
@Override
|
||||
public String fun(Artifact artifact) {
|
||||
return artifact.getName();
|
||||
}
|
||||
});
|
||||
ArtifactManager.getInstance(myProject).getAllArtifactsIncludingInvalid(),
|
||||
(Function<Artifact, String>)artifact -> artifact.getName());
|
||||
|
||||
assertUnorderedElementsAreEqual(actualNames, expectedNames);
|
||||
}
|
||||
|
||||
protected Module getModule(final String name) {
|
||||
AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
|
||||
try {
|
||||
Module m = ModuleManager.getInstance(myProject).findModuleByName(name);
|
||||
assertNotNull("Module " + name + " not found", m);
|
||||
return m;
|
||||
}
|
||||
finally {
|
||||
accessToken.finish();
|
||||
}
|
||||
}
|
||||
|
||||
private ContentEntry getContentRoot(String moduleName) {
|
||||
ContentEntry[] ee = getContentRoots(moduleName);
|
||||
List<String> roots = new ArrayList<>();
|
||||
@@ -415,7 +396,7 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest
|
||||
}
|
||||
|
||||
protected void ignoreData(BooleanFunction<DataNode<?>> booleanFunction, final boolean ignored) {
|
||||
final ExternalProjectInfo externalProjectInfo = ProjectDataManager.getInstance().getExternalProjectData(
|
||||
final ExternalProjectInfo externalProjectInfo = ProjectDataManagerImpl.getInstance().getExternalProjectData(
|
||||
myProject, getExternalSystemId(), getCurrentExternalProjectSettings().getExternalProjectPath());
|
||||
assertNotNull(externalProjectInfo);
|
||||
|
||||
|
||||
+5
-1
@@ -462,9 +462,13 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase {
|
||||
}
|
||||
|
||||
protected Module getModule(final String name) {
|
||||
return getModule(myProject, name);
|
||||
}
|
||||
|
||||
protected Module getModule(Project project, String name) {
|
||||
AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
|
||||
try {
|
||||
Module m = ModuleManager.getInstance(myProject).findModuleByName(name);
|
||||
Module m = ModuleManager.getInstance(project).findModuleByName(name);
|
||||
assertNotNull("Module " + name + " not found", m);
|
||||
return m;
|
||||
}
|
||||
|
||||
@@ -152,6 +152,13 @@ public class ChooseByNamePopup extends ChooseByNameBase implements ChooseByNameP
|
||||
|
||||
preferredScrollPaneSize.width = Math.max(myTextFieldPanel.getWidth(), preferredScrollPaneSize.width);
|
||||
|
||||
// in 'focus follows mouse' mode, to avoid focus escaping to editor, don't reduce popup size when list size is reduced
|
||||
if (myDropdownPopup != null && !isCloseByFocusLost()) {
|
||||
Dimension currentSize = myDropdownPopup.getSize();
|
||||
if (preferredScrollPaneSize.width < currentSize.width) preferredScrollPaneSize.width = currentSize.width;
|
||||
if (preferredScrollPaneSize.height < currentSize.height) preferredScrollPaneSize.height = currentSize.height;
|
||||
}
|
||||
|
||||
Rectangle preferredBounds = new Rectangle(bounds.x, bounds.y, preferredScrollPaneSize.width, preferredScrollPaneSize.height);
|
||||
Rectangle original = new Rectangle(preferredBounds);
|
||||
|
||||
@@ -190,13 +197,7 @@ public class ChooseByNamePopup extends ChooseByNameBase implements ChooseByNameP
|
||||
}
|
||||
else {
|
||||
myDropdownPopup.setLocation(preferredBounds.getLocation());
|
||||
|
||||
// in 'focus follows mouse' mode, to avoid focus escaping to editor, don't reduce popup size when list size is reduced
|
||||
final Dimension currentSize = myDropdownPopup.getSize();
|
||||
if (UISettings.getInstance().getHideNavigationOnFocusLoss() ||
|
||||
preferredBounds.width > currentSize.width || preferredBounds.height > currentSize.height) {
|
||||
myDropdownPopup.setSize(preferredBounds.getSize());
|
||||
}
|
||||
myDropdownPopup.setSize(preferredBounds.getSize());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.intellij.ui.FontComboBox;
|
||||
import com.intellij.ui.ListCellRendererWrapper;
|
||||
import com.intellij.ui.components.JBCheckBox;
|
||||
import com.intellij.util.ui.GraphicsUtil;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -198,9 +199,11 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
|
||||
settings.setAllowMergeButtons(myComponent.myAllowMergeButtons.isSelected());
|
||||
update |= settings.getCycleScrolling() != myComponent.myCycleScrollingCheckBox.isSelected();
|
||||
settings.setCycleScrolling(myComponent.myCycleScrollingCheckBox.isSelected());
|
||||
boolean shouldResetLafFonts = false;
|
||||
if (settings.getOverrideLafFonts() != myComponent.myOverrideLAFFonts.isSelected()) {
|
||||
shouldUpdateUI = true;
|
||||
update = true;
|
||||
shouldResetLafFonts = !myComponent.myOverrideLAFFonts.isSelected();
|
||||
}
|
||||
settings.setOverrideLafFonts(myComponent.myOverrideLAFFonts.isSelected());
|
||||
settings.setMoveMouseOnDefaultButton(myComponent.myMoveMouseOnDefaultButtonCheckBox.isSelected());
|
||||
@@ -253,6 +256,14 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
|
||||
|
||||
if (shouldUpdateUI) {
|
||||
lafManager.updateUI();
|
||||
if (shouldResetLafFonts) {
|
||||
int defSize = JBUI.Fonts.label().getSize();
|
||||
settings.setFontSize(defSize);
|
||||
myComponent.myFontSizeCombo.getModel().setSelectedItem(String.valueOf(defSize));
|
||||
String defName = JBUI.Fonts.label().getFontName();
|
||||
settings.setFontFace(defName);
|
||||
myComponent.myFontCombo.setFontName(defName);
|
||||
}
|
||||
}
|
||||
|
||||
if (WindowManagerEx.getInstanceEx().isAlphaModeSupported()) {
|
||||
|
||||
@@ -1314,7 +1314,7 @@ public class AbstractPopup implements JBPopup {
|
||||
}
|
||||
}
|
||||
|
||||
size = computeWindowSize(size);
|
||||
size.height += getAdComponentHeight();
|
||||
|
||||
final Window window = getContentWindow(myContent);
|
||||
if (window != null) {
|
||||
@@ -1590,27 +1590,27 @@ public class AbstractPopup implements JBPopup {
|
||||
}
|
||||
else {
|
||||
if (adjustByContent) {
|
||||
toSet = computeWindowSize(toSet);
|
||||
toSet.height += getAdComponentHeight();
|
||||
}
|
||||
updateMaskAndAlpha(setSize(myContent, toSet));
|
||||
}
|
||||
}
|
||||
|
||||
private Dimension computeWindowSize(Dimension size) {
|
||||
if (myAdComponent != null && myAdComponent.isShowing()) {
|
||||
size.height += myAdComponent.getPreferredSize().height + 1;
|
||||
}
|
||||
return size;
|
||||
private int getAdComponentHeight() {
|
||||
return myAdComponent != null && myAdComponent.isShowing() ? myAdComponent.getPreferredSize().height + 1 : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getSize() {
|
||||
if (myPopup != null) {
|
||||
final Window popupWindow = getContentWindow(myContent);
|
||||
return (popupWindow == null) ? myForcedSize : popupWindow.getSize();
|
||||
} else {
|
||||
return myForcedSize;
|
||||
if (popupWindow != null) {
|
||||
Dimension size = popupWindow.getSize();
|
||||
size.height -= getAdComponentHeight();
|
||||
return size;
|
||||
}
|
||||
}
|
||||
return myForcedSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,8 +19,11 @@
|
||||
<externalSystemNotificationExtension implementation="com.intellij.openapi.externalSystem.service.notification.ExternalSystemNotificationExtensionImpl" />
|
||||
|
||||
<!--Project structure management services-->
|
||||
<applicationService serviceImplementation="com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager"/>
|
||||
<projectService serviceImplementation="com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager" order="first"/>
|
||||
<applicationService serviceInterface="com.intellij.openapi.externalSystem.service.project.ProjectDataManager"
|
||||
serviceImplementation="com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManagerImpl"/>
|
||||
<projectService serviceInterface="com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager"
|
||||
serviceImplementation="com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl"
|
||||
order="first"/>
|
||||
<projectService serviceImplementation="com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsDataStorage"/>
|
||||
<externalProjectDataService implementation="com.intellij.openapi.externalSystem.service.project.manage.ProjectDataServiceImpl"/>
|
||||
<externalProjectDataService implementation="com.intellij.openapi.externalSystem.service.project.manage.LibraryDataService"/>
|
||||
|
||||
@@ -291,7 +291,7 @@ public class GeneralCommandLineTest {
|
||||
if (argument.trim().isEmpty()) continue; // would report "ECHO is on"
|
||||
GeneralCommandLine commandLine = createCommandLine(ExecUtil.getWindowsShellName(), "/D", "/C", "echo", argument);
|
||||
String output = execAndGetOutput(commandLine);
|
||||
assertEquals(commandLine.getPreparedCommandLine(), argument + "\n", output);
|
||||
assertEquals(commandLine.getPreparedCommandLine(), filterExpectedOutput(argument) + "\n", output);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,7 +305,7 @@ public class GeneralCommandLineTest {
|
||||
for (String argument : ARGUMENTS) {
|
||||
GeneralCommandLine commandLine = createCommandLine(cygwinPrintf.getPath(), "[%s]\\\\n", argument);
|
||||
String output = execAndGetOutput(commandLine);
|
||||
assertEquals(commandLine.getPreparedCommandLine(), filterExpectedOutput("[" + argument + "]\n"), output);
|
||||
assertEquals(commandLine.getPreparedCommandLine(), filterExpectedOutput("[" + argument + "]") + "\n", output);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ public class PtyCommandLineTest extends GeneralCommandLineTest {
|
||||
@NotNull
|
||||
@Override
|
||||
protected String filterExpectedOutput(@NotNull String output) {
|
||||
if (SystemInfo.isWindows) output = expandTabs(output, 8);
|
||||
if (SystemInfo.isWindows) output = StringUtil.trimTrailing(expandTabs(output, 8));
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -1560,6 +1560,20 @@ public class ContainerUtil extends ContainerUtilRt {
|
||||
return result.isEmpty() ? ContainerUtil.<T>emptyList() : result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Contract(pure=true)
|
||||
public static <E extends Enum<E>> EnumSet<E> intersection(@NotNull EnumSet<E> collection1, @NotNull EnumSet<E> collection2) {
|
||||
if (collection1.isEmpty()) return collection1;
|
||||
if (collection2.isEmpty()) return collection2;
|
||||
|
||||
EnumSet<E> smallerCollection = collection1.size() < collection2.size() ? collection1 : collection2;
|
||||
EnumSet<E> biggerCollection = collection1.size() < collection2.size() ? collection2 : collection1;
|
||||
|
||||
EnumSet<E> result = EnumSet.copyOf(smallerCollection);
|
||||
result.removeAll(EnumSet.complementOf(biggerCollection));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Contract(pure=true)
|
||||
public static <T> T getFirstItem(@Nullable Collection<T> items) {
|
||||
|
||||
@@ -152,6 +152,8 @@ public class JBUI {
|
||||
|
||||
static {
|
||||
setUserScaleFactor(UIUtil.isJreHiDPIEnabled() ? 1f : SYSTEM_SCALE_FACTOR);
|
||||
LOG.info("System scale factor: " + SYSTEM_SCALE_FACTOR + " (" +
|
||||
(UIUtil.isJreHiDPIEnabled() ? "JRE-managed" : "IDE-managed") + " HiDPI)");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -315,7 +317,7 @@ public class JBUI {
|
||||
|
||||
private static void setUserScaleFactorProperty(float scale) {
|
||||
PCS.firePropertyChange(USER_SCALE_FACTOR_PROPERTY, userScaleFactor, userScaleFactor = scale);
|
||||
LOG.info("UI scale factor: " + userScaleFactor);
|
||||
LOG.info("User scale factor: " + userScaleFactor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.vcs.log;
|
||||
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Enables showing diff between revisions and comparing file or directory state between a revision and a local version in log-based file history.
|
||||
* Methods of this class could be called from EDT, so it should deal with it appropriately by starting a background task for long operations,
|
||||
* eg for loading revisions content.
|
||||
*/
|
||||
public interface VcsLogDiffHandler {
|
||||
|
||||
/**
|
||||
* Show diff between (the after-state of) two revisions in the specified files or directories.
|
||||
*
|
||||
* @param root repository root.
|
||||
* @param leftPath path to the file on the left, null means file is missing in this revision.
|
||||
* @param leftHash hash of the revision on the left.
|
||||
* @param rightPath path to the file on the right, null means file is missing in this revision.
|
||||
* @param rightHash hash of the revision on the right.
|
||||
*/
|
||||
void showDiff(@NotNull VirtualFile root,
|
||||
@Nullable FilePath leftPath, @NotNull Hash leftHash,
|
||||
@Nullable FilePath rightPath, @NotNull Hash rightHash);
|
||||
|
||||
/**
|
||||
* Show diff between (the after-state of) specified revision and local version for the specified file or directory.
|
||||
*
|
||||
* @param root repository root.
|
||||
* @param revisionPath path to the file in the specified revision, null means file is not present in the revision.
|
||||
* @param hash hash of the revision.
|
||||
* @param localPath local path to the file.
|
||||
*/
|
||||
void showDiffWithLocal(@NotNull VirtualFile root,
|
||||
@Nullable FilePath revisionPath,
|
||||
@NotNull Hash hash, @NotNull FilePath localPath);
|
||||
}
|
||||
@@ -147,6 +147,14 @@ public interface VcsLogProvider {
|
||||
@Nullable
|
||||
String getCurrentBranch(@NotNull VirtualFile root);
|
||||
|
||||
/**
|
||||
* Returns {@link VcsLogDiffHandler} for this provider in order to support comparing commits and with local version from log-based file history.
|
||||
*
|
||||
* @return diff handler or null if unsupported.
|
||||
*/
|
||||
@Nullable
|
||||
VcsLogDiffHandler getDiffHandler();
|
||||
|
||||
interface Requirements {
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsDataKeys;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.history.VcsFileRevision;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -35,6 +36,7 @@ import com.intellij.vcs.log.ui.frame.DetailsPanel;
|
||||
import com.intellij.vcs.log.ui.table.VcsLogGraphTable;
|
||||
import com.intellij.vcs.log.util.VcsLogUiUtil;
|
||||
import com.intellij.vcs.log.visible.VisiblePack;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -51,6 +53,7 @@ public class FileHistoryPanel extends JPanel implements DataProvider, Disposable
|
||||
@NotNull private final JBSplitter myDetailsSplitter;
|
||||
@NotNull private final FilePath myFilePath;
|
||||
@NotNull private final FileHistoryUi myUi;
|
||||
@NotNull private final VirtualFile myRoot;
|
||||
|
||||
public FileHistoryPanel(@NotNull FileHistoryUi ui,
|
||||
@NotNull VcsLogData logData,
|
||||
@@ -58,6 +61,7 @@ public class FileHistoryPanel extends JPanel implements DataProvider, Disposable
|
||||
@NotNull FilePath filePath) {
|
||||
myUi = ui;
|
||||
myFilePath = filePath;
|
||||
myRoot = notNull(VcsUtil.getVcsRootFor(logData.getProject(), myFilePath));
|
||||
myGraphTable = new VcsLogGraphTable(myUi, logData, visiblePack) {
|
||||
@Override
|
||||
protected boolean isSpeedSearchEnabled() {
|
||||
@@ -150,6 +154,9 @@ public class FileHistoryPanel extends JPanel implements DataProvider, Disposable
|
||||
else if (VcsDataKeys.VCS_NON_LOCAL_HISTORY_SESSION.is(dataId)) {
|
||||
return false;
|
||||
}
|
||||
else if (VcsLogInternalDataKeys.LOG_DIFF_HANDLER.is(dataId)) {
|
||||
return myUi.getLogData().getLogProvider(myRoot).getDiffHandler();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +130,21 @@ public class FileHistoryUi extends AbstractVcsLogUi {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FilePath getPath(@NotNull VcsFullCommitDetails details) {
|
||||
if (myPath.isDirectory()) return myPath;
|
||||
|
||||
List<Change> changes = collectRelevantChanges(details);
|
||||
for (Change change : changes) {
|
||||
ContentRevision revision = change.getAfterRevision();
|
||||
if (revision != null) {
|
||||
return revision.getFile();
|
||||
}
|
||||
}
|
||||
|
||||
return null;// file was deleted
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<Change> collectRelevantChanges(@NotNull VcsFullCommitDetails details) {
|
||||
Set<FilePath> fileNames = getFileNames(details);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.vcs.log.ui;
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataKey;
|
||||
import com.intellij.vcs.log.VcsLogDiffHandler;
|
||||
import com.intellij.vcs.log.history.FileHistoryUi;
|
||||
import com.intellij.vcs.log.impl.VcsLogManager;
|
||||
import com.intellij.vcs.log.impl.VcsLogUiProperties;
|
||||
@@ -24,4 +25,5 @@ public class VcsLogInternalDataKeys {
|
||||
public static final DataKey<VcsLogManager> LOG_MANAGER = DataKey.create("Vcs.Log.Manager");
|
||||
public static final DataKey<VcsLogUiProperties> LOG_UI_PROPERTIES = DataKey.create("Vcs.Log.Ui.Properties");
|
||||
public static final DataKey<FileHistoryUi> FILE_HISTORY_UI = DataKey.create("Vcs.FileHistory.Ui");
|
||||
public static final DataKey<VcsLogDiffHandler> LOG_DIFF_HANDLER = DataKey.create("Vcs.Log.Diff.Handler");
|
||||
}
|
||||
|
||||
+28
-34
@@ -18,22 +18,25 @@ package com.intellij.vcs.log.ui.actions.history;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsDataKeys;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.actions.diff.ShowDiffAction;
|
||||
import com.intellij.openapi.vcs.changes.actions.diff.ShowDiffContext;
|
||||
import com.intellij.openapi.vcs.history.DiffFromHistoryHandler;
|
||||
import com.intellij.openapi.vcs.history.StandardDiffFromHistoryHandler;
|
||||
import com.intellij.openapi.vcs.history.VcsDiffUtil;
|
||||
import com.intellij.openapi.vcs.history.VcsFileRevision;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.vcs.log.CommitId;
|
||||
import com.intellij.vcs.log.VcsFullCommitDetails;
|
||||
import com.intellij.vcs.log.data.LoadingDetails;
|
||||
import com.intellij.vcs.log.VcsLogDiffHandler;
|
||||
import com.intellij.vcs.log.history.FileHistoryUi;
|
||||
import com.intellij.vcs.log.impl.VcsLogUtil;
|
||||
import com.intellij.vcs.log.ui.VcsLogInternalDataKeys;
|
||||
@@ -43,12 +46,13 @@ import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.notNull;
|
||||
|
||||
public class CompareRevisionsFromHistoryAction extends AnAction implements DumbAware {
|
||||
private static final String COMPARE_TEXT = "Compare";
|
||||
private static final String COMPARE_DESCRIPTION = "Compare selected versions";
|
||||
private static final String DIFF_TEXT = "Show Diff";
|
||||
private static final String DIFF_DESCRIPTION = "Show diff with previous version";
|
||||
@NotNull private final DiffFromHistoryHandler myDiffHandler = new StandardDiffFromHistoryHandler();
|
||||
|
||||
public void update(@NotNull AnActionEvent e) {
|
||||
Project project = e.getProject();
|
||||
@@ -61,31 +65,20 @@ public class CompareRevisionsFromHistoryAction extends AnAction implements DumbA
|
||||
|
||||
e.getPresentation().setVisible(true);
|
||||
|
||||
List<VcsFullCommitDetails> details = ui.getVcsLog().getSelectedDetails();
|
||||
|
||||
List<CommitId> commits = ui.getVcsLog().getSelectedCommits();
|
||||
if (e.getInputEvent() instanceof KeyEvent) {
|
||||
e.getPresentation().setEnabled(true);
|
||||
}
|
||||
else {
|
||||
if (details.size() == 2) {
|
||||
VcsFullCommitDetails detail0 = details.get(0);
|
||||
VcsFullCommitDetails detail1 = details.get(1);
|
||||
if (detail0 != null && !(detail0 instanceof LoadingDetails) &&
|
||||
detail1 != null && !(detail1 instanceof LoadingDetails)) {
|
||||
VcsFileRevision newestRevision = ui.createRevision(detail0);
|
||||
VcsFileRevision olderRevision = ui.createRevision(detail1);
|
||||
e.getPresentation().setEnabled(newestRevision != null && olderRevision != null && !filePath.isDirectory());
|
||||
}
|
||||
else {
|
||||
e.getPresentation().setEnabled(!filePath.isDirectory());
|
||||
}
|
||||
if (commits.size() == 2) {
|
||||
e.getPresentation().setEnabled(e.getData(VcsLogInternalDataKeys.LOG_DIFF_HANDLER) != null);
|
||||
}
|
||||
else {
|
||||
e.getPresentation().setEnabled(details.size() == 1);
|
||||
e.getPresentation().setEnabled(commits.size() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (details.size() == 2) {
|
||||
if (commits.size() == 2) {
|
||||
e.getPresentation().setText(COMPARE_TEXT);
|
||||
e.getPresentation().setDescription(COMPARE_DESCRIPTION);
|
||||
}
|
||||
@@ -109,24 +102,25 @@ public class CompareRevisionsFromHistoryAction extends AnAction implements DumbA
|
||||
VcsLogUtil.triggerUsage(e);
|
||||
|
||||
List<CommitId> commits = ui.getVcsLog().getSelectedCommits();
|
||||
if (filePath.isDirectory()) {
|
||||
if (commits.size() != 1) return;
|
||||
}
|
||||
else {
|
||||
if (commits.size() != 1 && commits.size() != 2) return;
|
||||
}
|
||||
if (commits.size() != 1 && commits.size() != 2) return;
|
||||
|
||||
VcsLogDiffHandler handler = e.getData(VcsLogInternalDataKeys.LOG_DIFF_HANDLER);
|
||||
// this check is needed here since we may come on key event without performing proper checks
|
||||
if (commits.size() == 2 && handler == null) return;
|
||||
|
||||
List<Integer> commitIds = ContainerUtil.map(commits, c -> ui.getLogData().getCommitIndex(c.getHash(), c.getRoot()));
|
||||
ui.getLogData().getCommitDetailsGetter().loadCommitsData(commitIds, details -> {
|
||||
if (details.size() == 2) {
|
||||
VcsFileRevision newestRevision = ui.createRevision(details.get(0));
|
||||
VcsFileRevision olderRevision = ui.createRevision(details.get(1));
|
||||
if (olderRevision != null && newestRevision != null) {
|
||||
myDiffHandler.showDiffForTwo(project, filePath, olderRevision, newestRevision);
|
||||
}
|
||||
// we only need details here to get file names for each revision
|
||||
// in order to fix this FileNamesData should be refactored
|
||||
// so that it could return a single file path for each revision
|
||||
VcsFullCommitDetails newestDetail = details.get(0);
|
||||
VcsFullCommitDetails olderDetail = details.get(1);
|
||||
notNull(handler).showDiff(olderDetail.getRoot(), ui.getPath(olderDetail), olderDetail.getId(),
|
||||
ui.getPath(newestDetail), newestDetail.getId());
|
||||
}
|
||||
else if (details.size() == 1) {
|
||||
VcsFullCommitDetails detail = ObjectUtils.notNull(ContainerUtil.getFirstItem(details));
|
||||
VcsFullCommitDetails detail = notNull(ContainerUtil.getFirstItem(details));
|
||||
List<Change> changes = ui.collectRelevantChanges(detail);
|
||||
if (filePath.isDirectory()) {
|
||||
VcsDiffUtil.showChangesDialog(project, "Changes in " + detail.getId().toShortString() + " for " + filePath.getName(),
|
||||
|
||||
+6
-21
@@ -20,33 +20,21 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsDataKeys;
|
||||
import com.intellij.openapi.vcs.changes.ChangeListManager;
|
||||
import com.intellij.openapi.vcs.history.CurrentRevision;
|
||||
import com.intellij.openapi.vcs.history.StandardDiffFromHistoryHandler;
|
||||
import com.intellij.openapi.vcs.history.VcsFileRevision;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import com.intellij.vcs.log.VcsFullCommitDetails;
|
||||
import com.intellij.vcs.log.VcsLogDiffHandler;
|
||||
import com.intellij.vcs.log.history.FileHistoryUi;
|
||||
import com.intellij.vcs.log.ui.VcsLogInternalDataKeys;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.notNull;
|
||||
|
||||
public class ShowDiffWithLocalFromHistoryAction extends FileHistorySingleCommitAction {
|
||||
|
||||
@Override
|
||||
protected boolean isEnabled(@NotNull FileHistoryUi ui, @Nullable VcsFullCommitDetails detail, @NotNull AnActionEvent e) {
|
||||
FilePath filePath = e.getData(VcsDataKeys.FILE_PATH);
|
||||
if (filePath == null || filePath.isDirectory() || filePath.getVirtualFile() == null) {
|
||||
// currently not working for directories, to be fixed later
|
||||
return false;
|
||||
}
|
||||
VcsLogDiffHandler handler = e.getData(VcsLogInternalDataKeys.LOG_DIFF_HANDLER);
|
||||
|
||||
if (detail != null) {
|
||||
VcsFileRevision fileRevision = ui.createRevision(detail);
|
||||
if (fileRevision == null) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return filePath != null && filePath.getVirtualFile() != null && handler != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,11 +45,8 @@ public class ShowDiffWithLocalFromHistoryAction extends FileHistorySingleCommitA
|
||||
if (ChangeListManager.getInstance(project).isFreezedWithNotification(null)) return;
|
||||
|
||||
FilePath path = e.getRequiredData(VcsDataKeys.FILE_PATH);
|
||||
VcsFileRevision revision = ui.createRevision(detail);
|
||||
VcsLogDiffHandler handler = e.getRequiredData(VcsLogInternalDataKeys.LOG_DIFF_HANDLER);
|
||||
|
||||
if (revision != null) {
|
||||
StandardDiffFromHistoryHandler handler = new StandardDiffFromHistoryHandler();
|
||||
handler.showDiffForTwo(project, path, revision, new CurrentRevision(notNull(path.getVirtualFile()), VcsRevisionNumber.NULL));
|
||||
}
|
||||
handler.showDiffWithLocal(detail.getRoot(), ui.getPath(detail), detail.getId(), path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,6 +234,12 @@ public class TestVcsLogProvider implements VcsLogProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public VcsLogDiffHandler getDiffHandler() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class MockRefManager implements VcsLogRefManager {
|
||||
|
||||
public static final Comparator<VcsRef> FAKE_COMPARATOR = (o1, o2) -> 0;
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package git4idea.log;
|
||||
|
||||
import com.intellij.diff.DiffContentFactoryEx;
|
||||
import com.intellij.diff.DiffManager;
|
||||
import com.intellij.diff.contents.DiffContent;
|
||||
import com.intellij.diff.contents.EmptyContent;
|
||||
import com.intellij.diff.requests.DiffRequest;
|
||||
import com.intellij.diff.requests.SimpleDiffRequest;
|
||||
import com.intellij.diff.util.DiffUserDataKeysEx;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.history.VcsDiffUtil;
|
||||
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.vcs.log.Hash;
|
||||
import com.intellij.vcs.log.VcsLogDiffHandler;
|
||||
import com.intellij.vcsUtil.VcsFileUtil;
|
||||
import git4idea.GitRevisionNumber;
|
||||
import git4idea.changes.GitChangeUtils;
|
||||
import git4idea.util.GitFileUtils;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
import static com.intellij.diff.DiffRequestFactoryImpl.getTitle;
|
||||
import static com.intellij.util.ObjectUtils.chooseNotNull;
|
||||
|
||||
public class GitLogDiffHandler implements VcsLogDiffHandler {
|
||||
private static final Logger LOG = Logger.getInstance(GitLogDiffHandler.class);
|
||||
@NotNull private final Project myProject;
|
||||
@NotNull private final DiffContentFactoryEx myDiffContentFactory;
|
||||
|
||||
public GitLogDiffHandler(@NotNull Project project) {
|
||||
myProject = project;
|
||||
myDiffContentFactory = DiffContentFactoryEx.getInstanceEx();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showDiff(@NotNull VirtualFile root,
|
||||
@Nullable FilePath leftPath,
|
||||
@NotNull Hash leftHash,
|
||||
@Nullable FilePath rightPath,
|
||||
@NotNull Hash rightHash) {
|
||||
if (leftPath == null && rightPath == null) return;
|
||||
|
||||
if (chooseNotNull(leftPath, rightPath).isDirectory()) {
|
||||
showDiffForDirectory(root, chooseNotNull(leftPath, rightPath), leftHash, rightHash);
|
||||
}
|
||||
else {
|
||||
loadDiffAndShow(new ThrowableComputable<DiffRequest, VcsException>() {
|
||||
@Override
|
||||
public DiffRequest compute() throws VcsException {
|
||||
DiffContent leftDiffContent = createDiffContent(root, leftPath, leftHash);
|
||||
DiffContent rightDiffContent = createDiffContent(root, rightPath, rightHash);
|
||||
|
||||
return new SimpleDiffRequest(getTitle(leftPath, rightPath, " -> "),
|
||||
leftDiffContent, rightDiffContent,
|
||||
leftHash.asString(), rightHash.asString());
|
||||
}
|
||||
},
|
||||
request -> DiffManager.getInstance().showDiff(myProject, request),
|
||||
"Calculating Diff for " + chooseNotNull(rightPath, leftPath).getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showDiffWithLocal(@NotNull VirtualFile root, @Nullable FilePath revisionPath, @NotNull Hash revisionHash,
|
||||
@NotNull FilePath localPath) {
|
||||
if (localPath.isDirectory()) {
|
||||
showDiffForDirectory(root, localPath, revisionHash, null);
|
||||
}
|
||||
else {
|
||||
loadDiffAndShow(new ThrowableComputable<DiffRequest, VcsException>() {
|
||||
@Override
|
||||
public DiffRequest compute() throws VcsException {
|
||||
DiffContent leftDiffContent = createDiffContent(root, revisionPath, revisionHash);
|
||||
|
||||
VirtualFile file = localPath.getVirtualFile();
|
||||
LOG.assertTrue(file != null);
|
||||
DiffContent rightDiffContent = myDiffContentFactory.create(myProject, file);
|
||||
|
||||
return new SimpleDiffRequest(getTitle(revisionPath, localPath, " -> "),
|
||||
leftDiffContent, rightDiffContent,
|
||||
revisionHash.asString(), "(Local)");
|
||||
}
|
||||
},
|
||||
request -> DiffManager.getInstance().showDiff(myProject, request), "Calculating Diff for " + localPath.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private void showDiffForDirectory(@NotNull VirtualFile root,
|
||||
@NotNull FilePath directoryPath,
|
||||
@NotNull Hash leftRevision, @Nullable Hash rightRevision) {
|
||||
loadDiffAndShow(() -> GitChangeUtils.getDiff(myProject, root,
|
||||
leftRevision.asString(), rightRevision == null ? null : rightRevision.asString(),
|
||||
Collections.singleton(directoryPath)),
|
||||
(diff) -> {
|
||||
String dialogTitle = "Changes between " +
|
||||
leftRevision.asString() +
|
||||
" and " +
|
||||
(rightRevision == null ? "current revision" : rightRevision.asString()) +
|
||||
" in " +
|
||||
getTitle(directoryPath, directoryPath, " -> ");
|
||||
VcsDiffUtil.showChangesDialog(myProject, dialogTitle, ContainerUtil.newArrayList(diff));
|
||||
}, "Calculating Diff for " + directoryPath.getName());
|
||||
}
|
||||
|
||||
private <T> void loadDiffAndShow(@NotNull ThrowableComputable<T, VcsException> load,
|
||||
@NotNull Consumer<T> show,
|
||||
@NotNull @Nls(capitalization = Nls.Capitalization.Title) String title) {
|
||||
if (ApplicationManager.getApplication().isDispatchThread()) {
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(myProject, title + "...", false) {
|
||||
@Nullable private T myResult;
|
||||
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
try {
|
||||
myResult = load.compute();
|
||||
}
|
||||
catch (VcsException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
if (myResult != null) {
|
||||
show.consume(myResult);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onThrowable(@NotNull Throwable error) {
|
||||
VcsBalloonProblemNotifier.showOverVersionControlView(myProject, title + " failed\n" +
|
||||
error.getMessage(), MessageType.ERROR);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
try {
|
||||
T result = load.compute();
|
||||
ApplicationManager.getApplication().invokeLater(() -> show.consume(result));
|
||||
}
|
||||
catch (VcsException e) {
|
||||
VcsBalloonProblemNotifier.showOverVersionControlView(myProject, title + " failed\n" +
|
||||
e.getMessage(), MessageType.ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private DiffContent createDiffContent(@NotNull VirtualFile root,
|
||||
@Nullable FilePath path,
|
||||
@NotNull Hash hash) throws VcsException {
|
||||
|
||||
DiffContent diffContent;
|
||||
if (path == null) {
|
||||
diffContent = new EmptyContent();
|
||||
}
|
||||
else {
|
||||
try {
|
||||
byte[] content = GitFileUtils.getFileContent(myProject, root, hash.asString(), VcsFileUtil.relativePath(root, path));
|
||||
diffContent = myDiffContentFactory.createFromBytes(myProject, content, path);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new VcsException(e);
|
||||
}
|
||||
}
|
||||
|
||||
diffContent.putUserData(DiffUserDataKeysEx.REVISION_INFO, new Pair<>(path, new GitRevisionNumber(hash.asString())));
|
||||
|
||||
return diffContent;
|
||||
}
|
||||
}
|
||||
@@ -529,6 +529,12 @@ public class GitLogProvider implements VcsLogProvider {
|
||||
return currentBranchName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public VcsLogDiffHandler getDiffHandler() {
|
||||
return new GitLogDiffHandler(myProject);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
@Override
|
||||
|
||||
@@ -32,8 +32,8 @@ import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo;
|
||||
import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData;
|
||||
import com.intellij.openapi.externalSystem.service.project.ExternalSystemProjectResolver;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.autoimport.CachingExternalSystemAutoImportAware;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.ui.DefaultExternalSystemUiAware;
|
||||
import com.intellij.openapi.externalSystem.task.ExternalSystemTaskManager;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
@@ -53,7 +53,6 @@ import com.intellij.util.Function;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.PathsList;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import com.intellij.util.execution.ParametersListUtil;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import icons.GradleIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
+1
-1
@@ -193,7 +193,7 @@ public class GradleResourceCompilerConfigurationGenerator {
|
||||
|
||||
final ExternalProject externalRootProject = lazyExternalProjectMap.get(gradleProjectPath);
|
||||
if (externalRootProject == null) {
|
||||
context.addMessage(CompilerMessageCategory.ERROR,
|
||||
context.addMessage(CompilerMessageCategory.WARNING,
|
||||
String.format("Unable to make the module: %s, related gradle configuration was not found. " +
|
||||
"Please, re-import the Gradle project and try again.",
|
||||
module.getName()), VfsUtilCore.pathToUrl(gradleProjectPath), -1, -1);
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ import com.intellij.openapi.externalSystem.model.ExternalProjectInfo;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectKeys;
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
|
||||
+1
-1
@@ -28,8 +28,8 @@ import com.intellij.openapi.compiler.CompileTask;
|
||||
import com.intellij.openapi.compiler.CompilerManager;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.startup.StartupActivity;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.externalSystem.model.ExternalProjectInfo;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.ui.ExternalProjectPathField;
|
||||
import com.intellij.openapi.externalSystem.service.ui.SelectExternalProjectDialog;
|
||||
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
|
||||
|
||||
+8
-1
@@ -24,7 +24,7 @@ import com.intellij.openapi.externalSystem.model.internal.InternalExternalProjec
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtil;
|
||||
import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.wizard.AbstractExternalProjectImportBuilder;
|
||||
import com.intellij.openapi.externalSystem.service.ui.ExternalProjectDataSelectorDialog;
|
||||
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
|
||||
@@ -54,6 +54,13 @@ import java.util.List;
|
||||
*/
|
||||
public class GradleProjectImportBuilder extends AbstractExternalProjectImportBuilder<ImportFromGradleControl> {
|
||||
|
||||
/**
|
||||
* @deprecated use {@link GradleProjectImportBuilder#GradleProjectImportBuilder(ProjectDataManager)}
|
||||
*/
|
||||
public GradleProjectImportBuilder(@NotNull com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager dataManager) {
|
||||
this((ProjectDataManager)dataManager);
|
||||
}
|
||||
|
||||
public GradleProjectImportBuilder(@NotNull ProjectDataManager dataManager) {
|
||||
super(dataManager, new ImportFromGradleControl(), GradleConstants.SYSTEM_ID);
|
||||
}
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ import com.intellij.openapi.externalSystem.model.ExternalProjectInfo;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectKeys;
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
|
||||
+82
@@ -22,6 +22,8 @@ import com.intellij.ide.impl.ProjectUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataImportListener;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.projectRoots.ProjectJdkTable;
|
||||
@@ -31,12 +33,17 @@ import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.profile.codeInspection.InspectionProfileManager;
|
||||
import com.intellij.profile.codeInspection.ProjectInspectionProfileManager;
|
||||
import com.intellij.testFramework.PlatformTestUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.concurrency.Semaphore;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
||||
import org.junit.Test;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -94,6 +101,81 @@ public class GradleProjectOpenProcessorTest extends GradleImportingTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGradleSettingsFileModification() throws IOException {
|
||||
VirtualFile foo = createProjectSubDir("foo");
|
||||
createProjectSubFile("foo/build.gradle", "apply plugin: 'java'");
|
||||
createProjectSubFile("foo/.idea/modules.xml",
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<project version=\"4\">\n" +
|
||||
" <component name=\"ProjectModuleManager\">\n" +
|
||||
" <modules>\n" +
|
||||
" <module fileurl=\"file://$PROJECT_DIR$/foo.iml\" filepath=\"$PROJECT_DIR$/foo.iml\" />\n" +
|
||||
" <module fileurl=\"file://$PROJECT_DIR$/bar.iml\" filepath=\"$PROJECT_DIR$/bar.iml\" />\n" +
|
||||
" </modules>\n" +
|
||||
" </component>\n" +
|
||||
"</project>");
|
||||
createProjectSubFile("foo/foo.iml",
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<module type=\"JAVA_MODULE\" version=\"4\">\n" +
|
||||
" <component name=\"NewModuleRootManager\" inherit-compiler-output=\"true\">\n" +
|
||||
" <content url=\"file://$MODULE_DIR$\">\n" +
|
||||
" </content>\n" +
|
||||
" </component>\n" +
|
||||
"</module>");
|
||||
createProjectSubFile("foo/bar.iml",
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<module type=\"JAVA_MODULE\" version=\"4\">\n" +
|
||||
" <component name=\"NewModuleRootManager\" inherit-compiler-output=\"true\">\n" +
|
||||
" </component>\n" +
|
||||
"</module>");
|
||||
|
||||
Project fooProject = executeOnEdt(() -> ProjectUtil.openProject(foo.getPath(), null, true));
|
||||
|
||||
try {
|
||||
assertTrue(fooProject.isOpen());
|
||||
edt(() -> UIUtil.dispatchAllInvocationEvents());
|
||||
assertModules(fooProject, "foo", "bar");
|
||||
|
||||
Semaphore semaphore = new Semaphore(1);
|
||||
final MessageBusConnection myBusConnection = fooProject.getMessageBus().connect();
|
||||
myBusConnection.subscribe(ProjectDataImportListener.TOPIC, path -> semaphore.up());
|
||||
createProjectSubFile("foo/.idea/gradle.xml",
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<project version=\"4\">\n" +
|
||||
" <component name=\"GradleSettings\">\n" +
|
||||
" <option name=\"linkedExternalProjectsSettings\">\n" +
|
||||
" <GradleProjectSettings>\n" +
|
||||
" <option name=\"distributionType\" value=\"DEFAULT_WRAPPED\" />\n" +
|
||||
" <option name=\"externalProjectPath\" value=\"$PROJECT_DIR$\" />\n" +
|
||||
" <option name=\"gradleJvm\" value=\"" + GRADLE_JDK_NAME + "\" />\n" +
|
||||
" <option name=\"modules\">\n" +
|
||||
" <set>\n" +
|
||||
" <option value=\"$PROJECT_DIR$\" />\n" +
|
||||
" </set>\n" +
|
||||
" </option>\n" +
|
||||
" <option name=\"resolveModulePerSourceSet\" value=\"false\" />\n" +
|
||||
" </GradleProjectSettings>\n" +
|
||||
" </option>\n" +
|
||||
" </component>\n" +
|
||||
"</project>");
|
||||
edt(() -> UIUtil.dispatchAllInvocationEvents());
|
||||
edt(() -> PlatformTestUtil.saveProject(fooProject));
|
||||
assert semaphore.waitFor(100000);
|
||||
assertTrue("The module has not been linked",
|
||||
ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, getModule(fooProject, "foo")));
|
||||
}
|
||||
finally {
|
||||
edt(() -> closeProject(fooProject));
|
||||
}
|
||||
assertFalse(fooProject.isOpen());
|
||||
assertTrue(fooProject.isDisposed());
|
||||
|
||||
//edt(() -> PlatformTestUtil.saveProject(myProject));
|
||||
//importProject("apply plugin: 'java'");
|
||||
//assertModules("project", "project_main", "project_test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpenAndImportProjectInHeadlessMode() throws Exception {
|
||||
VirtualFile foo = createProjectSubDir("foo");
|
||||
|
||||
-16
@@ -61,20 +61,4 @@ public class Annotation {
|
||||
annMarker.done(GroovyElementTypes.ANNOTATION);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void parseAnnotationOptional(PsiBuilder builder, GroovyParser parser) {
|
||||
PsiBuilder.Marker annOptMarker = builder.mark();
|
||||
|
||||
boolean hasAnnotations = false;
|
||||
while (parse(builder, parser)) {
|
||||
ParserUtils.getToken(builder, GroovyTokenTypes.mNLS);
|
||||
hasAnnotations = true;
|
||||
}
|
||||
|
||||
if (hasAnnotations) {
|
||||
annOptMarker.done(GroovyElementTypes.MODIFIERS);
|
||||
} else {
|
||||
annOptMarker.rollbackTo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-1
@@ -35,7 +35,12 @@ import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils;
|
||||
*/
|
||||
|
||||
public class Modifiers {
|
||||
|
||||
public static boolean parse(PsiBuilder builder, GroovyParser parser) {
|
||||
return parse(builder, parser, false);
|
||||
}
|
||||
|
||||
public static boolean parse(PsiBuilder builder, GroovyParser parser, boolean annotationsOnly) {
|
||||
|
||||
PsiBuilder.Marker modifiersMarker = builder.mark();
|
||||
boolean hasModifiers = false;
|
||||
@@ -44,7 +49,7 @@ public class Modifiers {
|
||||
final PsiBuilder.Marker modifierListItem = builder.mark();
|
||||
|
||||
if (hasModifiers) ParserUtils.getToken(builder, GroovyTokenTypes.mNLS);
|
||||
final boolean parsed = Annotation.parse(builder, parser) || parseModifier(builder);
|
||||
final boolean parsed = Annotation.parse(builder, parser) || (!annotationsOnly && parseModifier(builder));
|
||||
|
||||
if (parsed) {
|
||||
if (PathExpression.isQualificationDot(builder)) {
|
||||
|
||||
+2
-2
@@ -21,7 +21,7 @@ import org.jetbrains.plugins.groovy.GroovyBundle;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.parser.GroovyParser;
|
||||
import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.annotations.Annotation;
|
||||
import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.modifiers.Modifiers;
|
||||
import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.arguments.ArgumentList;
|
||||
import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions.TypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils;
|
||||
@@ -35,7 +35,7 @@ public class EnumConstant {
|
||||
PsiBuilder.Marker ecMarker = builder.mark();
|
||||
ParserUtils.getToken(builder, GroovyTokenTypes.mNLS);
|
||||
|
||||
Annotation.parseAnnotationOptional(builder, parser);
|
||||
Modifiers.parse(builder, parser, true);
|
||||
|
||||
if (!ParserUtils.getToken(builder, GroovyTokenTypes.mIDENT)) {
|
||||
ecMarker.rollbackTo();
|
||||
|
||||
+6
@@ -55,6 +55,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrImplements
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAnnotationMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList;
|
||||
@@ -228,6 +229,11 @@ public class GroovyIndentProcessor extends GroovyElementVisitor {
|
||||
myResult = Indent.getContinuationWithoutFirstIndent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnumConstant(@NotNull GrEnumConstant enumConstant) {
|
||||
Indent.getNoneIndent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitDocComment(@NotNull GrDocComment comment) {
|
||||
if (myChildType != GroovyDocTokenTypes.mGDOC_COMMENT_START) {
|
||||
|
||||
+5
-1
@@ -317,7 +317,11 @@ public class GroovySpacingProcessor extends GroovyElementVisitor {
|
||||
|
||||
@Override
|
||||
public void visitEnumConstant(@NotNull GrEnumConstant enumConstant) {
|
||||
manageSpaceBeforeCallLParenth();
|
||||
if (myType1 == GroovyElementTypes.MODIFIERS) {
|
||||
createSpaceInCode(true);
|
||||
} else {
|
||||
manageSpaceBeforeCallLParenth();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -688,6 +688,36 @@ def foooo(
|
||||
''')
|
||||
}
|
||||
|
||||
void testEnumAnnotations() {
|
||||
checkFormatting('''\
|
||||
enum GroovyEnum {
|
||||
FOO,
|
||||
@Deprecated
|
||||
BAR(""),
|
||||
DAR
|
||||
}
|
||||
''', '''\
|
||||
enum GroovyEnum {
|
||||
FOO,
|
||||
@Deprecated
|
||||
BAR(""),
|
||||
DAR
|
||||
}
|
||||
''')
|
||||
}
|
||||
|
||||
void testEnumAnnotationsSingleLine() {
|
||||
checkFormatting('''\
|
||||
enum GroovyEnum {
|
||||
@Deprecated BAR("")
|
||||
}
|
||||
''', '''\
|
||||
enum GroovyEnum {
|
||||
@Deprecated BAR("")
|
||||
}
|
||||
''')
|
||||
}
|
||||
|
||||
void testAlignFor() {
|
||||
groovySettings.ALIGN_MULTILINE_FOR = true
|
||||
checkFormatting('''\
|
||||
|
||||
@@ -18,6 +18,8 @@ Groovy script
|
||||
PsiWhiteSpace('\n ')
|
||||
Enumeration constants
|
||||
Enumeration constant
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('CONST')
|
||||
PsiElement(new line)('\n ')
|
||||
Variable definitions
|
||||
|
||||
@@ -20,15 +20,21 @@ Groovy script
|
||||
PsiWhiteSpace('\n ')
|
||||
Enumeration constants
|
||||
Enumeration constant
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('Const1')
|
||||
PsiElement(new line)('\n ')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
Enumeration constant
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('Const2')
|
||||
PsiElement(,)(',')
|
||||
Enumeration constant
|
||||
PsiElement(new line)('\n ')
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('Const3')
|
||||
PsiElement(new line)('\n ')
|
||||
Variable definitions
|
||||
|
||||
@@ -17,6 +17,8 @@ Groovy script
|
||||
PsiWhiteSpace('\n ')
|
||||
Enumeration constants
|
||||
Enumeration constant
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('Const')
|
||||
PsiElement(;)(';')
|
||||
PsiWhiteSpace(' ')
|
||||
|
||||
@@ -14,5 +14,7 @@ Groovy script
|
||||
PsiElement({)('{')
|
||||
Enumeration constants
|
||||
Enumeration constant
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('CONST')
|
||||
PsiElement(})('}')
|
||||
@@ -19,6 +19,8 @@ Groovy script
|
||||
PsiWhiteSpace('\n ')
|
||||
Enumeration constants
|
||||
Enumeration constant
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('foo')
|
||||
PsiWhiteSpace(' ')
|
||||
Arguments
|
||||
|
||||
@@ -17,6 +17,8 @@ Groovy script
|
||||
PsiWhiteSpace('\n ')
|
||||
Enumeration constants
|
||||
Enumeration constant
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('foo')
|
||||
PsiElement(new line)('\n')
|
||||
PsiElement(})('}')
|
||||
@@ -18,11 +18,15 @@ Groovy script
|
||||
PsiWhiteSpace('\n ')
|
||||
Enumeration constants
|
||||
Enumeration constant
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('CONST1')
|
||||
PsiElement(new line)('\n ')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
Enumeration constant
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('CONST2')
|
||||
PsiElement(new line)('\n')
|
||||
PsiElement(})('}')
|
||||
@@ -17,6 +17,8 @@ Groovy script
|
||||
PsiWhiteSpace('\n ')
|
||||
Enumeration constants
|
||||
Enumeration constant
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('CONST1')
|
||||
PsiErrorElement:';', '}' or new line expected
|
||||
<empty list>
|
||||
|
||||
@@ -37,30 +37,44 @@ Groovy script
|
||||
PsiWhiteSpace('\n ')
|
||||
Enumeration constants
|
||||
Enumeration constant
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('SUNDAY')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
Enumeration constant
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('MONDAY')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
Enumeration constant
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('TUESDAY')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
Enumeration constant
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('WEDNESDAY')
|
||||
PsiElement(,)(',')
|
||||
Enumeration constant
|
||||
PsiElement(new line)('\n ')
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('THURSDAY')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
Enumeration constant
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('FRIDAY')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
Enumeration constant
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('SATURDAY')
|
||||
PsiElement(new line)('\n ')
|
||||
PsiElement(})('}')
|
||||
|
||||
@@ -335,6 +335,12 @@ public class HgLogProvider implements VcsLogProvider {
|
||||
return repository.getCurrentBranchName();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public VcsLogDiffHandler getDiffHandler() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T getPropertyValue(VcsLogProperties.VcsLogProperty<T> property) {
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.lang.properties.psi.impl;
|
||||
|
||||
import com.intellij.lang.properties.parsing.PropertiesTokenTypes;
|
||||
import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.impl.PsiTreeChangeEventImpl;
|
||||
import com.intellij.psi.impl.PsiTreeChangePreprocessorBase;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PropertiesPsiTreeChangePreprocessor extends PsiTreeChangePreprocessorBase {
|
||||
private static final TokenSet CODE_BLOCK_ELEMENTS = TokenSet.create(PropertiesTokenTypes.VALUE_CHARACTERS,
|
||||
PropertiesTokenTypes.END_OF_LINE_COMMENT,
|
||||
PropertiesTokenTypes.WHITE_SPACE,
|
||||
PropertiesTokenTypes.KEY_VALUE_SEPARATOR);
|
||||
|
||||
public PropertiesPsiTreeChangePreprocessor(@NotNull PsiManager psiManager) {
|
||||
super(psiManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTreeChanged(@NotNull PsiTreeChangeEventImpl event) {
|
||||
if (event.isGenericChange()) return;
|
||||
switch (event.getCode()) {
|
||||
case BEFORE_PROPERTY_CHANGE:
|
||||
case BEFORE_CHILD_REMOVAL:
|
||||
case BEFORE_CHILD_ADDITION:
|
||||
case BEFORE_CHILD_MOVEMENT:
|
||||
case BEFORE_CHILDREN_CHANGE:
|
||||
case BEFORE_CHILD_REPLACEMENT:
|
||||
return;
|
||||
case CHILD_ADDED:
|
||||
if (isCodeBlock(event.getChild())) return;
|
||||
break;
|
||||
case CHILD_REMOVED:
|
||||
if (isCodeBlock(event.getChild())) return;
|
||||
break;
|
||||
case CHILD_REPLACED:
|
||||
if (isCodeBlock(event.getOldChild()) || isCodeBlock(event.getNewChild())) return;
|
||||
break;
|
||||
case CHILD_MOVED:
|
||||
if (isCodeBlock(event.getChild())) return;
|
||||
break;
|
||||
case CHILDREN_CHANGED:
|
||||
if (isCodeBlock(event.getParent())) return;
|
||||
case PROPERTY_CHANGED:
|
||||
break;
|
||||
}
|
||||
doIncOutOfCodeBlockCounter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean acceptsEvent(@NotNull PsiTreeChangeEventImpl event) {
|
||||
return event.getFile() instanceof PropertiesFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isOutOfCodeBlock(@NotNull PsiElement element) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
private static boolean isCodeBlock(@NotNull PsiElement element) {
|
||||
return CODE_BLOCK_ELEMENTS.contains(PsiUtilCore.getElementType(element));
|
||||
}
|
||||
}
|
||||
@@ -123,6 +123,8 @@
|
||||
|
||||
<lang.inspectionSuppressor language="Properties" implementationClass="com.intellij.codeInspection.PropertiesInspectionSuppressor"/>
|
||||
<qualifiedNameProvider implementation="com.intellij.ide.actions.PropertiesQualifiedNameProvider"/>
|
||||
|
||||
<psi.treeChangePreprocessor implementation="com.intellij.lang.properties.psi.impl.PropertiesPsiTreeChangePreprocessor"/>
|
||||
</extensions>
|
||||
|
||||
<project-components>
|
||||
|
||||
+3
-39
@@ -22,6 +22,7 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.formatter.FormattingDocumentModelImpl;
|
||||
import com.intellij.psi.formatter.PsiBasedFormattingModel;
|
||||
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
|
||||
import com.intellij.psi.impl.source.tree.TreeElement;
|
||||
import com.intellij.psi.impl.source.tree.TreeUtil;
|
||||
@@ -34,10 +35,10 @@ import org.jetbrains.annotations.Nullable;
|
||||
public class PropertiesFormattingModelBuilder implements FormattingModelBuilder {
|
||||
@NotNull
|
||||
@Override
|
||||
public PropertiesFormattingModel createModel(PsiElement element, CodeStyleSettings settings) {
|
||||
public FormattingModel createModel(PsiElement element, CodeStyleSettings settings) {
|
||||
final ASTNode root = TreeUtil.getFileElement((TreeElement)SourceTreeToPsiMap.psiElementToTree(element));
|
||||
final FormattingDocumentModelImpl documentModel = FormattingDocumentModelImpl.createOn(element.getContainingFile());
|
||||
return new PropertiesFormattingModel(root, documentModel, settings);
|
||||
return new PsiBasedFormattingModel(element.getContainingFile(), new PropertiesRootBlock(root, settings), documentModel);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -45,41 +46,4 @@ public class PropertiesFormattingModelBuilder implements FormattingModelBuilder
|
||||
public TextRange getRangeAffectingIndent(PsiFile file, int offset, ASTNode elementAtOffset) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class PropertiesFormattingModel implements FormattingModel {
|
||||
private final FormattingDocumentModelImpl myDocumentModel;
|
||||
private PropertiesRootBlock myRoot;
|
||||
|
||||
public PropertiesFormattingModel(ASTNode root, FormattingDocumentModelImpl documentModel, CodeStyleSettings settings) {
|
||||
myRoot = new PropertiesRootBlock(root, settings);
|
||||
myDocumentModel = documentModel;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Block getRootBlock() {
|
||||
return myRoot;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FormattingDocumentModel getDocumentModel() {
|
||||
return myDocumentModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextRange replaceWhiteSpace(TextRange textRange, String whiteSpace) {
|
||||
return textRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextRange shiftIndentInsideRange(ASTNode node, TextRange range, int indent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commitChanges() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.lang.properties;
|
||||
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PropertiesModificationTest extends LightCodeInsightFixtureTestCase {
|
||||
|
||||
public void testValueEditing() {
|
||||
doTestEditing(" # comment<caret>", false);
|
||||
}
|
||||
|
||||
public void testKeyEditing() {
|
||||
doTestEditing("key<caret> = value", true);
|
||||
}
|
||||
|
||||
public void testCommentEditing() {
|
||||
doTestEditing("key = value<caret>", false);
|
||||
}
|
||||
|
||||
public void testKeyReplacement() {
|
||||
doTestReplacement("<selection>key</selection> = value", true);
|
||||
}
|
||||
|
||||
public void testValueReplacement() {
|
||||
doTestReplacement("key = <selection>value</selection>", false);
|
||||
}
|
||||
|
||||
public void testCommentReplacement() {
|
||||
doTestReplacement("key = value \n# <selection>comment</selection> \n key2 = value2", false);
|
||||
}
|
||||
|
||||
public void testKeyDeletion() {
|
||||
doTestDeletion("<selection>key</selection> = value", true);
|
||||
}
|
||||
|
||||
public void testPropertiesDeletion() {
|
||||
doTestDeletion("ke<selection>y1 = value1 \n" +
|
||||
"key2 = value2 \n" +
|
||||
"key3 = value3 \n" +
|
||||
"key4 = value4 \n" +
|
||||
"key5 = val</selection>ue5 \n", true);
|
||||
}
|
||||
|
||||
private void doTestEditing(@NotNull String text, boolean isOutOfBlockModificationExpected) {
|
||||
doTest(text, () -> myFixture.type("xxx"), isOutOfBlockModificationExpected);
|
||||
}
|
||||
|
||||
private void doTestReplacement(@NotNull String text, boolean isOutOfBlockModificationExpected) {
|
||||
doTest(text, () -> WriteCommandAction.runWriteCommandAction(getProject(), () -> {
|
||||
SelectionModel sel = getEditor().getSelectionModel();
|
||||
getEditor().getDocument().replaceString(sel.getSelectionStart(), sel.getSelectionEnd(), "xxx");
|
||||
}), isOutOfBlockModificationExpected);
|
||||
}
|
||||
|
||||
private void doTestDeletion(@NotNull String text, boolean isOutOfBlockModificationExpected) {
|
||||
doTest(text, () -> WriteCommandAction.runWriteCommandAction(getProject(), () -> {
|
||||
SelectionModel sel = getEditor().getSelectionModel();
|
||||
getEditor().getDocument().deleteString(sel.getSelectionStart(), sel.getSelectionEnd());
|
||||
}), isOutOfBlockModificationExpected);
|
||||
}
|
||||
|
||||
private void doTest(@NotNull String text, Runnable modificationAction, boolean isOutOfBlockModificationExpected) {
|
||||
myFixture.configureByText("test.properties", text);
|
||||
PsiModificationTracker tracker = myFixture.getPsiManager().getModificationTracker();
|
||||
long oldMod = tracker.getOutOfCodeBlockModificationCount();
|
||||
modificationAction.run();
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
|
||||
long newMod = tracker.getOutOfCodeBlockModificationCount();
|
||||
assertTrue(isOutOfBlockModificationExpected ^ oldMod == newMod);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user