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:
@@ -504,28 +504,29 @@ public class JavaCompletionUtil {
|
||||
}
|
||||
if (plainQualifier != null) {
|
||||
Object o = item.getObject();
|
||||
if (containsMember(plainQualifier, o)) {
|
||||
if (!(o instanceof PsiMethod)) {
|
||||
return item;
|
||||
}
|
||||
if (o instanceof PsiMethod) {
|
||||
PsiType castType = castTypeItem.getPsiType();
|
||||
if (plainQualifier instanceof PsiClassType && castType instanceof PsiClassType) {
|
||||
PsiMethod method = (PsiMethod)o;
|
||||
PsiClassType.ClassResolveResult plainResult = ((PsiClassType)plainQualifier).resolveGenerics();
|
||||
PsiClass plainClass = plainResult.getElement();
|
||||
PsiClass castClass = ((PsiClassType)castType).resolveGenerics().getElement();
|
||||
if (plainClass != null && plainClass.findMethodBySignature(method, true) != null) {
|
||||
PsiClass castClass = ((PsiClassType)castType).resolveGenerics().getElement();
|
||||
|
||||
if (castClass == null || plainClass == null || !castClass.isInheritor(plainClass, true)) {
|
||||
return item;
|
||||
}
|
||||
if (castClass == null || !castClass.isInheritor(plainClass, true)) {
|
||||
return item;
|
||||
}
|
||||
|
||||
PsiSubstitutor plainSub = plainResult.getSubstitutor();
|
||||
PsiSubstitutor castSub = TypeConversionUtil.getSuperClassSubstitutor(plainClass, (PsiClassType)castType);
|
||||
if (method.getSignature(plainSub).equals(method.getSignature(castSub)) &&
|
||||
plainSub.substitute(method.getReturnType()).equals(castSub.substitute(method.getReturnType()))) {
|
||||
return item;
|
||||
PsiSubstitutor plainSub = plainResult.getSubstitutor();
|
||||
PsiSubstitutor castSub = TypeConversionUtil.getSuperClassSubstitutor(plainClass, (PsiClassType)castType);
|
||||
if (method.getSignature(plainSub).equals(method.getSignature(castSub)) &&
|
||||
plainSub.substitute(method.getReturnType()).equals(castSub.substitute(method.getReturnType()))) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (containsMember(plainQualifier, o)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -123,7 +123,11 @@ public class StandardInstructionVisitor extends InstructionVisitor {
|
||||
final DfaValue qualifier = memState.pop();
|
||||
if (instruction.getExpression().isPhysical() && !memState.applyNotNull(qualifier)) {
|
||||
onInstructionProducesNPE(instruction, runner);
|
||||
return DfaInstructionState.EMPTY_ARRAY;
|
||||
|
||||
if (qualifier instanceof DfaVariableValue) {
|
||||
final DfaNotNullValue.Factory factory = runner.getFactory().getNotNullFactory();
|
||||
memState.setVarValue((DfaVariableValue)qualifier, factory.create(((DfaVariableValue)qualifier).getPsiVariable().getType()));
|
||||
}
|
||||
}
|
||||
|
||||
return nextInstruction(instruction, runner, memState);
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
public class Util2 {
|
||||
void foo(XmlAttribute o ) {
|
||||
if (o instanceof XmlAttributeImpl) {
|
||||
o.getpar<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface PsiElement {
|
||||
PsiElement getParent();
|
||||
}
|
||||
interface XmlAttribute extends PsiElement {}
|
||||
class XmlAttributeImpl implements XmlAttribute {
|
||||
@Override
|
||||
public PsiElement getParent() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
public class Util2 {
|
||||
void foo(XmlAttribute o ) {
|
||||
if (o instanceof XmlAttributeImpl) {
|
||||
o.getParent()<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface PsiElement {
|
||||
PsiElement getParent();
|
||||
}
|
||||
interface XmlAttribute extends PsiElement {}
|
||||
class XmlAttributeImpl implements XmlAttribute {
|
||||
@Override
|
||||
public PsiElement getParent() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+1
@@ -1325,5 +1325,6 @@ public class ListUtils {
|
||||
}
|
||||
|
||||
public void testListArrayListCast() { doTest('\n') }
|
||||
public void testInterfaceImplementationNoCast() { doTest() }
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ public class ChangeListsScopesProvider extends CustomScopesProviderEx {
|
||||
if (IdeBundle.message("scope.modified.files").equals(name)) {
|
||||
return createScope(changeListManager.getAffectedFiles(), IdeBundle.message("scope.modified.files"));
|
||||
}
|
||||
final LocalChangeList changeList = changeListManager.getChangeList(name);
|
||||
final LocalChangeList changeList = changeListManager.findChangeList(name);
|
||||
if (changeList != null) {
|
||||
return createChangeListScope(changeList);
|
||||
}
|
||||
|
||||
+96
-69
@@ -379,22 +379,8 @@ public class SingleInspectionProfilePanel extends JPanel {
|
||||
});
|
||||
|
||||
actions.addSeparator();
|
||||
actions.add(new AddScopeAction(myTree){
|
||||
protected InspectionProfileImpl getSelectedProfile() {
|
||||
return mySelectedProfile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
super.actionPerformed(e);
|
||||
updateOptionsAndDescriptionPanel(myTree.getSelectionPath());
|
||||
}
|
||||
});
|
||||
actions.add(new DeleteScopeAction(myTree){
|
||||
protected InspectionProfileImpl getSelectedProfile() {
|
||||
return mySelectedProfile;
|
||||
}
|
||||
});
|
||||
actions.add(new MyAddScopeAction());
|
||||
actions.add(new MyDeleteScopeAction());
|
||||
actions.add(new MoveScopeAction(myTree, "Move Scope Up", IconLoader.getIcon("/actions/moveUp.png"), -1) {
|
||||
protected boolean isEnabledFor(int idx, InspectionConfigTreeNode parent) {
|
||||
return idx > 0;
|
||||
@@ -568,7 +554,7 @@ public class SingleInspectionProfilePanel extends JPanel {
|
||||
}
|
||||
|
||||
private JPopupMenu compoundPopup() {
|
||||
final JPopupMenu popup = new JPopupMenu(InspectionsBundle.message("inspection.error.level.popup.menu.title"));
|
||||
final DefaultActionGroup group = new DefaultActionGroup();
|
||||
final SeverityRegistrar severityRegistrar = ((SeverityProvider)mySelectedProfile.getProfileManager()).getOwnSeverityRegistrar();
|
||||
TreeSet<HighlightSeverity> severities = new TreeSet<HighlightSeverity>(severityRegistrar);
|
||||
severities.add(HighlightSeverity.ERROR);
|
||||
@@ -581,12 +567,18 @@ public class SingleInspectionProfilePanel extends JPanel {
|
||||
}
|
||||
for (HighlightSeverity severity : severities) {
|
||||
final HighlightDisplayLevel level = HighlightDisplayLevel.find(severity);
|
||||
final JMenuItem item = new JMenuItem(renderSeverity(level.getSeverity()));
|
||||
item.setIcon(level.getIcon()); //todo correct position
|
||||
item.addActionListener(new LevelSelection(level));
|
||||
popup.add(item);
|
||||
group.add(new AnAction(renderSeverity(severity), renderSeverity(severity), level.getIcon()) {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
setNewHighlightingLevel(level);
|
||||
}
|
||||
});
|
||||
}
|
||||
return popup;
|
||||
group.add(Separator.getInstance());
|
||||
group.add(new MyAddScopeAction());
|
||||
group.add(new MyDeleteScopeAction());
|
||||
ActionPopupMenu menu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.UNKNOWN, group);
|
||||
return menu.getComponent();
|
||||
}
|
||||
|
||||
static String renderSeverity(HighlightSeverity severity) {
|
||||
@@ -1051,6 +1043,57 @@ public class SingleInspectionProfilePanel extends JPanel {
|
||||
super.setVisible(aFlag);
|
||||
}
|
||||
|
||||
private void setNewHighlightingLevel(final HighlightDisplayLevel level) {
|
||||
final int[] rows = myTree.getSelectionRows();
|
||||
final boolean showOptionsAndDescriptorPanels = rows != null && rows.length == 1;
|
||||
for (int i = 0; rows != null && i < rows.length; i++) {
|
||||
final InspectionConfigTreeNode node = (InspectionConfigTreeNode)myTree.getPathForRow(rows[i]).getLastPathComponent();
|
||||
final InspectionConfigTreeNode parent = (InspectionConfigTreeNode)node.getParent();
|
||||
if (node.getUserObject() instanceof Descriptor) {
|
||||
updateErrorLevel(node, showOptionsAndDescriptorPanels, level);
|
||||
updateUpHierarchy(node, parent);
|
||||
}
|
||||
else {
|
||||
node.isProperSetting = false;
|
||||
for (int j = 0; j < node.getChildCount(); j++) {
|
||||
final InspectionConfigTreeNode child = (InspectionConfigTreeNode)node.getChildAt(j);
|
||||
if (child.getUserObject() instanceof Descriptor) { //group node
|
||||
updateErrorLevel(child, showOptionsAndDescriptorPanels, level);
|
||||
}
|
||||
else { //root node
|
||||
child.isProperSetting = false;
|
||||
for (int k = 0; k < child.getChildCount(); k++) {
|
||||
final InspectionConfigTreeNode descriptorNode = (InspectionConfigTreeNode)child.getChildAt(k);
|
||||
if (descriptorNode.getUserObject() instanceof Descriptor) {
|
||||
updateErrorLevel(descriptorNode, showOptionsAndDescriptorPanels, level);
|
||||
}
|
||||
child.isProperSetting |= descriptorNode.isProperSetting;
|
||||
}
|
||||
}
|
||||
node.isProperSetting |= child.isProperSetting;
|
||||
}
|
||||
updateUpHierarchy(node, parent);
|
||||
}
|
||||
}
|
||||
if (rows != null && rows.length == 1) {
|
||||
updateOptionsAndDescriptionPanel(myTree.getPathForRow(rows[0]));
|
||||
}
|
||||
else {
|
||||
initOptionsAndDescriptionPanel();
|
||||
}
|
||||
repaintTableData();
|
||||
}
|
||||
|
||||
private void updateErrorLevel(final InspectionConfigTreeNode child,
|
||||
final boolean showOptionsAndDescriptorPanels, final HighlightDisplayLevel level) {
|
||||
final HighlightDisplayKey key = child.getDesriptor().getKey();
|
||||
mySelectedProfile.setErrorLevel(key, level, child.isInspectionNode() || child.isByDefault() ? -1 : child.getParent().getIndex(child));
|
||||
child.isProperSetting = mySelectedProfile.isProperSetting(key);
|
||||
if (showOptionsAndDescriptorPanels) {
|
||||
updateOptionsAndDescriptionPanel(new TreePath(child.getPath()));
|
||||
}
|
||||
}
|
||||
|
||||
private class LevelSelection implements ActionListener {
|
||||
private final HighlightDisplayLevel myLevel;
|
||||
|
||||
@@ -1059,53 +1102,7 @@ public class SingleInspectionProfilePanel extends JPanel {
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final int[] rows = myTree.getSelectionRows();
|
||||
final boolean showOptionsAndDescriptorPanels = rows != null && rows.length == 1;
|
||||
for (int i = 0; rows != null && i < rows.length; i++) {
|
||||
final InspectionConfigTreeNode node = (InspectionConfigTreeNode)myTree.getPathForRow(rows[i]).getLastPathComponent();
|
||||
final InspectionConfigTreeNode parent = (InspectionConfigTreeNode)node.getParent();
|
||||
if (node.getUserObject() instanceof Descriptor) {
|
||||
updateErrorLevel(node, showOptionsAndDescriptorPanels);
|
||||
updateUpHierarchy(node, parent);
|
||||
}
|
||||
else {
|
||||
node.isProperSetting = false;
|
||||
for (int j = 0; j < node.getChildCount(); j++) {
|
||||
final InspectionConfigTreeNode child = (InspectionConfigTreeNode)node.getChildAt(j);
|
||||
if (child.getUserObject()instanceof Descriptor) { //group node
|
||||
updateErrorLevel(child, showOptionsAndDescriptorPanels);
|
||||
}
|
||||
else { //root node
|
||||
child.isProperSetting = false;
|
||||
for (int k = 0; k < child.getChildCount(); k++) {
|
||||
final InspectionConfigTreeNode descriptorNode = (InspectionConfigTreeNode)child.getChildAt(k);
|
||||
if (descriptorNode.getUserObject()instanceof Descriptor) {
|
||||
updateErrorLevel(descriptorNode, showOptionsAndDescriptorPanels);
|
||||
}
|
||||
child.isProperSetting |= descriptorNode.isProperSetting;
|
||||
}
|
||||
}
|
||||
node.isProperSetting |= child.isProperSetting;
|
||||
}
|
||||
updateUpHierarchy(node, parent);
|
||||
}
|
||||
}
|
||||
if (rows != null && rows.length == 1) {
|
||||
updateOptionsAndDescriptionPanel(myTree.getPathForRow(rows[0]));
|
||||
}
|
||||
else {
|
||||
initOptionsAndDescriptionPanel();
|
||||
}
|
||||
repaintTableData();
|
||||
}
|
||||
|
||||
private void updateErrorLevel(final InspectionConfigTreeNode child, final boolean showOptionsAndDescriptorPanels) {
|
||||
final HighlightDisplayKey key = child.getDesriptor().getKey();
|
||||
mySelectedProfile.setErrorLevel(key, myLevel, child.isInspectionNode() || child.isByDefault() ? -1 : child.getParent().getIndex(child));
|
||||
child.isProperSetting = mySelectedProfile.isProperSetting(key);
|
||||
if (showOptionsAndDescriptorPanels) {
|
||||
updateOptionsAndDescriptionPanel(new TreePath(child.getPath()));
|
||||
}
|
||||
setNewHighlightingLevel(myLevel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1135,4 +1132,34 @@ public class SingleInspectionProfilePanel extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
private class MyAddScopeAction extends AddScopeAction {
|
||||
public MyAddScopeAction() {
|
||||
super(SingleInspectionProfilePanel.this.myTree);
|
||||
}
|
||||
|
||||
protected InspectionProfileImpl getSelectedProfile() {
|
||||
return mySelectedProfile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
super.actionPerformed(e);
|
||||
final TreePath[] paths = myTree.getSelectionPaths();
|
||||
if (paths != null && paths.length == 1) {
|
||||
updateOptionsAndDescriptionPanel(myTree.getSelectionPath());
|
||||
} else {
|
||||
initOptionsAndDescriptionPanel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MyDeleteScopeAction extends DeleteScopeAction {
|
||||
public MyDeleteScopeAction() {
|
||||
super(SingleInspectionProfilePanel.this.myTree);
|
||||
}
|
||||
|
||||
protected InspectionProfileImpl getSelectedProfile() {
|
||||
return mySelectedProfile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+39
-26
@@ -59,54 +59,67 @@ public abstract class AddScopeAction extends AnAction {
|
||||
final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
|
||||
if (project == null) return;
|
||||
final InspectionConfigTreeNode[] nodes = myTree.getSelectedNodes(InspectionConfigTreeNode.class, null);
|
||||
if (nodes.length > 0) {
|
||||
final InspectionConfigTreeNode node = nodes[0];
|
||||
final List<Descriptor> descriptors = new ArrayList<Descriptor>();
|
||||
for (InspectionConfigTreeNode node : nodes) {
|
||||
final Descriptor descriptor = node.getDesriptor();
|
||||
if (descriptor != null && node.getScopeName() == null && !getAvailableScopes(descriptor, project).isEmpty()) {
|
||||
presentation.setEnabled(true);
|
||||
if (descriptor != null && node.getScopeName() == null) {
|
||||
descriptors.add(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
presentation.setEnabled(!getAvailableScopes(project, descriptors).isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final InspectionConfigTreeNode[] nodes = myTree.getSelectedNodes(InspectionConfigTreeNode.class, null);
|
||||
final InspectionConfigTreeNode node = nodes[0];
|
||||
final Descriptor descriptor = node.getDesriptor();
|
||||
LOG.assertTrue(descriptor != null);
|
||||
final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
|
||||
final InspectionProfileEntry tool = descriptor.getTool(); //copy
|
||||
final List<String> availableScopes = getAvailableScopes(descriptor, project);
|
||||
List<Descriptor> descriptors = new ArrayList<Descriptor>();
|
||||
for (InspectionConfigTreeNode node : nodes) {
|
||||
final Descriptor descriptor = node.getDesriptor();
|
||||
if (node.getScopeName() == null && descriptor != null) {
|
||||
descriptors.add(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
|
||||
final List<String> availableScopes = getAvailableScopes(project, descriptors);
|
||||
final int idx = Messages.showChooseDialog(myTree, "Scope:", "Choose Scope", ArrayUtil.toStringArray(availableScopes), availableScopes.get(0), Messages.getQuestionIcon());
|
||||
if (idx == -1) return;
|
||||
final NamedScope chosenScope = NamedScopesHolder.getScope(project, availableScopes.get(idx));
|
||||
final ScopeToolState scopeToolState = getSelectedProfile().addScope(tool, chosenScope,
|
||||
getSelectedProfile().getErrorLevel(descriptor.getKey(), chosenScope),
|
||||
getSelectedProfile().isToolEnabled(descriptor.getKey()));
|
||||
final Descriptor addedDescriptor = new Descriptor(scopeToolState, getSelectedProfile());
|
||||
if (node.getChildCount() == 0) {
|
||||
node.add(new InspectionConfigTreeNode(descriptor, scopeToolState, true, true, false));
|
||||
|
||||
for (InspectionConfigTreeNode node : nodes) {
|
||||
final Descriptor descriptor = node.getDesriptor();
|
||||
if (node.getScopeName() != null || descriptor == null) continue;
|
||||
final InspectionProfileEntry tool = descriptor.getTool(); //copy
|
||||
final ScopeToolState scopeToolState = getSelectedProfile().addScope(tool, chosenScope,
|
||||
getSelectedProfile().getErrorLevel(descriptor.getKey(), chosenScope),
|
||||
getSelectedProfile().isToolEnabled(descriptor.getKey()));
|
||||
final Descriptor addedDescriptor = new Descriptor(scopeToolState, getSelectedProfile());
|
||||
if (node.getChildCount() == 0) {
|
||||
node.add(new InspectionConfigTreeNode(descriptor, scopeToolState, true, true, false));
|
||||
}
|
||||
node.insert(new InspectionConfigTreeNode(addedDescriptor, scopeToolState, false, true, false), 0);
|
||||
node.setInspectionNode(false);
|
||||
node.isProperSetting = getSelectedProfile().isProperSetting(HighlightDisplayKey.find(tool.getShortName()));
|
||||
((DefaultTreeModel)myTree.getModel()).reload(node);
|
||||
myTree.expandPath(new TreePath(node.getPath()));
|
||||
}
|
||||
node.insert(new InspectionConfigTreeNode(addedDescriptor, scopeToolState, false, true, false), 0);
|
||||
node.setInspectionNode(false);
|
||||
node.isProperSetting = getSelectedProfile().isProperSetting(HighlightDisplayKey.find(tool.getShortName()));
|
||||
((DefaultTreeModel)myTree.getModel()).reload(node);
|
||||
myTree.expandPath(new TreePath(node.getPath()));
|
||||
myTree.revalidate();
|
||||
}
|
||||
|
||||
private List<String> getAvailableScopes(Descriptor descriptor, Project project) {
|
||||
private List<String> getAvailableScopes(Project project, List<Descriptor> descriptors) {
|
||||
final ArrayList<NamedScope> scopes = new ArrayList<NamedScope>();
|
||||
for (NamedScopesHolder holder : NamedScopesHolder.getAllNamedScopeHolders(project)) {
|
||||
Collections.addAll(scopes, holder.getScopes());
|
||||
}
|
||||
scopes.remove(DefaultScopesProvider.getAllScope());
|
||||
final Set<NamedScope> used = new HashSet<NamedScope>();
|
||||
final List<ScopeToolState> nonDefaultTools = getSelectedProfile().getNonDefaultTools(descriptor.getKey().toString());
|
||||
if (nonDefaultTools != null) {
|
||||
for (ScopeToolState state : nonDefaultTools) {
|
||||
used.add(state.getScope(project));
|
||||
for (Descriptor descriptor : descriptors) {
|
||||
final List<ScopeToolState> nonDefaultTools = getSelectedProfile().getNonDefaultTools(descriptor.getKey().toString());
|
||||
if (nonDefaultTools != null) {
|
||||
for (ScopeToolState state : nonDefaultTools) {
|
||||
used.add(state.getScope(project));
|
||||
}
|
||||
}
|
||||
}
|
||||
scopes.removeAll(used);
|
||||
|
||||
@@ -581,7 +581,8 @@
|
||||
<editorActionHandler action="EditorBackSpace" implementationClass="com.intellij.codeInsight.lookup.impl.BackspaceHandler"/>
|
||||
|
||||
<!-- TemplateManagerActions -->
|
||||
<editorActionHandler action="EditorEscape" implementationClass="com.intellij.codeInsight.template.impl.editorActions.EscapeHandler"/>
|
||||
<editorActionHandler action="EditorEscape" implementationClass="com.intellij.codeInsight.template.impl.editorActions.EscapeHandler"
|
||||
id="templateEscape" order="after hide-hints"/>
|
||||
<editorActionHandler action="EditorEnter" implementationClass="com.intellij.codeInsight.template.impl.editorActions.EnterHandler"
|
||||
id="templateEnter" order="before editorEnter"/>
|
||||
<editorActionHandler action="EditorLineStart" implementationClass="com.intellij.codeInsight.template.impl.editorActions.HomeHandler"/>
|
||||
|
||||
+6
-11
@@ -13,17 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package git4idea.roots;
|
||||
package com.intellij.util;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
public interface GitRootsListener {
|
||||
|
||||
void gitRootsChanged(Collection<VirtualFile> roots);
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface NotNullProducer<T> extends Producer<T> {
|
||||
@Override
|
||||
@NotNull
|
||||
T produce();
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.intellij.util.concurrency;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.Semaphore;
|
||||
@@ -27,7 +28,7 @@ public class FutureResult<T> implements Future<T> {
|
||||
return myValue != null;
|
||||
}
|
||||
|
||||
public void set(T result) {
|
||||
public void set(@Nullable T result) {
|
||||
assert myValue == null;
|
||||
|
||||
myValue = Ref.create(Pair.create((Object)result, true));
|
||||
|
||||
@@ -16,72 +16,32 @@
|
||||
|
||||
package git4idea;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.AbstractVcs;
|
||||
import com.intellij.openapi.vcs.VcsDirectoryMapping;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import git4idea.repo.GitRepositoryManager;
|
||||
import git4idea.roots.GitRootDetector;
|
||||
import git4idea.roots.GitRootsListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Given VFS content roots, filters them and returns only those, which are actual Git roots.
|
||||
*/
|
||||
public class GitRootConverter implements AbstractVcs.RootsConvertor, GitRootsListener {
|
||||
public class GitRootConverter implements AbstractVcs.RootsConvertor {
|
||||
|
||||
@NotNull private final Project myProject;
|
||||
@NotNull private final PlatformFacade myPlatformFacade;
|
||||
|
||||
@Nullable private Collection<VirtualFile> myDetectedRoots;
|
||||
|
||||
public GitRootConverter(@NotNull Project project, @NotNull PlatformFacade facade) {
|
||||
myProject = project;
|
||||
myPlatformFacade = facade;
|
||||
myProject.getMessageBus().connect().subscribe(GitRepositoryManager.GIT_ROOTS_CHANGE, this);
|
||||
}
|
||||
public static final GitRootConverter INSTANCE = new GitRootConverter();
|
||||
|
||||
@NotNull
|
||||
public List<VirtualFile> convertRoots(@NotNull List<VirtualFile> result) {
|
||||
if (myDetectedRoots == null) {
|
||||
myDetectedRoots = new GitRootDetector(myProject, myPlatformFacade).detect().getRoots();
|
||||
}
|
||||
|
||||
// TODO this should be faster, because it is called rather often. gitRootOrNull could be a bottle-neck.
|
||||
ArrayList<VirtualFile> roots = new ArrayList<VirtualFile>();
|
||||
if (hasProjectMapping()) {
|
||||
roots.addAll(myDetectedRoots);
|
||||
}
|
||||
|
||||
HashSet<VirtualFile> listed = new HashSet<VirtualFile>();
|
||||
for (VirtualFile f : result) {
|
||||
VirtualFile r = GitUtil.gitRootOrNull(f);
|
||||
if (r != null && listed.add(r)) {
|
||||
if (!roots.contains(r)) {
|
||||
roots.add(r);
|
||||
}
|
||||
roots.add(r);
|
||||
}
|
||||
}
|
||||
return roots;
|
||||
}
|
||||
|
||||
private boolean hasProjectMapping() {
|
||||
for (VcsDirectoryMapping mapping : myPlatformFacade.getVcsManager(myProject).getDirectoryMappings()) {
|
||||
if (mapping.isDefaultMapping()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gitRootsChanged(Collection<VirtualFile> roots) {
|
||||
myDetectedRoots = roots;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
@@ -93,6 +94,43 @@ public class GitUtil {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VirtualFile findGitDir(@NotNull VirtualFile rootDir) {
|
||||
VirtualFile child = rootDir.findChild(".git");
|
||||
if (child == null) {
|
||||
return null;
|
||||
}
|
||||
if (child.isDirectory()) {
|
||||
return child;
|
||||
}
|
||||
|
||||
// this is standard for submodules, although probably it can
|
||||
String content = readFile(child);
|
||||
String pathToDir;
|
||||
String prefix = "gitdir:";
|
||||
if (content.startsWith(prefix)) {
|
||||
pathToDir = content.substring(prefix.length()).trim();
|
||||
}
|
||||
else {
|
||||
pathToDir = content;
|
||||
}
|
||||
return VcsUtil.getVirtualFile(pathToDir);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String readFile(@NotNull VirtualFile file) {
|
||||
Exception exception = null;
|
||||
for (int attempts = 0; attempts < 3; attempts++) {
|
||||
try {
|
||||
return new String(file.contentsToByteArray());
|
||||
}
|
||||
catch (IOException e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Couldn't read " + file, exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort files by Git root
|
||||
*
|
||||
|
||||
@@ -135,7 +135,6 @@ public class GitVcs extends AbstractVcs<CommittedChangeList> {
|
||||
private GitBranchWidget myBranchWidget;
|
||||
|
||||
private GitVersion myVersion = GitVersion.NULL; // version of Git which this plugin uses.
|
||||
private final GitRootConverter myRootConverter;
|
||||
|
||||
@Nullable
|
||||
public static GitVcs getInstance(Project project) {
|
||||
@@ -175,7 +174,6 @@ public class GitVcs extends AbstractVcs<CommittedChangeList> {
|
||||
myTaskQueue = new BackgroundTaskQueue(myProject, GitBundle.getString("task.queue.title"));
|
||||
myExecutableValidator = new GitExecutableValidator(myProject, this);
|
||||
myPlatformFacade = ServiceManager.getService(myProject, PlatformFacade.class);
|
||||
myRootConverter = new GitRootConverter(myProject, myPlatformFacade);
|
||||
}
|
||||
|
||||
|
||||
@@ -497,7 +495,7 @@ public class GitVcs extends AbstractVcs<CommittedChangeList> {
|
||||
|
||||
@Override
|
||||
public RootsConvertor getCustomConvertor() {
|
||||
return myRootConverter;
|
||||
return GitRootConverter.INSTANCE;
|
||||
}
|
||||
|
||||
public static VcsKey getKey() {
|
||||
|
||||
@@ -59,4 +59,6 @@ public interface PlatformFacade {
|
||||
* Invokes {@link com.intellij.openapi.application.Application#runReadAction(Computable)}.
|
||||
*/
|
||||
<T> T runReadAction(@NotNull Computable<T> computable);
|
||||
|
||||
void runReadAction(@NotNull Runnable runnable);
|
||||
}
|
||||
|
||||
@@ -57,6 +57,11 @@ public class PlatformFacadeImpl implements PlatformFacade {
|
||||
return ApplicationManager.getApplication().runReadAction(computable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runReadAction(@NotNull Runnable runnable) {
|
||||
ApplicationManager.getApplication().runReadAction(runnable);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public AbstractVcs getVcs(@NotNull Project project) {
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.intellij.util.messages.MessageBus;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import com.intellij.util.messages.Topic;
|
||||
import git4idea.GitBranch;
|
||||
import git4idea.GitUtil;
|
||||
import git4idea.branch.GitBranchesCollection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -174,12 +175,12 @@ public final class GitRepository implements Disposable {
|
||||
myProject = project;
|
||||
Disposer.register(parentDisposable, this);
|
||||
|
||||
myGitDir = myRootDir.findChild(".git");
|
||||
myGitDir = GitUtil.findGitDir(myRootDir);
|
||||
assert myGitDir != null : ".git directory wasn't found under " + rootDir.getPresentableUrl();
|
||||
|
||||
myReader = new GitRepositoryReader(VfsUtil.virtualToIoFile(myGitDir));
|
||||
|
||||
myUntrackedFilesHolder = new GitUntrackedFilesHolder(rootDir, project);
|
||||
myUntrackedFilesHolder = new GitUntrackedFilesHolder(this);
|
||||
Disposer.register(this, myUntrackedFilesHolder);
|
||||
|
||||
myMessageBus = project.getMessageBus();
|
||||
@@ -222,6 +223,11 @@ public final class GitRepository implements Disposable {
|
||||
return myRootDir;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public VirtualFile getGitDir() {
|
||||
return myGitDir;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getPresentableUrl() {
|
||||
return getRoot().getPresentableUrl();
|
||||
|
||||
@@ -45,16 +45,13 @@ public class GitRepositoryFiles {
|
||||
private final String myCommitMessagePath;
|
||||
private final String myExcludePath;
|
||||
|
||||
public static GitRepositoryFiles getInstance(@NotNull VirtualFile root) {
|
||||
public static GitRepositoryFiles getInstance(@NotNull VirtualFile gitDir) {
|
||||
// maybe will be cached later to store a single GitRepositoryFiles for a root.
|
||||
return new GitRepositoryFiles(root);
|
||||
return new GitRepositoryFiles(gitDir);
|
||||
}
|
||||
|
||||
private GitRepositoryFiles(@NotNull VirtualFile root) {
|
||||
private GitRepositoryFiles(@NotNull VirtualFile gitDir) {
|
||||
// add .git/ and .git/refs/heads to the VFS
|
||||
VirtualFile gitDir = root.findChild(".git");
|
||||
assert gitDir != null;
|
||||
|
||||
// save paths of the files, that we will watch
|
||||
String gitDirPath = GitFileUtils.stripFileProtocolPrefix(gitDir.getPath());
|
||||
myConfigFilePath = gitDirPath + "/config";
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
package git4idea.repo;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.messages.Topic;
|
||||
import git4idea.roots.GitRootsListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -29,8 +27,6 @@ import java.util.List;
|
||||
*/
|
||||
public interface GitRepositoryManager {
|
||||
|
||||
Topic<GitRootsListener> GIT_ROOTS_CHANGE = Topic.create("Git Roots change", GitRootsListener.class);
|
||||
|
||||
/**
|
||||
* Returns the {@link GitRepository} which tracks the Git repository located in the given directory,
|
||||
* or {@code null} if the given file is not a Git root known to this {@link com.intellij.openapi.project.Project}.
|
||||
|
||||
@@ -50,11 +50,10 @@ final class GitRepositoryUpdater implements Disposable, BulkFileListener {
|
||||
myRepository = repository;
|
||||
VirtualFile root = repository.getRoot();
|
||||
|
||||
VirtualFile gitDir = root.findChild(".git");
|
||||
assert gitDir != null;
|
||||
VirtualFile gitDir = repository.getGitDir();
|
||||
LocalFileSystem.getInstance().addRootToWatch(gitDir.getPath(), true);
|
||||
|
||||
myRepositoryFiles = GitRepositoryFiles.getInstance(root);
|
||||
myRepositoryFiles = GitRepositoryFiles.getInstance(gitDir);
|
||||
visitGitDirVfs(gitDir);
|
||||
myHeadsDir = VcsUtil.getVirtualFile(myRepositoryFiles.getRefsHeadsPath());
|
||||
myRemotesDir = VcsUtil.getVirtualFile(myRepositoryFiles.getRefsRemotesPath());
|
||||
|
||||
@@ -89,14 +89,18 @@ public class GitUntrackedFilesHolder implements Disposable, BulkFileListener {
|
||||
private Set<VirtualFile> myPossiblyTrackedFiles = new HashSet<VirtualFile>();
|
||||
private boolean myReady; // if false, total refresh is needed
|
||||
private final Object LOCK = new Object();
|
||||
private final GitRepositoryManager myRepositoryManager;
|
||||
|
||||
GitUntrackedFilesHolder(@NotNull VirtualFile root, @NotNull Project project) {
|
||||
myProject = project;
|
||||
myRoot = root;
|
||||
myRepositoryFiles = GitRepositoryFiles.getInstance(root);
|
||||
myChangeListManager = ChangeListManager.getInstance(project);
|
||||
myDirtyScopeManager = VcsDirtyScopeManager.getInstance(project);
|
||||
GitUntrackedFilesHolder(@NotNull GitRepository repository) {
|
||||
myProject = repository.getProject();
|
||||
myRoot = repository.getRoot();
|
||||
myChangeListManager = ChangeListManager.getInstance(myProject);
|
||||
myDirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject);
|
||||
myGit = ServiceManager.getService(Git.class);
|
||||
|
||||
myRepositoryManager = GitUtil.getRepositoryManager(myProject);
|
||||
assert myRepositoryManager != null;
|
||||
myRepositoryFiles = GitRepositoryFiles.getInstance(repository.getGitDir());
|
||||
}
|
||||
|
||||
void setupVfsListener(@NotNull Project project) {
|
||||
@@ -302,7 +306,7 @@ public class GitUntrackedFilesHolder implements Disposable, BulkFileListener {
|
||||
}
|
||||
|
||||
private boolean belongsToThisRepository(VirtualFile file) {
|
||||
final GitRepository repository = GitUtil.getRepositoryManager(myProject).getRepositoryForFile(file);
|
||||
final GitRepository repository = myRepositoryManager.getRepositoryForFile(file);
|
||||
return repository != null && repository.getRoot().equals(myRoot);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,9 @@ import com.intellij.openapi.vcs.AbstractVcs;
|
||||
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
|
||||
import com.intellij.openapi.vcs.VcsDirectoryMapping;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import git4idea.Notificator;
|
||||
import git4idea.PlatformFacade;
|
||||
import git4idea.commands.Git;
|
||||
@@ -74,9 +76,10 @@ public class GitIntegrationEnabler {
|
||||
notificator.notifySuccess("", String.format("Added Git %s: %s", pluralize("root", roots.size()), joinRootsPaths(roots)));
|
||||
}
|
||||
|
||||
private boolean gitInitOrNotifyError(@NotNull Notificator notificator, @NotNull VirtualFile projectDir) {
|
||||
private boolean gitInitOrNotifyError(@NotNull Notificator notificator, @NotNull final VirtualFile projectDir) {
|
||||
try {
|
||||
myGit.init(myProject, projectDir);
|
||||
refreshGitDir(projectDir);
|
||||
notificator.notifySuccess("", "Created Git repository in \n" + projectDir.getPresentableUrl());
|
||||
return true;
|
||||
}
|
||||
@@ -87,6 +90,18 @@ public class GitIntegrationEnabler {
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshGitDir(final VirtualFile projectDir) {
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override public void run() {
|
||||
myPlatformFacade.runReadAction(new Runnable() {
|
||||
@Override public void run() {
|
||||
LocalFileSystem.getInstance().refreshAndFindFileByPath(projectDir.getPath() + "/.git");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void addVcsRoots(@NotNull Collection<VirtualFile> roots) {
|
||||
ProjectLevelVcsManager vcsManager = myPlatformFacade.getVcsManager(myProject);
|
||||
AbstractVcs vcs = myPlatformFacade.getVcs(myProject);
|
||||
|
||||
@@ -35,7 +35,7 @@ public class GitRootChecker implements VcsRootChecker {
|
||||
private final boolean myProjectMappingIsInvalid;
|
||||
|
||||
public GitRootChecker(@NotNull Project project, @NotNull PlatformFacade platformFacade) {
|
||||
myErrors = new GitRootErrorsFinder(project, platformFacade).find(new GitRootDetector(project, platformFacade).detect());
|
||||
myErrors = new GitRootErrorsFinder(project, platformFacade).find();
|
||||
myProjectMappingIsInvalid = isProjectMappingInvalid();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import git4idea.PlatformFacade;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@@ -48,26 +49,22 @@ public class GitRootErrorsFinder {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<VcsRootError> find(@NotNull GitRootDetectInfo rootDetectInfo) {
|
||||
public Collection<VcsRootError> find() {
|
||||
List<VcsDirectoryMapping> mappings = myVcsManager.getDirectoryMappings(myVcs);
|
||||
Collection<VirtualFile> gitRoots = rootDetectInfo.getRoots();
|
||||
Collection<VirtualFile> gitRoots = new GitRootDetector(myProject, myPlatformFacade).detect().getRoots();
|
||||
|
||||
Collection<VcsRootError> errors = new ArrayList<VcsRootError>();
|
||||
Collection<String> gitPaths = rootsToPaths(gitRoots);
|
||||
errors.addAll(findExtraMappings(mappings, gitPaths));
|
||||
errors.addAll(findUnregisteredRoots(mappings, gitPaths));
|
||||
errors.addAll(findExtraMappings(mappings, rootsToPaths(gitRoots)));
|
||||
errors.addAll(findUnregisteredRoots(gitRoots));
|
||||
return errors;
|
||||
}
|
||||
|
||||
private Collection<VcsRootError> findUnregisteredRoots(List<VcsDirectoryMapping> mappings, Collection<String> gitPaths) {
|
||||
private Collection<VcsRootError> findUnregisteredRoots(Collection<VirtualFile> gitRoots) {
|
||||
Collection<VcsRootError> errors = new ArrayList<VcsRootError>();
|
||||
if (hasProjectMapping(myPlatformFacade.getVcsManager(myProject).getDirectoryMappings())) {
|
||||
return errors;
|
||||
}
|
||||
List<String> mappedPaths = mappingsToPaths(mappings);
|
||||
for (String gitPath : gitPaths) {
|
||||
if (!mappedPaths.contains(gitPath)) {
|
||||
errors.add(new VcsRootError(VcsRootError.Type.UNREGISTERED_ROOT, gitPath));
|
||||
Collection<VirtualFile> vcsRoots = Arrays.asList(myVcsManager.getRootsUnderVcs(myVcs));
|
||||
for (VirtualFile gitRoot : gitRoots) {
|
||||
if (!vcsRoots.contains(gitRoot)) {
|
||||
errors.add(new VcsRootError(VcsRootError.Type.UNREGISTERED_ROOT, gitRoot.getPath()));
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
@@ -100,23 +97,4 @@ public class GitRootErrorsFinder {
|
||||
return gitPaths;
|
||||
}
|
||||
|
||||
private static List<String> mappingsToPaths(List<VcsDirectoryMapping> mappings) {
|
||||
List<String> paths = new ArrayList<String>();
|
||||
for (VcsDirectoryMapping mapping : mappings) {
|
||||
if (!mapping.isDefaultMapping()) {
|
||||
paths.add(mapping.systemIndependentPath());
|
||||
}
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
private static boolean hasProjectMapping(List<VcsDirectoryMapping> mappings) {
|
||||
for (VcsDirectoryMapping mapping : mappings) {
|
||||
if (mapping.isDefaultMapping()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -67,19 +67,17 @@ public class GitRootProblemNotifier {
|
||||
mySettings = VcsConfiguration.getInstance(myProject);
|
||||
}
|
||||
|
||||
public GitRootDetectInfo rescanAndNotifyIfNeeded() {
|
||||
GitRootDetectInfo detectInfo = new GitRootDetector(myProject, myPlatformFacade).detect();
|
||||
|
||||
public void rescanAndNotifyIfNeeded() {
|
||||
if (!mySettings.SHOW_VCS_ERROR_NOTIFICATIONS) {
|
||||
return detectInfo;
|
||||
return;
|
||||
}
|
||||
|
||||
Collection<VcsRootError> errors = scan(detectInfo);
|
||||
Collection<VcsRootError> errors = scan();
|
||||
if (errors.isEmpty()) {
|
||||
synchronized (NOTIFICATION_LOCK) {
|
||||
expireNotification();
|
||||
}
|
||||
return detectInfo;
|
||||
return;
|
||||
}
|
||||
|
||||
Collection<String> unregisteredRoots = getUnregisteredRoots(errors);
|
||||
@@ -91,10 +89,9 @@ public class GitRootProblemNotifier {
|
||||
synchronized (NOTIFICATION_LOCK) {
|
||||
expireNotification();
|
||||
myNotification = createNotification(IMPORTANT_ERROR_NOTIFICATION, title, description, ERROR,
|
||||
new MyNotificationListener(myProject, mySettings, myPlatformFacade));
|
||||
new MyNotificationListener(myProject, mySettings));
|
||||
myPlatformFacade.getNotificator(myProject).notify(myNotification);
|
||||
}
|
||||
return detectInfo;
|
||||
}
|
||||
|
||||
private void expireNotification() {
|
||||
@@ -112,8 +109,8 @@ public class GitRootProblemNotifier {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<VcsRootError> scan(GitRootDetectInfo detectInfo) {
|
||||
return new GitRootErrorsFinder(myProject, myPlatformFacade).find(detectInfo);
|
||||
private Collection<VcsRootError> scan() {
|
||||
return new GitRootErrorsFinder(myProject, myPlatformFacade).find();
|
||||
}
|
||||
|
||||
@SuppressWarnings("StringConcatenationInsideStringBufferAppend")
|
||||
@@ -198,12 +195,10 @@ public class GitRootProblemNotifier {
|
||||
|
||||
@NotNull private final Project myProject;
|
||||
@NotNull private final VcsConfiguration mySettings;
|
||||
@NotNull private final PlatformFacade myPlatformFacade;
|
||||
|
||||
private MyNotificationListener(@NotNull Project project, @NotNull VcsConfiguration settings, @NotNull PlatformFacade facade) {
|
||||
private MyNotificationListener(@NotNull Project project, @NotNull VcsConfiguration settings) {
|
||||
myProject = project;
|
||||
mySettings = settings;
|
||||
myPlatformFacade = facade;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -211,8 +206,7 @@ public class GitRootProblemNotifier {
|
||||
if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
|
||||
if (event.getDescription().equals("configure")) {
|
||||
ShowSettingsUtil.getInstance().showSettingsDialog(myProject, ActionsBundle.message("group.VcsGroup.text"));
|
||||
Collection<VcsRootError> errorsAfterPossibleFix = GitRootProblemNotifier.getInstance(myProject).scan(
|
||||
new GitRootDetector(myProject, myPlatformFacade).detect());
|
||||
Collection<VcsRootError> errorsAfterPossibleFix = GitRootProblemNotifier.getInstance(myProject).scan();
|
||||
if (errorsAfterPossibleFix.isEmpty() && !notification.isExpired()) {
|
||||
notification.expire();
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import git4idea.repo.GitRepositoryManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -41,7 +40,6 @@ import java.util.List;
|
||||
*/
|
||||
public class GitRootScanner implements BulkFileListener, ModuleRootListener, Disposable, VcsListener {
|
||||
|
||||
@NotNull private final Project myProject;
|
||||
@NotNull private final Runnable myExecuteAfterScan;
|
||||
@NotNull private final GitRootProblemNotifier myRootProblemNotifier;
|
||||
|
||||
@@ -51,7 +49,6 @@ public class GitRootScanner implements BulkFileListener, ModuleRootListener, Dis
|
||||
@NotNull private final Object SCAN_LOCK = new Object();
|
||||
|
||||
public GitRootScanner(@NotNull Project project, @NotNull Runnable executeAfterScan) {
|
||||
myProject = project;
|
||||
myExecuteAfterScan = executeAfterScan;
|
||||
|
||||
StartupManager.getInstance(project).runWhenProjectIsInitialized(new DumbAwareRunnable() {
|
||||
@@ -132,8 +129,7 @@ public class GitRootScanner implements BulkFileListener, ModuleRootListener, Dis
|
||||
return;
|
||||
}
|
||||
myScanning = true;
|
||||
GitRootDetectInfo detectInfo = myRootProblemNotifier.rescanAndNotifyIfNeeded();
|
||||
myProject.getMessageBus().syncPublisher(GitRepositoryManager.GIT_ROOTS_CHANGE).gitRootsChanged(detectInfo.getRoots());
|
||||
myRootProblemNotifier.rescanAndNotifyIfNeeded();
|
||||
myExecuteAfterScan.run();
|
||||
myScanning = false;
|
||||
}
|
||||
|
||||
@@ -131,19 +131,20 @@ class GitRootErrorsFinderTest extends AbstractGitRootTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void "Project root, git below project folder not in a content root, then correct since folders are auto-detected"() {
|
||||
void "Project root, git below project folder not in a content root, then unregistered root error"() {
|
||||
// this is to be fixed: auto-detection of Git repositories in subfolders for the <Project> mapping
|
||||
doTest content_roots: ["."],
|
||||
git: ["community"],
|
||||
roots: [PROJECT],
|
||||
errors: []
|
||||
errors: [unreg: ["community"]]
|
||||
}
|
||||
|
||||
@Test
|
||||
void "Project root, git for full project, content root, linked source, folder below project, then correct since folders are detected"() {
|
||||
void "Project root, git for full project, content root, linked source, folder below project, then error in folder below"() {
|
||||
doTest content_roots: [".", "content_root", "../linked_source_root"],
|
||||
git: [".", "content_root", "../linked_source_root", "folder"],
|
||||
roots: [PROJECT],
|
||||
errors: []
|
||||
errors: [unreg: ["folder"]]
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -172,8 +173,7 @@ class GitRootErrorsFinderTest extends AbstractGitRootTest {
|
||||
expected.addAll map.errors.unreg.collect { unreg(it) }
|
||||
expected.addAll map.errors.extra.collect { extra(it) }
|
||||
|
||||
Collection<VcsRootError> actual = new GitRootErrorsFinder(myProject, myPlatformFacade).find(
|
||||
new GitRootDetector(myProject, myPlatformFacade).detect())
|
||||
Collection<VcsRootError> actual = new GitRootErrorsFinder(myProject, myPlatformFacade).find()
|
||||
assertEquals expected.toSet(), actual.toSet()
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ public class GitMockVcsManager extends ProjectLevelVcsManager {
|
||||
List<VirtualFile> roots = myRoots.collect { new GitMockVirtualFile(it) }
|
||||
roots.addAll(myPlatformFacade.getProjectRootManager(myProject).getContentRoots())
|
||||
roots
|
||||
// new GitRootConverter(myProject, myPlatformFacade).convertRoots(roots)
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -77,6 +77,11 @@ public class GitTestPlatformFacade implements PlatformFacade {
|
||||
computable.compute()
|
||||
}
|
||||
|
||||
@Override
|
||||
void runReadAction(Runnable runnable) {
|
||||
runnable.run()
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
AbstractVcs getVcs(@NotNull Project project) {
|
||||
|
||||
@@ -14,7 +14,7 @@ gradle.import.structure.tree.node.content.root=content-root
|
||||
gradle.import.structure.tree.node.libraries=libraries
|
||||
gradle.import.structure.settings.label.name=Name:
|
||||
gradle.import.structure.settings.label.language.level=Language level:
|
||||
gradle.import.structure.settings.label.sdk=Sdk:
|
||||
gradle.import.structure.settings.label.sdk=SDK:
|
||||
gradle.import.structure.settings.no.sdk.for.language.level.text=<no registered sdk matches language level>
|
||||
gradle.import.structure.settings.label.project.config.location=Project config location:
|
||||
gradle.import.structure.settings.title.project.config.location=Project config location
|
||||
|
||||
@@ -108,6 +108,7 @@
|
||||
<group id="Gradle.ChangeActionsToolbar">
|
||||
<reference id="Gradle.RefreshProject"/>
|
||||
<reference id="Gradle.OpenScript"/>
|
||||
<reference id="ContextHelp"/>
|
||||
</group>
|
||||
|
||||
<action id="Gradle.ImportEntity" class="org.jetbrains.plugins.gradle.action.GradleImportEntityAction" icon="/icons/gradleImport.png"/>
|
||||
|
||||
+18
-15
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.gradle.config.GradleGroovyEnabler;
|
||||
import org.jetbrains.plugins.gradle.config.GradleSettings;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.*;
|
||||
import org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangesModel;
|
||||
import org.jetbrains.plugins.gradle.task.GradleResolveProjectTask;
|
||||
import org.jetbrains.plugins.gradle.util.GradleBundle;
|
||||
import org.jetbrains.plugins.gradle.util.GradleLog;
|
||||
@@ -318,6 +319,21 @@ public class GradleModulesImporter {
|
||||
finally {
|
||||
writeLock.finish();
|
||||
}
|
||||
final GradleSettings settings = GradleSettings.getInstance(intellijProject);
|
||||
final String gradleHome = settings.getGradleHome();
|
||||
if (gradleHome != null) {
|
||||
final GradleGroovyEnabler groovyEnabler = intellijProject.getComponent(GradleGroovyEnabler.class);
|
||||
libraryToPreserve.set(groovyEnabler.setupGroovySdkIfNecessary(gradleHome));
|
||||
}
|
||||
|
||||
// Force refresh the infrastructure in order to apply newly introduce intellij project structure changes
|
||||
final GradleProjectStructureChangesModel changesModel = intellijProject.getComponent(GradleProjectStructureChangesModel.class);
|
||||
if (changesModel != null) {
|
||||
final GradleProject project = changesModel.getGradleProject();
|
||||
if (project != null) {
|
||||
changesModel.update(project);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -337,21 +353,8 @@ public class GradleModulesImporter {
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Runnable setupGroovyTask = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final GradleSettings settings = GradleSettings.getInstance(intellijProject);
|
||||
final String gradleHome = settings.getGradleHome();
|
||||
if (gradleHome != null) {
|
||||
final GradleGroovyEnabler groovyEnabler = intellijProject.getComponent(GradleGroovyEnabler.class);
|
||||
libraryToPreserve.set(groovyEnabler.setupGroovySdkIfNecessary(gradleHome));
|
||||
}
|
||||
resolveDependenciesTask.run();
|
||||
}
|
||||
};
|
||||
|
||||
UIUtil.invokeLaterIfNeeded(setupGroovyTask);
|
||||
|
||||
UIUtil.invokeLaterIfNeeded(resolveDependenciesTask);
|
||||
}
|
||||
|
||||
private static void doSetupLibraries(@NotNull Map<GradleModule, Module> moduleMappings,
|
||||
|
||||
+3
-2
@@ -23,6 +23,7 @@ import org.jetbrains.plugins.gradle.model.gradle.GradleModule;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleProject;
|
||||
import org.jetbrains.plugins.gradle.ui.GradleIcons;
|
||||
import org.jetbrains.plugins.gradle.util.GradleBundle;
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
||||
import org.jetbrains.plugins.gradle.util.GradleUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -78,8 +79,8 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder<GradleProje
|
||||
public List<Module> commit(final Project project,
|
||||
ModifiableModuleModel model,
|
||||
ModulesProvider modulesProvider,
|
||||
ModifiableArtifactModel artifactModel)
|
||||
{
|
||||
ModifiableArtifactModel artifactModel) {
|
||||
System.setProperty(GradleConstants.NEWLY_IMPORTED_PROJECT, Boolean.TRUE.toString());
|
||||
final Runnable task = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
+5
-1
@@ -152,7 +152,11 @@ public class GradleAdjustImportSettingsStep extends AbstractImportFromGradleWiza
|
||||
public JComponent getComponent() {
|
||||
return myComponent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpId() {
|
||||
return GradleConstants.HELP_TOPIC_ADJUST_SETTINGS_STEP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStep() {
|
||||
if (myOnValidateAttempt) {
|
||||
|
||||
+6
@@ -13,6 +13,7 @@ import org.jetbrains.plugins.gradle.config.GradleHomeSettingType;
|
||||
import org.jetbrains.plugins.gradle.importing.GradleProjectImportBuilder;
|
||||
import org.jetbrains.plugins.gradle.importing.wizard.AbstractImportFromGradleWizardStep;
|
||||
import org.jetbrains.plugins.gradle.util.GradleBundle;
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
||||
import org.jetbrains.plugins.gradle.util.GradleUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -86,6 +87,11 @@ public class GradleSelectProjectStep extends AbstractImportFromGradleWizardStep
|
||||
public void updateDataModel() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpId() {
|
||||
return GradleConstants.HELP_TOPIC_IMPORT_SELECT_PROJECT_STEP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate() throws ConfigurationException {
|
||||
if (myConfigurable.getCurrentGradleHomeSettingType() == GradleHomeSettingType.EXPLICIT_INCORRECT) {
|
||||
|
||||
@@ -236,7 +236,10 @@ public class GradleApiFacadeManager {
|
||||
GradleLog.LOG.warn("Detected unexpected duplicate tooling api facade instance creation");
|
||||
return myFacade.get().first;
|
||||
}
|
||||
result.applySettings(getRemoteSettings());
|
||||
if (!StringUtil.isEmpty(newPair.second.getJavaHome())) {
|
||||
GradleLog.LOG.info("Instructing gradle to use java from " + newPair.second.getJavaHome());
|
||||
}
|
||||
result.applySettings(newPair.second);
|
||||
RemoteGradleProgressNotificationManager exported = myExportedProgressManager.get();
|
||||
if (exported == null) {
|
||||
try {
|
||||
|
||||
+15
-3
@@ -16,14 +16,18 @@ import java.io.Serializable;
|
||||
*/
|
||||
public class RemoteGradleProcessSettings implements Serializable {
|
||||
|
||||
private static final boolean USE_VERBOSE_GRADLE_API_BY_DEFAULT = Boolean.parseBoolean(System.getProperty("gradle.api.verbose"));
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final String myGradleHome;
|
||||
private long myTtlInMs;
|
||||
private String myJavaHome;
|
||||
private final String myGradleHome;
|
||||
private long myTtlInMs;
|
||||
private String myJavaHome;
|
||||
private boolean myVerboseApi;
|
||||
|
||||
public RemoteGradleProcessSettings(@NotNull String gradleHome) {
|
||||
myGradleHome = gradleHome;
|
||||
setVerboseApi(USE_VERBOSE_GRADLE_API_BY_DEFAULT);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -51,6 +55,14 @@ public class RemoteGradleProcessSettings implements Serializable {
|
||||
myJavaHome = javaHome;
|
||||
}
|
||||
|
||||
public boolean isVerboseApi() {
|
||||
return myVerboseApi;
|
||||
}
|
||||
|
||||
public void setVerboseApi(boolean verboseApi) {
|
||||
myVerboseApi = verboseApi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "home: " + myGradleHome;
|
||||
|
||||
+4
@@ -8,6 +8,7 @@ import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.containers.ConcurrentHashSet;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.gradle.tooling.*;
|
||||
import org.gradle.tooling.internal.consumer.DefaultGradleConnector;
|
||||
import org.gradle.tooling.model.DomainObjectSet;
|
||||
import org.gradle.tooling.model.idea.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -398,6 +399,9 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro
|
||||
RemoteGradleProcessSettings settings = mySettings.get();
|
||||
if (settings != null) {
|
||||
connector.useInstallation(new File(settings.getGradleHome()));
|
||||
if (settings.isVerboseApi() && connector instanceof DefaultGradleConnector) {
|
||||
((DefaultGradleConnector)connector).setVerboseLogging(true);
|
||||
}
|
||||
}
|
||||
connector.forProjectDirectory(projectDir);
|
||||
ProjectConnection connection = connector.connect();
|
||||
|
||||
+5
-1
@@ -3,6 +3,7 @@ package org.jetbrains.plugins.gradle.sync;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.startup.StartupActivity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
||||
import org.jetbrains.plugins.gradle.util.GradleUtil;
|
||||
|
||||
/**
|
||||
@@ -14,8 +15,11 @@ import org.jetbrains.plugins.gradle.util.GradleUtil;
|
||||
* @since 3/13/12 12:01 PM
|
||||
*/
|
||||
public class GradleInitialProjectRefresher implements StartupActivity {
|
||||
@SuppressWarnings("UseOfArchaicSystemPropertyAccessors")
|
||||
@Override
|
||||
public void runActivity(@NotNull Project project) {
|
||||
GradleUtil.refreshProject(project);
|
||||
if (!Boolean.getBoolean(GradleConstants.NEWLY_IMPORTED_PROJECT)) {
|
||||
GradleUtil.refreshProject(project);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-4
@@ -47,7 +47,7 @@ import java.util.List;
|
||||
*/
|
||||
public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel {
|
||||
|
||||
private static final int TOOLTIP_DELAY_MILLIS = 500;
|
||||
private static final int TOOLTIP_DELAY_MILLIS = 300;
|
||||
private static final int COLLAPSE_STATE_PROCESSING_DELAY_MILLIS = 200;
|
||||
|
||||
private static final Comparator<TreePath> PATH_COMPARATOR = new Comparator<TreePath>() {
|
||||
@@ -59,7 +59,7 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel {
|
||||
|
||||
private final Alarm myToolbarAppearanceAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
|
||||
private final Alarm myToolbarTrackingAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
|
||||
private final Alarm myCollapseStateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
|
||||
private final Alarm myCollapseStateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
|
||||
private final List<JComponent> myToolbarControls = new ArrayList<JComponent>();
|
||||
|
||||
/** Holds list of paths which 'expand/collapse' state should be restored. */
|
||||
@@ -213,14 +213,14 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel {
|
||||
final @NotNull ActionToolbar toolbar,
|
||||
final @NotNull JComponent toolbarComponent)
|
||||
{
|
||||
if (mySuppressToolbar || node == myNodeWithActiveToolbar) {
|
||||
if (mySuppressToolbar || node == myNodeWithActiveToolbar || myTree.getSelectionCount() > 1) {
|
||||
return;
|
||||
}
|
||||
myToolbarAppearanceAlarm.cancelAllRequests();
|
||||
myToolbarAppearanceAlarm.addRequest(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (myNodeUnderMouse != node) {
|
||||
if (myNodeUnderMouse != node || myTree.getSelectionCount() > 1) {
|
||||
return;
|
||||
}
|
||||
final Point mouseLocation = MouseInfo.getPointerInfo().getLocation();
|
||||
@@ -319,6 +319,9 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else if (PlatformDataKeys.HELP_ID.is(dataId)) {
|
||||
return GradleConstants.HELP_TOPIC_TOOL_WINDOW;
|
||||
}
|
||||
else {
|
||||
return super.getData(dataId);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ import org.jetbrains.plugins.gradle.ui.GradleProjectStructureNodeDescriptor;
|
||||
*/
|
||||
public class GradleConstants {
|
||||
|
||||
@NonNls public static final String NEWLY_IMPORTED_PROJECT = "gradle.newly.imported";
|
||||
|
||||
@NonNls public static final String EXTENSION = "gradle";
|
||||
@NonNls public static final String DEFAULT_SCRIPT_NAME = "build.gradle";
|
||||
|
||||
@@ -23,7 +25,10 @@ public class GradleConstants {
|
||||
@NonNls public static final String SYNC_TREE_FILTER_PLACE = "GRADLE_SYNC_TREE_FILTER_PLACE";
|
||||
|
||||
@NonNls public static final String ACTION_GROUP_SYNC_TREE = "Gradle.SyncTreeGroup";
|
||||
|
||||
|
||||
@NonNls public static final String HELP_TOPIC_IMPORT_SELECT_PROJECT_STEP = "reference.dialogs.new.project.import.gradle.page1";
|
||||
@NonNls public static final String HELP_TOPIC_ADJUST_SETTINGS_STEP = "reference.dialogs.new.project.import.gradle.page2";
|
||||
@NonNls public static final String HELP_TOPIC_TOOL_WINDOW = "reference.toolwindows.gradle";
|
||||
|
||||
public static final GradleProjectStructureNodeDescriptor<GradleSyntheticId> DEPENDENCIES_NODE_DESCRIPTOR
|
||||
= GradleUtil.buildSyntheticDescriptor(GradleBundle.message("gradle.project.structure.tree.node.dependencies"));
|
||||
|
||||
+28
-19
@@ -119,38 +119,32 @@ public class MavenResumeAction extends AnAction {
|
||||
String text = event.getText().trim();
|
||||
if (text.isEmpty()) return;
|
||||
|
||||
String textWithoutInfo = "";
|
||||
if (text.startsWith("[INFO] ")) {
|
||||
textWithoutInfo = text.substring("[INFO] ".length()).trim();
|
||||
}
|
||||
|
||||
switch (myState) {
|
||||
case STATE_INITIAL: // initial state.
|
||||
if (text.equals("[INFO] Reactor build order:")) {
|
||||
if (textWithoutInfo.equalsIgnoreCase("Reactor build order:")) {
|
||||
myState = STATE_READING_PROJECT_LIST;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_READING_PROJECT_LIST:
|
||||
if (text.equals("[INFO] ------------------------------------------------------------------------")) {
|
||||
if (textWithoutInfo.equals("------------------------------------------------------------------------")) {
|
||||
myState = STATE_WAIT_FOR_BUILD;
|
||||
}
|
||||
else if (text.startsWith("[INFO] ")) {
|
||||
String projectName = text.substring("[INFO] ".length());
|
||||
if (projectName.isEmpty()) {
|
||||
myState = STATE_WTF;
|
||||
log("Empty project name in \"Reactor build order\" section!!! other project names: " + myMavenProjectNames);
|
||||
}
|
||||
else {
|
||||
myMavenProjectNames.add(projectName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
myState = STATE_WTF;
|
||||
log("\"Reactor build order\" doesn't end by \"-----\"!!! it's end by: " + text);
|
||||
else if (textWithoutInfo.length() > 0) {
|
||||
myMavenProjectNames.add(textWithoutInfo);
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_WAIT_FOR_BUILD:
|
||||
if (text.startsWith("[INFO] Building ")) {
|
||||
String projectName = text.substring("[INFO] Building ".length());
|
||||
if (textWithoutInfo.startsWith("Building ")) {
|
||||
String projectName = textWithoutInfo.substring("Building ".length());
|
||||
if (myBuildingProjectIndex > myMavenProjectNames.size() ||
|
||||
!myMavenProjectNames.get(myBuildingProjectIndex).equals(projectName)) {
|
||||
!projectName.startsWith(myMavenProjectNames.get(myBuildingProjectIndex))) {
|
||||
myState = STATE_WTF;
|
||||
log(String.format("Invalid project building order. Defined order: %s, error index: %d, invalid line: %s",
|
||||
myMavenProjectNames, myBuildingProjectIndex, text));
|
||||
@@ -163,7 +157,7 @@ public class MavenResumeAction extends AnAction {
|
||||
break;
|
||||
|
||||
case STATE_WAIT_FOR______:
|
||||
if (text.equals("[INFO] ------------------------------------------------------------------------")) {
|
||||
if (textWithoutInfo.equals("------------------------------------------------------------------------")) {
|
||||
myState = STATE_WAIT_FOR_BUILD;
|
||||
}
|
||||
break;
|
||||
@@ -216,6 +210,21 @@ public class MavenResumeAction extends AnAction {
|
||||
}
|
||||
}
|
||||
|
||||
if (candidate != null) {
|
||||
return candidate;
|
||||
}
|
||||
|
||||
for (MavenProject mavenProject : projects) {
|
||||
if (projectName.equals(mavenProject.getMavenId().getArtifactId())) {
|
||||
if (candidate == null) {
|
||||
candidate = mavenProject;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return candidate;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.ide.browsers.chrome;
|
||||
|
||||
import com.intellij.execution.configurations.ParametersList;
|
||||
import com.intellij.ide.browsers.BrowserSpecificSettings;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
@@ -30,6 +31,7 @@ public class ChromeSettings extends BrowserSpecificSettings {
|
||||
@NonNls public static final String REMOTE_DEBUGGING_PORT_ARG = "--remote-debugging-port=";
|
||||
@NonNls public static final String USER_DATA_DIR_ARG = "--user-data-dir=";
|
||||
public static final int DEFAULT_REMOTE_SHELL_PORT = 7930;
|
||||
private String myCommandLineOptions = "";
|
||||
private String myUserDataDirectoryPath;
|
||||
private boolean myUseCustomProfile;
|
||||
private boolean myEnableRemoteDebug;
|
||||
@@ -59,6 +61,15 @@ public class ChromeSettings extends BrowserSpecificSettings {
|
||||
return myRemoteShellPort;
|
||||
}
|
||||
|
||||
@Tag("command-line-options")
|
||||
public String getCommandLineOptions() {
|
||||
return myCommandLineOptions;
|
||||
}
|
||||
|
||||
public void setCommandLineOptions(String commandLineOptions) {
|
||||
myCommandLineOptions = commandLineOptions;
|
||||
}
|
||||
|
||||
public void setEnableRemoteDebug(boolean enableRemoteDebug) {
|
||||
myEnableRemoteDebug = enableRemoteDebug;
|
||||
}
|
||||
@@ -94,7 +105,7 @@ public class ChromeSettings extends BrowserSpecificSettings {
|
||||
remoteShellArg = ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
}
|
||||
|
||||
return ArrayUtil.mergeArrays(customProfileArg, remoteShellArg);
|
||||
return ArrayUtil.mergeArrays(ParametersList.parse(myCommandLineOptions), ArrayUtil.mergeArrays(customProfileArg, remoteShellArg));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.ide.browsers.chrome.ChromeSettingsConfigurable">
|
||||
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="7" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="400"/>
|
||||
@@ -10,7 +10,7 @@
|
||||
<children>
|
||||
<component id="6d1fc" class="javax.swing.JCheckBox" binding="myUseCustomProfileCheckBox">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="&Use custom profile directory:"/>
|
||||
@@ -18,12 +18,12 @@
|
||||
</component>
|
||||
<vspacer id="eb956">
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="e97dd" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myUserDataDirField">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="2" use-parent-layout="false">
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="2" use-parent-layout="false">
|
||||
<preferred-size width="350" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
@@ -31,7 +31,7 @@
|
||||
</component>
|
||||
<component id="b4c6c" class="javax.swing.JCheckBox" binding="myEnableRemoteDebugCheckBox">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Enable remote &debug on port:"/>
|
||||
@@ -39,12 +39,26 @@
|
||||
</component>
|
||||
<component id="72606" class="javax.swing.JTextField" binding="myPortField">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="2" use-parent-layout="false">
|
||||
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="2" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="3fc23" class="com.intellij.ui.RawCommandLineEditor" binding="myCommandLineOptionsEditor">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="2" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="4b3a7" class="javax.swing.JLabel" binding="myCommandLineOptionsLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="&Command line options:"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.ui.RawCommandLineEditor;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -40,6 +41,8 @@ public class ChromeSettingsConfigurable implements Configurable {
|
||||
private TextFieldWithBrowseButton myUserDataDirField;
|
||||
private JCheckBox myEnableRemoteDebugCheckBox;
|
||||
private JTextField myPortField;
|
||||
private JLabel myCommandLineOptionsLabel;
|
||||
private RawCommandLineEditor myCommandLineOptionsEditor;
|
||||
private final String myDefaultUserDirPath;
|
||||
|
||||
public ChromeSettingsConfigurable(@NotNull ChromeSettings settings) {
|
||||
@@ -59,6 +62,7 @@ public class ChromeSettingsConfigurable implements Configurable {
|
||||
myPortField.setEnabled(myEnableRemoteDebugCheckBox.isSelected());
|
||||
}
|
||||
});
|
||||
myCommandLineOptionsLabel.setLabelFor(myCommandLineOptionsEditor.getTextField());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,7 +74,8 @@ public class ChromeSettingsConfigurable implements Configurable {
|
||||
public boolean isModified() {
|
||||
if (myEnableRemoteDebugCheckBox.isSelected() != mySettings.isEnableRemoteDebug()
|
||||
|| !myPortField.getText().equals(String.valueOf(mySettings.getRemoteShellPort()))
|
||||
|| myUseCustomProfileCheckBox.isSelected() != mySettings.isUseCustomProfile()) {
|
||||
|| myUseCustomProfileCheckBox.isSelected() != mySettings.isUseCustomProfile()
|
||||
|| !myCommandLineOptionsEditor.getText().equals(mySettings.getCommandLineOptions())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -93,6 +98,7 @@ public class ChromeSettingsConfigurable implements Configurable {
|
||||
catch (NumberFormatException ignored) {
|
||||
throw new ConfigurationException("Port is not integer!");
|
||||
}
|
||||
mySettings.setCommandLineOptions(myCommandLineOptionsEditor.getText());
|
||||
mySettings.setUseCustomProfile(myUseCustomProfileCheckBox.isSelected());
|
||||
mySettings.setUserDataDirectoryPath(getConfiguredUserDataDirPath());
|
||||
mySettings.setEnableRemoteDebug(myEnableRemoteDebugCheckBox.isSelected());
|
||||
@@ -104,6 +110,7 @@ public class ChromeSettingsConfigurable implements Configurable {
|
||||
myPortField.setText(String.valueOf(mySettings.getRemoteShellPort()));
|
||||
myPortField.setEnabled(mySettings.isEnableRemoteDebug());
|
||||
|
||||
myCommandLineOptionsEditor.setText(mySettings.getCommandLineOptions());
|
||||
myUseCustomProfileCheckBox.setSelected(mySettings.isUseCustomProfile());
|
||||
myUserDataDirField.setEnabled(mySettings.isUseCustomProfile());
|
||||
String path = mySettings.getUserDataDirectoryPath();
|
||||
|
||||
Reference in New Issue
Block a user