Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2011-12-05 18:40:43 +01:00
27 changed files with 422 additions and 110 deletions
@@ -110,7 +110,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
ButtonGroup group = new ButtonGroup();
group.add(myRbAllThatOverride);
group.add(myRbFromList);
myToStringFilterEditor = new ClassFilterEditor(myProject);
myToStringFilterEditor = new ClassFilterEditor(myProject, null, "reference.viewBreakpoints.classFilters.newPattern");
myCbEnableToString.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
final boolean enabled = myCbEnableToString.isSelected();
@@ -110,7 +110,7 @@ public class DebuggerSteppingConfigurable implements SearchableConfigurable, Con
panel.add(myCbSkipSimpleGetters, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0),0, 0));
panel.add(myCbStepInfoFiltersEnabled, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(8, 0, 0, 0),0, 0));
mySteppingFilterEditor = new ClassFilterEditor(myProject);
mySteppingFilterEditor = new ClassFilterEditor(myProject, null, "reference.viewBreakpoints.classFilters.newPattern");
panel.add(mySteppingFilterEditor, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 5, 0, 0),0, 0));
myCbStepInfoFiltersEnabled.addActionListener(new ActionListener() {
@@ -20,12 +20,12 @@
*/
package com.intellij.debugger.ui.breakpoints;
import com.intellij.ide.util.ClassFilter;
import com.intellij.ui.classFilter.ClassFilterEditor;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.ide.util.ClassFilter;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.classFilter.ClassFilterEditor;
import javax.swing.*;
import java.awt.*;
@@ -54,13 +54,13 @@ public class EditClassFiltersDialog extends DialogWrapper {
Box mainPanel = Box.createHorizontalBox();
myClassFilterEditor = new ClassFilterEditor(myProject, myChooserFilter);
myClassFilterEditor = new ClassFilterEditor(myProject, myChooserFilter, "reference.viewBreakpoints.classFilters.newPattern");
myClassFilterEditor.setPreferredSize(new Dimension(400, 200));
myClassFilterEditor.setBorder(IdeBorderFactory.createTitledBorder(
DebuggerBundle.message("class.filters.dialog.inclusion.filters.group"), false, false, true));
mainPanel.add(myClassFilterEditor);
myClassExclusionFilterEditor = new ClassFilterEditor(myProject, myChooserFilter);
myClassExclusionFilterEditor = new ClassFilterEditor(myProject, myChooserFilter, "reference.viewBreakpoints.classFilters.newPattern");
myClassExclusionFilterEditor.setPreferredSize(new Dimension(400, 200));
myClassExclusionFilterEditor.setBorder(IdeBorderFactory.createTitledBorder(
DebuggerBundle.message("class.filters.dialog.exclusion.filters.group"), false, false, true));
@@ -92,4 +92,8 @@ public class EditClassFiltersDialog extends DialogWrapper {
public com.intellij.ui.classFilter.ClassFilter[] getExclusionFilters() {
return myClassExclusionFilterEditor.getFilters();
}
protected String getHelpId() {
return "reference.viewBreakpoints.classFilters";
}
}
@@ -59,13 +59,20 @@ public class ClassFilterEditor extends JPanel implements ComponentWithEmptyText
private final JButton myRemoveButton;
protected final Project myProject;
private final ClassFilter myChooserFilter;
@Nullable
private final String myPatternsHelpId;
public ClassFilterEditor(Project project) {
this (project, null);
}
public ClassFilterEditor(Project project, com.intellij.ide.util.ClassFilter classFilter) {
public ClassFilterEditor(Project project, ClassFilter classFilter) {
this (project, classFilter, null);
}
public ClassFilterEditor(Project project, ClassFilter classFilter, @Nullable String patternsHelpId) {
super(new GridBagLayout());
myPatternsHelpId = patternsHelpId;
myAddClassButton = new JButton(getAddButtonText());
myAddPatternButton = new JButton(getAddPatternButtonText());
myRemoveButton = new JButton(UIBundle.message("button.remove"));
@@ -302,7 +309,7 @@ public class ClassFilterEditor extends JPanel implements ComponentWithEmptyText
}
protected void addPatternFilter() {
ClassFilterEditorAddDialog dialog = new ClassFilterEditorAddDialog(myProject);
ClassFilterEditorAddDialog dialog = new ClassFilterEditorAddDialog(myProject, myPatternsHelpId);
dialog.show();
if (dialog.isOK()) {
String pattern = dialog.getPattern();
@@ -30,6 +30,7 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.ui.UIBundle;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -39,10 +40,13 @@ import java.awt.event.ActionListener;
class ClassFilterEditorAddDialog extends DialogWrapper {
private final Project myProject;
private TextFieldWithBrowseButton myClassName;
@Nullable
private final String myHelpId;
public ClassFilterEditorAddDialog(Project project) {
public ClassFilterEditorAddDialog(Project project, @Nullable String helpId) {
super(project, true);
myProject = project;
myHelpId = helpId;
setTitle(UIBundle.message("class.filter.editor.add.dialog.title"));
init();
}
@@ -104,4 +108,9 @@ class ClassFilterEditorAddDialog extends DialogWrapper {
protected String getDimensionServiceKey(){
return "#com.intellij.debugger.ui.breakpoints.BreakpointsConfigurationDialogFactory.BreakpointsConfigurationDialog.AddFieldBreakpointDialog";
}
@Override @Nullable
protected String getHelpId() {
return myHelpId;
}
}
@@ -526,9 +526,12 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
@NotNull
private DocumentEvent doBeforeChangedUpdate(int offset, CharSequence oldString, CharSequence newString, boolean wholeTextReplaced) {
VirtualFile file = FileDocumentManager.getInstance().getFile(this);
if (file != null && !file.isValid()) {
LOG.error("File of this document has been deleted.");
FileDocumentManager manager = FileDocumentManager.getInstance();
if (manager != null) {
VirtualFile file = manager.getFile(this);
if (file != null && !file.isValid()) {
LOG.error("File of this document has been deleted.");
}
}
DocumentEvent event = new DocumentEventImpl(this, offset, oldString, newString, myModificationStamp, wholeTextReplaced);
@@ -25,6 +25,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class StructureViewModuleNode extends AbstractModuleNode {
@@ -34,15 +35,20 @@ public class StructureViewModuleNode extends AbstractModuleNode {
@NotNull
public Collection<AbstractTreeNode> getChildren() {
final Module module = getValue();
if (module == null) {
// just deleted a module from project view
return Collections.emptyList();
}
final List<AbstractTreeNode> children = new ArrayList<AbstractTreeNode>(2);
children.add(new LibraryGroupNode(getProject(), new LibraryGroupElement(getValue()), getSettings()) {
children.add(new LibraryGroupNode(getProject(), new LibraryGroupElement(module), getSettings()) {
@Override
public boolean isAlwaysExpand() {
return true;
}
});
children.add(new ModuleListNode(getProject(), getValue(), getSettings()));
children.add(new ModuleListNode(getProject(), module, getSettings()));
return children;
}
@@ -23,6 +23,7 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.IndexPattern;
import com.intellij.psi.search.IndexPatternProvider;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
@@ -40,6 +41,12 @@ public interface CacheManager {
boolean processFilesWithWord(@NotNull Processor<PsiFile> processor,@NotNull String word, short occurenceMask, @NotNull GlobalSearchScope scope, final boolean caseSensitively);
// IMPORTANT!!!
// Do not call indices directly or indirectly from 'process' method, deadlocks are possible (IDEADEV-42137).
public void collectVirtualFilesWithWord(@NotNull final CommonProcessors.CollectProcessor<VirtualFile> fileProcessor,
@NotNull final String word, final short occurrenceMask,
@NotNull final GlobalSearchScope scope, final boolean caseSensitively);
/**
* @return all VirtualFile's that contain todo-items under project roots
*/
@@ -45,9 +45,7 @@ import com.intellij.util.indexing.FileBasedIndex;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.*;
/**
* @author Eugene Zhuravlev
@@ -78,44 +76,52 @@ public class IndexCacheManagerImpl implements CacheManager{
return (scope.isSearchOutsideRootModel() || index.isInContent(virtualFile) || index.isInLibrarySource(virtualFile)) && !virtualFile.getFileType().isBinary();
}
// IMPORTANT!!!
// Since implementation of virtualFileProcessor.process() may call indices directly or indirectly,
// we cannot call it inside FileBasedIndex.processValues() method except in collecting form
// If we do, deadlocks are possible (IDEADEV-42137). Process the files without not holding indices' read lock.
@Override
public boolean processFilesWithWord(@NotNull final Processor<PsiFile> psiFileProcessor, @NotNull final String word, final short occurrenceMask, @NotNull final GlobalSearchScope scope, final boolean caseSensitively) {
public void collectVirtualFilesWithWord(@NotNull final CommonProcessors.CollectProcessor<VirtualFile> fileProcessor,
@NotNull final String word, final short occurrenceMask,
@NotNull final GlobalSearchScope scope, final boolean caseSensitively) {
if (myProject.isDefault()) {
return true;
return;
}
final Set<VirtualFile> vFiles = new THashSet<VirtualFile>();
final GlobalSearchScope projectScope = GlobalSearchScope.allScope(myProject).union(scope);
try {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
FileBasedIndex.getInstance().processValues(IdIndex.NAME, new IdIndexEntry(word, caseSensitively), null, new FileBasedIndex.ValueProcessor<Integer>() {
final FileIndexFacade index = FileIndexFacade.getInstance(myProject);
@Override
public boolean process(final VirtualFile file, final Integer value) {
ProgressManager.checkCanceled();
final int mask = value.intValue();
if ((mask & occurrenceMask) != 0) {
vFiles.add(file);
if ((mask & occurrenceMask) != 0 && scope.contains(file) && shouldBeFound(scope, file, index)) {
if (!fileProcessor.process(file)) return false;
}
return true;
}
}, projectScope);
}, GlobalSearchScope.allScope(myProject).union(scope));
}
});
}
catch (IndexNotReadyException e) {
throw new ProcessCanceledException();
}
}
@Override
public boolean processFilesWithWord(@NotNull final Processor<PsiFile> psiFileProcessor, @NotNull final String word, final short occurrenceMask, @NotNull final GlobalSearchScope scope, final boolean caseSensitively) {
final List<VirtualFile> vFiles = new ArrayList<VirtualFile>(5);
collectVirtualFilesWithWord(new CommonProcessors.CollectProcessor<VirtualFile>(vFiles), word, occurrenceMask, scope, caseSensitively);
if (vFiles.isEmpty()) return true;
final FileIndexFacade index = FileIndexFacade.getInstance(myProject);
final Processor<VirtualFile> virtualFileProcessor = new ReadActionProcessor<VirtualFile>() {
@Override
public boolean processInReadAction(VirtualFile virtualFile) {
LOG.assertTrue(virtualFile.isValid());
if (virtualFile.isValid() && scope.contains(virtualFile) && shouldBeFound(scope, virtualFile, index)) {
if (virtualFile.isValid()) {
final PsiFile psiFile = myPsiManager.findFile(virtualFile);
return psiFile == null || psiFileProcessor.process(psiFile);
}
@@ -21,6 +21,7 @@ import com.intellij.concurrency.JobUtil;
import com.intellij.ide.todo.TodoIndexPatternProvider;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.application.ReadActionProcessor;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
@@ -346,13 +347,14 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
myManager.startBatchFilesProcessingMode();
try {
final List<VirtualFile> result = new ArrayList<VirtualFile>();
boolean success = processFilesWithText(scope, searchContext, caseSensitively, text, new Processor<PsiFile>() {
@Override
public boolean process(PsiFile file) {
result.add(file.getViewProvider().getVirtualFile());
return true;
}
}, progress);
boolean success = processFilesWithText(
scope,
searchContext,
caseSensitively,
text,
new CommonProcessors.CollectProcessor<VirtualFile>(result),
progress
);
LOG.assertTrue(success);
return result;
}
@@ -365,7 +367,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
final short searchContext,
final boolean caseSensitively,
@NotNull String text,
@NotNull final Processor<PsiFile> processor,
@NotNull final Processor<VirtualFile> processor,
@Nullable ProgressIndicator progress) {
List<String> words = StringUtil.getWordsIn(text);
if (words.isEmpty()) return true;
@@ -375,10 +377,12 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
return o2.length() - o1.length();
}
});
final Set<PsiFile> fileSet;
final Set<VirtualFile> fileSet;
CacheManager cacheManager = CacheManager.SERVICE.getInstance(myManager.getProject());
if (words.size() > 1) {
fileSet = new THashSet<PsiFile>();
Set<PsiFile> copy = new THashSet<PsiFile>();
fileSet = new THashSet<VirtualFile>();
Set<VirtualFile> copy = new THashSet<VirtualFile>();
for (int i = 0; i < words.size() - 1; i++) {
if (progress != null) {
progress.checkCanceled();
@@ -387,11 +391,14 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
ProgressManager.checkCanceled();
}
final String word = words.get(i);
CacheManager.SERVICE.getInstance(myManager.getProject()).processFilesWithWord(new CommonProcessors.CollectProcessor<PsiFile>(copy), word, searchContext, scope, caseSensitively);
if (i == 0) {
fileSet.addAll(copy);
}
else {
final int finalI = i;
cacheManager.collectVirtualFilesWithWord(new CommonProcessors.CollectProcessor<VirtualFile>(i != 0 ? copy:fileSet) {
@Override
protected boolean accept(VirtualFile virtualFile) {
return finalI == 0 || fileSet.contains(virtualFile);
}
}, word, searchContext, scope, caseSensitively);
if (i != 0) {
fileSet.retainAll(copy);
}
copy.clear();
@@ -402,15 +409,37 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
else {
fileSet = null;
}
return CacheManager.SERVICE.getInstance(myManager.getProject()).processFilesWithWord(new Processor<PsiFile>() {
@Override
public boolean process(PsiFile psiFile) {
if (fileSet != null && !fileSet.contains(psiFile)) {
final String lastWord = words.get(words.size() - 1);
if (processor instanceof CommonProcessors.CollectProcessor) {
final CommonProcessors.CollectProcessor collectProcessor = (CommonProcessors.CollectProcessor)processor;
cacheManager.collectVirtualFilesWithWord(new CommonProcessors.CollectProcessor<VirtualFile>(collectProcessor.getResults()) {
@Override
public boolean process(VirtualFile virtualFile) {
if (fileSet == null || fileSet.contains(virtualFile)) return collectProcessor.process(virtualFile);
return true;
}
return processor.process(psiFile);
}, lastWord, searchContext, scope, caseSensitively);
return true;
} else {
THashSet<VirtualFile> files = new THashSet<VirtualFile>();
cacheManager.collectVirtualFilesWithWord(new CommonProcessors.CollectProcessor<VirtualFile>(files) {
@Override
protected boolean accept(VirtualFile virtualFile) {
return fileSet == null || fileSet.contains(virtualFile);
}
}, lastWord, searchContext, scope, caseSensitively);
ReadActionProcessor<VirtualFile> readActionProcessor = new ReadActionProcessor<VirtualFile>() {
@Override
public boolean processInReadAction(VirtualFile virtualFile) {
return processor.process(virtualFile);
}
};
for(VirtualFile file:files) {
if (!readActionProcessor.process(file)) return false;
}
}, words.get(words.size() - 1), searchContext, scope, caseSensitively);
return true;
}
}
@Override
@@ -828,22 +857,21 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
@NotNull GlobalSearchScope scope,
@Nullable final PsiFile fileToIgnoreOccurencesIn,
@Nullable ProgressIndicator progress) {
final int[] count = {0};
if (!processFilesWithText(scope, UsageSearchContext.ANY, true, name, new Processor<PsiFile>() {
final AtomicInteger count = new AtomicInteger();
if (!processFilesWithText(scope, UsageSearchContext.ANY, true, name, new CommonProcessors.CollectProcessor<VirtualFile> (Collections.<VirtualFile>emptyList()) {
private final VirtualFile fileToIgnoreOccurencesInVirtualFile =
fileToIgnoreOccurencesIn != null ? fileToIgnoreOccurencesIn.getVirtualFile():null;
@Override
public boolean process(PsiFile file) {
if (file == fileToIgnoreOccurencesIn) return true;
synchronized (count) {
count[0]++;
return count[0] <= 10;
}
public boolean process(VirtualFile file) {
if (file == fileToIgnoreOccurencesInVirtualFile) return true;
int value = count.incrementAndGet();
return value < 10;
}
}, progress)) {
return SearchCostResult.TOO_MANY_OCCURRENCES;
}
synchronized (count) {
return count[0] == 0 ? SearchCostResult.ZERO_OCCURRENCES : SearchCostResult.FEW_OCCURRENCES;
}
return count.get() == 0 ? SearchCostResult.ZERO_OCCURRENCES : SearchCostResult.FEW_OCCURRENCES;
}
}
@@ -551,7 +551,7 @@ public class FileReference implements FileReferenceOwner, PsiPolyVariantReferenc
public String getUnresolvedMessagePattern() {
return LangBundle.message("error.cannot.resolve")
+ " " + (isLast() ? LangBundle.message("terms.file") : LangBundle.message("terms.directory"))
+ " ''" + decode(getCanonicalText()) + "''";
+ " ''" + StringUtil.escapePattern(decode(getCanonicalText())) + "''";
}
public final boolean isLast() {
@@ -243,8 +243,13 @@ public class NotificationsManagerImpl extends NotificationsManager implements No
}
}
@Nullable
public static Window findWindowForBalloon(Project project) {
return WindowManager.getInstance().getFrame(project);
final JFrame frame = WindowManager.getInstance().getFrame(project);
if (frame == null && project == null) {
return KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
}
return frame;
}
public static Balloon createBalloon(final Notification notification, final boolean showCallout, final boolean hideOnClickOutside, final boolean fadeOut) {
@@ -419,7 +419,7 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
LOG.error(t);
}
finally {
ReflectionUtil.resetThreadLocals();
//ReflectionUtil.resetThreadLocals();
Thread.interrupted(); // reset interrupted status
}
}
@@ -440,7 +440,7 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
LOG.error(t);
}
finally {
ReflectionUtil.resetThreadLocals();
//ReflectionUtil.resetThreadLocals();
Thread.interrupted(); // reset interrupted status
}
return null;
@@ -53,6 +53,7 @@ import com.intellij.openapi.editor.impl.softwrap.SoftWrapHelper;
import com.intellij.openapi.editor.markup.*;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
import com.intellij.openapi.fileEditor.impl.EditorsSplitters;
import com.intellij.openapi.options.FontSize;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
@@ -65,6 +66,7 @@ import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.IdeGlassPane;
import com.intellij.ui.GuiUtils;
import com.intellij.ui.LightweightHint;
import com.intellij.ui.SideBorder;
import com.intellij.ui.components.JBScrollBar;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.util.Alarm;
@@ -6119,6 +6121,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
@Override
public void setupCorners() {
super.setupCorners();
setBorder(new TablessBorder());
setCorner(getVerticalScrollbarOrientation() == EditorEx.VERTICAL_SCROLLBAR_LEFT ?
LOWER_RIGHT_CORNER :
LOWER_LEFT_CORNER, new JPanel() {
@@ -6146,6 +6151,38 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
});
}
}
private static class TablessBorder extends SideBorder {
private TablessBorder() {
super(UIUtil.getBorderColor(), SideBorder.ALL);
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
if (c instanceof JComponent) {
Insets insets = ((JComponent)c).getInsets();
if (insets.left > 0) {
super.paintBorder(c, g, x, y, width, height);
} else {
g.setColor(UIUtil.getPanelBackground());
g.drawLine(x, y, x + width, y);
g.setColor(new Color(0, 0, 0, 90));
g.drawLine(x, y, x + width, y);
}
}
}
@Override
public Insets getBorderInsets(Component c) {
Container splitters = SwingUtilities.getAncestorOfClass(EditorsSplitters.class, c);
return splitters == null ? super.getBorderInsets(c) : new Insets(1, 0, 0, 0);
}
@Override
public boolean isBorderOpaque() {
return true;
}
}
private class MyHeaderPanel extends JPanel {
private int myOldHeight = 0;
@@ -560,10 +560,14 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
}
public void setSize(int width, int height) {
Point location = getLocation();
_setSizeForLocation(width, height, null);
}
private void _setSizeForLocation(int width, int height, @Nullable Point initial) {
Point location = initial != null ? initial : getLocation();
Rectangle rect = new Rectangle(location.x, location.y, width, height);
ScreenUtil.fitToScreen(rect);
if (location.x != rect.x || location.y != rect.y) {
if (initial != null || location.x != rect.x || location.y != rect.y) {
setLocation(rect.x, rect.y);
}
@@ -609,7 +613,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
Dimension size = DimensionService.getInstance().getSize(myDimensionServiceKey, projectGuess);
if (size != null) {
myInitialSize = (Dimension)size.clone();
setSize(myInitialSize);
_setSizeForLocation(myInitialSize.width, myInitialSize.height, location);
}
}
@@ -54,6 +54,11 @@ public class StringUtil {
}
};
@NotNull
public static String escapePattern(final @NotNull String text) {
return text.replace("'", "''").replace("{", "'{'");
}
public static <T> Function<T, String> createToStringFunction(Class<T> cls) {
return new Function<T, String>() {
@Override
@@ -37,7 +37,7 @@ public abstract class AndroidOutputReceiver extends MultiLineReceiver {
public void processNewLines(String[] lines) {
if (!myTryAgain) {
for (String line : lines) {
line = decodeIso8859_1(line);
//line = decodeIso8859_1(line);
processNewLine(line);
if (line.indexOf(BAD_ACCESS_ERROR) >= 0) {
myTryAgain = true;
@@ -42,7 +42,7 @@ public class UpdateXmlCopyrightsProvider extends UpdateCopyrightsProvider {
return createDefaultOptions(false);
}
private static class UpdateXmlFileCopyright extends UpdatePsiFileCopyright
public static class UpdateXmlFileCopyright extends UpdatePsiFileCopyright
{
public UpdateXmlFileCopyright(Project project, Module module, VirtualFile root, CopyrightProfile options)
{
@@ -42,7 +42,9 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.net.ProxySelector;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
@@ -91,6 +93,10 @@ public final class GitHttpAdapter {
logException(repository, remote.getName(), remoteUrl, e, "fetching");
return GitFetchResult.error(e);
}
catch (URISyntaxException e) {
logException(repository, remote.getName(), remoteUrl, e, "fetching");
return GitFetchResult.error(e);
}
return new GitFetchResult(resultType);
}
@@ -117,11 +123,11 @@ public final class GitHttpAdapter {
}
@NotNull
public static GitSimplePushResult push(@NotNull final GitRepository repository, @NotNull final GitRemote remote, @NotNull final String remoteUrl) {
public static GitSimplePushResult push(@NotNull final GitRepository repository, @NotNull final GitRemote remote, @NotNull final String remoteUrl, @NotNull String pushSpec) {
try {
final Git git = convertToGit(repository);
final GitHttpCredentialsProvider provider = new GitHttpCredentialsProvider(repository.getProject(), remoteUrl);
GitHttpRemoteCommand.Push pushCommand = new GitHttpRemoteCommand.Push(git, provider, remoteUrl, convertRefSpecs(remote.getPushRefSpecs()));
GitHttpRemoteCommand.Push pushCommand = new GitHttpRemoteCommand.Push(git, provider, remote.getName(), remoteUrl, convertRefSpecs(Collections.singletonList(pushSpec)));
GeneralResult result = callWithAuthRetry(pushCommand);
GitSimplePushResult pushResult = pushCommand.getResult();
if (pushResult == null) {
@@ -144,6 +150,10 @@ public final class GitHttpAdapter {
logException(repository, remote.getName(), remoteUrl, e, "pushing");
return makeErrorResultFromException(e);
}
catch (URISyntaxException e) {
logException(repository, remote.getName(), remoteUrl, e, "pushing");
return makeErrorResultFromException(e);
}
}
@NotNull
@@ -162,6 +172,10 @@ public final class GitHttpAdapter {
LOG.info("Exception while cloning " + url + " to " + directory, e);
return GitFetchResult.error(e);
}
catch (URISyntaxException e) {
LOG.info("Exception while cloning " + url + " to " + directory, e);
return GitFetchResult.error(e);
}
return new GitFetchResult(resultType);
}
@@ -191,7 +205,7 @@ public final class GitHttpAdapter {
* If user enters incorrect data, he has 2 more attempts to go before failure.
* Cleanups are executed after each incorrect attempt to enter password, and after other retriable actions.
*/
private static GeneralResult callWithAuthRetry(@NotNull GitHttpRemoteCommand command) throws InvalidRemoteException, IOException {
private static GeneralResult callWithAuthRetry(@NotNull GitHttpRemoteCommand command) throws InvalidRemoteException, IOException, URISyntaxException {
ProxySelector defaultProxySelector = ProxySelector.getDefault();
if (GitHttpProxySupport.shouldUseProxy()) {
ProxySelector.setDefault(GitHttpProxySupport.newProxySelector());
@@ -17,18 +17,27 @@ package git4idea.jgit;
import com.intellij.openapi.util.io.FileUtil;
import git4idea.push.GitSimplePushResult;
import org.eclipse.jgit.JGitText;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.FetchCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.PushCommand;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.transport.PushResult;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.RemoteRefUpdate;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.errors.NotSupportedException;
import org.eclipse.jgit.errors.TransportException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -40,7 +49,7 @@ interface GitHttpRemoteCommand {
String getUrl();
void setUrl(String url);
void run() throws InvalidRemoteException;
void run() throws InvalidRemoteException, URISyntaxException;
void cleanup();
GitHttpCredentialsProvider getCredentialsProvider();
@@ -136,25 +145,44 @@ interface GitHttpRemoteCommand {
private final Git myGit;
private final GitHttpCredentialsProvider myCredentialsProvider;
private GitSimplePushResult myPushResult;
private String myRemoteName;
private String myUrl;
private final List<RefSpec> myRefSpecs;
private final List<RefSpec> myPushSpecs;
Push(@NotNull Git git, @NotNull GitHttpCredentialsProvider credentialsProvider, String url, List<RefSpec> refSpecs) {
Push(@NotNull Git git, @NotNull GitHttpCredentialsProvider credentialsProvider, @NotNull String remoteName, @NotNull String url, @NotNull List<RefSpec> pushSpecs) {
myGit = git;
myCredentialsProvider = credentialsProvider;
myRemoteName = remoteName;
myUrl = url;
myRefSpecs = refSpecs;
myPushSpecs = pushSpecs;
}
@Override
public void run() throws InvalidRemoteException {
public void run() throws InvalidRemoteException, URISyntaxException {
PushCommand pushCommand = myGit.push();
if (myUrl != null) {
pushCommand.setRemote(myUrl);
pushCommand.setRefSpecs(myRefSpecs);
}
pushCommand.setRemote(myRemoteName);
pushCommand.setRefSpecs(myPushSpecs);
pushCommand.setCredentialsProvider(myCredentialsProvider);
Iterable<PushResult> results = pushCommand.call();
/*
Need to push to remote NAME (to let push update the remote reference), but to probably another URL.
So constructing RemoteConfig based on the original config for the remote, but with other url.
No need in fetch urls => just removing them.
Remove all push urls (we don't support pushing to multiple urls anyway yet), leaving only single correct url.
Then pass the url to the push command.
*/
RemoteConfig rc = new RemoteConfig(myGit.getRepository().getConfig(), myRemoteName);
List<URIish> uris = new ArrayList<URIish>(rc.getURIs());
for (URIish uri : uris) {
rc.removeURI(uri);
}
uris = new ArrayList<URIish>(rc.getPushURIs());
for (URIish uri : uris) {
rc.removePushURI(uri);
}
rc.addPushURI(new URIish(myUrl));
Iterable<PushResult> results = call(pushCommand, rc);
myPushResult = analyzeResults(results);
}
@@ -214,6 +242,101 @@ interface GitHttpRemoteCommand {
return GitSimplePushResult.error(errorReport.toString());
}
}
/*
A copy-paste from org.eclipse.jgit.api.PushCommand#call with the following differences:
1. Fields are not accessible, so they are substituted by getters, except for credentialsProvider, which we have stored as an instance field.
2. checkCallable() won't fail (according to the PushCommand code), so it's safe to remove it.
3. Actual push is performed via
Transport.openAll(repo, remoteConfig, Transport.Operation.PUSH)
instead of
Transport.openAll(repo, remote, Transport.Operation.PUSH)
where remoteConfig is passed to the method.
Original code constructs the remoteConfig based on .git/config.
*/
@NotNull
private Iterable<PushResult> call(PushCommand pushCommand, RemoteConfig remoteConfig) throws JGitInternalException, InvalidRemoteException {
ArrayList<PushResult> pushResults = new ArrayList<PushResult>(3);
List<RefSpec> refSpecs = pushCommand.getRefSpecs();
Repository repo = pushCommand.getRepository();
boolean force = pushCommand.isForce();
int timeout = pushCommand.getTimeout();
CredentialsProvider credentialsProvider = myCredentialsProvider;
String receivePack = pushCommand.getReceivePack();
boolean thin = pushCommand.isThin();
boolean dryRun = pushCommand.isDryRun();
String remote = pushCommand.getRemote();
ProgressMonitor monitor = pushCommand.getProgressMonitor();
try {
if (refSpecs.isEmpty()) {
RemoteConfig config = new RemoteConfig(repo.getConfig(), pushCommand.getRemote());
refSpecs.addAll(config.getPushRefSpecs());
}
if (refSpecs.isEmpty()) {
Ref head = repo.getRef(Constants.HEAD);
if (head != null && head.isSymbolic()) {
refSpecs.add(new RefSpec(head.getLeaf().getName()));
}
}
if (force) {
for (int i = 0; i < refSpecs.size(); i++) {
refSpecs.set(i, refSpecs.get(i).setForceUpdate(true));
}
}
final List<Transport> transports;
transports = Transport.openAll(repo, remoteConfig, Transport.Operation.PUSH);
for (final Transport transport : transports) {
if (0 <= timeout) {
transport.setTimeout(timeout);
}
transport.setPushThin(thin);
if (receivePack != null) {
transport.setOptionReceivePack(receivePack);
}
transport.setDryRun(dryRun);
if (credentialsProvider != null) {
transport.setCredentialsProvider(credentialsProvider);
}
final Collection<RemoteRefUpdate> toPush = transport
.findRemoteRefUpdatesFor(refSpecs);
try {
PushResult result = transport.push(monitor, toPush);
pushResults.add(result);
}
catch (TransportException e) {
throw new JGitInternalException(
JGitText.get().exceptionCaughtDuringExecutionOfPushCommand,
e);
}
finally {
transport.close();
}
}
}
catch (URISyntaxException e) {
throw new InvalidRemoteException(MessageFormat.format(
JGitText.get().invalidRemote, remote));
}
catch (NotSupportedException e) {
throw new JGitInternalException(
JGitText.get().exceptionCaughtDuringExecutionOfPushCommand,
e);
}
catch (IOException e) {
throw new JGitInternalException(
JGitText.get().exceptionCaughtDuringExecutionOfPushCommand,
e);
}
return pushResults;
}
}
}
@@ -326,7 +326,7 @@ public final class GitPusher {
return pushNatively(repository, pushSpec);
}
else {
return GitHttpAdapter.isHttpUrlWithoutUserCredentials(remoteUrl) ? GitHttpAdapter.push(repository, null, remoteUrl) : pushNatively(repository, pushSpec);
return GitHttpAdapter.isHttpUrlWithoutUserCredentials(remoteUrl) ? GitHttpAdapter.push(repository, null, remoteUrl, null) : pushNatively(repository, pushSpec);
}
}
else {
@@ -340,7 +340,7 @@ public final class GitPusher {
}
}
if (httpUrl != null) {
return GitHttpAdapter.push(repository, remote, httpUrl);
return GitHttpAdapter.push(repository, remote, httpUrl, formPushSpec(pushSpec, remote));
}
else {
return pushNatively(repository, pushSpec);
@@ -348,6 +348,21 @@ public final class GitPusher {
}
}
@NotNull
private static String formPushSpec(@NotNull GitPushSpec spec, @NotNull GitRemote remote) {
String destWithRemote = spec.getDest().getName();
String prefix = remote.getName() + "/";
String destName;
if (destWithRemote.startsWith(prefix)) {
destName = destWithRemote.substring(prefix.length());
}
else {
LOG.error("Destination remote branch has invalid name. Remote branch name: " + destWithRemote + "\nRemote: " + remote);
destName = destWithRemote;
}
return spec.getSource().getName() + ":" + destName;
}
@NotNull
private static GitSimplePushResult pushNatively(GitRepository repository, GitPushSpec pushSpec) {
GitPushRejectedDetector rejectedDetector = new GitPushRejectedDetector();
@@ -234,8 +234,7 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler {
StringBuffer unparsedBuffer = processHandler.getStdErr();
if (unparsedBuffer.length() != 0) {
compileContext.addMessage(CompilerMessageCategory.ERROR, unparsedBuffer.toString(), null, -1, -1);
hasMessages = true;
compileContext.addMessage(CompilerMessageCategory.INFORMATION, unparsedBuffer.toString(), null, -1, -1);
}
final int exitCode = processHandler.getProcess().exitValue();
@@ -39,6 +39,7 @@ import com.intellij.openapi.roots.ui.configuration.ClasspathEditor;
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.ModificationTracker;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -47,6 +48,8 @@ import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
@@ -165,7 +168,7 @@ public abstract class MvcFramework {
return null;
}
@Nullable
public VirtualFile findAppRoot(@Nullable PsiElement element) {
VirtualFile appDirectory = findAppDirectory(element);
@@ -185,7 +188,7 @@ public abstract class MvcFramework {
return null;
}
@Nullable
public VirtualFile findAppDirectory(@Nullable PsiElement element) {
if (element == null) return null;
@@ -404,7 +407,7 @@ public abstract class MvcFramework {
env = new HashMap<String, String>();
params.setEnv(env);
}
env.put("JAVA_HOME", FileUtil.toSystemDependentName(path));
}
}
@@ -620,17 +623,27 @@ public abstract class MvcFramework {
}
@Nullable
public static MvcFramework getInstance(@Nullable Module module) {
public static MvcFramework getInstance(@Nullable final Module module) {
if (module == null) {
return null;
}
for (final MvcFramework framework : EP_NAME.getExtensions()) {
if (framework.hasSupport(module)) {
return framework;
final Project project = module.getProject();
final ModificationTracker tracker = MvcModuleStructureSynchronizer.getInstance(project).getFileAndRootsModificationTracker();
return CachedValuesManager.getManager(project).getCachedValue(module, new CachedValueProvider<MvcFramework>() {
@Override
public Result<MvcFramework> compute() {
for (final MvcFramework framework : EP_NAME.getExtensions()) {
if (framework.hasSupport(module)) {
return Result.create(framework, tracker);
}
}
return Result.create(null, tracker);
}
}
return null;
});
}
@Nullable
@@ -39,6 +39,7 @@ public class HgCatCommand {
final HgCommandExecutor executor = new HgCommandExecutor(myProject);
executor.setOptions(Collections.<String>emptyList());
executor.setSilent(true);
executor.setCharset(charset);
final HgCommandResult result = executor.executeInCurrentThread(hgFile.getRepo(), "cat", arguments);
if (result == null) { // in case of error
@@ -98,7 +98,7 @@ public final class HgCommandExecutor {
@Nullable
public HgCommandResult executeInCurrentThread(@Nullable final VirtualFile repo, final String operation, final List<String> arguments) {
LOG.assertTrue(!ApplicationManager.getApplication().isDispatchThread());
//LOG.assertTrue(!ApplicationManager.getApplication().isDispatchThread()); disabled for release
if (myProject == null || myProject.isDisposed() || myVcs == null) {
return null;
}
@@ -23,7 +23,6 @@ import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.PropertiesLanguage;
import com.intellij.lang.properties.ResourceBundle;
import com.intellij.lang.properties.ResourceBundleImpl;
import com.intellij.lang.properties.charset.Native2AsciiCharset;
import com.intellij.lang.properties.editor.ResourceBundleAsVirtualFile;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.components.PersistentStateComponent;
@@ -42,8 +41,8 @@ import gnu.trove.TIntLongHashMap;
import gnu.trove.TIntProcedure;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import java.io.UnsupportedEncodingException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -132,12 +131,9 @@ public class PropertiesSeparatorManager implements PersistentStateComponent<Elem
for (Element fileElement : files) {
String url = fileElement.getAttributeValue(URL_ELEMENT, "");
String separator = fileElement.getAttributeValue(SEPARATOR_ATTR,"");
try {
@NonNls String baseCharset = "ISO-8859-1";
separator = new String(separator.getBytes(baseCharset), Native2AsciiCharset.makeNative2AsciiEncodingName(baseCharset));
}
catch (UnsupportedEncodingException e) {
//can't be
separator = decodeSeparator(separator);
if (separator == null) {
continue;
}
VirtualFile file;
ResourceBundle resourceBundle = ResourceBundleImpl.createByUrl(url);
@@ -153,6 +149,36 @@ public class PropertiesSeparatorManager implements PersistentStateComponent<Elem
}
}
@Nullable
private static String decodeSeparator(String separator) {
if (separator.length() % 6 != 0) {
return null;
}
StringBuilder result = new StringBuilder();
int pos = 0;
while (pos < separator.length()) {
String encodedCharacter = separator.substring(pos, pos+6);
if (!encodedCharacter.startsWith("\\u")) {
return null;
}
int d1 = Character.digit(encodedCharacter.charAt(2), 16);
int d2 = Character.digit(encodedCharacter.charAt(3), 16);
int d3 = Character.digit(encodedCharacter.charAt(4), 16);
int d4 = Character.digit(encodedCharacter.charAt(5), 16);
if (d1 == -1 || d2 == -1 || d3 == -1 || d4 == -1) {
return null;
}
int b1 = (d1 << 12) & 0xF000;
int b2 = (d2 << 8) & 0x0F00;
int b3 = (d3 << 4) & 0x00F0;
int b4 = (d4 << 0) & 0x000F;
char code = (char) (b1 | b2 | b3 | b4);
result.append(code);
pos += 6;
}
return result.toString();
}
public Element getState() {
Element element = new Element("PropertiesSeparatorManager");
for (VirtualFile file : mySeparators.keySet()) {
@@ -165,7 +191,7 @@ public class PropertiesSeparatorManager implements PersistentStateComponent<Elem
url = file.getUrl();
}
String separator = mySeparators.get(file);
StringBuffer encoded = new StringBuffer(separator.length());
StringBuilder encoded = new StringBuilder(separator.length());
for (int i=0;i<separator.length();i++) {
char c = separator.charAt(i);
encoded.append("\\u");
@@ -650,7 +650,7 @@ public class XmlHighlightVisitor extends XmlElementVisitor implements HighlightV
catch (IllegalArgumentException ex) {
// unresolvedMessage provided by third-party reference contains wrong format string (e.g. {}), tolerate it
description = message;
LOG.warn(XmlErrorMessages.message("plugin.reference.message.problem", reference.getClass().getName(), message));
LOG.error(XmlErrorMessages.message("plugin.reference.message.problem", reference.getClass().getName(), message));
}
return description;
}