mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote branch 'origin/master'
This commit is contained in:
@@ -238,7 +238,14 @@ public def layoutCommunityPlugins(String home) {
|
||||
}
|
||||
}
|
||||
fileset(dir: "$home/plugins/xslt-debugger/rt/lib") {
|
||||
includes: "**/*.jar, **/*.html"
|
||||
include(name: "**/rmi-stubs.jar")
|
||||
}
|
||||
dir("rt") {
|
||||
fileset(dir: "$home/plugins/xslt-debugger/rt/lib") {
|
||||
include(name: "**/*.jar")
|
||||
exclude(name: "**/rmi-stubs.jar")
|
||||
include(name: "**/*.html")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ public abstract class InspectionProfileEntry {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.InspectionProfileEntry");
|
||||
|
||||
private static final SkipDefaultValuesSerializationFilters DEFAULT_FILTER = new SkipDefaultValuesSerializationFilters();
|
||||
private static Set<String> myBlackList = null;
|
||||
private Boolean myUseNewSerializer = null;
|
||||
|
||||
@@ -189,7 +190,7 @@ public abstract class InspectionProfileEntry {
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
@Nullable
|
||||
protected SerializationFilter getSerializationFilter() {
|
||||
return new SkipDefaultValuesSerializationFilters();
|
||||
return DEFAULT_FILTER;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -57,7 +58,7 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable
|
||||
return computeIconNow(element, request.getFlags());
|
||||
}
|
||||
};
|
||||
private TIntObjectHashMap<Icon> myBaseIcon;
|
||||
private static final Key<TIntObjectHashMap<Icon>> BASE_ICONS = Key.create("BASE_ICONS");
|
||||
|
||||
private static final Icon VISIBILITY_ICON_PLACEHOLDER = new EmptyIcon(Icons.PUBLIC_ICON);
|
||||
public static final Icon ICON_PLACEHOLDER = IconLoader.getIcon("/nodes/nodePlaceholder.png");
|
||||
@@ -86,28 +87,26 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable
|
||||
@Nullable
|
||||
private Icon computeIcon(final int flags) {
|
||||
PsiElement psiElement = (PsiElement)this;
|
||||
Icon baseIcon = LastComputedIcon.get(psiElement, flags);
|
||||
if (baseIcon == null) {
|
||||
if (myBaseIcon == null) {
|
||||
myBaseIcon = new TIntObjectHashMap<Icon>(3);
|
||||
}
|
||||
if (!myBaseIcon.containsKey(flags)) {
|
||||
myBaseIcon.put(flags, computeBaseIcon(flags));
|
||||
}
|
||||
baseIcon = myBaseIcon.get(flags);
|
||||
}
|
||||
|
||||
if (!psiElement.isValid()) return null;
|
||||
if (isToDeferIconLoading()) {
|
||||
|
||||
if (Registry.is("psi.deferIconLoading")) {
|
||||
Icon baseIcon = LastComputedIcon.get(psiElement, flags);
|
||||
if (baseIcon == null) {
|
||||
TIntObjectHashMap<Icon> cache = getUserData(BASE_ICONS);
|
||||
if (cache == null) {
|
||||
cache = putUserDataIfAbsent(BASE_ICONS, new TIntObjectHashMap<Icon>());
|
||||
}
|
||||
synchronized (cache) {
|
||||
if (!cache.containsKey(flags)) {
|
||||
cache.put(flags, computeBaseIcon(flags));
|
||||
}
|
||||
baseIcon = cache.get(flags);
|
||||
}
|
||||
}
|
||||
return IconDeferrer.getInstance().defer(baseIcon, new ElementIconRequest(psiElement, flags), ICON_COMPUTE);
|
||||
}
|
||||
else {
|
||||
return computeIconNow(psiElement, flags);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isToDeferIconLoading() {
|
||||
return Registry.is("psi.deferIconLoading");
|
||||
return computeIconNow(psiElement, flags);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+4
-2
@@ -534,8 +534,10 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
|
||||
for (TextRange editable : editables) {
|
||||
TextRange hostRange = ((DocumentWindow)documentRange).injectedToHost(editable);
|
||||
HighlightInfo patched = HighlightInfo.createHighlightInfo(info.type, element, hostRange.getStartOffset(),
|
||||
hostRange.getEndOffset(), info.description, info.toolTip);
|
||||
if (patched != null) {
|
||||
hostRange.getEndOffset(), info.description, info.toolTip);
|
||||
if (patched != null &&
|
||||
(patched.startOffset != patched.endOffset ||
|
||||
info.startOffset == info.endOffset)) {
|
||||
registerQuickFixes(tool, descriptor, patched, emptyActionRegistered);
|
||||
outInfos.add(patched);
|
||||
}
|
||||
|
||||
+8
-8
@@ -24,6 +24,7 @@ import com.intellij.openapi.editor.highlighter.HighlighterIterator;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
@@ -46,19 +47,18 @@ public abstract class BraceMatcherBasedSelectioner extends ExtendWordSelectionHa
|
||||
final BraceMatcher braceMatcher = BraceMatchingUtil.getBraceMatcher(fileType, iterator);
|
||||
|
||||
final ArrayList<TextRange> result = new ArrayList<TextRange>();
|
||||
final LinkedList<Pair<Integer, IElementType>> stack = new LinkedList<Pair<Integer, IElementType>>();
|
||||
final LinkedList<Trinity<Integer, Integer, IElementType>> stack = new LinkedList<Trinity<Integer, Integer, IElementType>>();
|
||||
while (!iterator.atEnd() && iterator.getStart() < totalRange.getEndOffset()) {
|
||||
final Pair<Integer, IElementType> last;
|
||||
final Trinity<Integer, Integer, IElementType> last;
|
||||
if (braceMatcher.isLBraceToken(iterator, editorText, fileType)) {
|
||||
stack.addLast(Pair.create(iterator.getStart(), iterator.getTokenType()));
|
||||
stack.addLast(Trinity.create(iterator.getStart(), iterator.getEnd(), iterator.getTokenType()));
|
||||
}
|
||||
else if (braceMatcher.isRBraceToken(iterator, editorText, fileType)
|
||||
&& !stack.isEmpty() && braceMatcher.isPairBraces((last = stack.getLast()).second, iterator.getTokenType())) {
|
||||
&& !stack.isEmpty() && braceMatcher.isPairBraces((last = stack.getLast()).third, iterator.getTokenType())) {
|
||||
stack.removeLast();
|
||||
final int start = last.first;
|
||||
result.addAll(expandToWholeLine(editorText, new TextRange(start, iterator.getEnd())));
|
||||
int bodyStart = start + 1;
|
||||
int bodyEnd = iterator.getEnd() - 1;
|
||||
result.addAll(expandToWholeLine(editorText, new TextRange(last.first, iterator.getEnd())));
|
||||
int bodyStart = last.second + 1;
|
||||
int bodyEnd = iterator.getStart();
|
||||
while (Character.isWhitespace(editorText.charAt(bodyStart))) bodyStart ++;
|
||||
while (Character.isWhitespace(editorText.charAt(bodyEnd - 1))) bodyEnd --;
|
||||
result.addAll(expandToWholeLine(editorText, new TextRange(bodyStart, bodyEnd)));
|
||||
|
||||
+10
-10
@@ -30,7 +30,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
class PairedBraceMatcherAdapter implements NontrivialBraceMatcher {
|
||||
public class PairedBraceMatcherAdapter implements NontrivialBraceMatcher {
|
||||
private final PairedBraceMatcher myMatcher;
|
||||
private final Language myLanguage;
|
||||
|
||||
@@ -47,22 +47,22 @@ class PairedBraceMatcherAdapter implements NontrivialBraceMatcher {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public boolean isLBraceToken(HighlighterIterator iterator, CharSequence fileText, FileType fileType) {
|
||||
@Nullable
|
||||
public BracePair findPair(boolean left, HighlighterIterator iterator, CharSequence fileText, FileType fileType) {
|
||||
final IElementType tokenType = iterator.getTokenType();
|
||||
final BracePair[] pairs = myMatcher.getPairs();
|
||||
for (BracePair pair : pairs) {
|
||||
if (tokenType == pair.getLeftBraceType()) return true;
|
||||
if (tokenType == (left? pair.getLeftBraceType() : pair.getRightBraceType())) return pair;
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isLBraceToken(HighlighterIterator iterator, CharSequence fileText, FileType fileType) {
|
||||
return findPair(true, iterator, fileText, fileType) != null;
|
||||
}
|
||||
|
||||
public boolean isRBraceToken(HighlighterIterator iterator, CharSequence fileText, FileType fileType) {
|
||||
final IElementType tokenType = iterator.getTokenType();
|
||||
final BracePair[] pairs = myMatcher.getPairs();
|
||||
for (BracePair pair : pairs) {
|
||||
if (tokenType == pair.getRightBraceType()) return true;
|
||||
}
|
||||
return false;
|
||||
return findPair(false, iterator, fileText, fileType) != null;
|
||||
}
|
||||
|
||||
public IElementType getOppositeBraceTokenType(@NotNull final IElementType type) {
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
@@ -134,6 +135,9 @@ public class FindUsagesManager implements JDOMExternalizable {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (IndexNotReadyException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
@@ -144,6 +148,9 @@ public class FindUsagesManager implements JDOMExternalizable {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (IndexNotReadyException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
|
||||
@@ -20,23 +20,32 @@ import com.intellij.execution.filters.HyperlinkInfo;
|
||||
import com.intellij.execution.impl.ConsoleViewImpl;
|
||||
import com.intellij.execution.ui.ConsoleViewContentType;
|
||||
import com.intellij.notification.impl.NotificationSettings;
|
||||
import com.intellij.notification.impl.NotificationsConfigurable;
|
||||
import com.intellij.notification.impl.NotificationsConfiguration;
|
||||
import com.intellij.notification.impl.NotificationsManagerImpl;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.AbstractProjectComponent;
|
||||
import com.intellij.openapi.options.ShowSettingsUtil;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.ui.SimpleToolWindowPanel;
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.*;
|
||||
import com.intellij.openapi.wm.ex.StatusBarEx;
|
||||
import com.intellij.ui.content.Content;
|
||||
import com.intellij.ui.content.ContentFactory;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@@ -111,15 +120,20 @@ public class EventLog implements Notifications {
|
||||
|
||||
final NotificationType type = notification.getType();
|
||||
view.print(mainText, type == NotificationType.ERROR
|
||||
? ConsoleViewContentType.ERROR_OUTPUT
|
||||
: type == NotificationType.INFORMATION
|
||||
? ConsoleViewContentType.NORMAL_OUTPUT
|
||||
: ConsoleViewContentType.WARNING_OUTPUT);
|
||||
? ConsoleViewContentType.ERROR_OUTPUT
|
||||
: type == NotificationType.INFORMATION
|
||||
? ConsoleViewContentType.NORMAL_OUTPUT
|
||||
: ConsoleViewContentType.WARNING_OUTPUT);
|
||||
if (showLink) {
|
||||
view.print(" ", ConsoleViewContentType.NORMAL_OUTPUT);
|
||||
view.printHyperlink("more", new HyperlinkInfo() {
|
||||
@Override
|
||||
public void navigate(Project project) {
|
||||
Balloon balloon = notification.getBalloon();
|
||||
if (balloon != null) {
|
||||
balloon.hide();
|
||||
}
|
||||
|
||||
NotificationsManagerImpl.notifyByBalloon(notification, NotificationDisplayType.STICKY_BALLOON, project);
|
||||
}
|
||||
});
|
||||
@@ -194,9 +208,25 @@ public class EventLog implements Notifications {
|
||||
return project.getComponent(ProjectTracker.class);
|
||||
}
|
||||
public static class FactoryItself implements ToolWindowFactory, DumbAware {
|
||||
public void createToolWindowContent(Project project, ToolWindow toolWindow) {
|
||||
public void createToolWindowContent(final Project project, ToolWindow toolWindow) {
|
||||
final ProjectTracker tracker = getProjectComponent(project);
|
||||
final Content content = ContentFactory.SERVICE.getInstance().createContent(tracker.myConsoleView.getComponent(), "", false);
|
||||
|
||||
SimpleToolWindowPanel panel = new SimpleToolWindowPanel(false, true);
|
||||
panel.setContent(tracker.myConsoleView.getComponent());
|
||||
|
||||
DefaultActionGroup group = new DefaultActionGroup();
|
||||
group.add(new DumbAwareAction("Settings", "Edit notification settings", IconLoader.getIcon("/general/secondaryGroup.png")) {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
ShowSettingsUtil.getInstance().editConfigurable(project, new NotificationsConfigurable());
|
||||
}
|
||||
});
|
||||
group.addAll(ContainerUtil.subList(Arrays.asList(tracker.myConsoleView.createConsoleActions()), 2)); // no next/prev
|
||||
ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, false);
|
||||
toolbar.setTargetComponent(panel);
|
||||
panel.setToolbar(toolbar.getComponent());
|
||||
|
||||
final Content content = ContentFactory.SERVICE.getInstance().createContent(panel, "", false);
|
||||
toolWindow.getContentManager().addContent(content);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.FileAttribute;
|
||||
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
|
||||
import com.intellij.util.io.IOUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -55,17 +56,10 @@ public class ForcedBuildFileAttribute {
|
||||
if (is != null) {
|
||||
try {
|
||||
try {
|
||||
/*
|
||||
//todo[lene] IOUtil throws java.io.EOFException
|
||||
at java.io.DataInputStream.readFully(DataInputStream.java:180)
|
||||
at java.io.DataInputStream.readFully(DataInputStream.java:152)
|
||||
at com.intellij.util.io.IOUtil.readString(IOUtil.java:40)
|
||||
at com.intellij.buildfiles.ForcedBuildFileAttribute.getFrameworkIdOfBuildFile(ForcedBuildFileAttribute.java:59)
|
||||
*/
|
||||
if (is.available() == 0) {
|
||||
return null;
|
||||
}
|
||||
return is.readUTF();
|
||||
return IOUtil.readString(is);
|
||||
}
|
||||
finally {
|
||||
is.close();
|
||||
@@ -82,12 +76,12 @@ public class ForcedBuildFileAttribute {
|
||||
|
||||
|
||||
public static void forceFileToFramework(VirtualFile file, String frameworkId, boolean value) {
|
||||
if (value) {//belongs to other framework
|
||||
String existingFrameworkId = getFrameworkIdOfBuildFile(file);
|
||||
if (!StringUtil.isEmpty(existingFrameworkId) && !frameworkId.equals(existingFrameworkId)) {
|
||||
return;
|
||||
}
|
||||
//belongs to other framework - do not override!
|
||||
String existingFrameworkId = getFrameworkIdOfBuildFile(file);
|
||||
if (!StringUtil.isEmpty(existingFrameworkId) && !frameworkId.equals(existingFrameworkId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (value) {//write framework
|
||||
forceBuildFile(file, frameworkId);
|
||||
}
|
||||
@@ -102,7 +96,7 @@ public class ForcedBuildFileAttribute {
|
||||
final DataOutputStream os = FRAMEWORK_FILE_ATTRIBUTE.writeAttribute(file);
|
||||
try {
|
||||
try {
|
||||
os.writeUTF(StringUtil.notNullize(value));
|
||||
IOUtil.writeString(StringUtil.notNullize(value), os);
|
||||
}
|
||||
finally {
|
||||
os.close();
|
||||
|
||||
@@ -20,17 +20,11 @@ import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.encoding.EncodingManager;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: lene
|
||||
@@ -72,68 +66,11 @@ public class ScriptRunnerUtil {
|
||||
}
|
||||
});
|
||||
}
|
||||
processHandler.startNotify();
|
||||
|
||||
//ProcessTerminatedListener.attach(processHandler, project);
|
||||
return processHandler;
|
||||
}
|
||||
|
||||
public static Pair<String, String[]> getExePathAndCommand(List<String> commandToExecute) {
|
||||
@NonNls String exePath = "";
|
||||
@NonNls List<String> parameters = new ArrayList<String>();
|
||||
if (SystemInfo.isOS2) {
|
||||
exePath = "cmd";
|
||||
parameters.add("/c");
|
||||
}
|
||||
else if (SystemInfo.isWindows) {
|
||||
if (!SystemInfo.isWindows9x) {
|
||||
exePath = "cmd";
|
||||
}
|
||||
else {
|
||||
exePath = "command.com";
|
||||
}
|
||||
parameters.add("/c");
|
||||
|
||||
/*if exe-path and at least one of parameters contain spaces the whole command must be quoted,
|
||||
e.g. instead of
|
||||
cmd /c "C:\Program Files\jdk1.5\bin\java" "-Dproperty=a b c" myclass
|
||||
must be used
|
||||
cmd /c ""C:\Program Files\jdk1.5\bin\java" "-Dproperty=a b c" myclass"
|
||||
*/
|
||||
boolean quoteWholeCommand = false;
|
||||
for (int i = 1; i < commandToExecute.size(); i++) {
|
||||
quoteWholeCommand |= commandToExecute.get(i).contains(" ");
|
||||
}
|
||||
quoteWholeCommand &= commandToExecute.size() > 0 && commandToExecute.get(0).contains(" ");
|
||||
|
||||
if (quoteWholeCommand) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append('"');
|
||||
for (int i = 0; i < commandToExecute.size(); i++) {
|
||||
if (i > 0) {
|
||||
builder.append(' ');
|
||||
}
|
||||
builder.append(GeneralCommandLine.quote(commandToExecute.get(i)));
|
||||
}
|
||||
builder.append('"');
|
||||
|
||||
parameters.add(builder.toString());
|
||||
return Pair.create(exePath, ArrayUtil.toStringArray(parameters));
|
||||
}
|
||||
}
|
||||
|
||||
int firstParamIdx = 0;
|
||||
if (SystemInfo.isUnix) {
|
||||
exePath = commandToExecute.get(0);
|
||||
firstParamIdx = 1;
|
||||
}
|
||||
|
||||
for (int i = firstParamIdx; i < commandToExecute.size(); i++) {
|
||||
parameters.add(commandToExecute.get(i));
|
||||
}
|
||||
|
||||
return Pair.create(exePath, ArrayUtil.toStringArray(parameters));
|
||||
}
|
||||
|
||||
public static ScriptOutput executeScriptInConsoleWithFullOutput(String exePathString,
|
||||
@Nullable VirtualFile scriptFile,
|
||||
@Nullable String workingDirectory,
|
||||
@@ -148,6 +85,7 @@ public class ScriptRunnerUtil {
|
||||
final StringBuilder mergedOutput =
|
||||
(scriptOutputType.readStandardOutput() && scriptOutputType.readErrorOutput()) ? new StringBuilder() : null;
|
||||
addReadingProcessListener(scriptOutputType, processHandler, standardOutput, errorOutput, mergedOutput);
|
||||
processHandler.startNotify();
|
||||
|
||||
if (!processHandler.waitFor(timeout)) {
|
||||
LOG.warn("Process did not complete in " + timeout / 1000 + "s");
|
||||
|
||||
+1
-1
@@ -302,7 +302,7 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx {
|
||||
if (!anchor.equals("__AUTODETECT__")) {
|
||||
final List<String> parts = StringUtil.split(anchor, " ");
|
||||
if (parts.size() < 2 || !myWidgetMap.keySet().contains(parts.get(1))) {
|
||||
wid = "Notifications";
|
||||
wid = "Memory";
|
||||
before = true;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -122,6 +122,10 @@ public class ContainerUtil {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T> List<T> subList(List<T> list, int from) {
|
||||
return list.subList(from, list.size());
|
||||
}
|
||||
|
||||
public static <T> void addAll(@NotNull Collection<T> collection, @NotNull Iterable<T> appendix) {
|
||||
addAll(collection, appendix.iterator());
|
||||
}
|
||||
|
||||
@@ -110,7 +110,6 @@ class BeanBinding implements Binding {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void deserializeInto(final Object bean, final Element element) {
|
||||
_deserializeInto(bean, element);
|
||||
}
|
||||
@@ -134,11 +133,11 @@ class BeanBinding implements Binding {
|
||||
|
||||
ArrayList<Binding> bindings = new ArrayList<Binding>(myPropertyBindings.keySet());
|
||||
|
||||
|
||||
MultiMap<Binding, Object> data = new MultiMap<Binding, Object>();
|
||||
|
||||
final Object[] children = JDOMUtil.getChildNodesWithAttrs(e);
|
||||
nextNode: for (Object child : children) {
|
||||
nextNode:
|
||||
for (Object child : children) {
|
||||
if (XmlSerializerImpl.isIgnoredNode(child)) continue;
|
||||
|
||||
for (Binding binding : bindings) {
|
||||
@@ -188,11 +187,9 @@ class BeanBinding implements Binding {
|
||||
return Element.class;
|
||||
}
|
||||
|
||||
|
||||
private static String getTagName(Class<?> aClass) {
|
||||
Tag tag = aClass.getAnnotation(Tag.class);
|
||||
if (tag != null && tag.value().length() != 0) return tag.value();
|
||||
|
||||
return aClass.getSimpleName();
|
||||
}
|
||||
|
||||
@@ -201,27 +198,26 @@ class BeanBinding implements Binding {
|
||||
try {
|
||||
List<Accessor> accessors = new ArrayList<Accessor>();
|
||||
|
||||
BeanInfo info = Introspector.getBeanInfo(aClass);
|
||||
BeanInfo info = Introspector.getBeanInfo(aClass, Introspector.IGNORE_ALL_BEANINFO);
|
||||
|
||||
PropertyDescriptor[] propertyDescriptors = info.getPropertyDescriptors();
|
||||
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
|
||||
if (propertyDescriptor.getName().equals(CLASS_PROPERTY)) continue;
|
||||
|
||||
final Method readMethod = propertyDescriptor.getReadMethod();
|
||||
final Method writeMethod = propertyDescriptor.getWriteMethod();
|
||||
|
||||
if (readMethod == null) continue;
|
||||
if (writeMethod == null) continue;
|
||||
|
||||
if (XmlSerializerImpl.findAnnotation(readMethod.getAnnotations(), Transient.class) != null ||
|
||||
XmlSerializerImpl.findAnnotation(writeMethod.getAnnotations(), Transient.class) != null) continue;
|
||||
|
||||
accessors.add(new PropertyAccessor(propertyDescriptor));
|
||||
if (readMethod != null && writeMethod != null &&
|
||||
XmlSerializerImpl.findAnnotation(readMethod.getAnnotations(), Transient.class) == null &&
|
||||
XmlSerializerImpl.findAnnotation(writeMethod.getAnnotations(), Transient.class) == null) {
|
||||
accessors.add(new PropertyAccessor(propertyDescriptor));
|
||||
}
|
||||
}
|
||||
|
||||
Field[] fields = aClass.getFields();
|
||||
for (Field field : fields) {
|
||||
int modifiers = field.getModifiers();
|
||||
if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers) &&
|
||||
final int modifiers = field.getModifiers();
|
||||
if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers) &&
|
||||
!Modifier.isFinal(modifiers) && !Modifier.isTransient(modifiers) &&
|
||||
XmlSerializerImpl.findAnnotation(field.getAnnotations(), Transient.class) == null) {
|
||||
accessors.add(new FieldAccessor(field));
|
||||
}
|
||||
@@ -260,7 +256,6 @@ class BeanBinding implements Binding {
|
||||
return new AttributeBinding(accessor, attribute, xmlSerializer);
|
||||
}
|
||||
|
||||
|
||||
if (tag != null) {
|
||||
if (tag.value().length() > 0) return new TagBinding(accessor, tag, xmlSerializer);
|
||||
}
|
||||
@@ -281,5 +276,4 @@ class BeanBinding implements Binding {
|
||||
OptionTag optionTag = XmlSerializerImpl.findAnnotation(accessor.getAnnotations(), OptionTag.class);
|
||||
return new OptionTagBinding(accessor, xmlSerializer, optionTag);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -144,13 +144,17 @@ public class ChangesBrowserNode<T> extends DefaultMutableTreeNode {
|
||||
}
|
||||
|
||||
public List<Change> getAllChangesUnder() {
|
||||
List<Change> changes = new ArrayList<Change>();
|
||||
return getAllObjectsUnder(Change.class);
|
||||
}
|
||||
|
||||
public <T> List<T> getAllObjectsUnder(final Class<T> clazz) {
|
||||
List<T> changes = new ArrayList<T>();
|
||||
final Enumeration enumeration = depthFirstEnumeration();
|
||||
while (enumeration.hasMoreElements()) {
|
||||
ChangesBrowserNode child = (ChangesBrowserNode)enumeration.nextElement();
|
||||
final Object value = child.getUserObject();
|
||||
if (value instanceof Change) {
|
||||
changes.add((Change)value);
|
||||
if (clazz.isAssignableFrom(value.getClass())) {
|
||||
changes.add((T) value);
|
||||
}
|
||||
}
|
||||
return changes;
|
||||
|
||||
@@ -77,6 +77,7 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan
|
||||
@NonNls public static final String ourHelpId = "ideaInterface.changes";
|
||||
@NonNls public static final DataKey<List<VirtualFile>> UNVERSIONED_FILES_DATA_KEY = DataKey.create("ChangeListView.UnversionedFiles");
|
||||
@NonNls public static final DataKey<List<FilePath>> MISSING_FILES_DATA_KEY = DataKey.create("ChangeListView.MissingFiles");
|
||||
@NonNls public static final DataKey<List<LocallyDeletedChange>> LOCALLY_DELETED_CHANGES = DataKey.create("ChangeListView.LocallyDeletedChanges");
|
||||
@NonNls public static final DataKey<String> HELP_ID_DATA_KEY = DataKey.create(HELP_ID_KEY);
|
||||
|
||||
private ActionGroup myMenuGroup;
|
||||
@@ -195,8 +196,9 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan
|
||||
}
|
||||
else if (key == VcsDataKeys.MODIFIED_WITHOUT_EDITING_DATA_KEY) {
|
||||
sink.put(VcsDataKeys.MODIFIED_WITHOUT_EDITING_DATA_KEY, getSelectedModifiedWithoutEditing());
|
||||
}
|
||||
else if (key == MISSING_FILES_DATA_KEY) {
|
||||
} else if (key == LOCALLY_DELETED_CHANGES) {
|
||||
sink.put(LOCALLY_DELETED_CHANGES, getSelectedLocallyDeletedChanges());
|
||||
} else if (key == MISSING_FILES_DATA_KEY) {
|
||||
sink.put(MISSING_FILES_DATA_KEY, getSelectedMissingFiles());
|
||||
} else if (VcsDataKeys.HAVE_LOCALLY_DELETED == key) {
|
||||
sink.put(VcsDataKeys.HAVE_LOCALLY_DELETED, haveLocallyDeleted());
|
||||
@@ -265,6 +267,24 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan
|
||||
return new ArrayList<FilePath>(files);
|
||||
}
|
||||
|
||||
private List<LocallyDeletedChange> getSelectedLocallyDeletedChanges() {
|
||||
Set<LocallyDeletedChange> files = new HashSet<LocallyDeletedChange>();
|
||||
final TreePath[] paths = getSelectionPaths();
|
||||
if (paths != null) {
|
||||
for (TreePath path : paths) {
|
||||
if (path.getPathCount() > 1) {
|
||||
ChangesBrowserNode firstNode = (ChangesBrowserNode)path.getPathComponent(1);
|
||||
if (firstNode.getUserObject() == TreeModelBuilder.LOCALLY_DELETED_NODE) {
|
||||
ChangesBrowserNode node = (ChangesBrowserNode)path.getLastPathComponent();
|
||||
final List<LocallyDeletedChange> objectsUnder = node.getAllObjectsUnder(LocallyDeletedChange.class);
|
||||
files.addAll(objectsUnder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ArrayList<LocallyDeletedChange>(files);
|
||||
}
|
||||
|
||||
private List<FilePath> getSelectedMissingFiles() {
|
||||
return getSelectedFilePaths(TreeModelBuilder.LOCALLY_DELETED_NODE);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.changes.*;
|
||||
import com.intellij.openapi.vcs.changes.actions.MoveChangesToAnotherListAction;
|
||||
@@ -123,14 +124,16 @@ public class CommitHelper {
|
||||
@Override
|
||||
public NotificationInfo notifyFinished() {
|
||||
final List<Change> changesFailedToCommit = processor.getChangesFailedToCommit();
|
||||
|
||||
String text = (myIncludedChanges.size() - changesFailedToCommit.size()) + " Change(s) Commited";
|
||||
if (changesFailedToCommit.size() > 0) {
|
||||
text += ", " + changesFailedToCommit.size() + " Change(s) Failed To Commit";
|
||||
|
||||
int failed = changesFailedToCommit.size();
|
||||
int committed = myIncludedChanges.size() - failed;
|
||||
|
||||
String text = committed + " " + StringUtil.pluralize("change", committed) + " committed";
|
||||
if (failed > 0) {
|
||||
text += ", " + failed + " " + StringUtil.pluralize("change", failed) + " failed to commit";
|
||||
}
|
||||
final String title = "VCS Commit Finished";
|
||||
AbstractCommonUpdateAction.NOTIFICATION_GROUP.createNotification(title + ", " + text, myCommitMessage, NotificationType.INFORMATION, null).notify( myProject);
|
||||
return new NotificationInfo("VCS Commit", title, text, true);
|
||||
AbstractCommonUpdateAction.NOTIFICATION_GROUP.createNotification(text, myCommitMessage, NotificationType.INFORMATION, null).notify( myProject);
|
||||
return new NotificationInfo("VCS Commit", "VCS Commit Finished", text, true);
|
||||
}
|
||||
};
|
||||
ProgressManager.getInstance().run(task);
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.ide.BrowserUtil;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
@@ -148,6 +149,14 @@ public class GithubOpenInBrowserAction extends DumbAwareAction {
|
||||
if (branch.startsWith("origin/")){
|
||||
branch = branch.substring(7);
|
||||
}
|
||||
BrowserUtil.launchBrowser("https://github.com/" + repoInfo + "/blob/" + branch + path.substring(rootPath.length()));
|
||||
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("https://github.com/").append(repoInfo).append("/blob/").append(branch).append(path.substring(rootPath.length()));
|
||||
final Editor editor = e.getData(PlatformDataKeys.EDITOR);
|
||||
if (editor != null){
|
||||
final int line = editor.getCaretModel().getLogicalPosition().line;
|
||||
builder.append("#L").append(line);
|
||||
}
|
||||
BrowserUtil.launchBrowser(builder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
+6
-2
@@ -66,8 +66,13 @@ public class ConvertConcatenationToGstringIntention extends Intention {
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
String text = builder.toString();
|
||||
if (builder.indexOf("\n") < 0 && builder.indexOf("\r") < 0) {
|
||||
text = GrStringUtil.escapeSymbols(builder.toString(), "\"");
|
||||
}
|
||||
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(element.getProject());
|
||||
final GrExpression newExpr = factory.createExpressionFromText(GrStringUtil.addQuotes(builder.toString(), true));
|
||||
final GrExpression newExpr = factory.createExpressionFromText(GrStringUtil.addQuotes(text, true));
|
||||
final GrExpression expression = ((GrExpression)element).replaceWithExpression(newExpr, true);
|
||||
if (expression instanceof GrString) {
|
||||
GrStringUtil.removeUnnecessaryBracesInGString((GrString)expression);
|
||||
@@ -87,7 +92,6 @@ public class ConvertConcatenationToGstringIntention extends Intention {
|
||||
}
|
||||
else if (operand instanceof GrLiteral) {
|
||||
String text = GrStringUtil.escapeSymbolsForGString(GrStringUtil.removeQuotes(operand.getText()), false);
|
||||
if (text.contains("\n")) text = GrStringUtil.escapeSymbolsForGString(text, true);
|
||||
builder.append(text);
|
||||
}
|
||||
else if (MyPredicate.satisfiedBy(operand, false)) {
|
||||
|
||||
+1
-2
@@ -152,8 +152,7 @@ public class ConvertGStringToStringIntention extends Intention {
|
||||
}
|
||||
if (text.length() == 0) return null;
|
||||
|
||||
String escaped = GrStringUtil.escapeSymbolsForString(text, false);
|
||||
if (escaped.contains("\n")) escaped = GrStringUtil.escapeSymbolsForGString(escaped, true);
|
||||
String escaped = GrStringUtil.escapeSymbolsForString(text, !text.contains("\n") && !text.contains("\r"));
|
||||
return GrStringUtil.addQuotes(escaped, false);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-1
@@ -50,10 +50,19 @@ public class PathExpression implements GroovyElementTypes {
|
||||
*/
|
||||
public static Result parsePathExprQualifierForExprStatement(PsiBuilder builder, GroovyParser parser) {
|
||||
PsiBuilder.Marker marker = builder.mark();
|
||||
final IElementType qualifierType = PrimaryExpression.parsePrimaryExpression(builder, parser);
|
||||
final PsiBuilder.Marker marker1 = builder.mark();
|
||||
IElementType qualifierType = PrimaryExpression.parsePrimaryExpression(builder, parser);
|
||||
if (qualifierType != WRONGWAY) {
|
||||
Result result;
|
||||
if (isPathElementStart(builder)) {
|
||||
if (builder.getTokenType() == mLPAREN && qualifierType == LITERAL) {
|
||||
marker1.rollbackTo();
|
||||
qualifierType = PrimaryExpression.parsePrimaryExpression(builder, parser, true);
|
||||
assert qualifierType != WRONGWAY;
|
||||
}
|
||||
else {
|
||||
marker1.drop();
|
||||
}
|
||||
PsiBuilder.Marker newMarker = marker.precede();
|
||||
marker.drop();
|
||||
if (checkForLCurly(builder)) {
|
||||
@@ -67,12 +76,14 @@ public class PathExpression implements GroovyElementTypes {
|
||||
}
|
||||
}
|
||||
else {
|
||||
marker1.drop();
|
||||
marker.drop();
|
||||
result = INVOKED_EXPR;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
marker1.drop();
|
||||
marker.drop();
|
||||
return WRONG_WAY;
|
||||
}
|
||||
|
||||
+24
-15
@@ -36,47 +36,56 @@ import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils;
|
||||
*/
|
||||
public class PrimaryExpression implements GroovyElementTypes {
|
||||
|
||||
public static IElementType parsePrimaryExpression(PsiBuilder builder, GroovyParser parser) {
|
||||
|
||||
if (TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType())) {
|
||||
public static IElementType parsePrimaryExpression(PsiBuilder builder, GroovyParser parser) {
|
||||
return parsePrimaryExpression(builder, parser, false);
|
||||
}
|
||||
public static IElementType parsePrimaryExpression(PsiBuilder builder, GroovyParser parser, boolean literalsAsRefExprs) {
|
||||
|
||||
final IElementType tokenType = builder.getTokenType();
|
||||
if (TokenSets.BUILT_IN_TYPE.contains(tokenType)) {
|
||||
ParserUtils.eatElement(builder, BUILT_IN_TYPE_EXPRESSION);
|
||||
return BUILT_IN_TYPE_EXPRESSION;
|
||||
}
|
||||
if (kTHIS == builder.getTokenType()) {
|
||||
if (kTHIS == tokenType) {
|
||||
ParserUtils.eatElement(builder, THIS_REFERENCE_EXPRESSION);
|
||||
return THIS_REFERENCE_EXPRESSION;
|
||||
}
|
||||
if (kSUPER == builder.getTokenType()) {
|
||||
if (kSUPER == tokenType) {
|
||||
ParserUtils.eatElement(builder, SUPER_REFERENCE_EXPRESSION);
|
||||
return SUPER_REFERENCE_EXPRESSION;
|
||||
}
|
||||
if (kNEW == builder.getTokenType()) {
|
||||
if (kNEW == tokenType) {
|
||||
return newExprParse(builder, parser);
|
||||
}
|
||||
if (mIDENT == builder.getTokenType()) {
|
||||
if (mIDENT == tokenType) {
|
||||
ParserUtils.eatElement(builder, REFERENCE_EXPRESSION);
|
||||
return REFERENCE_EXPRESSION;
|
||||
}
|
||||
if (mGSTRING_BEGIN == builder.getTokenType()) {
|
||||
if (mGSTRING_BEGIN == tokenType) {
|
||||
return StringConstructorExpression.parse(builder, parser);
|
||||
}
|
||||
if (mREGEX_BEGIN == builder.getTokenType()) {
|
||||
if (mREGEX_BEGIN == tokenType) {
|
||||
return RegexConstructorExpression.parse(builder, parser);
|
||||
}
|
||||
if (mLBRACK == builder.getTokenType()) {
|
||||
if (mLBRACK == tokenType) {
|
||||
return ListOrMapConstructorExpression.parse(builder, parser);
|
||||
}
|
||||
if (mLPAREN == builder.getTokenType()) {
|
||||
if (mLPAREN == tokenType) {
|
||||
return parenthesizedExprParse(builder, parser);
|
||||
}
|
||||
if (mLCURLY == builder.getTokenType()) {
|
||||
if (mLCURLY == tokenType) {
|
||||
return OpenOrClosableBlock.parseClosableBlock(builder, parser);
|
||||
}
|
||||
if (TokenSets.CONSTANTS.contains(builder.getTokenType())) {
|
||||
ParserUtils.eatElement(builder, LITERAL);
|
||||
return LITERAL;
|
||||
if (tokenType == mSTRING_LITERAL ||
|
||||
tokenType == mGSTRING_LITERAL ||
|
||||
tokenType == mREGEX_LITERAL) {
|
||||
return ParserUtils.eatElement(builder, literalsAsRefExprs ? REFERENCE_EXPRESSION : LITERAL);
|
||||
}
|
||||
if (mWRONG_REGEX_LITERAL == builder.getTokenType()) {
|
||||
if (TokenSets.CONSTANTS.contains(tokenType)) {
|
||||
return ParserUtils.eatElement(builder, LITERAL);
|
||||
}
|
||||
if (mWRONG_REGEX_LITERAL == tokenType) {
|
||||
PsiBuilder.Marker marker = builder.mark();
|
||||
builder.advanceLexer();
|
||||
builder.error(GroovyBundle.message("wrong.string"));
|
||||
|
||||
-11
@@ -35,17 +35,6 @@ public class StringConstructorExpression implements GroovyElementTypes {
|
||||
|
||||
Marker sMarker = builder.mark();
|
||||
if (ParserUtils.getToken(builder, mGSTRING_BEGIN)) {
|
||||
ParserUtils.getToken(builder, mGSTRING_CONTENT);
|
||||
if (mGSTRING_END.equals(builder.getTokenType())) {
|
||||
sMarker.rollbackTo();
|
||||
sMarker = builder.mark();
|
||||
builder.advanceLexer();
|
||||
builder.advanceLexer();
|
||||
builder.advanceLexer();
|
||||
sMarker.done(LITERAL);
|
||||
return LITERAL;
|
||||
}
|
||||
|
||||
while (ParserUtils.getToken(builder, mGSTRING_CONTENT) || mDOLLAR.equals(builder.getTokenType())) {
|
||||
if (mDOLLAR.equals(builder.getTokenType())) {
|
||||
stringConstructorValuePart(builder, parser);
|
||||
|
||||
-3
@@ -155,9 +155,6 @@ public class GrArgumentLabelImpl extends GroovyPsiElementImpl implements GrArgum
|
||||
if (value instanceof String) {
|
||||
return (String)value;
|
||||
}
|
||||
if (value instanceof Number) {
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
|
||||
final IElementType elemType = element.getNode().getElementType();
|
||||
|
||||
+51
-8
@@ -22,6 +22,7 @@ import com.intellij.psi.impl.PsiSubstitutorImpl;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.containers.ComparatorUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
@@ -38,6 +39,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinary
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrMapType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureImpl;
|
||||
@@ -283,14 +285,11 @@ public class TypesUtil {
|
||||
public static boolean isAssignableByMethodCallConversion(PsiType lType, PsiType rType, PsiManager manager, GlobalSearchScope scope) {
|
||||
if (lType == null || rType == null) return false;
|
||||
|
||||
if (rType instanceof GrTupleType) {
|
||||
final GrTupleType tuple = (GrTupleType)rType;
|
||||
if (tuple.getComponentTypes().length == 0) {
|
||||
if (lType instanceof PsiArrayType ||
|
||||
InheritanceUtil.isInheritor(lType, JAVA_UTIL_LIST) ||
|
||||
InheritanceUtil.isInheritor(lType, JAVA_UTIL_SET)) {
|
||||
return true;
|
||||
}
|
||||
if (rType instanceof GrTupleType && ((GrTupleType)rType).getComponentTypes().length == 0) {
|
||||
if (lType instanceof PsiArrayType ||
|
||||
InheritanceUtil.isInheritor(lType, JAVA_UTIL_LIST) ||
|
||||
InheritanceUtil.isInheritor(lType, JAVA_UTIL_SET)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,10 +317,54 @@ public class TypesUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rType instanceof GrMapType || rType instanceof GrTupleType) {
|
||||
Boolean result = isAssignableForNativeTypes(lType, (PsiClassType)rType, manager, scope);
|
||||
if (result != null) return result.booleanValue();
|
||||
}
|
||||
|
||||
return TypeConversionUtil.isAssignable(lType, rType);
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Boolean isAssignableForNativeTypes(PsiType lType, PsiClassType rType, PsiManager manager, GlobalSearchScope scope) {
|
||||
if (!(lType instanceof PsiClassType)) return null;
|
||||
final PsiClassType.ClassResolveResult leftResult = ((PsiClassType)lType).resolveGenerics();
|
||||
final PsiClassType.ClassResolveResult rightResult = rType.resolveGenerics();
|
||||
final PsiClass leftClass = leftResult.getElement();
|
||||
PsiClass rightClass = rightResult.getElement();
|
||||
if (rightClass == null || leftClass == null) return null;
|
||||
|
||||
if (!InheritanceUtil.isInheritorOrSelf(rightClass, leftClass, true)) return Boolean.FALSE;
|
||||
|
||||
PsiSubstitutor rightSubstitutor = rightResult.getSubstitutor();
|
||||
|
||||
if (!leftClass.hasTypeParameters()) return Boolean.TRUE;
|
||||
PsiSubstitutor leftSubstitutor = leftResult.getSubstitutor();
|
||||
|
||||
if (!leftClass.getManager().areElementsEquivalent(leftClass, rightClass)) {
|
||||
rightSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(leftClass, rightClass, rightSubstitutor);
|
||||
rightClass = leftClass;
|
||||
}
|
||||
else if (!rightClass.hasTypeParameters()) return Boolean.TRUE;
|
||||
|
||||
Iterator<PsiTypeParameter> li = PsiUtil.typeParametersIterator(leftClass);
|
||||
Iterator<PsiTypeParameter> ri = PsiUtil.typeParametersIterator(rightClass);
|
||||
while (li.hasNext()) {
|
||||
if (!ri.hasNext()) return Boolean.FALSE;
|
||||
PsiTypeParameter lp = li.next();
|
||||
PsiTypeParameter rp = ri.next();
|
||||
final PsiType typeLeft = leftSubstitutor.substitute(lp);
|
||||
if (typeLeft == null) continue;
|
||||
final PsiType typeRight = rightSubstitutor.substituteWithBoundsPromotion(rp);
|
||||
if (typeRight == null) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
if (!isAssignableByMethodCallConversion(typeLeft, typeRight, manager, scope)) return Boolean.FALSE;
|
||||
}
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
public static boolean isNumericType(PsiType type) {
|
||||
if (type instanceof PsiClassType) {
|
||||
return TYPE_TO_RANK.contains(type.getCanonicalText());
|
||||
|
||||
@@ -4,7 +4,9 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
@@ -27,76 +29,145 @@ public class GrStringUtil {
|
||||
}
|
||||
|
||||
public static String escapeSymbolsForGString(String s, boolean escapeDoubleQuotes) {
|
||||
return escapeSymbolsForGString(s, escapeDoubleQuotes, false);
|
||||
}
|
||||
|
||||
public static String escapeSymbolsForGString(String s, boolean escapeDoubleQuotes, boolean forInjection) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
final char[] chars = s.toCharArray();
|
||||
final int len = chars.length - 1;
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (chars[i] == '\\') {
|
||||
final char next = chars[i + 1];
|
||||
if (next == '\'') {
|
||||
b.append('\'');
|
||||
i++;
|
||||
}
|
||||
else if (next == 'n') {
|
||||
b.append('\n');
|
||||
i++;
|
||||
}
|
||||
else if (escapeDoubleQuotes && next == '"') {
|
||||
b.append('"');
|
||||
i++;
|
||||
}
|
||||
else {
|
||||
b.append(chars[i]);
|
||||
i++;
|
||||
b.append(chars[i]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (chars[i] == '"' || chars[i] == '$') b.append('\\');
|
||||
b.append(chars[i]);
|
||||
}
|
||||
if (i == len) {
|
||||
if (chars[i] == '"') b.append('\\');
|
||||
b.append(chars[i]);
|
||||
escapeStringCharacters(s.length(), s, escapeDoubleQuotes ? "$\"" : "$", false, forInjection, b);
|
||||
if (!forInjection) {
|
||||
unescapeCharacters(b, escapeDoubleQuotes ? "'" : "'\"", true);
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public static String escapeSymbolsForString(String s, boolean escapeQuotes) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
final char[] chars = s.toCharArray();
|
||||
final int len = chars.length - 1;
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (chars[i] == '\\') {
|
||||
final char next = chars[i + 1];
|
||||
if (next == '"' || next == '$') {
|
||||
b.append(next);
|
||||
return escapeSymbolsForString(s, escapeQuotes, false);
|
||||
}
|
||||
|
||||
public static String escapeSymbolsForString(String s, boolean escapeQuotes, boolean forInjection) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
escapeStringCharacters(s.length(), s, escapeQuotes ? "'" : "", false, forInjection, builder);
|
||||
if (!forInjection) {
|
||||
unescapeCharacters(builder, escapeQuotes ? "$\"" : "$'\"", true);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static StringBuilder escapeStringCharacters(int length,
|
||||
@NotNull String str,
|
||||
@Nullable String additionalChars,
|
||||
boolean escapeNR,
|
||||
boolean escapeSlash,
|
||||
@NotNull @NonNls StringBuilder buffer) {
|
||||
for (int idx = 0; idx < length; idx++) {
|
||||
char ch = str.charAt(idx);
|
||||
switch (ch) {
|
||||
case '\b':
|
||||
buffer.append("\\b");
|
||||
break;
|
||||
|
||||
case '\t':
|
||||
buffer.append("\\t");
|
||||
break;
|
||||
|
||||
case '\f':
|
||||
buffer.append("\\f");
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
if (escapeSlash) {
|
||||
buffer.append("\\\\");
|
||||
}
|
||||
else {
|
||||
buffer.append("\\");
|
||||
}
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
if (escapeNR) {
|
||||
buffer.append("\\n");
|
||||
}
|
||||
else {
|
||||
buffer.append('\n');
|
||||
}
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
if (escapeNR) {
|
||||
buffer.append("\\r");
|
||||
}
|
||||
else {
|
||||
buffer.append('\r');
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (additionalChars != null && additionalChars.indexOf(ch) > -1) {
|
||||
buffer.append("\\").append(ch);
|
||||
}
|
||||
else if (Character.isISOControl(ch)) {
|
||||
String hexCode = Integer.toHexString(ch).toUpperCase();
|
||||
buffer.append("\\u");
|
||||
int paddingCount = 4 - hexCode.length();
|
||||
while (paddingCount-- > 0) {
|
||||
buffer.append(0);
|
||||
}
|
||||
buffer.append(hexCode);
|
||||
}
|
||||
else {
|
||||
buffer.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static void unescapeCharacters(StringBuilder builder, String toUnescape, boolean isMultiLine) {
|
||||
for (int i = 0; i < builder.length(); i++) {
|
||||
if (builder.charAt(i) != '\\') continue;
|
||||
if (i + 1 == builder.length()) break;
|
||||
char next = builder.charAt(i + 1);
|
||||
if (next == 'n') {
|
||||
if (isMultiLine) {
|
||||
builder.replace(i, i + 2, "\n");
|
||||
}
|
||||
else if (next == 'n') {
|
||||
b.append('\n');
|
||||
}
|
||||
else if (escapeQuotes && next == '\'') {
|
||||
b.append(next);
|
||||
}
|
||||
else {
|
||||
b.append('\\');
|
||||
b.append(next);
|
||||
}
|
||||
else if (next == 'r') {
|
||||
if (isMultiLine) {
|
||||
builder.replace(i, i + 2, "\r");
|
||||
}
|
||||
}
|
||||
else if (toUnescape.indexOf(next) != -1) {
|
||||
builder.delete(i, i + 1);
|
||||
}
|
||||
else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String escapeSymbols(String s, String toEscape) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
boolean escaped = false;
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
final char ch = s.charAt(i);
|
||||
if (escaped) {
|
||||
builder.append(ch);
|
||||
escaped = false;
|
||||
continue;
|
||||
}
|
||||
if (chars[i] == '\'') b.append('\\');
|
||||
b.append(chars[i]);
|
||||
}
|
||||
if (ch == '\\') {
|
||||
escaped = true;
|
||||
}
|
||||
if (toEscape.indexOf(ch) >= 0) {
|
||||
builder.append('\\');
|
||||
}
|
||||
|
||||
if (i == len) {
|
||||
if (chars[i] == '\'') b.append('\\');
|
||||
b.append(chars[i]);
|
||||
builder.append(ch);
|
||||
}
|
||||
return b.toString();
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static String removeQuotes(@NotNull String s) {
|
||||
@@ -121,7 +192,7 @@ public class GrStringUtil {
|
||||
|
||||
public static String addQuotes(String s, boolean forGString) {
|
||||
if (forGString) {
|
||||
if (s.contains("\n")) {
|
||||
if (s.contains("\n") || s.contains("\r")) {
|
||||
return TRIPLE_DOUBLE_QUOTES + s + TRIPLE_DOUBLE_QUOTES;
|
||||
}
|
||||
else {
|
||||
@@ -129,7 +200,7 @@ public class GrStringUtil {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (s.contains("\n")) {
|
||||
if (s.contains("\n") || s.contains("\r")) {
|
||||
return TRIPLE_QUOTES + s + TRIPLE_QUOTES;
|
||||
}
|
||||
else {
|
||||
|
||||
+27
-6
@@ -16,20 +16,32 @@
|
||||
package org.jetbrains.plugins.groovy.lang.resolve;
|
||||
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.AbstractElementManipulator;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
|
||||
|
||||
public class GroovyStringLiteralManipulator extends AbstractElementManipulator<GrLiteral> {
|
||||
public GrLiteral handleContentChange(GrLiteral expr, TextRange range, String newContent) throws IncorrectOperationException {
|
||||
if (!(expr.getValue() instanceof String)) throw new IncorrectOperationException("cannot handle content change");
|
||||
String oldText = expr.getText();
|
||||
newContent = StringUtil.escapeStringCharacters(newContent);
|
||||
String newText = oldText.substring(0, range.getStartOffset()) + newContent + oldText.substring(range.getEndOffset());
|
||||
if (oldText.startsWith("'")) {
|
||||
newContent = GrStringUtil.escapeSymbolsForString(newContent, !oldText.startsWith("'''"), true);
|
||||
}
|
||||
else {
|
||||
newContent = GrStringUtil.escapeSymbolsForGString(newContent, !oldText.startsWith("\"\"\""), true);
|
||||
}
|
||||
String newText;
|
||||
if (range.getStartOffset() == 1 && (newContent.indexOf('\n') >= 0 || newContent.indexOf('\r') >= 0)) {
|
||||
String corner = oldText.substring(0, 1) + oldText.substring(0, 1) + oldText.substring(0, 1);
|
||||
newText = corner + newContent + corner;
|
||||
}
|
||||
else {
|
||||
newText = oldText.substring(0, range.getStartOffset()) + newContent + oldText.substring(range.getEndOffset());
|
||||
}
|
||||
final GrExpression newExpr = GroovyPsiElementFactory.getInstance(expr.getProject()).createExpressionFromText(newText);
|
||||
|
||||
PsiElement firstChild = expr.getFirstChild();
|
||||
@@ -48,9 +60,18 @@ public class GroovyStringLiteralManipulator extends AbstractElementManipulator<G
|
||||
}
|
||||
|
||||
public static TextRange getLiteralRange(String text) {
|
||||
if (text.length() > 6 && text.startsWith("\"\"\"") && text.endsWith("\"\"\"")) {
|
||||
return new TextRange(3, text.length() - 3);
|
||||
int start = 1;
|
||||
int fin = text.length();
|
||||
|
||||
String begin = text.substring(0, 1);
|
||||
if (text.startsWith("\"\"\"") || text.startsWith("'''")) {
|
||||
start += 2;
|
||||
begin = text.substring(0, 3);
|
||||
}
|
||||
return new TextRange(1, Math.max(1, text.length() - 1));
|
||||
|
||||
if (text.length() >= begin.length()*2 && text.endsWith(begin)) {
|
||||
fin -= begin.length();
|
||||
}
|
||||
return new TextRange(start, Math.max(1, fin));
|
||||
}
|
||||
}
|
||||
@@ -420,4 +420,8 @@ public class GroovyHighlightingTest extends LightCodeInsightFixtureTestCase {
|
||||
public void testResultOfIncUsed() {
|
||||
doTest(new GroovyResultOfIncrementOrDecrementUsedInspection());
|
||||
}
|
||||
|
||||
public void testNativeMapAssignability() {
|
||||
doTest(new GroovyAssignabilityCheckInspection());
|
||||
}
|
||||
}
|
||||
+3
@@ -281,4 +281,7 @@ public class ExpressionsParsingTest extends GroovyParsingTestCase {
|
||||
public void testcommandExpr$keywords() {doTest()}
|
||||
|
||||
public void testDiamond() {doTest()}
|
||||
|
||||
void testpath$stringMethodCall1() {doTest()}
|
||||
void testpath$stringMethodCall2() {doTest()}
|
||||
}
|
||||
|
||||
+12
@@ -713,4 +713,16 @@ class Foo {
|
||||
PsiReference ref = configureByFile("staticImportInSamePackage/A.groovy", "A.groovy");
|
||||
assertNotNull(ref.resolve())
|
||||
}
|
||||
|
||||
void testStringRefExpr1() {
|
||||
assertNotNull(resolve("a.groovy"));
|
||||
}
|
||||
|
||||
void testStringRefExpr2() {
|
||||
assertNotNull(resolve("a.groovy"));
|
||||
}
|
||||
|
||||
void testStringRefExpr3() {
|
||||
assertNotNull(resolve("a.groovy"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
def foo(Map<String, Map<String, Object>> m) {}
|
||||
|
||||
foo(a:[b:'c'])
|
||||
foo<warning descr="'foo' in 'NativeMapAssignability' cannot be applied to '(['a':java.lang.String])'">(a:'b')</warning>
|
||||
foo<warning descr="'foo' in 'NativeMapAssignability' cannot be applied to '(['a':java.util.Map<java.lang.Integer, java.lang.Integer>])'">(a:[(2):4])</warning>
|
||||
@@ -1 +1 @@
|
||||
def map = [1:'d', <warning descr="Duplicate element in the map">(1)</warning>:'sd']
|
||||
def map = [1:'d', <warning descr="Duplicate element in the map">1</warning>:'sd']
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
'foo'()
|
||||
-----
|
||||
Groovy script
|
||||
Method call
|
||||
Reference expression
|
||||
PsiElement(string)(''foo'')
|
||||
Arguments
|
||||
PsiElement(()('(')
|
||||
PsiElement())(')')
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
'foo'.substring(0, 1)
|
||||
-----
|
||||
Groovy script
|
||||
Method call
|
||||
Reference expression
|
||||
Literal
|
||||
PsiElement(string)(''foo'')
|
||||
PsiElement(.)('.')
|
||||
PsiElement(identifier)('substring')
|
||||
Arguments
|
||||
PsiElement(()('(')
|
||||
Literal
|
||||
PsiElement(Integer)('0')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
Literal
|
||||
PsiElement(Integer)('1')
|
||||
PsiElement())(')')
|
||||
@@ -0,0 +1,3 @@
|
||||
def foo(){}
|
||||
|
||||
'f<ref>oo'()
|
||||
@@ -0,0 +1,3 @@
|
||||
def foo(){}
|
||||
|
||||
"f<ref>oo"()
|
||||
@@ -0,0 +1,3 @@
|
||||
def 'foo bar'(){}
|
||||
|
||||
'f<ref>oo bar'()
|
||||
@@ -86,6 +86,12 @@
|
||||
<separator/>
|
||||
<add-to-group group-id="SubversionFilePopupGroup" anchor="last"/>
|
||||
</group>
|
||||
<action id="Subversion.MarkLocallyDeletedTreeResolved" class="org.jetbrains.idea.svn.actions.MarkLocallyDeletedTreeConflictResolvedAction">
|
||||
<add-to-group group-id="ChangesViewPopupMenu" anchor="after" relative-to-action="ChangesView.Diff"/>
|
||||
</action>
|
||||
<reference id="Subversion.MarkTreeResolved">
|
||||
<add-to-group group-id="ChangesViewPopupMenu" anchor="after" relative-to-action="ChangesView.Diff"/>
|
||||
</reference>
|
||||
<group id="SubversionUpdateActionGroup" class="org.jetbrains.idea.svn.actions.SubversionGroup">
|
||||
<reference id="Subversion.Add"/>
|
||||
<reference id="ChangesView.Rollback"/>
|
||||
|
||||
@@ -239,6 +239,9 @@ class SvnChangeProviderContext implements StatusReceiver {
|
||||
myChangelistBuilder.processChangeInList(createChange(SvnContentRevision.create(myVcs, filePath, status.getCommittedRevision()),
|
||||
CurrentContentRevision.create(filePath), FileStatus.MODIFIED, status), changeListNameFromStatus(status),
|
||||
SvnVcs.getKey());
|
||||
} else if (status.getTreeConflict() != null) {
|
||||
myChangelistBuilder.processChange(createChange(SvnContentRevision.create(myVcs, filePath, status.getCommittedRevision()),
|
||||
CurrentContentRevision.create(filePath), FileStatus.MODIFIED, status), SvnVcs.getKey());
|
||||
}
|
||||
checkSwitched(filePath, myChangelistBuilder, status, fStatus);
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
package org.jetbrains.idea.svn;
|
||||
|
||||
import com.intellij.openapi.vcs.changes.LocallyDeletedChange;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.changes.LocallyDeletedChange;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -42,4 +42,8 @@ public class SvnLocallyDeletedChange extends LocallyDeletedChange {
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
public ConflictState getConflictState() {
|
||||
return myConflictState;
|
||||
}
|
||||
}
|
||||
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.idea.svn.actions;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vcs.AbstractVcsHelper;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsDataKeys;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.BackgroundFromStartOption;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.LocallyDeletedChange;
|
||||
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
|
||||
import com.intellij.openapi.vcs.changes.ui.ChangesListView;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.svn.ConflictedSvnChange;
|
||||
import org.jetbrains.idea.svn.SvnBundle;
|
||||
import org.jetbrains.idea.svn.SvnLocallyDeletedChange;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.tmatesoft.svn.core.SVNDepth;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.wc.SVNConflictChoice;
|
||||
import org.tmatesoft.svn.core.wc.SVNWCClient;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author irengrig
|
||||
* Date: 6/8/11
|
||||
* Time: 4:58 PM
|
||||
*/
|
||||
public class MarkLocallyDeletedTreeConflictResolvedAction extends AnAction {
|
||||
public MarkLocallyDeletedTreeConflictResolvedAction() {
|
||||
super(SvnBundle.message("action.mark.tree.conflict.resolved.text"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final MyLocallyDeletedChecker locallyDeletedChecker = new MyLocallyDeletedChecker(e);
|
||||
if (! locallyDeletedChecker.isEnabled()) return;
|
||||
|
||||
final String markText = SvnBundle.message("action.mark.tree.conflict.resolved.confirmation.title");
|
||||
final Project project = locallyDeletedChecker.getProject();
|
||||
final int result = Messages.showYesNoDialog(project,
|
||||
SvnBundle.message("action.mark.tree.conflict.resolved.confirmation.text"), markText,
|
||||
Messages.getQuestionIcon());
|
||||
if (result == DialogWrapper.OK_EXIT_CODE) {
|
||||
final Ref<VcsException> exception = new Ref<VcsException>();
|
||||
ProgressManager
|
||||
.getInstance().run(new Task.Backgroundable(project, markText, true, BackgroundFromStartOption.getInstance()) {
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
resolveLocallyDeletedTextConflict(locallyDeletedChecker, exception);
|
||||
}
|
||||
});
|
||||
if (! exception.isNull()) {
|
||||
AbstractVcsHelper.getInstance(project).showError(exception.get(), markText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
final MyLocallyDeletedChecker locallyDeletedChecker = new MyLocallyDeletedChecker(e);
|
||||
e.getPresentation().setVisible(locallyDeletedChecker.isEnabled());
|
||||
e.getPresentation().setEnabled(locallyDeletedChecker.isEnabled());
|
||||
//e.getPresentation().setText(SvnBundle.message("action.mark.tree.conflict.resolved.text"));
|
||||
}
|
||||
|
||||
private void resolveLocallyDeletedTextConflict(MyLocallyDeletedChecker checker, Ref<VcsException> exception) {
|
||||
final FilePath path = checker.getPath();
|
||||
resolve(checker.getProject(), exception, path);
|
||||
VcsDirtyScopeManager.getInstance(checker.getProject()).filePathsDirty(Collections.singletonList(path), null);
|
||||
}
|
||||
|
||||
private void resolve(Project project, Ref<VcsException> exception, FilePath path) {
|
||||
final SVNWCClient client = SvnVcs.getInstance(project).createWCClient();
|
||||
try {
|
||||
client.doResolve(path.getIOFile(), SVNDepth.EMPTY, false, false, true, SVNConflictChoice.MERGED);
|
||||
}
|
||||
catch (SVNException e1) {
|
||||
exception.set(new VcsException(e1));
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyLocallyDeletedChecker {
|
||||
private final boolean myEnabled;
|
||||
private final FilePath myPath;
|
||||
private final Project myProject;
|
||||
|
||||
public MyLocallyDeletedChecker(final AnActionEvent e) {
|
||||
final DataContext dc = e.getDataContext();
|
||||
myProject = PlatformDataKeys.PROJECT.getData(dc);
|
||||
if (myProject == null) {
|
||||
myPath = null;
|
||||
myEnabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
final List<LocallyDeletedChange> missingFiles = e.getData(ChangesListView.LOCALLY_DELETED_CHANGES);
|
||||
|
||||
if (missingFiles == null || missingFiles.size() != 1) {
|
||||
final Change[] changes = e.getData(VcsDataKeys.CHANGES);
|
||||
if (changes == null || changes.length != 1 || changes[0].getAfterRevision() != null) {
|
||||
myPath = null;
|
||||
myEnabled = false;
|
||||
return;
|
||||
}
|
||||
myEnabled = changes[0] instanceof ConflictedSvnChange && ((ConflictedSvnChange) changes[0]).getConflictState().isTree();
|
||||
if (myEnabled) {
|
||||
myPath = changes[0].getBeforeRevision().getFile();
|
||||
} else {
|
||||
myPath = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final LocallyDeletedChange change = missingFiles.get(0);
|
||||
myEnabled = change instanceof SvnLocallyDeletedChange && ((SvnLocallyDeletedChange) change).getConflictState().isTree();
|
||||
if (myEnabled) {
|
||||
myPath = ((SvnLocallyDeletedChange) change).getPath();
|
||||
}
|
||||
else {
|
||||
myPath = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return myEnabled;
|
||||
}
|
||||
|
||||
public FilePath getPath() {
|
||||
return myPath;
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return myProject;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user