diff --git a/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java
index 24ed7b49b907..61e32f8aa50b 100644
--- a/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java
+++ b/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java
@@ -50,9 +50,9 @@ public class CompilerUIConfigurable implements SearchableConfigurable, Configura
myCbUseCompileServer.setVisible(ApplicationManager.getApplication().isInternal());
myPatternLegendLabel.setText("" +
"Use ; to separate patterns and ! to negate a pattern.
" +
- "Accepted wildcards: ? - exactly one symbol; * - zero or more symbols;
" +
- " / - path separator; /**/ - any number of directories;
" +
- " resources:* - for everything under a source root named resources" +
+ "Accepted wildcards: ? — exactly one symbol; * — zero or more symbols;
" +
+ " / — path separator; /**/ — any number of directories;
" +
+ " <dir_name>:<pattern> — restrict to source roots with the specified name" +
"");
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/SmartStepIntoActionHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java
similarity index 50%
rename from java/debugger/impl/src/com/intellij/debugger/actions/SmartStepIntoActionHandler.java
rename to java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java
index 3786d50a9f8c..294718ee7843 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/SmartStepIntoActionHandler.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2011 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,75 +15,33 @@
*/
package com.intellij.debugger.actions;
-import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.SourcePosition;
-import com.intellij.debugger.engine.RequestHint;
-import com.intellij.debugger.engine.SuspendContextImpl;
-import com.intellij.debugger.impl.DebuggerContextImpl;
-import com.intellij.debugger.impl.DebuggerSession;
-import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.fileEditor.FileEditor;
-import com.intellij.openapi.fileEditor.FileEditorManager;
-import com.intellij.openapi.fileEditor.TextEditor;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.popup.JBPopupFactory;
-import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.containers.OrderedSet;
import com.intellij.util.text.CharArrayUtil;
-import com.intellij.xdebugger.impl.actions.DebuggerActionHandler;
-import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import gnu.trove.TObjectHashingStrategy;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
-public class SmartStepIntoActionHandler extends DebuggerActionHandler {
- public void perform(@NotNull final Project project, final AnActionEvent event) {
- final DebuggerContextImpl debuggerContext = (DebuggerManagerEx.getInstanceEx(project)).getContext();
- doStep(project, debuggerContext.getSourcePosition(), debuggerContext.getDebuggerSession());
+/**
+ * User: Alexander Podkhalyuzin
+ * Date: 22.11.11
+ */
+public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
+ @Override
+ public boolean isAvailable(final SourcePosition position) {
+ final PsiFile file = position.getFile();
+ return file.getLanguage().isKindOf(JavaLanguage.INSTANCE);
}
-
- private static void doStep(final @NotNull Project project, final @Nullable SourcePosition position, final @NotNull DebuggerSession session) {
- final VirtualFile file = position != null ? position.getFile().getVirtualFile() : null;
- final FileEditor fileEditor = file != null? FileEditorManager.getInstance(project).getSelectedEditor(file) : null;
- if (fileEditor instanceof TextEditor) {
- final List methods = findReferencedMethods(position);
- if (methods.size() > 0) {
- if (methods.size() == 1) {
- session.stepInto(true, createSmartStepFilter(methods.get(0)));
- }
- else {
- final PsiMethodListPopupStep popupStep = new PsiMethodListPopupStep(methods, new PsiMethodListPopupStep.OnChooseRunnable() {
- public void execute(PsiMethod chosenMethod) {
- session.stepInto(true, createSmartStepFilter(chosenMethod));
- }
- });
- final ListPopup popup = JBPopupFactory.getInstance().createListPopup(popupStep);
- final RelativePoint point = DebuggerUIUtil.calcPopupLocation(((TextEditor)fileEditor).getEditor(), position.getLine());
- popup.show(point);
- }
- return;
- }
- }
- session.stepInto(true, null);
- }
-
- @Nullable
- private static RequestHint.SmartStepFilter createSmartStepFilter(final PsiMethod method) {
- return new RequestHint.SmartStepFilter(method);
- }
-
-
- private static List findReferencedMethods(final SourcePosition position) {
+ @Override
+ public List findReferencedMethods(final SourcePosition position) {
final int line = position.getLine();
if (line < 0) {
return Collections.emptyList(); // the document has been changed
@@ -95,8 +53,9 @@ public class SmartStepIntoActionHandler extends DebuggerActionHandler {
// the file is not physical
return Collections.emptyList();
}
-
+
final Document doc = FileDocumentManager.getInstance().getDocument(vFile);
+ if (doc == null) return Collections.emptyList();
if (line >= doc.getLineCount()) {
return Collections.emptyList(); // the document has been changed
}
@@ -144,13 +103,4 @@ public class SmartStepIntoActionHandler extends DebuggerActionHandler {
}
return Collections.emptyList();
}
-
- public boolean isEnabled(@NotNull final Project project, final AnActionEvent event) {
- final DebuggerContextImpl context = (DebuggerManagerEx.getInstanceEx(project)).getContext();
- DebuggerSession debuggerSession = context.getDebuggerSession();
- final boolean isPaused = debuggerSession != null && debuggerSession.isPaused();
- final SuspendContextImpl suspendContext = context.getSuspendContext();
- final boolean hasCurrentThread = suspendContext != null && suspendContext.getThread() != null;
- return isPaused && hasCurrentThread;
- }
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JvmSmartStepIntoActionHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/JvmSmartStepIntoActionHandler.java
new file mode 100644
index 000000000000..512ab134c392
--- /dev/null
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/JvmSmartStepIntoActionHandler.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.actions;
+
+import com.intellij.debugger.DebuggerManagerEx;
+import com.intellij.debugger.SourcePosition;
+import com.intellij.debugger.engine.RequestHint;
+import com.intellij.debugger.engine.SuspendContextImpl;
+import com.intellij.debugger.impl.DebuggerContextImpl;
+import com.intellij.debugger.impl.DebuggerSession;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.TextEditor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.ui.popup.ListPopup;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.ui.awt.RelativePoint;
+import com.intellij.util.containers.OrderedSet;
+import com.intellij.util.text.CharArrayUtil;
+import com.intellij.xdebugger.impl.actions.DebuggerActionHandler;
+import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
+import gnu.trove.TObjectHashingStrategy;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.List;
+
+public class JvmSmartStepIntoActionHandler extends DebuggerActionHandler {
+ public void perform(@NotNull final Project project, final AnActionEvent event) {
+ final DebuggerContextImpl debuggerContext = (DebuggerManagerEx.getInstanceEx(project)).getContext();
+ doStep(project, debuggerContext.getSourcePosition(), debuggerContext.getDebuggerSession());
+ }
+
+ private static void doStep(final @NotNull Project project, final @Nullable SourcePosition position, final @NotNull DebuggerSession session) {
+ final VirtualFile file = position != null ? position.getFile().getVirtualFile() : null;
+ final FileEditor fileEditor = file != null? FileEditorManager.getInstance(project).getSelectedEditor(file) : null;
+ if (fileEditor instanceof TextEditor) {
+ for (JvmSmartStepIntoHandler handler : Extensions.getExtensions(JvmSmartStepIntoHandler.EP_NAME)) {
+ if (handler.isAvailable(position) && handler.doSmartStep(position, session, (TextEditor)fileEditor)) return;
+ }
+ }
+ session.stepInto(true, null);
+ }
+
+ public boolean isEnabled(@NotNull final Project project, final AnActionEvent event) {
+ final DebuggerContextImpl context = (DebuggerManagerEx.getInstanceEx(project)).getContext();
+ DebuggerSession debuggerSession = context.getDebuggerSession();
+ final boolean isPaused = debuggerSession != null && debuggerSession.isPaused();
+ final SuspendContextImpl suspendContext = context.getSuspendContext();
+ final boolean hasCurrentThread = suspendContext != null && suspendContext.getThread() != null;
+ return isPaused && hasCurrentThread;
+ }
+}
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JvmSmartStepIntoHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/JvmSmartStepIntoHandler.java
new file mode 100644
index 000000000000..d02029d7bf1b
--- /dev/null
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/JvmSmartStepIntoHandler.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2000-2011 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.debugger.actions;
+
+import com.intellij.debugger.SourcePosition;
+import com.intellij.debugger.engine.RequestHint;
+import com.intellij.debugger.impl.DebuggerSession;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.fileEditor.TextEditor;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.ui.popup.ListPopup;
+import com.intellij.psi.PsiMethod;
+import com.intellij.ui.awt.RelativePoint;
+import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * User: Alexander Podkhalyuzin
+ * Date: 22.11.11
+ */
+public abstract class JvmSmartStepIntoHandler {
+ public static ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.debugger.jvmSmartStepIntoHandler");
+
+ public abstract List findReferencedMethods(SourcePosition position);
+
+ public abstract boolean isAvailable(SourcePosition position);
+
+ /**
+ * Override this if you haven't PsiMethod, like in Kotlin.
+ * @param position
+ * @param session
+ * @param fileEditor
+ * @return false to continue for another handler or for default action (step into)
+ */
+ public boolean doSmartStep(SourcePosition position, final DebuggerSession session, TextEditor fileEditor) {
+ final List methods = findReferencedMethods(position);
+ if (methods.size() > 0) {
+ if (methods.size() == 1) {
+ session.stepInto(true, getSmartStepFilter(methods.get(0)));
+ }
+ else {
+ final PsiMethodListPopupStep popupStep = new PsiMethodListPopupStep(methods, new PsiMethodListPopupStep.OnChooseRunnable() {
+ public void execute(PsiMethod chosenMethod) {
+ session.stepInto(true, getSmartStepFilter(chosenMethod));
+ }
+ });
+ final ListPopup popup = JBPopupFactory.getInstance().createListPopup(popupStep);
+ final RelativePoint point = DebuggerUIUtil.calcPopupLocation(((TextEditor)fileEditor).getEditor(), position.getLine());
+ popup.show(point);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Override in case if your JVMNames slightly different then it can be provided by getJvmSignature method.
+ * @param method
+ * @return SmartStepFilter
+ */
+ protected RequestHint.SmartStepFilter getSmartStepFilter(PsiMethod method) {
+ return new RequestHint.SmartStepFilter(method);
+ }
+}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java
index 0a8eaa55aa8b..3408858cec81 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java
@@ -64,7 +64,7 @@ public class JavaDebuggerSupport extends DebuggerSupport {
private final QuickEvaluateActionHandler myQuickEvaluateHandler = new QuickEvaluateActionHandler();
private final JavaDebuggerSettingsPanelProvider myDebuggerSettingsPanelProvider = new JavaDebuggerSettingsPanelProvider();
private final MuteBreakpointsActionHandler myMuteBreakpointsHandler = new MuteBreakpointsActionHandler();
- private final DebuggerActionHandler mySmartStepIntoHandler = new SmartStepIntoActionHandler();
+ private final DebuggerActionHandler mySmartStepIntoHandler = new JvmSmartStepIntoActionHandler();
private final DebuggerActionHandler myAddToWatchedActionHandler = new AddToWatchActionHandler();
private JavaMarkObjectActionHandler myMarkObjectActionHandler = new JavaMarkObjectActionHandler();
diff --git a/java/idea-ui/src/com/intellij/ide/util/importProject/RootsDetectionStep.java b/java/idea-ui/src/com/intellij/ide/util/importProject/RootsDetectionStep.java
index 1d6607a87cc3..d4cbf69d3191 100644
--- a/java/idea-ui/src/com/intellij/ide/util/importProject/RootsDetectionStep.java
+++ b/java/idea-ui/src/com/intellij/ide/util/importProject/RootsDetectionStep.java
@@ -140,7 +140,7 @@ public class RootsDetectionStep extends AbstractStepWithProgress selectedTypes = new HashSet();
for (DetectedRootData rootData : myDetectedRootsChooser.getMarkedElements()) {
for (ProjectStructureDetector detector : rootData.getSelectedDetectors()) {
- selectedTypes.add(detector.getClass().getName());
+ selectedTypes.add(detector.getDetectorId());
}
}
mySequence.setTypes(selectedTypes);
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromSourcesMode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromSourcesMode.java
index a1feb143647f..f4571186789c 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromSourcesMode.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromSourcesMode.java
@@ -68,7 +68,7 @@ public abstract class CreateFromSourcesMode extends WizardMode {
sequence.addCommonStep(new RootsDetectionStep(projectBuilder, context, sequence, icon, "reference.dialogs.new.project.fromCode.source"));
for (ProjectStructureDetector detector : ProjectStructureDetector.EP_NAME.getExtensions()) {
for (ModuleWizardStep step : detector.createWizardSteps(projectBuilder, projectBuilder.getProjectDescriptor(detector), icon)) {
- sequence.addSpecificStep(detector.getClass().getName(), step);
+ sequence.addSpecificStep(detector.getDetectorId(), step);
}
}
diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/JavaSourceRootDetector.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/JavaSourceRootDetector.java
index 8ce1f9c299fc..86786fa45d8b 100644
--- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/JavaSourceRootDetector.java
+++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/JavaSourceRootDetector.java
@@ -52,6 +52,11 @@ public abstract class JavaSourceRootDetector extends ProjectStructureDetector {
return DirectoryProcessingResult.PROCESS_CHILDREN;
}
+ @Override
+ public String getDetectorId() {
+ return "Java";
+ }
+
@NotNull
protected abstract String getLanguageName();
diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/ProjectStructureDetector.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/ProjectStructureDetector.java
index 636c791a6bef..71b53b25c185 100644
--- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/ProjectStructureDetector.java
+++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/ProjectStructureDetector.java
@@ -68,6 +68,10 @@ public abstract class ProjectStructureDetector {
return Collections.emptyList();
}
+ public String getDetectorId() {
+ return getClass().getName();
+ }
+
/**
* Setup modules and libraries for the selected roots
*/
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java
index 17a1a42ccb02..2647a908975e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java
@@ -19,7 +19,8 @@ import com.intellij.codeInsight.AutoPopupController;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.ExpectedTypesProvider;
import com.intellij.codeInsight.lookup.LookupElement;
-import com.intellij.openapi.application.ex.ApplicationManagerEx;
+import com.intellij.diagnostic.LogMessageEx;
+import com.intellij.diagnostic.errordialog.Attachment;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -105,11 +106,8 @@ class JavaClassNameInsertHandler implements InsertHandler myRemotes;
+ private final Collection myBranchTrackInfos;
- private GitConfig(Collection remotes) {
+ private GitConfig(Collection remotes, @NotNull Collection branchTrackInfos) {
myRemotes = remotes;
+ myBranchTrackInfos = branchTrackInfos;
}
/**
@@ -75,10 +79,19 @@ class GitConfig {
*
* @return Git remotes defined in {@code .git/config}.
*/
+ @NotNull
Collection getRemotes() {
return myRemotes;
}
+ /**
+ * @return branch tracking information defined in {@code .git/config}.
+ */
+ @NotNull
+ public Collection getBranchTrackInfos() {
+ return myBranchTrackInfos;
+ }
+
/**
* Creates an instance of GitConfig by reading information from the specified {@code .git/config} file.
* @param configFile
@@ -102,6 +115,76 @@ class GitConfig {
IdeaPluginDescriptor plugin = PluginManager.getPlugin(PluginManager.getPluginByClassName(GitConfig.class.getName()));
ClassLoader classLoader = plugin == null ? null : plugin.getPluginClassLoader(); // null if IDEA is started from IDEA
+ Collection gitRemotes = parseRemotes(ini, classLoader);
+ Collection trackedInfos = parseTrackedInfos(ini, classLoader, gitRemotes);
+
+ return new GitConfig(gitRemotes, trackedInfos);
+ }
+
+ private static Collection parseTrackedInfos(Ini ini, ClassLoader classLoader, Collection remotes) {
+ Collection branchTrackInfos = new ArrayList();
+ for (Map.Entry stringSectionEntry : ini.entrySet()) {
+ String sectionName = stringSectionEntry.getKey();
+ Profile.Section section = stringSectionEntry.getValue();
+ if (sectionName.startsWith("branch")) {
+ BranchConfig branchConfig = parseBranchSection(sectionName, section, classLoader);
+ GitBranchTrackInfo branchTrackInfo = convertBranchConfig(branchConfig, remotes);
+ if (branchTrackInfo != null) {
+ branchTrackInfos.add(branchTrackInfo);
+ }
+ }
+ }
+ return branchTrackInfos;
+ }
+
+ @Nullable
+ private static GitBranchTrackInfo convertBranchConfig(@Nullable BranchConfig branchConfig, @NotNull Collection remotes) {
+ if (branchConfig == null) {
+ return null;
+ }
+ String branchName = branchConfig.getName();
+ String remoteName = branchConfig.getBean().getRemote();
+ String mergeName = branchConfig.getBean().getMerge();
+ String rebaseName = branchConfig.getBean().getRebase();
+
+ if (StringUtil.isEmptyOrSpaces(mergeName) && StringUtil.isEmptyOrSpaces(rebaseName)) {
+ LOG.info("No branch." + branchName + ".merge/rebase item in the .git/config");
+ return null;
+ }
+ if (StringUtil.isEmptyOrSpaces(remoteName)) {
+ LOG.info("No branch." + branchName + ".remote item in the .git/config");
+ return null;
+ }
+ boolean merge = mergeName != null;
+ String remoteBranch = (merge ? mergeName : rebaseName);
+
+ GitRemote branchRemote = null;
+ for (GitRemote remote : remotes) {
+ if (remote.getName().equals(remoteName)) {
+ branchRemote = remote;
+ break;
+ }
+ }
+ if (branchRemote == null) {
+ LOG.info("No remote found with name " + remoteName);
+ return null;
+ }
+
+ return new GitBranchTrackInfo(branchName, branchRemote, remoteBranch, merge);
+ }
+
+ @Nullable
+ private static BranchConfig parseBranchSection(String sectionName, Profile.Section section, ClassLoader classLoader) {
+ BranchBean branchBean = section.as(BranchBean.class, classLoader);
+ Matcher matcher = BRANCH_SECTION.matcher(sectionName);
+ if (matcher.matches()) {
+ return new BranchConfig(matcher.group(1), branchBean);
+ }
+ LOG.error(String.format("Invalid branch section format in .git/config. sectionName: %s section: %s", sectionName, section));
+ return null;
+ }
+
+ private static Collection parseRemotes(Ini ini, ClassLoader classLoader) {
Collection remotes = new ArrayList();
Collection urls = new ArrayList();
for (Map.Entry stringSectionEntry : ini.entrySet()) {
@@ -122,9 +205,7 @@ class GitConfig {
}
}
- Collection gitRemotes = makeGitRemotes(remotes, urls);
- return new GitConfig(gitRemotes);
-
+ return makeGitRemotes(remotes, urls);
}
// populate GitRemotes with substituting urls when needed
@@ -345,6 +426,30 @@ class GitConfig {
@Nullable String getInsteadOf();
@Nullable String getPushInsteadOf();
}
+
+ private static class BranchConfig {
+ private final String myName;
+ private final BranchBean myBean;
+
+ public BranchConfig(String name, BranchBean bean) {
+ myName = name;
+ myBean = bean;
+ }
+
+ public String getName() {
+ return myName;
+ }
+
+ public BranchBean getBean() {
+ return myBean;
+ }
+ }
+
+ private interface BranchBean {
+ @Nullable String getRemote();
+ @Nullable String getMerge();
+ @Nullable String getRebase();
+ }
@NotNull
private static String notNull(@Nullable String s) {
diff --git a/plugins/git4idea/testData/config/branch/b0_no/b0_config.txt b/plugins/git4idea/testData/config/branch/b0_no/b0_config.txt
new file mode 100644
index 000000000000..af107929f2da
--- /dev/null
+++ b/plugins/git4idea/testData/config/branch/b0_no/b0_config.txt
@@ -0,0 +1,6 @@
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+ ignorecase = true
diff --git a/plugins/git4idea/testData/config/branch/b0_no/b0_desc.txt b/plugins/git4idea/testData/config/branch/b0_no/b0_desc.txt
new file mode 100644
index 000000000000..da5842a6ef7b
--- /dev/null
+++ b/plugins/git4idea/testData/config/branch/b0_no/b0_desc.txt
@@ -0,0 +1 @@
+b0 No branches
\ No newline at end of file
diff --git a/plugins/git4idea/testData/config/r0_no/r0_result.txt b/plugins/git4idea/testData/config/branch/b0_no/b0_result.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r0_no/r0_result.txt
rename to plugins/git4idea/testData/config/branch/b0_no/b0_result.txt
diff --git a/plugins/git4idea/testData/config/branch/b1_no_remotes_or_no_merge/b1_config.txt b/plugins/git4idea/testData/config/branch/b1_no_remotes_or_no_merge/b1_config.txt
new file mode 100644
index 000000000000..8eee9225b5cc
--- /dev/null
+++ b/plugins/git4idea/testData/config/branch/b1_no_remotes_or_no_merge/b1_config.txt
@@ -0,0 +1,14 @@
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+ ignorecase = true
+[remote "origin"]
+ fetch = +refs/heads/*:refs/remotes/origin/*
+ url = /Users/loki/temp/parent.git
+[branch "unexistant_remote"]
+ remote = unexistant
+ merge = refs/heads/master
+[branch "no_merge_item"]
+ remote = origin
\ No newline at end of file
diff --git a/plugins/git4idea/testData/config/branch/b1_no_remotes_or_no_merge/b1_desc.txt b/plugins/git4idea/testData/config/branch/b1_no_remotes_or_no_merge/b1_desc.txt
new file mode 100644
index 000000000000..b607b5f18161
--- /dev/null
+++ b/plugins/git4idea/testData/config/branch/b1_no_remotes_or_no_merge/b1_desc.txt
@@ -0,0 +1,2 @@
+b1 No valid branches
+One with incorrect remote, other without merge/rebase item
\ No newline at end of file
diff --git a/plugins/git4idea/testData/config/branch/b1_no_remotes_or_no_merge/b1_result.txt b/plugins/git4idea/testData/config/branch/b1_no_remotes_or_no_merge/b1_result.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/plugins/git4idea/testData/config/branch/b2_one/b2_config.txt b/plugins/git4idea/testData/config/branch/b2_one/b2_config.txt
new file mode 100644
index 000000000000..59de1dea4b04
--- /dev/null
+++ b/plugins/git4idea/testData/config/branch/b2_one/b2_config.txt
@@ -0,0 +1,12 @@
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+ ignorecase = true
+[remote "origin"]
+ fetch = +refs/heads/*:refs/remotes/origin/*
+ url = git@git.labs.intellij.net:idea/community
+[branch "master"]
+ remote = origin
+ merge = refs/heads/master
diff --git a/plugins/git4idea/testData/config/branch/b2_one/b2_desc.txt b/plugins/git4idea/testData/config/branch/b2_one/b2_desc.txt
new file mode 100644
index 000000000000..cc57fd61e33a
--- /dev/null
+++ b/plugins/git4idea/testData/config/branch/b2_one/b2_desc.txt
@@ -0,0 +1 @@
+b2 One branch
\ No newline at end of file
diff --git a/plugins/git4idea/testData/config/branch/b2_one/b2_result.txt b/plugins/git4idea/testData/config/branch/b2_one/b2_result.txt
new file mode 100644
index 000000000000..77e04be9712f
--- /dev/null
+++ b/plugins/git4idea/testData/config/branch/b2_one/b2_result.txt
@@ -0,0 +1,6 @@
+BRANCH
+master
+origin git@git.labs.intellij.net:idea/community git@git.labs.intellij.net:idea/community +refs/heads/*:refs/remotes/origin/* +refs/heads/*:refs/remotes/origin/*
+refs/heads/master
+origin/master
+merge
\ No newline at end of file
diff --git a/plugins/git4idea/testData/config/branch/b3_two_and_rebase/b3_config.txt b/plugins/git4idea/testData/config/branch/b3_two_and_rebase/b3_config.txt
new file mode 100644
index 000000000000..8965d12d3c97
--- /dev/null
+++ b/plugins/git4idea/testData/config/branch/b3_two_and_rebase/b3_config.txt
@@ -0,0 +1,20 @@
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+ ignorecase = true
+
+[remote "origin"]
+ fetch = +refs/heads/*:refs/remotes/origin/*
+ url = git@git.labs.intellij.net:idea/community
+[remote "github"]
+ fetch = +refs/heads/*:refs/remotes/github/*
+ url = https://github.com/JetBrains/intellij-community.git
+
+[branch "master"]
+ remote = origin
+ merge = refs/heads/master
+[branch "github_feature"]
+ remote = github
+ rebase = refs/heads/feature
diff --git a/plugins/git4idea/testData/config/branch/b3_two_and_rebase/b3_desc.txt b/plugins/git4idea/testData/config/branch/b3_two_and_rebase/b3_desc.txt
new file mode 100644
index 000000000000..22bc285c51dd
--- /dev/null
+++ b/plugins/git4idea/testData/config/branch/b3_two_and_rebase/b3_desc.txt
@@ -0,0 +1,2 @@
+b3 Two different branches
+Two valid branches with 2 remotes. One merge, second rebase.
\ No newline at end of file
diff --git a/plugins/git4idea/testData/config/branch/b3_two_and_rebase/b3_result.txt b/plugins/git4idea/testData/config/branch/b3_two_and_rebase/b3_result.txt
new file mode 100644
index 000000000000..cb9e2f5463e5
--- /dev/null
+++ b/plugins/git4idea/testData/config/branch/b3_two_and_rebase/b3_result.txt
@@ -0,0 +1,12 @@
+BRANCH
+master
+origin git@git.labs.intellij.net:idea/community git@git.labs.intellij.net:idea/community +refs/heads/*:refs/remotes/origin/* +refs/heads/*:refs/remotes/origin/*
+refs/heads/master
+origin/master
+merge
+BRANCH
+github_feature
+github https://github.com/JetBrains/intellij-community.git https://github.com/JetBrains/intellij-community.git +refs/heads/*:refs/remotes/github/* +refs/heads/*:refs/remotes/github/*
+refs/heads/feature
+github/feature
+rebase
diff --git a/plugins/git4idea/testData/config/branch/b4_merge_and_rebase/b4_config.txt b/plugins/git4idea/testData/config/branch/b4_merge_and_rebase/b4_config.txt
new file mode 100644
index 000000000000..40b8c1998a68
--- /dev/null
+++ b/plugins/git4idea/testData/config/branch/b4_merge_and_rebase/b4_config.txt
@@ -0,0 +1,13 @@
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+ ignorecase = true
+[remote "origin"]
+ fetch = +refs/heads/*:refs/remotes/origin/*
+ url = git@git.labs.intellij.net:idea/community
+[branch "master"]
+ remote = origin
+ merge = refs/heads/master
+ rebase = refs/heads/master
diff --git a/plugins/git4idea/testData/config/branch/b4_merge_and_rebase/b4_desc.txt b/plugins/git4idea/testData/config/branch/b4_merge_and_rebase/b4_desc.txt
new file mode 100644
index 000000000000..a2029c60ff0c
--- /dev/null
+++ b/plugins/git4idea/testData/config/branch/b4_merge_and_rebase/b4_desc.txt
@@ -0,0 +1,2 @@
+b4 Branch with both merge and rebase
+Then only merge is taken into consideration.
\ No newline at end of file
diff --git a/plugins/git4idea/testData/config/branch/b4_merge_and_rebase/b4_result.txt b/plugins/git4idea/testData/config/branch/b4_merge_and_rebase/b4_result.txt
new file mode 100644
index 000000000000..77e04be9712f
--- /dev/null
+++ b/plugins/git4idea/testData/config/branch/b4_merge_and_rebase/b4_result.txt
@@ -0,0 +1,6 @@
+BRANCH
+master
+origin git@git.labs.intellij.net:idea/community git@git.labs.intellij.net:idea/community +refs/heads/*:refs/remotes/origin/* +refs/heads/*:refs/remotes/origin/*
+refs/heads/master
+origin/master
+merge
\ No newline at end of file
diff --git a/plugins/git4idea/testData/config/r0_no/r0_config.txt b/plugins/git4idea/testData/config/remote/r0_no/r0_config.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r0_no/r0_config.txt
rename to plugins/git4idea/testData/config/remote/r0_no/r0_config.txt
diff --git a/plugins/git4idea/testData/config/r0_no/r0_desc.txt b/plugins/git4idea/testData/config/remote/r0_no/r0_desc.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r0_no/r0_desc.txt
rename to plugins/git4idea/testData/config/remote/r0_no/r0_desc.txt
diff --git a/plugins/git4idea/testData/config/remote/r0_no/r0_result.txt b/plugins/git4idea/testData/config/remote/r0_no/r0_result.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/plugins/git4idea/testData/config/r1_one/r1_config.txt b/plugins/git4idea/testData/config/remote/r1_one/r1_config.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r1_one/r1_config.txt
rename to plugins/git4idea/testData/config/remote/r1_one/r1_config.txt
diff --git a/plugins/git4idea/testData/config/r1_one/r1_desc.txt b/plugins/git4idea/testData/config/remote/r1_one/r1_desc.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r1_one/r1_desc.txt
rename to plugins/git4idea/testData/config/remote/r1_one/r1_desc.txt
diff --git a/plugins/git4idea/testData/config/r1_one/r1_result.txt b/plugins/git4idea/testData/config/remote/r1_one/r1_result.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r1_one/r1_result.txt
rename to plugins/git4idea/testData/config/remote/r1_one/r1_result.txt
diff --git a/plugins/git4idea/testData/config/r2_two/r2_config.txt b/plugins/git4idea/testData/config/remote/r2_two/r2_config.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r2_two/r2_config.txt
rename to plugins/git4idea/testData/config/remote/r2_two/r2_config.txt
diff --git a/plugins/git4idea/testData/config/r2_two/r2_desc.txt b/plugins/git4idea/testData/config/remote/r2_two/r2_desc.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r2_two/r2_desc.txt
rename to plugins/git4idea/testData/config/remote/r2_two/r2_desc.txt
diff --git a/plugins/git4idea/testData/config/r2_two/r2_result.txt b/plugins/git4idea/testData/config/remote/r2_two/r2_result.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r2_two/r2_result.txt
rename to plugins/git4idea/testData/config/remote/r2_two/r2_result.txt
diff --git a/plugins/git4idea/testData/config/r3_pushurl/r3_config.txt b/plugins/git4idea/testData/config/remote/r3_pushurl/r3_config.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r3_pushurl/r3_config.txt
rename to plugins/git4idea/testData/config/remote/r3_pushurl/r3_config.txt
diff --git a/plugins/git4idea/testData/config/r3_pushurl/r3_desc.txt b/plugins/git4idea/testData/config/remote/r3_pushurl/r3_desc.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r3_pushurl/r3_desc.txt
rename to plugins/git4idea/testData/config/remote/r3_pushurl/r3_desc.txt
diff --git a/plugins/git4idea/testData/config/r3_pushurl/r3_result.txt b/plugins/git4idea/testData/config/remote/r3_pushurl/r3_result.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r3_pushurl/r3_result.txt
rename to plugins/git4idea/testData/config/remote/r3_pushurl/r3_result.txt
diff --git a/plugins/git4idea/testData/config/r4_insteadof/r4_config.txt b/plugins/git4idea/testData/config/remote/r4_insteadof/r4_config.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r4_insteadof/r4_config.txt
rename to plugins/git4idea/testData/config/remote/r4_insteadof/r4_config.txt
diff --git a/plugins/git4idea/testData/config/r4_insteadof/r4_desc.txt b/plugins/git4idea/testData/config/remote/r4_insteadof/r4_desc.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r4_insteadof/r4_desc.txt
rename to plugins/git4idea/testData/config/remote/r4_insteadof/r4_desc.txt
diff --git a/plugins/git4idea/testData/config/r4_insteadof/r4_result.txt b/plugins/git4idea/testData/config/remote/r4_insteadof/r4_result.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r4_insteadof/r4_result.txt
rename to plugins/git4idea/testData/config/remote/r4_insteadof/r4_result.txt
diff --git a/plugins/git4idea/testData/config/r5_pushinsteadof/r5_config.txt b/plugins/git4idea/testData/config/remote/r5_pushinsteadof/r5_config.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r5_pushinsteadof/r5_config.txt
rename to plugins/git4idea/testData/config/remote/r5_pushinsteadof/r5_config.txt
diff --git a/plugins/git4idea/testData/config/r5_pushinsteadof/r5_desc.txt b/plugins/git4idea/testData/config/remote/r5_pushinsteadof/r5_desc.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r5_pushinsteadof/r5_desc.txt
rename to plugins/git4idea/testData/config/remote/r5_pushinsteadof/r5_desc.txt
diff --git a/plugins/git4idea/testData/config/r5_pushinsteadof/r5_result.txt b/plugins/git4idea/testData/config/remote/r5_pushinsteadof/r5_result.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r5_pushinsteadof/r5_result.txt
rename to plugins/git4idea/testData/config/remote/r5_pushinsteadof/r5_result.txt
diff --git a/plugins/git4idea/testData/config/r6_two_urls/r6_config.txt b/plugins/git4idea/testData/config/remote/r6_two_urls/r6_config.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r6_two_urls/r6_config.txt
rename to plugins/git4idea/testData/config/remote/r6_two_urls/r6_config.txt
diff --git a/plugins/git4idea/testData/config/r6_two_urls/r6_desc.txt b/plugins/git4idea/testData/config/remote/r6_two_urls/r6_desc.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r6_two_urls/r6_desc.txt
rename to plugins/git4idea/testData/config/remote/r6_two_urls/r6_desc.txt
diff --git a/plugins/git4idea/testData/config/r6_two_urls/r6_result.txt b/plugins/git4idea/testData/config/remote/r6_two_urls/r6_result.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r6_two_urls/r6_result.txt
rename to plugins/git4idea/testData/config/remote/r6_two_urls/r6_result.txt
diff --git a/plugins/git4idea/testData/config/r7_empty_insteadof/r7_config.txt b/plugins/git4idea/testData/config/remote/r7_empty_insteadof/r7_config.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r7_empty_insteadof/r7_config.txt
rename to plugins/git4idea/testData/config/remote/r7_empty_insteadof/r7_config.txt
diff --git a/plugins/git4idea/testData/config/r7_empty_insteadof/r7_desc.txt b/plugins/git4idea/testData/config/remote/r7_empty_insteadof/r7_desc.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r7_empty_insteadof/r7_desc.txt
rename to plugins/git4idea/testData/config/remote/r7_empty_insteadof/r7_desc.txt
diff --git a/plugins/git4idea/testData/config/r7_empty_insteadof/r7_result.txt b/plugins/git4idea/testData/config/remote/r7_empty_insteadof/r7_result.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r7_empty_insteadof/r7_result.txt
rename to plugins/git4idea/testData/config/remote/r7_empty_insteadof/r7_result.txt
diff --git a/plugins/git4idea/testData/config/r8_insteadof_pushurl/r8_config.txt b/plugins/git4idea/testData/config/remote/r8_insteadof_pushurl/r8_config.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r8_insteadof_pushurl/r8_config.txt
rename to plugins/git4idea/testData/config/remote/r8_insteadof_pushurl/r8_config.txt
diff --git a/plugins/git4idea/testData/config/r8_insteadof_pushurl/r8_desc.txt b/plugins/git4idea/testData/config/remote/r8_insteadof_pushurl/r8_desc.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r8_insteadof_pushurl/r8_desc.txt
rename to plugins/git4idea/testData/config/remote/r8_insteadof_pushurl/r8_desc.txt
diff --git a/plugins/git4idea/testData/config/r8_insteadof_pushurl/r8_result.txt b/plugins/git4idea/testData/config/remote/r8_insteadof_pushurl/r8_result.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r8_insteadof_pushurl/r8_result.txt
rename to plugins/git4idea/testData/config/remote/r8_insteadof_pushurl/r8_result.txt
diff --git a/plugins/git4idea/testData/config/r9_one_capitalized/r9_config.txt b/plugins/git4idea/testData/config/remote/r9_one_capitalized/r9_config.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r9_one_capitalized/r9_config.txt
rename to plugins/git4idea/testData/config/remote/r9_one_capitalized/r9_config.txt
diff --git a/plugins/git4idea/testData/config/r9_one_capitalized/r9_desc.txt b/plugins/git4idea/testData/config/remote/r9_one_capitalized/r9_desc.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r9_one_capitalized/r9_desc.txt
rename to plugins/git4idea/testData/config/remote/r9_one_capitalized/r9_desc.txt
diff --git a/plugins/git4idea/testData/config/r9_one_capitalized/r9_result.txt b/plugins/git4idea/testData/config/remote/r9_one_capitalized/r9_result.txt
similarity index 100%
rename from plugins/git4idea/testData/config/r9_one_capitalized/r9_result.txt
rename to plugins/git4idea/testData/config/remote/r9_one_capitalized/r9_result.txt
diff --git a/plugins/git4idea/tests/git4idea/repo/GitConfigTest.java b/plugins/git4idea/tests/git4idea/repo/GitConfigTest.java
index fbbf060ee538..c8f53219667a 100644
--- a/plugins/git4idea/tests/git4idea/repo/GitConfigTest.java
+++ b/plugins/git4idea/tests/git4idea/repo/GitConfigTest.java
@@ -23,6 +23,7 @@ import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.io.File;
+import java.io.FilenameFilter;
import java.io.IOException;
import java.util.*;
@@ -33,11 +34,25 @@ import static org.testng.Assert.assertNotNull;
*/
public class GitConfigTest {
- @DataProvider(name = "provider")
- public Object[][] loadData() throws IOException {
+ @DataProvider(name = "remote")
+ public Object[][] loadRemotes() throws IOException {
+ return loadData("remote");
+ }
+
+ @DataProvider(name = "branch")
+ public Object[][] loadBranches() throws IOException {
+ return loadData("branch");
+ }
+
+ public static Object[][] loadData(String subfolder) throws IOException {
File pluginRoot = new File(PluginPathManager.getPluginHomePath("git4idea"));
- File dataDir = new File(new File(pluginRoot, "testData"), "config");
- File[] tests = dataDir.listFiles();
+ File dataDir = new File(new File(new File(pluginRoot, "testData"), "config"), subfolder);
+ File[] tests = dataDir.listFiles(new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return !name.startsWith(".");
+ }
+ });
Object[][] data = new Object[tests.length][];
for (int i = 0; i < tests.length; i++) {
File testDir = tests[i];
@@ -67,13 +82,44 @@ public class GitConfigTest {
return data;
}
- @Test(dataProvider = "provider")
- public void test(String testName, File configFile, File resultFile) throws IOException {
+ @Test(dataProvider = "remote")
+ public void testRemotes(String testName, File configFile, File resultFile) throws IOException {
GitConfig config = GitConfig.read(configFile);
- GitTestUtil.assertEqualCollections(config.getRemotes(), readResults(resultFile));
+ GitTestUtil.assertEqualCollections(config.getRemotes(), readRemoteResults(resultFile));
}
- private static Set readResults(File resultFile) throws IOException {
+ @Test(dataProvider = "branch")
+ public void testBranches(String testName, File configFile, File resultFile) throws IOException {
+ GitConfig config = GitConfig.read(configFile);
+ GitTestUtil.assertEqualCollections(config.getBranchTrackInfos(), readBranchResults(resultFile));
+ }
+
+ private static Collection readBranchResults(File file) throws IOException {
+ String content = FileUtil.loadFile(file);
+ Collection remotes = new ArrayList();
+ String[] remStrings = content.split("BRANCH\n");
+ for (String remString : remStrings) {
+ if (StringUtil.isEmptyOrSpaces(remString)) {
+ continue;
+ }
+ String[] info = remString.split("\n");
+ String branch = info[0];
+ GitRemote remote = getRemote(info[1]);
+ String remoteSpec = info[2];
+ String remoteBranchName = info[3];
+ boolean merge = info[4].equals("merge");
+ remotes.add(new GitBranchTrackInfo(branch, remote, remoteSpec, merge));
+ }
+ return remotes;
+ }
+
+ private static GitRemote getRemote(String remoteString) {
+ String[] remoteInfo = remoteString.split(" ");
+ return new GitRemote(getOrEmpty(remoteInfo, 0), Collections.singletonList(getOrEmpty(remoteInfo, 1)),
+ Collections.singletonList(getOrEmpty(remoteInfo, 2)), getOrEmpty(remoteInfo, 3), getOrEmpty(remoteInfo, 4));
+ }
+
+ private static Set readRemoteResults(File resultFile) throws IOException {
String content = FileUtil.loadFile(resultFile);
Set remotes = new HashSet();
String[] remStrings = content.split("REMOTE\n");
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovySourceRootDetector.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovySourceRootDetector.java
index 12d9045cce68..4d84be3be302 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovySourceRootDetector.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovySourceRootDetector.java
@@ -15,10 +15,17 @@
*/
package org.jetbrains.plugins.groovy;
-import com.intellij.ide.util.projectWizard.importSources.JavaSourceRootDetectionUtil;
import com.intellij.ide.util.projectWizard.importSources.JavaSourceRootDetector;
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.tree.IElementType;
import com.intellij.util.NullableFunction;
+import com.intellij.util.StringBuilderSpinAllocator;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.lang.lexer.GroovyLexer;
+import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
+import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
/**
* @author nik
@@ -41,9 +48,47 @@ public class GroovySourceRootDetector extends JavaSourceRootDetector {
return new NullableFunction() {
@Override
public String fun(CharSequence charSequence) {
- //todo[nik] implement groovy-specific package name parsing?
- return JavaSourceRootDetectionUtil.getPackageName(charSequence);
+ return getPackageName(charSequence);
}
};
}
+
+ @Nullable
+ public static String getPackageName(CharSequence text) {
+ Lexer lexer = new GroovyLexer();
+ lexer.start(text);
+ skipWhitespacesAndComments(lexer);
+ final IElementType firstToken = lexer.getTokenType();
+ if (firstToken != GroovyTokenTypes.kPACKAGE) {
+ return "";
+ }
+ lexer.advance();
+ skipWhitespacesAndComments(lexer);
+
+ final StringBuilder buffer = StringBuilderSpinAllocator.alloc();
+ try {
+ while(true){
+ if (lexer.getTokenType() != GroovyTokenTypes.mIDENT) break;
+ buffer.append(text, lexer.getTokenStart(), lexer.getTokenEnd());
+ lexer.advance();
+ skipWhitespacesAndComments(lexer);
+ if (lexer.getTokenType() != GroovyTokenTypes.mDOT) break;
+ buffer.append('.');
+ lexer.advance();
+ skipWhitespacesAndComments(lexer);
+ }
+ String packageName = buffer.toString();
+ if (packageName.length() == 0 || StringUtil.endsWithChar(packageName, '.')) return null;
+ return packageName;
+ }
+ finally {
+ StringBuilderSpinAllocator.dispose(buffer);
+ }
+ }
+
+ private static void skipWhitespacesAndComments(Lexer lexer) {
+ while(TokenSets.ALL_COMMENT_TOKENS.contains(lexer.getTokenType()) || TokenSets.WHITE_SPACES_SET.contains(lexer.getTokenType())) {
+ lexer.advance();
+ }
+ }
}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/ide/GroovySourceRootDetectorTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/ide/GroovySourceRootDetectorTest.groovy
new file mode 100644
index 000000000000..4ff5a90bfc35
--- /dev/null
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/ide/GroovySourceRootDetectorTest.groovy
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2011 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 org.jetbrains.plugins.groovy.ide
+
+import junit.framework.TestCase
+import org.jetbrains.plugins.groovy.GroovySourceRootDetector
+
+/**
+ * @author nik
+ */
+class GroovySourceRootDetectorTest extends TestCase {
+ public void testEmpty() {
+ doTest("", "")
+ }
+
+ public void testComment() {
+ doTest("//comment", "")
+ doTest(" /* comment */", "")
+ }
+
+ public void testStatement() {
+ doTest("def a = 0;", "")
+ }
+
+ public void testSimplePackage() {
+ doTest("package simple", "simple")
+ doTest("package simple;", "simple")
+ doTest("""//comment
+ package simple;""", "simple")
+ }
+
+ public void testComplexPackage() {
+ doTest("package com.simple", "com.simple")
+ doTest("package com.simple;", "com.simple")
+ doTest("""
+ package com.simple;""", "com.simple")
+ doTest("""/**
+ @author nik;
+ */
+ package com.simple;""", "com.simple")
+ }
+
+
+ def doTest(String text, String expectedPackageName) {
+ assertEquals(expectedPackageName, GroovySourceRootDetector.getPackageName(text))
+ }
+}
diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml
index 9853b3fe4eb9..35a81ac95aa2 100644
--- a/resources/src/META-INF/IdeaPlugin.xml
+++ b/resources/src/META-INF/IdeaPlugin.xml
@@ -89,6 +89,8 @@
+
@@ -1160,6 +1162,7 @@
+