Merge remote-tracking branch 'origin/master'

This commit is contained in:
Maxim.Medvedev
2012-03-15 17:23:05 +04:00
45 changed files with 467 additions and 309 deletions
@@ -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;
}
}
@@ -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);
@@ -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;
}
}
@@ -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;
}
}
@@ -1325,5 +1325,6 @@ public class ListUtils {
}
public void testListArrayListCast() { doTest('\n') }
public void testInterfaceImplementationNoCast() { doTest() }
}
@@ -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);
}
@@ -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;
}
}
}
@@ -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"/>
@@ -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
*
+1 -3
View File
@@ -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
+1
View File
@@ -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"/>
@@ -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,
@@ -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() {
@@ -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) {
@@ -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 {
@@ -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;
@@ -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();
@@ -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);
}
}
}
@@ -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"));
@@ -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="&amp;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 &amp;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="&amp;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();