From d75838ad201abb98562ef7a31d978124ace272f6 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Fri, 6 Sep 2013 16:35:43 +0200 Subject: [PATCH 01/22] =?UTF-8?q?continue=20WEB-1171=20javascript=20live?= =?UTF-8?q?=20console=20=E2=80=94=20works=20now,=20but=20UI=20is=20ugly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../console/LanguageConsoleImpl.java | 51 ++++++++++--------- .../console/LanguageConsoleViewImpl.java | 8 ++- .../openapi/util/text/StringUtilRt.java | 15 +++++- 3 files changed, 48 insertions(+), 26 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java index 53caeb97b999..680f936eed25 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java @@ -55,6 +55,7 @@ import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.util.text.StringUtilRt; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; @@ -380,10 +381,6 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { this.myTitle = title; } - public void addToHistory(final String text, final TextAttributes attributes) { - printToHistory(text, attributes); - } - public void printToHistory(@NotNull final List> attributedText) { ApplicationManager.getApplication().assertIsDispatchThread(); if (LOG.isDebugEnabled()) { @@ -400,7 +397,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { } final DocumentEx history = myHistoryViewer.getDocument(); final int oldHistoryLength = history.getTextLength(); - appendToHistoryDocument(history, sb.toString()); + appendToHistoryDocument(history, sb); assert oldHistoryLength + offsets[i] >= history.getTextLength() : "unexpected history length " + oldHistoryLength + " " + offsets[i] + " " + history.getTextLength(); @@ -435,9 +432,9 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { LOG.debug("printToHistory(): completed"); } - public void printToHistory(String text, final TextAttributes attributes) { + public void printToHistory(@NotNull CharSequence text, @NotNull TextAttributes attributes) { ApplicationManager.getApplication().assertIsDispatchThread(); - text = StringUtil.convertLineSeparators(text); + text = StringUtilRt.unifyLineSeparators(text); final boolean scrollToEnd = shouldScrollHistoryToEnd(); addTextToHistory(text, attributes); if (scrollToEnd) { @@ -446,8 +443,11 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { queueUiUpdate(scrollToEnd); } - protected void addTextToHistory(@Nullable String text, @Nullable TextAttributes attributes) { - if (text == null || text.length() == 0) return; + protected void addTextToHistory(@Nullable CharSequence text, @Nullable TextAttributes attributes) { + if (StringUtil.isEmpty(text)) { + return; + } + Document history = myHistoryViewer.getDocument(); MarkupModel markupModel = DocumentMarkupModel.forDocument(history, myProject, true); int offset = history.getTextLength(); @@ -557,7 +557,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { addTextToHistory(myPrompt, ConsoleViewContentType.USER_INPUT.getAttributes()); } - protected void appendToHistoryDocument(@NotNull Document history, @NotNull String text) { + protected void appendToHistoryDocument(@NotNull Document history, @NotNull CharSequence text) { ApplicationManager.getApplication().assertIsDispatchThread(); history.insertString(history.getTextLength(), text); } @@ -619,7 +619,6 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { public void calcData(DataKey key, DataSink sink) { if (OpenFileDescriptor.NAVIGATE_IN_EDITOR == key) { sink.put(OpenFileDescriptor.NAVIGATE_IN_EDITOR, myConsoleEditor); - return; } else if (getProject().isInitialized()) { FileEditorManager editorManager = FileEditorManager.getInstance(getProject()); @@ -729,8 +728,23 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { } } + public void printToHistoryOnEdt(@NotNull final CharSequence text, @NotNull final TextAttributes attributes) { + Application application = ApplicationManager.getApplication(); + if (application.isDispatchThread()) { + printToHistory(text, attributes); + } + else { + application.invokeLater(new Runnable() { + @Override + public void run() { + printToHistory(text, attributes); + } + }, ModalityState.stateForComponent(getComponent())); + } + } + public static void printToConsole(@NotNull final LanguageConsoleImpl console, - @NotNull final String string, + @NotNull final CharSequence string, @NotNull final ConsoleViewContentType mainType, @Nullable ConsoleViewContentType additionalType) { final TextAttributes mainAttributes = mainType.getAttributes(); @@ -743,18 +757,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { attributes.setBackgroundColor(mainAttributes.getBackgroundColor()); } - Application application = ApplicationManager.getApplication(); - if (application.isDispatchThread()) { - console.printToHistory(string, attributes); - } - else { - application.invokeLater(new Runnable() { - @Override - public void run() { - console.printToHistory(string, attributes); - } - }, ModalityState.stateForComponent(console.getComponent())); - } + console.printToHistoryOnEdt(string, attributes); } private class MyLayout extends AbstractLayoutManager { diff --git a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleViewImpl.java index 530d8394f68a..89f6da48b9f7 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleViewImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleViewImpl.java @@ -20,6 +20,7 @@ import com.intellij.lang.Language; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; +import com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -36,7 +37,12 @@ public class LanguageConsoleViewImpl extends ConsoleViewImpl implements Language } public LanguageConsoleViewImpl(@NotNull LanguageConsoleImpl console) { - super(console.getProject(), true); + this(console, true); + } + + public LanguageConsoleViewImpl(@NotNull LanguageConsoleImpl console, boolean usePredefinedMessageFilter) { + super(console.getProject(), GlobalSearchScope.allScope(console.getProject()), true, null, usePredefinedMessageFilter); + myConsole = console; Disposer.register(this, myConsole); } diff --git a/platform/util-rt/src/com/intellij/openapi/util/text/StringUtilRt.java b/platform/util-rt/src/com/intellij/openapi/util/text/StringUtilRt.java index 7130d22e1d38..1cffb307d76d 100644 --- a/platform/util-rt/src/com/intellij/openapi/util/text/StringUtilRt.java +++ b/platform/util-rt/src/com/intellij/openapi/util/text/StringUtilRt.java @@ -101,6 +101,19 @@ public class StringUtilRt { @NotNull String newSeparator, @Nullable int[] offsetsToKeep, boolean keepCarriageReturn) { + return unifyLineSeparators(text, newSeparator, offsetsToKeep, keepCarriageReturn).toString(); + } + + @NotNull + public static CharSequence unifyLineSeparators(@NotNull CharSequence text) { + return unifyLineSeparators(text, "\n", null, false); + } + + @NotNull + public static CharSequence unifyLineSeparators(@NotNull CharSequence text, + @NotNull String newSeparator, + @Nullable int[] offsetsToKeep, + boolean keepCarriageReturn) { StringBuilder buffer = null; int intactLength = 0; final boolean newSeparatorIsSlashN = "\n".equals(newSeparator); @@ -156,7 +169,7 @@ public class StringUtilRt { } } } - return buffer == null ? text : buffer.toString(); + return buffer == null ? text : buffer; } private static void shiftOffsets(int[] offsets, int changeOffset, int oldLength, int newLength) { From 238e31190f732321864c1f1e82e039920457e92f Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 9 Sep 2013 10:26:34 +0200 Subject: [PATCH 02/22] prefer to use interface LanguageConsoleView instead of impl class --- .../com/intellij/execution/console/LanguageConsoleView.java | 4 ++++ .../src/com/intellij/execution/impl/ConsoleViewImpl.java | 1 + 2 files changed, 5 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleView.java b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleView.java index 57dc911a89b4..1a53660c3017 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleView.java +++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleView.java @@ -16,6 +16,7 @@ package com.intellij.execution.console; import com.intellij.execution.ui.ConsoleView; +import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; /** @@ -24,4 +25,7 @@ import org.jetbrains.annotations.NotNull; public interface LanguageConsoleView extends ConsoleView { @NotNull LanguageConsoleImpl getConsole(); + + @NotNull + Project getProject(); } diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java index 74e53ce7fea9..00d39fcb09f3 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java @@ -1885,6 +1885,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo } } + @NotNull public Project getProject() { return myProject; } From 286cdc3bae037468a283aef390078c25f80fb761 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 9 Sep 2013 12:56:47 +0400 Subject: [PATCH 03/22] anonym -> lambda: unique param names (IDEA-113338) --- .../AnonymousCanBeLambdaInspection.java | 64 +++++++++++-------- .../afterComparableConflicts.java | 7 ++ .../beforeComparableConflicts.java | 12 ++++ 3 files changed, 58 insertions(+), 25 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/afterComparableConflicts.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeComparableConflicts.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java index b5b3d3e898be..b6398b22e7f5 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java @@ -23,6 +23,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.Function; @@ -151,13 +152,14 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection final PsiAnonymousClass anonymousClass = PsiTreeUtil.getParentOfType(element, PsiAnonymousClass.class); LOG.assertTrue(anonymousClass != null); ChangeContextUtil.encodeContextInfo(anonymousClass, true); - boolean validContext = LambdaUtil.isValidLambdaContext(anonymousClass.getParent().getParent()); + final PsiElement lambdaContext = anonymousClass.getParent().getParent(); + boolean validContext = LambdaUtil.isValidLambdaContext(lambdaContext); final String canonicalText = anonymousClass.getBaseClassType().getCanonicalText(); final PsiMethod method = anonymousClass.getMethods()[0]; LOG.assertTrue(method != null); - final String lambdaWithTypesDeclared = composeLambdaText(method, true); - final String withoutTypesDeclared = composeLambdaText(method, false); + final String lambdaWithTypesDeclared = composeLambdaText(method, lambdaContext, true); + final String withoutTypesDeclared = composeLambdaText(method, lambdaContext, false); final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project); PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)elementFactory.createExpressionFromText(withoutTypesDeclared, anonymousClass); @@ -229,32 +231,44 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection interfaceType) != null; } - private static String composeLambdaText(PsiMethod method, final boolean appendType) { + private static String composeLambdaText(PsiMethod method, final PsiElement lambdaContext, final boolean appendType) { final StringBuilder buf = new StringBuilder(); - if (appendType) { - buf.append(method.getParameterList().getText()); - } else { - final PsiParameter[] parameters = method.getParameterList().getParameters(); - if (parameters.length != 1) { - buf.append("("); - } - buf.append(StringUtil.join(parameters, - new Function() { - @Override - public String fun(PsiParameter parameter) { - String parameterName = parameter.getName(); - if (parameterName == null) { - parameterName = ""; - } - return parameterName; - } - }, ",")); - if (parameters.length != 1) { - buf.append(")"); - } + final PsiParameter[] parameters = method.getParameterList().getParameters(); + if (parameters.length != 1 || appendType) { + buf.append("("); + } + final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(lambdaContext.getProject()); + buf.append(StringUtil.join(parameters, + new Function() { + @Override + public String fun(PsiParameter parameter) { + return composeParameter(parameter, appendType, codeStyleManager, lambdaContext); + } + }, ",")); + if (parameters.length != 1 || appendType) { + buf.append(")"); } buf.append("-> {}"); return buf.toString(); } + + private static String composeParameter(PsiParameter parameter, + boolean appendType, + JavaCodeStyleManager codeStyleManager, + PsiElement lambdaContext) { + final String parameterType; + if (appendType) { + final PsiTypeElement typeElement = parameter.getTypeElement(); + parameterType = typeElement != null ? (typeElement.getText() + " ") : ""; + } + else { + parameterType = ""; + } + String parameterName = parameter.getName(); + if (parameterName == null) { + parameterName = ""; + } + return parameterType + codeStyleManager.suggestUniqueVariableName(parameterName, lambdaContext, true); + } } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/afterComparableConflicts.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/afterComparableConflicts.java new file mode 100644 index 000000000000..0dac8f456767 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/afterComparableConflicts.java @@ -0,0 +1,7 @@ +// "Replace with lambda" "true" +class Test { + { + String o = ""; + Comparable c = o1 -> 0; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeComparableConflicts.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeComparableConflicts.java new file mode 100644 index 000000000000..f8ba6ced6af4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeComparableConflicts.java @@ -0,0 +1,12 @@ +// "Replace with lambda" "true" +class Test { + { + String o = ""; + Comparable c = new Comparable() { + @Override + public int compareTo(String o) { + return 0; + } + }; + } +} \ No newline at end of file From f58251be07d7bb80b86819ed508810626d94f430 Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Mon, 9 Sep 2013 13:06:45 +0400 Subject: [PATCH 04/22] XDebugProcess.registerAdditionalContent method restored to keep compatibility with IDEA 12 API --- .../com/intellij/xdebugger/XDebugProcess.java | 19 +++++++++++++++---- ...ugLayouter.java => XDebugTabLayouter.java} | 2 +- .../xdebugger/impl/ui/XDebugSessionTab.java | 6 ++++-- 3 files changed, 20 insertions(+), 7 deletions(-) rename platform/xdebugger-api/src/com/intellij/xdebugger/ui/{XDebugLayouter.java => XDebugTabLayouter.java} (97%) diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java index cd42ae461212..f2b6003083aa 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java @@ -19,12 +19,13 @@ package com.intellij.xdebugger; import com.intellij.execution.filters.TextConsoleBuilderFactory; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.ui.ExecutionConsole; +import com.intellij.execution.ui.RunnerLayoutUi; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.xdebugger.breakpoints.XBreakpointHandler; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; import com.intellij.xdebugger.frame.XValueMarkerProvider; import com.intellij.xdebugger.stepping.XSmartStepIntoHandler; -import com.intellij.xdebugger.ui.XDebugLayouter; +import com.intellij.xdebugger.ui.XDebugTabLayouter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -171,6 +172,15 @@ public abstract class XDebugProcess { return null; } + /** + * Override this method to provide additional tabs for 'Debug' tool window + * + * @Deprecated use {@link com.intellij.xdebugger.ui.XDebugTabLayouter#registerAdditionalContent} instead + */ + @Deprecated + public void registerAdditionalContent(@NotNull RunnerLayoutUi ui) { + } + /** * Override this method to provide additional actions in 'Debug' tool window */ @@ -190,8 +200,8 @@ public abstract class XDebugProcess { } @NotNull - public XDebugLayouter createLayouter() { - return new XDebugLayouter(); + public XDebugTabLayouter createLayouter() { + return new XDebugTabLayouter(); } /** @@ -201,4 +211,5 @@ public abstract class XDebugProcess { public boolean isValuesCustomSorted() { return false; } -} \ No newline at end of file + +} diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/ui/XDebugLayouter.java b/platform/xdebugger-api/src/com/intellij/xdebugger/ui/XDebugTabLayouter.java similarity index 97% rename from platform/xdebugger-api/src/com/intellij/xdebugger/ui/XDebugLayouter.java rename to platform/xdebugger-api/src/com/intellij/xdebugger/ui/XDebugTabLayouter.java index 0cd80d9281d3..1734bdf8c593 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/ui/XDebugLayouter.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/ui/XDebugTabLayouter.java @@ -14,7 +14,7 @@ import org.jetbrains.annotations.NotNull; * * @author Sergey Simonchik */ -public class XDebugLayouter { +public class XDebugTabLayouter { /** * Registers tab for the given {@code console}. diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java index e5f0b40bb4f4..8ae4655d424a 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java @@ -46,7 +46,7 @@ import com.intellij.xdebugger.impl.frame.XFramesView; import com.intellij.xdebugger.impl.frame.XVariablesView; import com.intellij.xdebugger.impl.frame.XWatchesView; import com.intellij.xdebugger.impl.ui.tree.actions.SortValuesToggleAction; -import com.intellij.xdebugger.ui.XDebugLayouter; +import com.intellij.xdebugger.ui.XDebugTabLayouter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -127,10 +127,12 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { myUi.addContent(createFramesContent(session), 0, PlaceInGrid.left, false); myUi.addContent(createVariablesContent(session), 0, PlaceInGrid.center, false); myUi.addContent(createWatchesContent(session, sessionData), 0, PlaceInGrid.right, false); - XDebugLayouter layouter = debugProcess.createLayouter(); + XDebugTabLayouter layouter = debugProcess.createLayouter(); Content consoleContent = layouter.registerConsoleContent(myUi, myConsole); attachNotificationTo(consoleContent); + //noinspection deprecation + debugProcess.registerAdditionalContent(myUi); layouter.registerAdditionalContent(myUi); RunContentBuilder.addAdditionalConsoleEditorActions(myConsole, consoleContent); From 8d29e4f8fce1f00684eabdf141162f1fefb455f4 Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Mon, 9 Sep 2013 13:14:14 +0400 Subject: [PATCH 05/22] XDebugProcess method rename: createLayouter -> createTabLayouter --- .../xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java | 2 +- .../src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java index f2b6003083aa..ced315cd3d41 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java @@ -200,7 +200,7 @@ public abstract class XDebugProcess { } @NotNull - public XDebugTabLayouter createLayouter() { + public XDebugTabLayouter createTabLayouter() { return new XDebugTabLayouter(); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java index 8ae4655d424a..511953362951 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java @@ -127,7 +127,7 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { myUi.addContent(createFramesContent(session), 0, PlaceInGrid.left, false); myUi.addContent(createVariablesContent(session), 0, PlaceInGrid.center, false); myUi.addContent(createWatchesContent(session, sessionData), 0, PlaceInGrid.right, false); - XDebugTabLayouter layouter = debugProcess.createLayouter(); + XDebugTabLayouter layouter = debugProcess.createTabLayouter(); Content consoleContent = layouter.registerConsoleContent(myUi, myConsole); attachNotificationTo(consoleContent); From c7d70800d4620d805d2a0de546585e72917dc430 Mon Sep 17 00:00:00 2001 From: Alex Ruiz Date: Sun, 8 Sep 2013 16:15:31 -0700 Subject: [PATCH 06/22] Minor changes to NewProjectCheckoutListener to reuse its code. Change-Id: I4393552b2b4cc7adb6074b6e7bc7d71d62dd9d12 --- .../openapi/vcs/checkout/NewProjectCheckoutListener.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/java/idea-ui/src/com/intellij/openapi/vcs/checkout/NewProjectCheckoutListener.java b/java/idea-ui/src/com/intellij/openapi/vcs/checkout/NewProjectCheckoutListener.java index f395d48c2d42..0abd54fa51f2 100644 --- a/java/idea-ui/src/com/intellij/openapi/vcs/checkout/NewProjectCheckoutListener.java +++ b/java/idea-ui/src/com/intellij/openapi/vcs/checkout/NewProjectCheckoutListener.java @@ -27,6 +27,7 @@ import com.intellij.openapi.vcs.VcsKey; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.projectImport.ProjectImportProvider; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.Collections; @@ -48,7 +49,7 @@ public class NewProjectCheckoutListener implements VcsAwareCheckoutListener { final Project[] projects = pm.getOpenProjects(); final Set files = projectsLocationSet(projects); VirtualFile file = LocalFileSystem.getInstance().findFileByIoFile(directory); - AddModuleWizard wizard = ImportModuleAction.createImportWizard(null, null, file, ProjectImportProvider.PROJECT_IMPORT_PROVIDER.getExtensions()); + AddModuleWizard wizard = createImportWizard(file); if (wizard == null) return false; if (wizard.showAndGet()) { ImportModuleAction.createFromWizard(null, wizard); @@ -67,6 +68,11 @@ public class NewProjectCheckoutListener implements VcsAwareCheckoutListener { return false; } + @Nullable + protected AddModuleWizard createImportWizard(VirtualFile file) { + return ImportModuleAction.createImportWizard(null, null, file, ProjectImportProvider.PROJECT_IMPORT_PROVIDER.getExtensions()); + } + private static Set projectsLocationSet(Project[] projects) { final Set files = new HashSet(); for (Project project1 : projects) { From ac12238675f85de1c1774210782923cecd98e09a Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 9 Sep 2013 10:44:52 +0200 Subject: [PATCH 07/22] add Copyright --- .../runners/BaseConsoleExecuteActionHandler.java | 15 +++++++++++++++ .../execution/runners/ConsoleExecuteAction.java | 15 +++++++++++++++ .../runners/ConsoleExecuteActionHandler.java | 2 +- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/execution/runners/BaseConsoleExecuteActionHandler.java b/platform/lang-impl/src/com/intellij/execution/runners/BaseConsoleExecuteActionHandler.java index 42024c8eb48e..364662063cf2 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/BaseConsoleExecuteActionHandler.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/BaseConsoleExecuteActionHandler.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.execution.runners; import com.intellij.execution.console.LanguageConsoleImpl; diff --git a/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteAction.java b/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteAction.java index 7d340e8c7fdd..25849e7bc9ce 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteAction.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteAction.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.execution.runners; import com.intellij.codeInsight.lookup.Lookup; diff --git a/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteActionHandler.java b/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteActionHandler.java index b98b11b5ce64..98d849ac4d83 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteActionHandler.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteActionHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2013 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. From 0aa3d9d80528f54d9faa2933a5f5677b0b77c326 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 9 Sep 2013 11:53:52 +0200 Subject: [PATCH 08/22] continue WEB-1171 javascript live console: add history actions --- .../console/LanguageConsoleImpl.java | 1 + .../AbstractConsoleRunnerWithHistory.java | 24 +++----------- .../runners/ConsoleRunnerWithHistory.java | 13 -------- .../runners/LanguageConsoleBuilder.java | 32 +++++++++++++++++++ .../ProcessBackedConsoleExecuteAction.java | 21 ++++++++++++ 5 files changed, 58 insertions(+), 33 deletions(-) delete mode 100644 platform/lang-impl/src/com/intellij/execution/runners/ConsoleRunnerWithHistory.java create mode 100644 platform/lang-impl/src/com/intellij/execution/runners/LanguageConsoleBuilder.java create mode 100644 platform/lang-impl/src/com/intellij/execution/runners/ProcessBackedConsoleExecuteAction.java diff --git a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java index 680f936eed25..b985b1929ba7 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java @@ -86,6 +86,7 @@ import java.util.concurrent.atomic.AtomicBoolean; /** * @author Gregory.Shrago + * In case of REPL consider to use {@link com.intellij.execution.runners.LanguageConsoleBuilder} */ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { private static final Logger LOG = Logger.getInstance("#" + LanguageConsoleImpl.class.getName()); diff --git a/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java b/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java index ea1b098b80b3..a0c840d5d338 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java @@ -47,7 +47,7 @@ import java.util.List; * This class provides basic functionality for running consoles. * It launches external process and handles line input with history */ -public abstract class AbstractConsoleRunnerWithHistory extends ConsoleRunnerWithHistory { +public abstract class AbstractConsoleRunnerWithHistory { private final String myConsoleTitle; private ProcessHandler myProcessHandler; @@ -55,11 +55,12 @@ public abstract class AbstractConsoleRunnerWithHistory { - protected final Project myProject; - - public ConsoleRunnerWithHistory(@NotNull Project project) { - myProject = project; - } -} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/execution/runners/LanguageConsoleBuilder.java b/platform/lang-impl/src/com/intellij/execution/runners/LanguageConsoleBuilder.java new file mode 100644 index 000000000000..a64af30d8e25 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/execution/runners/LanguageConsoleBuilder.java @@ -0,0 +1,32 @@ +package com.intellij.execution.runners; + +import com.intellij.execution.console.ConsoleHistoryController; +import com.intellij.execution.console.LanguageConsoleImpl; +import com.intellij.execution.console.LanguageConsoleView; +import com.intellij.execution.process.ProcessHandler; +import org.jetbrains.annotations.NotNull; + +public class LanguageConsoleBuilder { + private LanguageConsoleImpl myConsole; + private ProcessHandler myProcessHandler; + + public LanguageConsoleBuilder console(@NotNull LanguageConsoleView console) { + myConsole = console.getConsole(); + return this; + } + + public LanguageConsoleBuilder processHandler(ProcessHandler processHandler) { + myProcessHandler = processHandler; + return this; + } + + public LanguageConsoleBuilder initActions(@NotNull BaseConsoleExecuteActionHandler executeActionHandler, @NotNull String historyType) { + ConsoleExecuteAction action = myProcessHandler == null + ? new ConsoleExecuteAction(myConsole, executeActionHandler) + : new ProcessBackedConsoleExecuteAction(myConsole, myProcessHandler, executeActionHandler); + action.registerCustomShortcutSet(action.getShortcutSet(), myConsole.getConsoleEditor().getComponent()); + + new ConsoleHistoryController(historyType, "", myConsole, executeActionHandler.getConsoleHistoryModel()).install(); + return this; + } +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/execution/runners/ProcessBackedConsoleExecuteAction.java b/platform/lang-impl/src/com/intellij/execution/runners/ProcessBackedConsoleExecuteAction.java new file mode 100644 index 000000000000..7132a2ef99ee --- /dev/null +++ b/platform/lang-impl/src/com/intellij/execution/runners/ProcessBackedConsoleExecuteAction.java @@ -0,0 +1,21 @@ +package com.intellij.execution.runners; + +import com.intellij.execution.console.LanguageConsoleImpl; +import com.intellij.execution.process.ProcessHandler; + +class ProcessBackedConsoleExecuteAction extends ConsoleExecuteAction { + private final ProcessHandler myProcessHandler; + + public ProcessBackedConsoleExecuteAction(LanguageConsoleImpl languageConsole, + ProcessHandler processHandler, + BaseConsoleExecuteActionHandler consoleExecuteActionHandler) { + super(languageConsole, consoleExecuteActionHandler); + + myProcessHandler = processHandler; + } + + @Override + protected boolean isEnabled() { + return !myProcessHandler.isProcessTerminated(); + } +} \ No newline at end of file From 2e3c2598054bc5440e7f590a2d82509bb7a5c6fc Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 9 Sep 2013 13:00:18 +0400 Subject: [PATCH 09/22] notnullification --- .../impl/runtime/deployment/debug/JavaDebuggerLauncherImpl.java | 2 +- .../remoteServer/runtime/deployment/DeploymentStatus.java | 1 + .../remoteServer/runtime/deployment/debug/DebuggerLauncher.java | 2 +- .../runtime/deployment/debug/JavaDebuggerLauncher.java | 2 ++ 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/debug/JavaDebuggerLauncherImpl.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/debug/JavaDebuggerLauncherImpl.java index 3ec24ef56075..76658698d034 100644 --- a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/debug/JavaDebuggerLauncherImpl.java +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/debug/JavaDebuggerLauncherImpl.java @@ -34,7 +34,7 @@ public class JavaDebuggerLauncherImpl extends JavaDebuggerLauncher { private static final Logger LOG = Logger.getInstance(JavaDebuggerLauncherImpl.class); @Override - public void startDebugSession(@NotNull JavaDebugConnectionData info, @NotNull ExecutionEnvironment executionEnvironment, RemoteServer server) + public void startDebugSession(@NotNull JavaDebugConnectionData info, @NotNull ExecutionEnvironment executionEnvironment, @NotNull RemoteServer server) throws ExecutionException { final Project project = executionEnvironment.getProject(); Executor executor = DefaultDebugExecutor.getDebugExecutorInstance(); diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/DeploymentStatus.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/DeploymentStatus.java index a9f7c285ebdb..e8e96751eb52 100644 --- a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/DeploymentStatus.java +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/DeploymentStatus.java @@ -13,6 +13,7 @@ public enum DeploymentStatus { myPresentableText = presentableText; } + @NotNull public String getPresentableText() { return myPresentableText; } diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/DebuggerLauncher.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/DebuggerLauncher.java index 6901fe8f4491..7b05ccda4a43 100644 --- a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/DebuggerLauncher.java +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/DebuggerLauncher.java @@ -9,5 +9,5 @@ import org.jetbrains.annotations.NotNull; * @author nik */ public interface DebuggerLauncher { - void startDebugSession(@NotNull D info, @NotNull ExecutionEnvironment executionEnvironment, RemoteServer server) throws ExecutionException; + void startDebugSession(@NotNull D info, @NotNull ExecutionEnvironment executionEnvironment, @NotNull RemoteServer server) throws ExecutionException; } diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/JavaDebuggerLauncher.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/JavaDebuggerLauncher.java index ad459ae1fb5c..2cf0b4592314 100644 --- a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/JavaDebuggerLauncher.java +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/JavaDebuggerLauncher.java @@ -1,11 +1,13 @@ package com.intellij.remoteServer.runtime.deployment.debug; import com.intellij.openapi.components.ServiceManager; +import org.jetbrains.annotations.NotNull; /** * @author nik */ public abstract class JavaDebuggerLauncher implements DebuggerLauncher { + @NotNull public static JavaDebuggerLauncher getInstance() { return ServiceManager.getService(JavaDebuggerLauncher.class); } From 1e9a0d8d813891b277ac7e48bfab9bcaac9207ba Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 9 Sep 2013 13:58:47 +0400 Subject: [PATCH 10/22] xdebugger: simplified calling old deprecated method & javadocs added --- .../src/com/intellij/xdebugger/XDebugProcess.java | 14 ++++++++++---- .../intellij/xdebugger/ui/XDebugTabLayouter.java | 1 + .../xdebugger/impl/ui/XDebugSessionTab.java | 2 -- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java index ced315cd3d41..62e2892b81c6 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java @@ -173,9 +173,7 @@ public abstract class XDebugProcess { } /** - * Override this method to provide additional tabs for 'Debug' tool window - * - * @Deprecated use {@link com.intellij.xdebugger.ui.XDebugTabLayouter#registerAdditionalContent} instead + * @deprecated override {@link #createTabLayouter()} and {@link com.intellij.xdebugger.ui.XDebugTabLayouter#registerAdditionalContent} instead */ @Deprecated public void registerAdditionalContent(@NotNull RunnerLayoutUi ui) { @@ -199,9 +197,17 @@ public abstract class XDebugProcess { return null; } + /** + * Override this method to customize content of tab in 'Debug' tool window + */ @NotNull public XDebugTabLayouter createTabLayouter() { - return new XDebugTabLayouter(); + return new XDebugTabLayouter() { + @Override + public void registerAdditionalContent(@NotNull RunnerLayoutUi ui) { + XDebugProcess.this.registerAdditionalContent(ui); + } + }; } /** diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/ui/XDebugTabLayouter.java b/platform/xdebugger-api/src/com/intellij/xdebugger/ui/XDebugTabLayouter.java index 1734bdf8c593..f884062b957b 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/ui/XDebugTabLayouter.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/ui/XDebugTabLayouter.java @@ -13,6 +13,7 @@ import org.jetbrains.annotations.NotNull; * Allows to customize xdebug layout for 'Debug' tool window. * * @author Sergey Simonchik + * @see com.intellij.xdebugger.XDebugProcess#createTabLayouter() */ public class XDebugTabLayouter { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java index 511953362951..befd7b7058bd 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java @@ -131,8 +131,6 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { Content consoleContent = layouter.registerConsoleContent(myUi, myConsole); attachNotificationTo(consoleContent); - //noinspection deprecation - debugProcess.registerAdditionalContent(myUi); layouter.registerAdditionalContent(myUi); RunContentBuilder.addAdditionalConsoleEditorActions(myConsole, consoleContent); From c51363b5f8ce111fe1a307b90dca42061372bf9d Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 9 Sep 2013 12:11:03 +0200 Subject: [PATCH 11/22] we should not call execute action if completion variant not focused --- .../com/intellij/execution/runners/ConsoleExecuteAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteAction.java b/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteAction.java index 25849e7bc9ce..065499ecd8f4 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteAction.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteAction.java @@ -50,7 +50,7 @@ public class ConsoleExecuteAction extends DumbAwareAction { EditorEx editor = myConsole.getConsoleEditor(); Lookup lookup = LookupManager.getActiveLookup(editor); e.getPresentation().setEnabled(!editor.isRendererMode() && isEnabled() && - (lookup == null || !(lookup.isCompletion() && lookup.isFocused()))); + (lookup == null || !lookup.isCompletion())); } @Override From c9fc4949ce5d89aeb9146717028e66d64aa7014a Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 9 Sep 2013 13:28:01 +0400 Subject: [PATCH 12/22] pull up: ensure that default won't be inserted for ll < 1.8 (IDEA-113323) --- .../src/com/intellij/refactoring/memberPullUp/PullUpHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java index 7a11a69e2d82..ea230e3517ce 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java @@ -236,7 +236,7 @@ public class PullUpHelper extends BaseRefactoringProcessor{ if (myIsTargetInterface || info.isToAbstract()) { ChangeContextUtil.clearContextInfo(method); - if (!info.isToAbstract() && !method.hasModifierProperty(PsiModifier.ABSTRACT)) { + if (!info.isToAbstract() && !method.hasModifierProperty(PsiModifier.ABSTRACT) && PsiUtil.isLanguageLevel8OrHigher(myTargetSuperClass)) { //pull as default RefactoringUtil.makeMethodDefault(methodCopy); isOriginalMethodAbstract = true; From 54872b0e1c2b3cb07ff1cd1267bcf9c0481b740a Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 9 Sep 2013 13:32:54 +0400 Subject: [PATCH 13/22] accept interfaces as main classes for java 8 (IDEA-113340) --- java/java-psi-api/src/com/intellij/psi/util/PsiMethodUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiMethodUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiMethodUtil.java index d241e3fc950c..a92ed0542b2c 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiMethodUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiMethodUtil.java @@ -31,7 +31,7 @@ public class PsiMethodUtil { @Override public boolean value(final PsiClass psiClass) { if (psiClass instanceof PsiAnonymousClass) return false; - if (psiClass.isInterface()) return false; + if (psiClass.isInterface() && !PsiUtil.isLanguageLevel8OrHigher(psiClass)) return false; return psiClass.getContainingClass() == null || psiClass.hasModifierProperty(PsiModifier.STATIC); } }; From ea4b4f205c78c579b5c288c81a2ea24705940a1d Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 9 Sep 2013 12:45:29 +0200 Subject: [PATCH 14/22] continue WEB-1171 javascript live console: execution enabled condition --- .../AbstractConsoleRunnerWithHistory.java | 3 +- .../runners/ConsoleExecuteAction.java | 12 +++++--- .../runners/LanguageConsoleBuilder.java | 30 +++++++++++++++---- .../ProcessBackedConsoleExecuteAction.java | 21 ------------- 4 files changed, 34 insertions(+), 32 deletions(-) delete mode 100644 platform/lang-impl/src/com/intellij/execution/runners/ProcessBackedConsoleExecuteAction.java diff --git a/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java b/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java index a0c840d5d338..55d8c3940017 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java @@ -246,7 +246,8 @@ public abstract class AbstractConsoleRunnerWithHistory myEnabledCondition; public ConsoleExecuteAction(@NotNull LanguageConsoleImpl console, @NotNull BaseConsoleExecuteActionHandler executeActionHandler) { - this(console, executeActionHandler, CONSOLE_EXECUTE_ACTION_ID); + this(console, executeActionHandler, CONSOLE_EXECUTE_ACTION_ID, Conditions.alwaysTrue()); } public ConsoleExecuteAction(@NotNull LanguageConsoleImpl console, @NotNull BaseConsoleExecuteActionHandler executeActionHandler, - @NotNull String emptyExecuteActionId) { + @NotNull String emptyExecuteActionId, @NotNull Condition enabledCondition) { super(null, null, AllIcons.Actions.Execute); myConsole = console; myExecuteActionHandler = executeActionHandler; + myEnabledCondition = enabledCondition; EmptyAction.setupAction(this, emptyExecuteActionId, null); } @@ -59,6 +63,6 @@ public class ConsoleExecuteAction extends DumbAwareAction { } protected boolean isEnabled() { - return true; + return myEnabledCondition.value(myConsole); } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/execution/runners/LanguageConsoleBuilder.java b/platform/lang-impl/src/com/intellij/execution/runners/LanguageConsoleBuilder.java index a64af30d8e25..e893386e802a 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/LanguageConsoleBuilder.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/LanguageConsoleBuilder.java @@ -4,29 +4,47 @@ import com.intellij.execution.console.ConsoleHistoryController; import com.intellij.execution.console.LanguageConsoleImpl; import com.intellij.execution.console.LanguageConsoleView; import com.intellij.execution.process.ProcessHandler; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Conditions; import org.jetbrains.annotations.NotNull; public class LanguageConsoleBuilder { private LanguageConsoleImpl myConsole; - private ProcessHandler myProcessHandler; + private Condition myExecutionEnabled = Conditions.alwaysTrue(); public LanguageConsoleBuilder console(@NotNull LanguageConsoleView console) { myConsole = console.getConsole(); return this; } - public LanguageConsoleBuilder processHandler(ProcessHandler processHandler) { - myProcessHandler = processHandler; + public LanguageConsoleBuilder processHandler(@NotNull ProcessHandler processHandler) { + myExecutionEnabled = new ProcessBackedExecutionEnabledCondition(processHandler); + return this; + } + + public LanguageConsoleBuilder executionEnabled(@NotNull Condition condition) { + myExecutionEnabled = condition; return this; } public LanguageConsoleBuilder initActions(@NotNull BaseConsoleExecuteActionHandler executeActionHandler, @NotNull String historyType) { - ConsoleExecuteAction action = myProcessHandler == null - ? new ConsoleExecuteAction(myConsole, executeActionHandler) - : new ProcessBackedConsoleExecuteAction(myConsole, myProcessHandler, executeActionHandler); + ConsoleExecuteAction action = new ConsoleExecuteAction(myConsole, executeActionHandler, ConsoleExecuteAction.CONSOLE_EXECUTE_ACTION_ID, myExecutionEnabled); action.registerCustomShortcutSet(action.getShortcutSet(), myConsole.getConsoleEditor().getComponent()); new ConsoleHistoryController(historyType, "", myConsole, executeActionHandler.getConsoleHistoryModel()).install(); return this; } + + static class ProcessBackedExecutionEnabledCondition implements Condition { + private ProcessHandler myProcessHandler; + + public ProcessBackedExecutionEnabledCondition(ProcessHandler myProcessHandler) { + this.myProcessHandler = myProcessHandler; + } + + @Override + public boolean value(LanguageConsoleImpl console) { + return !myProcessHandler.isProcessTerminated(); + } + } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/execution/runners/ProcessBackedConsoleExecuteAction.java b/platform/lang-impl/src/com/intellij/execution/runners/ProcessBackedConsoleExecuteAction.java deleted file mode 100644 index 7132a2ef99ee..000000000000 --- a/platform/lang-impl/src/com/intellij/execution/runners/ProcessBackedConsoleExecuteAction.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.intellij.execution.runners; - -import com.intellij.execution.console.LanguageConsoleImpl; -import com.intellij.execution.process.ProcessHandler; - -class ProcessBackedConsoleExecuteAction extends ConsoleExecuteAction { - private final ProcessHandler myProcessHandler; - - public ProcessBackedConsoleExecuteAction(LanguageConsoleImpl languageConsole, - ProcessHandler processHandler, - BaseConsoleExecuteActionHandler consoleExecuteActionHandler) { - super(languageConsole, consoleExecuteActionHandler); - - myProcessHandler = processHandler; - } - - @Override - protected boolean isEnabled() { - return !myProcessHandler.isProcessTerminated(); - } -} \ No newline at end of file From 5d70c6464a662a0ee619beda74f725701713dc0c Mon Sep 17 00:00:00 2001 From: Fedor Korotkov Date: Mon, 9 Sep 2013 13:30:48 +0400 Subject: [PATCH 15/22] Reverted 482c517 --- .../src/com/intellij/lexer/BaseHtmlLexer.java | 9 ++++++++- xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java | 6 +++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.java b/xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.java index aed3c551a2f6..5cb76ec529ef 100644 --- a/xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.java +++ b/xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.java @@ -154,6 +154,13 @@ abstract class BaseHtmlLexer extends DelegateLexer { } } } + + @Nullable + protected Language getScriptLanguage() { + Collection instancesByMimeType = Language.findInstancesByMimeType(scriptType != null ? scriptType.trim() : null); + return instancesByMimeType.isEmpty() ? null : instancesByMimeType.iterator().next(); + } + @Nullable protected IElementType getCurrentScriptElementType() { HtmlScriptContentProvider scriptContentProvider = findScriptContentProvider(scriptType); @@ -333,7 +340,7 @@ abstract class BaseHtmlLexer extends DelegateLexer { protected boolean isValidAttributeValueTokenType(final IElementType tokenType) { return tokenType == XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN || tokenType == XmlTokenType.XML_ENTITY_REF_TOKEN || - tokenType == XmlTokenType.XML_CHAR_ENTITY_REF; + tokenType == XmlTokenType.XML_CHAR_ENTITY_REF; } public void advance() { diff --git a/xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java b/xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java index dc0e4d3f6cfd..98858a387dff 100644 --- a/xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java +++ b/xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java @@ -16,7 +16,9 @@ package com.intellij.lexer; import com.intellij.lang.HtmlInlineScriptTokenTypesProvider; +import com.intellij.lang.Language; import com.intellij.lang.LanguageHtmlInlineScriptTokenTypesProvider; +import com.intellij.lang.LanguageUtil; import com.intellij.openapi.extensions.Extensions; import com.intellij.psi.TokenType; import com.intellij.psi.tree.IElementType; @@ -74,7 +76,9 @@ public class HtmlLexer extends BaseHtmlLexer { tokenType = ourInlineStyleElementType; } } else if (hasSeenScript()) { - if (hasSeenTag() && isStartOfEmbeddmentTagContent(tokenType)) { + Language scriptLanguage = getScriptLanguage(); + boolean canInject = scriptLanguage == null || LanguageUtil.isInjectableLanguage(scriptLanguage); + if (hasSeenTag() && isStartOfEmbeddmentTagContent(tokenType) && canInject) { myTokenEnd = skipToTheEndOfTheEmbeddment(); IElementType currentScriptElementType = getCurrentScriptElementType(); tokenType = currentScriptElementType == null ? XmlTokenType.XML_DATA_CHARACTERS : currentScriptElementType; From 0fcec290d921ed72d7593a9e58b4c98782b9de1a Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 9 Sep 2013 13:20:25 +0200 Subject: [PATCH 16/22] prevent IOE on array initializer without array type (e.g. Map m = {}) --- .../ipp/braces/ArrayCreationExpressionPredicate.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/ArrayCreationExpressionPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/ArrayCreationExpressionPredicate.java index 3675d8d5449c..f3bc646c25a5 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/ArrayCreationExpressionPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/ArrayCreationExpressionPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 Bas Leijdekkers + * Copyright 2011-2013 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,9 +15,7 @@ */ package com.siyeh.ipp.braces; -import com.intellij.psi.PsiArrayInitializerExpression; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiNewExpression; +import com.intellij.psi.*; import com.siyeh.ipp.base.PsiElementPredicate; import org.jetbrains.annotations.NotNull; @@ -27,9 +25,9 @@ class ArrayCreationExpressionPredicate implements PsiElementPredicate { if (!(element instanceof PsiArrayInitializerExpression)) { return false; } - final PsiArrayInitializerExpression arrayInitializerExpression = - (PsiArrayInitializerExpression)element; - if (arrayInitializerExpression.getType() == null) { + final PsiArrayInitializerExpression arrayInitializerExpression = (PsiArrayInitializerExpression)element; + final PsiType type = arrayInitializerExpression.getType(); + if (type == null || !(type instanceof PsiArrayType)) { return false; } final PsiElement parent = element.getParent(); From 660731f32e426b53903dadb20ef4fae42c0bc77c Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 9 Sep 2013 13:21:10 +0200 Subject: [PATCH 17/22] use TypeConversionUtil.erasure() instead of reinventing the wheel badly --- .../AddArrayCreationExpressionIntention.java | 34 ++++--------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/AddArrayCreationExpressionIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/AddArrayCreationExpressionIntention.java index e42f99a70613..08151745717b 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/AddArrayCreationExpressionIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/AddArrayCreationExpressionIntention.java @@ -16,6 +16,7 @@ package com.siyeh.ipp.braces; import com.intellij.psi.*; +import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.IntentionPowerPackBundle; import com.siyeh.ipp.base.MutablyNamedIntention; @@ -35,39 +36,18 @@ public class AddArrayCreationExpressionIntention extends MutablyNamedIntention { protected String getTextForElement(PsiElement element) { final PsiArrayInitializerExpression arrayInitializerExpression = (PsiArrayInitializerExpression)element; final PsiType type = arrayInitializerExpression.getType(); - final StringBuilder typeText = buildTypeText(type, new StringBuilder()); - return IntentionPowerPackBundle.message("add.array.creation.expression.intention.name", typeText.toString()); + return IntentionPowerPackBundle.message("add.array.creation.expression.intention.name", + TypeConversionUtil.erasure(type).getCanonicalText()); } @Override - protected void processIntention(@NotNull PsiElement element) - throws IncorrectOperationException { - final PsiArrayInitializerExpression arrayInitializerExpression = - (PsiArrayInitializerExpression)element; + protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + final PsiArrayInitializerExpression arrayInitializerExpression = (PsiArrayInitializerExpression)element; final PsiType type = arrayInitializerExpression.getType(); if (type == null) { return; } - @NonNls final StringBuilder text = new StringBuilder(); - text.append("new "); - buildTypeText(type, text); - text.append(arrayInitializerExpression.getText()); - replaceExpression(text.toString(), arrayInitializerExpression); - } - - private static StringBuilder buildTypeText(PsiType type, StringBuilder typeText) { - if (type instanceof PsiArrayType) { - final PsiArrayType arrayType = (PsiArrayType)type; - buildTypeText(arrayType.getComponentType(), typeText); - typeText.append("[]"); - } - else if (type instanceof PsiClassType) { - final PsiClassType classType = (PsiClassType)type; - typeText.append(classType.getClassName()); // no parameters -> no generic array creation - } - else { - typeText.append(type.getCanonicalText()); - } - return typeText; + replaceExpression("new " + TypeConversionUtil.erasure(type).getCanonicalText() + arrayInitializerExpression.getText(), + arrayInitializerExpression); } } From 0fcbc91e4f97686fdad9a08bfd35fe4739288629 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 9 Sep 2013 15:24:24 +0400 Subject: [PATCH 18/22] platform: correct formatting in the missing framework library validator --- .../impl/ui/libraries/FrameworkLibraryValidatorImpl.java | 5 ++--- .../platform-resources-en/src/messages/IdeBundle.properties | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FrameworkLibraryValidatorImpl.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FrameworkLibraryValidatorImpl.java index 56fe2f1a9fb8..95f012e6bf70 100644 --- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FrameworkLibraryValidatorImpl.java +++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FrameworkLibraryValidatorImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -26,7 +26,6 @@ import com.intellij.openapi.roots.ui.configuration.libraries.AddCustomLibraryDia import com.intellij.openapi.roots.ui.configuration.libraries.CustomLibraryDescription; import com.intellij.openapi.roots.ui.configuration.libraries.LibraryPresentationManager; import com.intellij.openapi.util.Ref; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Processor; import javax.swing.*; @@ -67,7 +66,7 @@ public class FrameworkLibraryValidatorImpl extends FrameworkLibraryValidator { }); if (found.get()) return ValidationResult.OK; - return new ValidationResult(StringUtil.capitalize(myLibraryCategoryName) + " library not found in the module dependencies list", new LibrariesQuickFix(myLibraryDescription)); + return new ValidationResult(IdeBundle.message("label.missed.libraries.text", myLibraryCategoryName), new LibrariesQuickFix(myLibraryDescription)); } private class LibrariesQuickFix extends FacetConfigurationQuickFix { diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index e88bcf0882e5..2dfda16db705 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -295,7 +295,7 @@ license.panel.buildit.evaluation.expires.in.one=1 day left license.panel.buildit.evaluation.expires.in.many={0} days left license.panel.discover.license.server.error.message=Unable to discover license server url license.panel.ping.license.server.error.message=No response from autodetected license server {0} -license.panel.ping.license.server.error.title=No response from server +license.panel.ping.license.server.error.title=No response from server license.panel.default.server.discover=Discover editbox.license.user.name=User name: editbox.license.license.key=License key: @@ -982,7 +982,7 @@ error.file.download.failed=Downloading failed: {0} maven.repository.presentable.name=Maven repository label.missed.libraries.prefix=The following libraries are missing: -label.missed.libraries.text={0}.
Class ''{1}'' not found +label.missed.libraries.text=''{0}'' library not found in the module dependencies list missing.libraries.fix.button=Fix... setup.library.dialog.title=Setup Library label.library.will.be.created.description.text={0} level library {1} with {2} {2, choice, 1#file|2#files} will be created From 631b36179da327859a2660f6da3d29f3edaf1b65 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Mon, 9 Sep 2013 15:33:13 +0400 Subject: [PATCH 19/22] Completion of dependency should honor section --- .../MavenDependenciesCompletionProvider.java | 89 +++++++++++++++--- .../MavenDependencySmartCompletionTest.java | 92 +++++++++++++++++++ 2 files changed, 166 insertions(+), 15 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenDependenciesCompletionProvider.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenDependenciesCompletionProvider.java index a080639b9818..21d35fa07485 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenDependenciesCompletionProvider.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenDependenciesCompletionProvider.java @@ -6,15 +6,23 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.icons.AllIcons; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.psi.xml.XmlText; import com.intellij.psi.xml.XmlTokenType; +import com.intellij.util.Processor; import com.intellij.util.xml.DomElement; +import com.intellij.util.xml.DomFileElement; import com.intellij.util.xml.DomManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.maven.dom.MavenDomProjectProcessorUtils; import org.jetbrains.idea.maven.dom.model.MavenDomDependency; +import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel; import org.jetbrains.idea.maven.indices.MavenProjectIndicesManager; /** @@ -59,6 +67,29 @@ public class MavenDependenciesCompletionProvider extends CompletionContributor { } } + private static MavenDomDependency findManagedDependency(MavenDomProjectModel domModel, Project project, + @NotNull final String groupId, @NotNull final String artifactId) { + + final Ref ref = new Ref(); + + MavenDomProjectProcessorUtils.processDependenciesInDependencyManagement(domModel, + new Processor() { + @Override + public boolean process(MavenDomDependency dependency) { + if (groupId.equals(dependency.getGroupId().getStringValue()) + && + artifactId.equals( + dependency.getArtifactId().getStringValue())) { + ref.set(dependency); + return false; + } + return true; + } + }, project); + + return ref.get(); + } + private static class MavenDependencyInsertHandler implements InsertHandler { public static final InsertHandler INSTANCE = new MavenDependencyInsertHandler(); @@ -71,21 +102,47 @@ public class MavenDependenciesCompletionProvider extends CompletionContributor { String groupId = s.substring(0, idx); String artifactId = s.substring(idx + 1); - - String value = "" + groupId + "\n" + - "" + artifactId + "\n" + - ""; - int startOffset = context.getStartOffset(); - context.getDocument().replaceString(startOffset, context.getSelectionEndOffset(), value); + PsiFile psiFile = context.getFile(); - context.getEditor().getCaretModel().moveToOffset(startOffset + value.length() - 10); + DomFileElement domModel = DomManager.getDomManager(context.getProject()).getFileElement((XmlFile)psiFile, MavenDomProjectModel.class); + if (domModel == null) return; + + boolean shouldInvokeCompletion = false; + + MavenDomDependency managedDependency = findManagedDependency(domModel.getRootElement(), context.getProject(), groupId, artifactId); + if (managedDependency == null) { + String value = "" + groupId + "\n" + + "" + artifactId + "\n" + + ""; + + context.getDocument().replaceString(startOffset, context.getSelectionEndOffset(), value); + + context.getEditor().getCaretModel().moveToOffset(startOffset + value.length() - 10); + + shouldInvokeCompletion = true; + } + else { + StringBuilder sb = new StringBuilder(); + sb.append("").append(groupId).append("\n") + .append("").append(artifactId).append("\n"); + + String type = managedDependency.getType().getStringValue(); + if (type != null && !type.equals("jar")) { + sb.append("").append(type).append("\n"); + } + + String classifier = managedDependency.getClassifier().getStringValue(); + if (StringUtil.isNotEmpty(classifier)) { + sb.append("").append(classifier).append("\n"); + } + + context.getDocument().replaceString(startOffset, context.getSelectionEndOffset(), sb); + } context.commitDocument(); - PsiFile psiFile = context.getFile(); - PsiElement e = psiFile.findElementAt(startOffset); while (e != null && (!(e instanceof XmlTag) || !"dependency".equals(((XmlTag)e).getName()))) { e = e.getParent(); @@ -95,12 +152,14 @@ public class MavenDependenciesCompletionProvider extends CompletionContributor { new ReformatCodeProcessor(psiFile.getProject(), psiFile, e.getTextRange(), true).run(); } - context.setLaterRunnable(new Runnable() { - @Override - public void run() { - new CodeCompletionHandlerBase(CompletionType.BASIC).invokeCompletion(context.getProject(), context.getEditor()); - } - }); + if (shouldInvokeCompletion) { + context.setLaterRunnable(new Runnable() { + @Override + public void run() { + new CodeCompletionHandlerBase(CompletionType.BASIC).invokeCompletion(context.getProject(), context.getEditor()); + } + }); + } } } } diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDependencySmartCompletionTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDependencySmartCompletionTest.java index 99b84d64c491..7642c1a57e35 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDependencySmartCompletionTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDependencySmartCompletionTest.java @@ -49,4 +49,96 @@ public class MavenDependencySmartCompletionTest extends MavenDomWithIndicesTestC "\n")); } + public void testInsertManagedDependency() throws IOException { + createProjectPom("test\n" + + "project\n" + + "1\n" + + + "\n" + + " \n" + + " \n" + + " junit\n" + + " junit\n" + + " 4.0\n" + + " \n" + + " \n" + + "\n" + + + "\n" + + " ju\n" + + "\n"); + + configTest(myProjectPom); + myFixture.complete(CompletionType.SMART); + + myFixture.checkResult(createPomXml("test\n" + + "project\n" + + "1\n" + + "\n" + + " \n" + + " \n" + + " junit\n" + + " junit\n" + + " 4.0\n" + + " \n" + + " \n" + + "\n" + + "\n" + + " \n" + + " junit\n" + + " junit\n" + + " \n" + + "\n")); + } + + public void testInsertManagedDependencyWithTypeAndClassifier() throws IOException { + createProjectPom("test\n" + + "project\n" + + "1\n" + + + "\n" + + " \n" + + " \n" + + " junit\n" + + " junit\n" + + " 4.0\n" + + " test-jar\n" + + " sources\n" + + " \n" + + " \n" + + "\n" + + + "\n" + + " ju\n" + + "\n"); + + configTest(myProjectPom); + myFixture.complete(CompletionType.SMART); + + myFixture.checkResult(createPomXml("test\n" + + "project\n" + + "1\n" + + + "\n" + + " \n" + + " \n" + + " junit\n" + + " junit\n" + + " 4.0\n" + + " test-jar\n" + + " sources\n" + + " \n" + + " \n" + + "\n" + + + "\n" + + " \n" + + " junit\n" + + " junit\n" + + " test-jar\n" + + " sources\n" + + " \n" + + "\n")); + } + } From bb9b1f5f28759b8275849aec403f5bd7be9c00b6 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 9 Sep 2013 14:42:33 +0200 Subject: [PATCH 20/22] IDEA-113391 Edit Method Contract intention for library methods --- .../dataFlow/ControlFlowAnalyzer.java | 14 +- .../dataFlow/DataFlowInspectionBase.java | 49 ++++--- .../dataFlow/EditContractIntention.java | 123 ++++++++++++++++++ .../intellij/codeInsight/AnnotationUtil.java | 7 + .../EditContractIntention/after.java.template | 10 ++ .../before.java.template | 7 + .../EditContractIntention/description.html | 27 ++++ resources/src/META-INF/IdeaPlugin.xml | 5 + 8 files changed, 216 insertions(+), 26 deletions(-) create mode 100644 java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java create mode 100644 resources-en/src/intentionDescriptions/EditContractIntention/after.java.template create mode 100644 resources-en/src/intentionDescriptions/EditContractIntention/before.java.template create mode 100644 resources-en/src/intentionDescriptions/EditContractIntention/description.html diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java index bb0c04861fa2..6e822579c78c 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java @@ -52,6 +52,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { throw new UnsupportedOperationException("Not implemented"); } }; + public static final String ORG_JETBRAINS_ANNOTATIONS_CONTRACT = "org.jetbrains.annotations.Contract"; private boolean myIgnoreAssertions; private static class CannotAnalyzeException extends RuntimeException { } @@ -1421,18 +1422,17 @@ class ControlFlowAnalyzer extends JavaElementVisitor { private static List getCallContracts(PsiMethodCallExpression expression) { PsiMethod resolved = expression.resolveMethod(); if (resolved != null) { - final PsiAnnotation contractAnno = AnnotationUtil.findAnnotation(resolved, "org.jetbrains.annotations.Contract"); + final PsiAnnotation contractAnno = findContractAnnotation(resolved); if (contractAnno != null) { final Project project = expression.getProject(); return CachedValuesManager.getManager(project).getCachedValue(contractAnno, new CachedValueProvider>() { @Nullable @Override public Result> compute() { - PsiAnnotationMemberValue value = contractAnno.findAttributeValue(null); - Object text = JavaPsiFacade.getInstance(project).getConstantEvaluationHelper().computeConstantExpression(value); - if (text instanceof String) { + String text = AnnotationUtil.getStringAttributeValue(contractAnno, null); + if (text != null) { try { - return Result.create(parseContract((String)text), contractAnno); + return Result.create(parseContract(text), contractAnno); } catch (Exception ignored) { } @@ -1507,6 +1507,10 @@ class ControlFlowAnalyzer extends JavaElementVisitor { return Collections.emptyList(); } + public static PsiAnnotation findContractAnnotation(PsiMethod method) { + return AnnotationUtil.findAnnotation(method, ORG_JETBRAINS_ANNOTATIONS_CONTRACT); + } + public static List parseContract(String text) throws ParseException { List result = ContainerUtil.newArrayList(); for (String clause : StringUtil.replace(text, " ", "").split(";")) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java index 962c7a3b5226..bc8d03b108e9 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java @@ -49,7 +49,6 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.SmartList; import com.intellij.util.containers.MultiMap; import org.jdom.Element; -import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -103,35 +102,43 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { @Override public void visitAnnotation(PsiAnnotation annotation) { - if (!Contract.class.getName().equals(annotation.getQualifiedName())) return; + if (!ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT.equals(annotation.getQualifiedName())) return; PsiMethod method = PsiTreeUtil.getParentOfType(annotation, PsiMethod.class); if (method == null) return; - PsiAnnotationMemberValue value = annotation.findAttributeValue(null); - Object text = JavaPsiFacade.getInstance(annotation.getProject()).getConstantEvaluationHelper().computeConstantExpression(value); - if (!(text instanceof String)) return; - - List contracts; - try { - contracts = ControlFlowAnalyzer.parseContract((String)text); - } - catch (ControlFlowAnalyzer.ParseException e) { - holder.registerProblem(value, e.getMessage()); - return; - } - int paramCount = method.getParameterList().getParametersCount(); - for (int i = 0; i < contracts.size(); i++) { - MethodContract contract = contracts.get(i); - if (contract.arguments.length != paramCount) { - holder.registerProblem(value, "Method takes " + paramCount + " parameters, while contract clause " + i + " expects " + contract.arguments.length); - return; - } + String text = AnnotationUtil.getStringAttributeValue(annotation, null); + if (text == null) return; + + String error = checkContract(method, text); + if (error != null) { + PsiAnnotationMemberValue value = annotation.findAttributeValue(null); + assert value != null; + holder.registerProblem(value, error); } } }; } + @Nullable + public static String checkContract(PsiMethod method, String text) { + List contracts; + try { + contracts = ControlFlowAnalyzer.parseContract(text); + } + catch (ControlFlowAnalyzer.ParseException e) { + return e.getMessage(); + } + int paramCount = method.getParameterList().getParametersCount(); + for (int i = 0; i < contracts.size(); i++) { + MethodContract contract = contracts.get(i); + if (contract.arguments.length != paramCount) { + return "Method takes " + paramCount + " parameters, while contract clause " + i + " expects " + contract.arguments.length; + } + } + return null; + } + private void analyzeCodeBlock(@Nullable final PsiElement scope, ProblemsHolder holder) { if (scope == null) return; diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java new file mode 100644 index 000000000000..2f856b99f5ea --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/EditContractIntention.java @@ -0,0 +1,123 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInspection.dataFlow; + +import com.intellij.codeInsight.AnnotationUtil; +import com.intellij.codeInsight.ExternalAnnotationsManager; +import com.intellij.codeInsight.intention.AddAnnotationPsiFix; +import com.intellij.codeInsight.intention.impl.BaseIntentionAction; +import com.intellij.openapi.application.AccessToken; +import com.intellij.openapi.application.WriteAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.InputValidatorEx; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.generate.tostring.util.StringUtil; + +/** + * @author peter + */ +public class EditContractIntention extends BaseIntentionAction { + + @NotNull + @Override + public String getFamilyName() { + return "Edit method contract"; + } + + @Nullable + private static PsiMethod getTargetMethod(@NotNull Project project, Editor editor, PsiFile file) { + PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); + if (element == null) return null; + if (!PsiUtil.isLanguageLevel5OrHigher(element)) return null; + if (!element.getManager().isInProject(element) || CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS) { + final PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(element); + if (owner instanceof PsiMethod) { + return (PsiMethod)owner; + } + } + return null; + } + + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + final PsiMethod method = getTargetMethod(project, editor, file); + if (method != null) { + boolean hasContract = ControlFlowAnalyzer.findContractAnnotation(method) != null; + setText(hasContract ? "Edit method contract" : "Add method contract"); + return true; + } + return false; + } + + @Override + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + final PsiMethod method = getTargetMethod(project, editor, file); + assert method != null; + PsiAnnotation existingAnno = ControlFlowAnalyzer.findContractAnnotation(method); + String oldContract = existingAnno != null ? AnnotationUtil.getStringAttributeValue(existingAnno, null) : null; + String prompt = + "Please specify the contract text

" + + "Example: _, null -> false
" + + "See intention action description for more details"; + String newContract = Messages.showInputDialog(project, prompt, "Edit Method Contract", null, oldContract, new InputValidatorEx() { + @Nullable + @Override + public String getErrorText(String inputString) { + if (StringUtil.isEmpty(inputString)) return null; + + return DataFlowInspectionBase.checkContract(method, inputString); + } + + @Override + public boolean checkInput(String inputString) { + return getErrorText(inputString) == null; + } + + @Override + public boolean canClose(String inputString) { + return checkInput(inputString); + } + }); + if (newContract == null) return; + + AccessToken token = WriteAction.start(); + try { + ExternalAnnotationsManager manager = ExternalAnnotationsManager.getInstance(project); + manager.deannotate(method, ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT); + if (StringUtil.isNotEmpty(newContract)) { + PsiAnnotation mockAnno = JavaPsiFacade.getElementFactory(project).createAnnotationFromText("@Foo(\"" + newContract + "\")", null); + manager.annotateExternally(method, ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT, file, + mockAnno.getParameterList().getAttributes()); + } + } + finally { + token.finish(); + } + } + + @Override + public boolean startInWriteAction() { + return false; + } +} diff --git a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java index d67dec73361f..06f12e7721b2 100644 --- a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java +++ b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java @@ -432,4 +432,11 @@ public class AnnotationUtil { public static boolean isInsideAnnotation(PsiElement element) { return PsiTreeUtil.getParentOfType(element, PsiNameValuePair.class, PsiArrayInitializerMemberValue.class) != null; } + + @Nullable + public static String getStringAttributeValue(PsiAnnotation anno, @Nullable final String attributeName) { + PsiAnnotationMemberValue attrValue = anno.findAttributeValue(attributeName); + Object constValue = JavaPsiFacade.getInstance(anno.getProject()).getConstantEvaluationHelper().computeConstantExpression(attrValue); + return constValue instanceof String ? (String)constValue : null; + } } diff --git a/resources-en/src/intentionDescriptions/EditContractIntention/after.java.template b/resources-en/src/intentionDescriptions/EditContractIntention/after.java.template new file mode 100644 index 000000000000..0714ecfe997a --- /dev/null +++ b/resources-en/src/intentionDescriptions/EditContractIntention/after.java.template @@ -0,0 +1,10 @@ +import org.jetbrains.annotations.Contract; + +class A { + + @Contract("any->null") + Object getObject() { + //do smth + return null; + } +} \ No newline at end of file diff --git a/resources-en/src/intentionDescriptions/EditContractIntention/before.java.template b/resources-en/src/intentionDescriptions/EditContractIntention/before.java.template new file mode 100644 index 000000000000..487121e2fb4c --- /dev/null +++ b/resources-en/src/intentionDescriptions/EditContractIntention/before.java.template @@ -0,0 +1,7 @@ +class A { + + Object getObject() { + //do smth + return null; + } +} \ No newline at end of file diff --git a/resources-en/src/intentionDescriptions/EditContractIntention/description.html b/resources-en/src/intentionDescriptions/EditContractIntention/description.html new file mode 100644 index 000000000000..24d6f9c6212c --- /dev/null +++ b/resources-en/src/intentionDescriptions/EditContractIntention/description.html @@ -0,0 +1,27 @@ + +This intention changes a library method contract. + +Method contract has the following syntax:
+ contract ::= (clause ';')* clause
+ clause ::= args '->' effect
+ args ::= ((arg ',')* arg )?
+ arg ::= value-constraint
+ value-constraint ::= 'any' | 'null' | '!null' | 'false' | 'true'
+ effect ::= value-constraint | 'fail' | 'exit'

+ +The constraints denote the following:
+

    +
  • _ - any value +
  • null - null value +
  • !null - a value statically proved to be not-null +
  • true - true boolean value +
  • false - false boolean value +
  • fail - the method throws exception, if the arguments satisfy argument constraints +
  • exit - the method terminates the current process, if the arguments satisfy argument constraints +
+Examples:

+@Contract("_, null -> null") - method returns null if its second argument is null
+@Contract("_, null -> null; _, !null -> !null") - method returns null if its second argument is null and not-null otherwise
+@Contract("true -> fail") - a typical assertFalse method which throws an exception if true is passed to it
+ + diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 56f15d2323df..1c0924477b60 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -693,6 +693,11 @@ Control Flow AddAnnotationFix + + com.intellij.codeInspection.dataFlow.EditContractIntention + Control Flow + EditContractIntention + com.intellij.codeInsight.daemon.impl.quickfix.IterateOverIterableIntention Control Flow From 66b72f8f597c170732ae98d66e97af78cf1a72c9 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 9 Sep 2013 15:05:48 +0200 Subject: [PATCH 21/22] fix test and add test for IOE --- .../ipp/braces/array_creation/NotAnArray.java | 7 ++++++ .../testSrc/com/siyeh/ipp/IPPTestCase.java | 22 +++++++++++++++++++ ...dArrayCreationExpressionIntentionTest.java | 3 ++- 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/array_creation/NotAnArray.java diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/array_creation/NotAnArray.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/array_creation/NotAnArray.java new file mode 100644 index 000000000000..c77494e77dec --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/braces/array_creation/NotAnArray.java @@ -0,0 +1,7 @@ +package com.siyeh.ipp.braces.array_creation; + +import java.util.Map; + +class NotAnArray {{ + Map m = {}; +}} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/IPPTestCase.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/IPPTestCase.java index 5060fbd1e9c2..d051ca98fb09 100644 --- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/IPPTestCase.java +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/IPPTestCase.java @@ -15,9 +15,14 @@ */ package com.siyeh.ipp; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInsight.intention.impl.config.IntentionActionWrapper; import com.intellij.openapi.application.PluginPathManager; import com.intellij.testFramework.fixtures.CodeInsightTestUtil; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import com.intellij.util.SmartList; + +import java.util.List; public abstract class IPPTestCase extends LightCodeInsightFixtureTestCase { @Override @@ -47,5 +52,22 @@ public abstract class IPPTestCase extends LightCodeInsightFixtureTestCase { myFixture.filterAvailableIntentions(intentionName)); } + protected void assertIntentionNotAvailable(Class intentionClass) { + myFixture.configureByFile(getTestName(false) + ".java"); + final List result = new SmartList(); + for (final IntentionAction intention : myFixture.getAvailableIntentions()) { + if (intentionClass.isInstance(intention)) { + result.add(intention); + } + else if (intention instanceof IntentionActionWrapper) { + final IntentionActionWrapper wrapper = (IntentionActionWrapper)intention; + if (intentionClass.isInstance(wrapper.getDelegate())) { + result.add(intention); + } + } + } + assertEmpty("Intention of class \'" + intentionClass + "\' is available but should not", result); + } + protected abstract String getIntentionName(); } diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/braces/AddArrayCreationExpressionIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/braces/AddArrayCreationExpressionIntentionTest.java index 3a6cf9e54922..bb45de803082 100644 --- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/braces/AddArrayCreationExpressionIntentionTest.java +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/braces/AddArrayCreationExpressionIntentionTest.java @@ -23,10 +23,11 @@ import com.siyeh.ipp.IPPTestCase; */ public class AddArrayCreationExpressionIntentionTest extends IPPTestCase { public void testGeneric() { doTest(); } + public void testNotAnArray() { assertIntentionNotAvailable(AddArrayCreationExpressionIntention.class); } @Override protected String getIntentionName() { - return IntentionPowerPackBundle.message("add.array.creation.expression.intention.name", "Map[][]"); + return IntentionPowerPackBundle.message("add.array.creation.expression.intention.name", "java.util.Map[][]"); } @Override From e6f6c94fc404015eb1474e625187d02b0f2ec245 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 9 Sep 2013 15:54:15 +0200 Subject: [PATCH 22/22] WEB-6780 JS Debugger / Variables: "Jump to Source" not working: This action should be available only for object or functions. --- .../src/com/intellij/xdebugger/frame/XValue.java | 10 ++++++++++ .../impl/ui/tree/actions/XJumpToSourceAction.java | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValue.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValue.java index a11eb41ebf66..ff2b3303d4da 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValue.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValue.java @@ -60,6 +60,16 @@ public abstract class XValue extends XValueContainer { navigatable.setSourcePosition(null); } + /** + * Return {@code true} from this method and override {@link #computeSourcePosition(XNavigatable)} if navigation to the source + * is supported for the value + * @return {@code true} if navigation to the value's source is supported + */ + public boolean canNavigateToSource() { + // should be false, but cannot be due to compatibility reasons + return true; + } + /** * Return {@code true} from this method and override {@link #computeTypeSourcePosition(XNavigatable)} if navigation to the value's type * is supported for the value diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XJumpToSourceAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XJumpToSourceAction.java index 8367b535459d..f502354e763c 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XJumpToSourceAction.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XJumpToSourceAction.java @@ -17,6 +17,7 @@ package com.intellij.xdebugger.impl.ui.tree.actions; import com.intellij.xdebugger.frame.XNavigatable; import com.intellij.xdebugger.frame.XValue; +import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; /** * @author nik @@ -26,4 +27,9 @@ public class XJumpToSourceAction extends XJumpToSourceActionBase { protected void startComputingSourcePosition(XValue value, XNavigatable navigatable) { value.computeSourcePosition(navigatable); } + + @Override + protected boolean isEnabled(XValueNodeImpl node) { + return super.isEnabled(node) && node.getValueContainer().canNavigateToSource(); + } }