mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+1
-1
@@ -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();
|
||||
|
||||
+1
-1
@@ -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() {
|
||||
|
||||
+8
-4
@@ -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);
|
||||
|
||||
+8
-2
@@ -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
|
||||
*/
|
||||
|
||||
+20
-14
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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() {
|
||||
|
||||
+6
-1
@@ -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) {
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
+35
-9
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user