From 8fdfb44a9dde5828221c8075ed208975ae84a978 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Fri, 11 Sep 2015 18:03:39 +0300 Subject: [PATCH 01/21] fixed blinking NodeRendererSettingsTest.testAutoRendererConfigurable --- .../render/ExpressionChildrenRenderer.java | 20 ++++++++----------- .../ui/tree/render/LabelRenderer.java | 15 +++++++------- .../ui/tree/render/ReferenceRenderer.java | 10 +++++++++- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ExpressionChildrenRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ExpressionChildrenRenderer.java index ec73034d3cd5..9fa7c96e981a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ExpressionChildrenRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ExpressionChildrenRenderer.java @@ -55,24 +55,20 @@ public class ExpressionChildrenRenderer extends ReferenceRenderer implements Chi private static final Key EXPRESSION_VALUE = new Key("EXPRESSION_VALUE"); private static final Key LAST_CHILDREN_RENDERER = new Key("LAST_CHILDREN_RENDERER"); - private final CachedEvaluator myChildrenExpandable = new CachedEvaluator() { - protected String getClassName() { - return ExpressionChildrenRenderer.this.getClassName(); - } - }; - - private final CachedEvaluator myChildrenExpression = new CachedEvaluator() { - protected String getClassName() { - return ExpressionChildrenRenderer.this.getClassName(); - } - }; + private CachedEvaluator myChildrenExpandable = createCachedEvaluator(); + private CachedEvaluator myChildrenExpression = createCachedEvaluator(); public String getUniqueId() { return UNIQUE_ID; } public ExpressionChildrenRenderer clone() { - return (ExpressionChildrenRenderer)super.clone(); + ExpressionChildrenRenderer clone = (ExpressionChildrenRenderer)super.clone(); + clone.myChildrenExpandable = createCachedEvaluator(); + clone.setChildrenExpandable(getChildrenExpandable()); + clone.myChildrenExpression = createCachedEvaluator(); + clone.setChildrenExpression(getChildrenExpression()); + return clone; } public void buildChildren(final Value value, final ChildrenBuilder builder, final EvaluationContext evaluationContext) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/LabelRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/LabelRenderer.java index 2f40df45cd7c..4e14423ce57b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/LabelRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/LabelRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -40,15 +40,11 @@ import javax.swing.*; * Date: Sep 20, 2003 * Time: 10:27:12 PM */ -public class LabelRenderer extends com.intellij.debugger.ui.tree.render.ReferenceRenderer implements ValueLabelRenderer{ +public class LabelRenderer extends ReferenceRenderer implements ValueLabelRenderer{ public static final @NonNls String UNIQUE_ID = "LabelRenderer"; private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.render.ClassLabelRenderer"); - private final CachedEvaluator myLabelExpression = new CachedEvaluator() { - protected String getClassName() { - return LabelRenderer.this.getClassName(); - } - }; + private CachedEvaluator myLabelExpression = createCachedEvaluator(); public LabelRenderer() { super(); @@ -59,7 +55,10 @@ public class LabelRenderer extends com.intellij.debugger.ui.tree.render.Referenc } public LabelRenderer clone() { - return (LabelRenderer)super.clone(); + LabelRenderer clone = (LabelRenderer)super.clone(); + clone.myLabelExpression = createCachedEvaluator(); + clone.setLabelExpression(getLabelExpression()); + return clone; } public Icon calcValueIcon(ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener listener) throws EvaluateException { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java index 9c664c3b0ece..4ac38e184c6b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -68,4 +68,12 @@ public abstract class ReferenceRenderer implements Renderer { public void readExternal(Element element) throws InvalidDataException { myProperties.readExternal(element); } + + protected CachedEvaluator createCachedEvaluator() { + return new CachedEvaluator() { + protected String getClassName() { + return ReferenceRenderer.this.getClassName(); + } + }; + } } From faa6581cfeda9c11c72c4b3e4330b19c2158e1ef Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 11 Sep 2015 15:52:49 +0200 Subject: [PATCH 02/21] give traces in FrequentEventDetector unique ids and reference them in short reports (IDEA-CR-4687) --- .../diagnostic/FrequentEventDetector.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/platform/util/src/com/intellij/openapi/diagnostic/FrequentEventDetector.java b/platform/util/src/com/intellij/openapi/diagnostic/FrequentEventDetector.java index 7a9062621658..fda9a025efc4 100644 --- a/platform/util/src/com/intellij/openapi/diagnostic/FrequentEventDetector.java +++ b/platform/util/src/com/intellij/openapi/diagnostic/FrequentEventDetector.java @@ -32,10 +32,11 @@ public class FrequentEventDetector { private long myStartedCounting = System.currentTimeMillis(); private final AtomicInteger myEventsPosted = new AtomicInteger(); - private final Map myRecentTraces = new LinkedHashMap() { + private final AtomicInteger myLastTraceId = new AtomicInteger(); + private final Map myRecentTraces = new LinkedHashMap() { @Override - protected boolean removeEldestEntry(Map.Entry eldest) { - return size() > 5; + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > 50; } }; private final int myEventCountThreshold; @@ -68,11 +69,18 @@ public class FrequentEventDetector { if (shouldLog) { String trace = ExceptionUtil.getThrowableText(new Throwable()); boolean logTrace; + int traceId; synchronized (myEventsPosted) { - logTrace = myRecentTraces.put(trace, trace) == null; + Integer existingTraceId = myRecentTraces.get(trace); + logTrace = existingTraceId == null; + if (logTrace) { + myRecentTraces.put(trace, traceId = myLastTraceId.incrementAndGet()); + } else { + traceId = existingTraceId; + } } - String message = "Too many events posted" + (logTrace ? "\n" + trace : ""); + String message = "Too many events posted, #" + traceId + (logTrace ? "\n" + trace : ""); if (myLevel == Level.INFO) { LOG.info(message); } From 6dbda85830680cbc82b03aa1d5911754c7deee8a Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 11 Sep 2015 17:05:22 +0200 Subject: [PATCH 03/21] use ThreeState instead of nullable Boolean in AbstractVcs.mayRemoveChangeList for clearer API, don't retain all changelists after the user says 'no' to delete one of them (IDEA-CR-4872) --- .../src/com/intellij/openapi/vcs/AbstractVcs.java | 9 +++++---- .../vcs/changes/actions/ChangeListRemoveConfirmation.kt | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcs.java b/platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcs.java index 1cd7016cf02e..f5228063d1c5 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcs.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcs.java @@ -36,6 +36,7 @@ import com.intellij.openapi.vcs.rollback.RollbackEnvironment; import com.intellij.openapi.vcs.update.UpdateEnvironment; import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ThreeState; import com.intellij.util.ThrowableRunnable; import com.intellij.util.containers.Convertor; import com.intellij.util.ui.VcsSynchronousProgressWrapper; @@ -268,13 +269,13 @@ public abstract class AbstractVcs extends S /** * Invoked when a changelist is deleted explicitly by user or implicitly (e.g. after default changelist switch when the previous one was empty). - * @return null if the VCS doesn't object to the deletion. A Boolean object indicating the permission to remove if a dialog was shown asking the user whether + * @return UNSURE if the VCS doesn't object to the deletion. YES or NO indicating the permission to remove if a dialog was shown asking the user whether * the changelist really is to be removed. */ @CalledInAwt - @Nullable - public Boolean mayRemoveChangeList(@NotNull LocalChangeList list) { - return null; + @NotNull + public ThreeState mayRemoveChangeList(@NotNull LocalChangeList list) { + return ThreeState.UNSURE; } public boolean isTrackingUnchangedContent() { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeListRemoveConfirmation.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeListRemoveConfirmation.kt index f93b3593c767..bc630ed98d9c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeListRemoveConfirmation.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeListRemoveConfirmation.kt @@ -19,6 +19,7 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.vcs.ProjectLevelVcsManager import com.intellij.openapi.vcs.changes.ChangeListManager import com.intellij.openapi.vcs.changes.LocalChangeList +import com.intellij.util.ThreeState import com.intellij.util.containers.ContainerUtil import kotlin.platform.platformStatic @@ -32,13 +33,13 @@ abstract class ChangeListRemoveConfirmation() { val confirmationAsked = ContainerUtil.newIdentityTroveSet() val doNotRemove = ContainerUtil.newIdentityTroveSet() - for (vcs in ProjectLevelVcsManager.getInstance(project).getAllActiveVcss()) { - for (list in allLists) { + for (list in allLists) { + for (vcs in ProjectLevelVcsManager.getInstance(project).getAllActiveVcss()) { val permission = vcs.mayRemoveChangeList(list) - if (permission != null) { + if (permission != ThreeState.UNSURE) { confirmationAsked.add(list) } - if (java.lang.Boolean.FALSE == permission) { + if (permission == ThreeState.NO) { doNotRemove.add(list) break } From 1f0bbc16920cb7d769dbc10b84ad77b034483f10 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Fri, 11 Sep 2015 18:27:49 +0300 Subject: [PATCH 04/21] EA-72967 - IOOBE: EditorImpl.offsetToLogicalLine --- .../completion/JavaAutoPopupTest.groovy | 28 ++++++++++++++++++- .../lookup/impl/LookupActionHandler.java | 7 +++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy index a2ceafc7c6e6..9aa3d4df9904 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -741,6 +741,32 @@ public interface Test { assert lookup assert !lookup.calculating } + + public void testMulticaretRightMovementWithOneCaretAtDocumentEnd() { + myFixture.configureByText("a.java", """ + class Foo { + void foo(String iterable) { + ter x + } + } + """) + edt { + int primaryCaretOffset = myFixture.editor.document.text.indexOf("ter x"); + myFixture.editor.caretModel.addCaret(myFixture.editor.offsetToVisualPosition(primaryCaretOffset)) + } + + type('i') + assert lookup + + edt { myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT) } + myFixture.checkResult """ + class Foo { + void foo(String iterable) { + iter x + } + } + i""" + } public void testTypingInAnotherEditor() { myFixture.configureByText("a.java", "") diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupActionHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupActionHandler.java index 9e073702b29b..a267a66191cd 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupActionHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupActionHandler.java @@ -215,7 +215,7 @@ public abstract class LookupActionHandler extends EditorActionHandler { protected void executeInLookup(LookupImpl lookup, DataContext context, final Caret caret) { final Editor editor = lookup.getEditor(); final int offset = editor.getCaretModel().getOffset(); - CharSequence seq = editor.getDocument().getCharsSequence(); + final CharSequence seq = editor.getDocument().getCharsSequence(); if (seq.length() <= offset || !lookup.isCompletion()) { myOriginalHandler.execute(editor, caret, context); return; @@ -236,7 +236,10 @@ public abstract class LookupActionHandler extends EditorActionHandler { @Override public void perform(Caret caret) { caret.removeSelection(); - caret.moveToOffset(caret.getOffset() + 1); + int caretOffset = caret.getOffset(); + if (caretOffset < seq.length()) { + caret.moveToOffset(caretOffset + 1); + } } }; if (caret == null) { From 9c8e1366da6cd7514aca7bed5cf7498d022f6b75 Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Fri, 11 Sep 2015 18:37:08 +0300 Subject: [PATCH 05/21] utility method calculating whether a file has errors --- .../execution/DelayedDocumentWatcher.java | 41 +-------- .../intellij/util/PsiErrorElementUtil.java | 88 +++++++++++++++++++ 2 files changed, 90 insertions(+), 39 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/util/PsiErrorElementUtil.java diff --git a/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java b/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java index 34deaec02d04..1a573cd5b663 100644 --- a/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java +++ b/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java @@ -29,17 +29,10 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.problems.WolfTheProblemSolver; -import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiFile; -import com.intellij.psi.util.CachedValue; -import com.intellij.psi.util.CachedValueProvider; -import com.intellij.psi.util.CachedValuesManager; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Alarm; import com.intellij.util.Consumer; +import com.intellij.util.PsiErrorElementUtil; import com.intellij.util.messages.MessageBusConnection; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; @@ -50,8 +43,6 @@ import java.util.Set; public class DelayedDocumentWatcher { - private static final Key> CONTAINS_ERROR_ELEMENT = Key.create("CONTAINS_ERROR_ELEMENT"); - // All instance fields are be accessed from EDT private final Project myProject; private final Alarm myAlarm; @@ -184,7 +175,7 @@ public class DelayedDocumentWatcher { @Override public Boolean compute() { for (VirtualFile file : files) { - if (hasErrors(file)) { + if (PsiErrorElementUtil.hasErrors(myProject, file)) { return true; } } @@ -200,32 +191,4 @@ public class DelayedDocumentWatcher { } }); } - - // This method is called in a background thread with a read lock acquired - private boolean hasErrors(@NotNull VirtualFile file) { - if (!file.isValid()) { - return false; - } - // don't use 'WolfTheProblemSolver.hasSyntaxErrors(file)' if possible - Document document = FileDocumentManager.getInstance().getDocument(file); - if (document != null) { - final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document); - if (psiFile != null) { - CachedValuesManager cachedValuesManager = CachedValuesManager.getManager(myProject); - return cachedValuesManager.getCachedValue( - psiFile, - CONTAINS_ERROR_ELEMENT, - new CachedValueProvider() { - @Override - public Result compute() { - boolean error = PsiTreeUtil.hasErrorElements(psiFile); - return Result.create(error, psiFile); - } - }, - false - ); - } - } - return WolfTheProblemSolver.getInstance(myProject).hasSyntaxErrors(file); - } } diff --git a/platform/platform-impl/src/com/intellij/util/PsiErrorElementUtil.java b/platform/platform-impl/src/com/intellij/util/PsiErrorElementUtil.java new file mode 100644 index 000000000000..d78df6a73360 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/util/PsiErrorElementUtil.java @@ -0,0 +1,88 @@ +/* + * Copyright 2000-2015 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.util; + +import com.intellij.codeInsight.highlighting.HighlightErrorFilter; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiErrorElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiManagerEx; +import com.intellij.psi.util.CachedValue; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; +import org.jetbrains.annotations.NotNull; + +public class PsiErrorElementUtil { + + private static final Key> CONTAINS_ERROR_ELEMENT = Key.create("CONTAINS_ERROR_ELEMENT"); + + private PsiErrorElementUtil() {} + + public static boolean hasErrors(@NotNull final Project project, @NotNull final VirtualFile virtualFile) { + if (project.isDisposed() || !virtualFile.isValid()) { + return false; + } + return ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public Boolean compute() { + PsiManagerEx psiManager = (PsiManagerEx)PsiManager.getInstance(project); + PsiFile psiFile = psiManager.getFileManager().findFile(virtualFile); + return psiFile != null && hasErrors(psiFile); + } + }); + } + + private static boolean hasErrors(@NotNull final PsiFile psiFile) { + CachedValuesManager cachedValuesManager = CachedValuesManager.getManager(psiFile.getProject()); + return cachedValuesManager.getCachedValue( + psiFile, + CONTAINS_ERROR_ELEMENT, + new CachedValueProvider() { + @Override + public Result compute() { + boolean error = hasErrorElements(psiFile); + return Result.create(error, psiFile); + } + }, + false + ); + } + + private static boolean hasErrorElements(@NotNull final PsiElement element) { + if (element instanceof PsiErrorElement) { + HighlightErrorFilter[] errorFilters = Extensions.getExtensions(HighlightErrorFilter.EP_NAME, element.getProject()); + for (HighlightErrorFilter errorFilter : errorFilters) { + if (!errorFilter.shouldHighlightErrorElement((PsiErrorElement)element)) { + return false; + } + } + return true; + } + for (PsiElement child : element.getChildren()) { + if (hasErrorElements(child)) { + return true; + } + } + return false; + } +} From 98acfeb273968e377be83cf4aa9e3870cbd13573 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Fri, 11 Sep 2015 18:44:32 +0300 Subject: [PATCH 06/21] do not hide caption when showing speedsearch --- .../src/com/intellij/ui/popup/AbstractPopup.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java index 44828bf0e4ba..0fb8af2501f4 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java @@ -1734,14 +1734,12 @@ public class AbstractPopup implements JBPopup { boolean doRevalidate = false; if (myHeaderComponent != null) { myHeaderPanel.remove(myHeaderComponent); - myHeaderPanel.add(myCaption, BorderLayout.NORTH); myHeaderComponent = null; doRevalidate = true; } if (c != null) { - myHeaderPanel.remove(myCaption); - myHeaderPanel.add(c, BorderLayout.NORTH); + myHeaderPanel.add(c, BorderLayout.CENTER); myHeaderComponent = c; final Dimension size = myContent.getSize(); From cdbe9716001280347143fda8afc356fad19082aa Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Fri, 11 Sep 2015 18:53:51 +0300 Subject: [PATCH 07/21] capitalization --- .../openapi/vcs/changes/patch/ApplyPatchExecutor.java | 2 ++ .../openapi/vcs/changes/patch/ImportToShelfExecutor.java | 4 ++-- .../idea/svn/treeConflict/ApplyPatchSaveToFileExecutor.java | 4 ++-- .../idea/svn/treeConflict/MergeFromTheirsResolver.java | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchExecutor.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchExecutor.java index 42ddc3ab9429..3266156e1874 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchExecutor.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchExecutor.java @@ -20,6 +20,7 @@ import com.intellij.openapi.vcs.changes.LocalChangeList; import com.intellij.openapi.vcs.changes.TransparentlyFailedValueI; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.MultiMap; +import org.jetbrains.annotations.Nls; import java.util.Map; @@ -29,6 +30,7 @@ import java.util.Map; * Time: 5:18 PM */ public interface ApplyPatchExecutor { + @Nls(capitalization = Nls.Capitalization.Title) String getName(); void apply(final MultiMap patchGroups, diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ImportToShelfExecutor.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ImportToShelfExecutor.java index 78c50dc26ef9..43a92c6b8c33 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ImportToShelfExecutor.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ImportToShelfExecutor.java @@ -49,7 +49,7 @@ import java.util.*; * Time: 6:21 PM */ public class ImportToShelfExecutor implements ApplyPatchExecutor { - public static final String IMPORT_TO_SHELF = "Import to shelf"; + public static final String IMPORT_TO_SHELF = "Import to Shelf"; private final Project myProject; public ImportToShelfExecutor(Project project) { @@ -122,7 +122,7 @@ public class ImportToShelfExecutor implements ApplyPatchExecutor>, PatchSyntaxException> additionalInfo) { final FileSaverDialog dialog = FileChooserFactory.getInstance().createSaveFileDialog( - new FileSaverDescriptor("Save patch to", ""), myProject); + new FileSaverDescriptor("Save Patch to", ""), myProject); final VirtualFile baseDir = myProject.getBaseDir(); final VirtualFileWrapper save = dialog.save(baseDir, "TheirsChanges.patch"); if (save != null) { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/MergeFromTheirsResolver.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/MergeFromTheirsResolver.java index 5f242fa5b5a4..33485e3fa079 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/MergeFromTheirsResolver.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/MergeFromTheirsResolver.java @@ -239,7 +239,7 @@ public class MergeFromTheirsResolver { @Override public String getName() { - return "Apply patch"; + return "Apply Patch"; } @Override From 59c03383d4c7e06a5f1a72aa6a0192fe471dbf36 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Fri, 11 Sep 2015 19:02:16 +0300 Subject: [PATCH 08/21] preserve tree selection after mark value in evaluate dialog --- .../src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java index 59ebc221562b..8fb9b78cc403 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java @@ -395,6 +395,7 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa public void nodeLoaded(@NotNull RestorableStateNode node, String name) { if (nodeFilter.value(node)) { setSelectionPath(node.getPath()); + removeTreeListener(this); // remove the listener on first match } } From ab6866188b6d359f8807831838a0f4e5530da781 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 11 Sep 2015 19:12:28 +0300 Subject: [PATCH 09/21] fxHelpBrowser removed (it was hidden by registry property and we plan to reimplement it to start in a separate process) --- build/conf/classVersions.txt | 1 - .../intellij/help/impl/HelpManagerImpl.java | 51 ------------------- .../util/resources/misc/registry.properties | 2 - 3 files changed, 54 deletions(-) diff --git a/build/conf/classVersions.txt b/build/conf/classVersions.txt index 85b9258e9f57..032c87b16199 100644 --- a/build/conf/classVersions.txt +++ b/build/conf/classVersions.txt @@ -30,7 +30,6 @@ 1.3 => lib/idea_rt.jar -1.7 => lib/fxHelpBrowser.jar 1.7 => lib/optimizedFileManager.jar 1.5 => plugins/Groovy/lib/groovy_rt.jar diff --git a/platform/platform-impl/src/com/intellij/help/impl/HelpManagerImpl.java b/platform/platform-impl/src/com/intellij/help/impl/HelpManagerImpl.java index 9afd799f741b..c13038d4bd3f 100644 --- a/platform/platform-impl/src/com/intellij/help/impl/HelpManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/help/impl/HelpManagerImpl.java @@ -27,8 +27,6 @@ import com.intellij.openapi.application.ex.ApplicationInfoEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.util.registry.Registry; import com.intellij.util.PlatformUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -36,9 +34,6 @@ import org.jetbrains.annotations.Nullable; import javax.help.BadIDException; import javax.help.HelpSet; import java.awt.*; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.net.URL; public class HelpManagerImpl extends HelpManager { @@ -48,7 +43,6 @@ public class HelpManagerImpl extends HelpManager { private HelpSet myHelpSet = null; private IdeaHelpBroker myBroker = null; - private Object myFXHelpBrowser = null; public void invokeHelp(@Nullable String id) { UsageTrigger.trigger("ide.help." + id); @@ -61,11 +55,6 @@ public class HelpManagerImpl extends HelpManager { return; } - if (SystemInfo.isJavaVersionAtLeast("1.7.0.40") && Registry.is("ide.help.fxbrowser")) { - showHelpInFXBrowser(id); - return; - } - if (myHelpSet == null) { ApplicationInfoEx info = ApplicationInfoEx.getInstanceEx(); String url = info.getWebHelpUrl() + "?"; @@ -102,46 +91,6 @@ public class HelpManagerImpl extends HelpManager { myBroker.setDisplayed(true); } - private void showHelpInFXBrowser(final String id) { - if (myHelpSet == null) { - Messages.showInfoMessage("Looks like you have enabled 'ide.help.fxbrowser' registry key but we cannot load JavaHelp bundle. " + - "Please put ideahelp.jar in the help directory.", - "Cannot Find JavaHelp Bundle"); - return; - } - try { - final Class myFXHelpBrowserClass = Class.forName("com.intellij.help.impl.FXHelpBrowser"); - - if (myFXHelpBrowser == null) { - Object[] arguments = {myHelpSet}; - - Class[] argTypes = {HelpSet.class}; - Constructor constructor = myFXHelpBrowserClass.getDeclaredConstructor(argTypes); - myFXHelpBrowser = constructor.newInstance(arguments); - } - Class[] showDocumentationMethodArgTypes = {String.class}; - Method showDocumentationMethod = myFXHelpBrowserClass.getDeclaredMethod("showDocumentationById", showDocumentationMethodArgTypes); - showDocumentationMethod.invoke(myFXHelpBrowser, id); - - } - catch (ClassNotFoundException e) { - LOG.error(e); - } - catch (IllegalAccessException e) { - LOG.error(e); - } - catch (NoSuchMethodException e) { - LOG.error(e); - } - catch (InvocationTargetException e) { - LOG.error(e); - } - catch (InstantiationException e) { - LOG.error(e); - } - - } - @Nullable private static HelpSet createHelpSet() { String urlToHelp = ApplicationInfo.getInstance().getHelpURL() + "/" + HELP_HS; diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index f0335efe1ec4..1ea56a814a46 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -90,8 +90,6 @@ ide.windowSystem.showListItemsPopup=true ide.windowSystem.asyncSplitters=true ide.windowSystem.showTooWindowButtonsSwitcher=true -ide.help.fxbrowser=false - passwordSafe.masterPassword.ttl=360 passwordSafe.memorySafe.ttl=-1 From 1adae2a50af9f7c0689a42df4bc72ce8dab09730 Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Fri, 11 Sep 2015 19:24:15 +0300 Subject: [PATCH 10/21] environment configuration for GeneralCommandLine --- .../configuration/EnvironmentVariablesData.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesData.java b/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesData.java index 9550f29db385..1799a3d03cc6 100644 --- a/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesData.java +++ b/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesData.java @@ -16,6 +16,7 @@ package com.intellij.execution.configuration; import com.google.common.collect.ImmutableMap; +import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.util.containers.ContainerUtil; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -114,6 +115,17 @@ public class EnvironmentVariablesData { parent.addContent(envsElement); } + public void configureCommandLine(@NotNull GeneralCommandLine commandLine, boolean shellParentEnvs) { + if (myPassParentEnvs) { + commandLine.withParentEnvironmentType(shellParentEnvs ? GeneralCommandLine.ParentEnvironmentType.SHELL + : GeneralCommandLine.ParentEnvironmentType.SYSTEM); + } + else { + commandLine.withParentEnvironmentType(GeneralCommandLine.ParentEnvironmentType.NONE); + } + commandLine.withEnvironment(myEnvs); + } + /** * @param envs Map instance containing user-defined environment variables * (iteration order should be reliable user-specified, like {@link LinkedHashMap} or {@link ImmutableMap}) From 7a067f329194ac1d678c1957106b270f429c7549 Mon Sep 17 00:00:00 2001 From: Alexander Doroshko Date: Fri, 11 Sep 2015 19:33:23 +0300 Subject: [PATCH 11/21] dart.server.observe option --- platform/util/resources/misc/registry.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 1ea56a814a46..a41689e189a3 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -649,6 +649,7 @@ ide.mac.yosemite.laf.description=Replaces Aqua LaF to enhanced IntelliJ LaF editor.detect.indent.by.formatter=true dart.server.additional.arguments= +dart.server.observe=false dart.server.driven.resolution=false dart.projects.without.pubspec=false From 4429af44cec28ad863e8acd28388d0195741d493 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 11 Sep 2015 11:56:18 +0300 Subject: [PATCH 12/21] enable introduce handlers for locals when applicable (IDEA-145028) --- .../com/intellij/refactoring/IntroduceHandlerBase.java | 8 +++++++- .../introduceVariable/IntroduceVariableHandler.java | 5 +++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/refactoring/IntroduceHandlerBase.java b/java/java-impl/src/com/intellij/refactoring/IntroduceHandlerBase.java index d452f465d0dd..176018ba213b 100644 --- a/java/java-impl/src/com/intellij/refactoring/IntroduceHandlerBase.java +++ b/java/java-impl/src/com/intellij/refactoring/IntroduceHandlerBase.java @@ -38,7 +38,13 @@ public abstract class IntroduceHandlerBase implements RefactoringActionHandler, @Override public boolean isAvailableForQuickList(@NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext dataContext) { final PsiElement[] elements = ExtractMethodHandler.getElements(file.getProject(), editor, file); - return elements != null && elements.length > 0; + if (elements != null && elements.length > 0) return true; + return acceptLocalVariable() && + PsiTreeUtil.getParentOfType(file.findElementAt(editor.getCaretModel().getOffset()), PsiLocalVariable.class) != null; + } + + protected boolean acceptLocalVariable() { + return true; } public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) { diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableHandler.java index e11b61825d62..8c99ae868ade 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableHandler.java @@ -103,4 +103,9 @@ public class IntroduceVariableHandler extends IntroduceVariableBase { } return ok; } + + @Override + protected boolean acceptLocalVariable() { + return false; + } } From b0d45cd4be386fc0d33435fb4dfa4c8396470502 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 11 Sep 2015 13:36:31 +0300 Subject: [PATCH 13/21] logging for EA-70141 - assert: ProblemDescriptorBase. --- .../codeInspection/ui/actions/SuppressActionWrapper.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java index 5eac7dd6e6d0..20db55e49ae9 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java @@ -98,6 +98,9 @@ public class SuppressActionWrapper extends ActionGroup { final CommonProblemDescriptor descriptor, final SuppressIntentionAction action, final RefEntity refEntity) { + if (action instanceof SuppressIntentionActionFromFix && !(descriptor instanceof ProblemDescriptor)) { + LOG.info("local suppression fix for specific problem descriptor: " + myToolWrapper.getTool().getClass().getName()); + } final PsiModificationTracker tracker = PsiManager.getInstance(myProject).getModificationTracker(); ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override From 9bbc955f9409a5768058e5a231a88c134170b1bb Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 11 Sep 2015 16:23:34 +0300 Subject: [PATCH 14/21] junit/testng: attach listener before test run so suggestion to change module would work (IDEA-145050) --- .../JUnitTreeByDescriptionHierarchyTest.java | 43 +++++++++---------- .../intellij/junit4/JUnit4TestListener.java | 4 +- .../TestNGTreeHierarchyTest.java | 15 ++++--- .../org/testng/IDEATestNGRemoteListener.java | 4 +- 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/plugins/junit/test/com/intellij/execution/junit/JUnitTreeByDescriptionHierarchyTest.java b/plugins/junit/test/com/intellij/execution/junit/JUnitTreeByDescriptionHierarchyTest.java index cbf3d4fe8067..9343911baf47 100644 --- a/plugins/junit/test/com/intellij/execution/junit/JUnitTreeByDescriptionHierarchyTest.java +++ b/plugins/junit/test/com/intellij/execution/junit/JUnitTreeByDescriptionHierarchyTest.java @@ -33,7 +33,8 @@ import java.util.List; public class JUnitTreeByDescriptionHierarchyTest { @Test public void testEmptySuite() throws Exception { - doTest(Description.createSuiteDescription("empty suite"), "##teamcity[treeEnded]\n"); + doTest(Description.createSuiteDescription("empty suite"), "##teamcity[enteredTheMatrix]\n" + + "##teamcity[treeEnded]\n"); } @Test @@ -46,6 +47,7 @@ public class JUnitTreeByDescriptionHierarchyTest { attachParameterizedTests(className, aTestClass, tests); } doTest(root, tests, + "##teamcity[enteredTheMatrix]\n" + "##teamcity[suiteTreeStarted name='TestA' locationHint='java:suite://a.TestA']\n" + "##teamcity[suiteTreeStarted name='|[0|]' locationHint='java:suite://a.TestA.|[0|]']\n" + "##teamcity[suiteTreeNode name='testName|[0|]' locationHint='java:test://a.TestA.testName|[0|]']\n" + @@ -65,7 +67,6 @@ public class JUnitTreeByDescriptionHierarchyTest { "##teamcity[treeEnded]\n", - "##teamcity[enteredTheMatrix]\n" + "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" + "##teamcity[testSuiteStarted name='TestA']\n" + "##teamcity[testSuiteStarted name='|[0|]']\n" + @@ -135,14 +136,14 @@ public class JUnitTreeByDescriptionHierarchyTest { tests.add(testDescription); aTestClass.addChild(testDescription); } - doTest(rootDescription, tests, "##teamcity[suiteTreeStarted name='MyTest' locationHint='java:suite://a.MyTest']\n" + + doTest(rootDescription, tests, "##teamcity[enteredTheMatrix]\n" + + "##teamcity[suiteTreeStarted name='MyTest' locationHint='java:suite://a.MyTest']\n" + "##teamcity[suiteTreeNode name='MyTest.testMe' locationHint='java:test://a.MyTest.testMe']\n" + "##teamcity[suiteTreeEnded name='MyTest']\n" + "##teamcity[suiteTreeStarted name='MyTest' locationHint='java:suite://b.MyTest']\n" + "##teamcity[suiteTreeNode name='MyTest.testMe' locationHint='java:test://b.MyTest.testMe']\n" + "##teamcity[suiteTreeEnded name='MyTest']\n" + "##teamcity[treeEnded]\n", - "##teamcity[enteredTheMatrix]\n" + "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" + "##teamcity[testSuiteStarted name='MyTest']\n" + "##teamcity[testStarted name='MyTest.testMe' locationHint='java:test://a.MyTest.testMe']\n" + @@ -165,6 +166,7 @@ public class JUnitTreeByDescriptionHierarchyTest { attachParameterizedTests(className, aTestClassDescription, tests); doTest(aTestClassDescription, tests, //tree + "##teamcity[enteredTheMatrix]\n" + "##teamcity[suiteTreeStarted name='|[0|]' locationHint='java:suite://a.TestA.|[0|]']\n" + "##teamcity[suiteTreeNode name='testName|[0|]' locationHint='java:test://a.TestA.testName|[0|]']\n" + "##teamcity[suiteTreeEnded name='|[0|]']\n" + @@ -173,7 +175,6 @@ public class JUnitTreeByDescriptionHierarchyTest { "##teamcity[suiteTreeEnded name='|[1|]']\n" + "##teamcity[treeEnded]\n", //start - "##teamcity[enteredTheMatrix]\n" + "##teamcity[rootName name = 'TestA' comment = 'a' location = 'java:suite://a.TestA']\n" + "##teamcity[testSuiteStarted name='|[0|]']\n" + "##teamcity[testStarted name='testName|[0|]' locationHint='java:test://a.TestA.testName|[0|]']\n" + @@ -201,6 +202,7 @@ public class JUnitTreeByDescriptionHierarchyTest { } doTest(aTestClassDescription, tests, //tree + "##teamcity[enteredTheMatrix]\n" + "##teamcity[suiteTreeStarted name='|[0|]' locationHint='java:suite://a.TestA.|[0|]']\n" + "##teamcity[suiteTreeNode name='testName|[0|]' locationHint='java:test://a.TestA.testName|[0|]']\n" + "##teamcity[suiteTreeEnded name='|[0|]']\n" + @@ -209,7 +211,6 @@ public class JUnitTreeByDescriptionHierarchyTest { "##teamcity[suiteTreeEnded name='|[0|]']\n" + "##teamcity[treeEnded]\n", //start - "##teamcity[enteredTheMatrix]\n" + "##teamcity[rootName name = 'TestA' comment = 'a' location = 'java:suite://a.TestA']\n" + "##teamcity[testSuiteStarted name='|[0|]']\n" + "##teamcity[testStarted name='testName|[0|]' locationHint='java:test://a.TestA.testName|[0|]']\n" + @@ -237,6 +238,7 @@ public class JUnitTreeByDescriptionHierarchyTest { } doTest(aTestClassDescription, tests, //tree + "##teamcity[enteredTheMatrix]\n" + "##teamcity[suiteTreeStarted name='|[0: with - 1.1|]' locationHint='java:suite://a.TestA.|[0: with - 1.1|]']\n" + "##teamcity[suiteTreeNode name='testName|[0: with - 1.1|]' locationHint='java:test://a.TestA.testName|[0: with - 1.1|]']\n" + "##teamcity[suiteTreeEnded name='|[0: with - 1.1|]']\n" + @@ -245,7 +247,6 @@ public class JUnitTreeByDescriptionHierarchyTest { "##teamcity[suiteTreeEnded name='|[1: with - 2.1|]']\n" + "##teamcity[treeEnded]\n", //start - "##teamcity[enteredTheMatrix]\n" + "##teamcity[rootName name = 'TestA' comment = 'a' location = 'java:suite://a.TestA']\n" + "##teamcity[testSuiteStarted name='|[0: with - 1.1|]']\n" + "##teamcity[testStarted name='testName|[0: with - 1.1|]' locationHint='java:test://a.TestA.testName|[0: with - 1.1|]']\n" + @@ -277,6 +278,7 @@ public class JUnitTreeByDescriptionHierarchyTest { doTest(root, tests, //expected tree + "##teamcity[enteredTheMatrix]\n" + "##teamcity[suiteTreeStarted name='ASuite1' locationHint='java:suite://ASuite1']\n" + "##teamcity[suiteTreeStarted name='ATest' locationHint='java:suite://ATest']\n" + "##teamcity[suiteTreeNode name='ATest.test1' locationHint='java:test://ATest.test1']\n" + @@ -290,7 +292,6 @@ public class JUnitTreeByDescriptionHierarchyTest { "##teamcity[treeEnded]\n", //started - "##teamcity[enteredTheMatrix]\n" + "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" + "##teamcity[testSuiteStarted name='ASuite1']\n" + "##teamcity[testSuiteStarted name='ATest']\n" + @@ -339,7 +340,8 @@ public class JUnitTreeByDescriptionHierarchyTest { final JUnit4TestListener sender = createListener(buf); sender.sendTree(root); - Assert.assertEquals("output: " + buf, "##teamcity[suiteTreeStarted name='TestA' locationHint='java:suite://TestA']\n" + + Assert.assertEquals("output: " + buf, "##teamcity[enteredTheMatrix]\n" + + "##teamcity[suiteTreeStarted name='TestA' locationHint='java:suite://TestA']\n" + "##teamcity[suiteTreeNode name='TestA.testName' locationHint='java:test://TestA.testName']\n" + "##teamcity[suiteTreeEnded name='TestA']\n" + "##teamcity[treeEnded]\n", StringUtil.convertLineSeparators(buf.toString())); @@ -352,8 +354,7 @@ public class JUnitTreeByDescriptionHierarchyTest { sender.testAssumptionFailure(new Failure(testA, exception)); sender.testRunFinished(new Result()); - Assert.assertEquals("output: " + buf, "##teamcity[enteredTheMatrix]\n" + - "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" + + Assert.assertEquals("output: " + buf, "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" + "##teamcity[testSuiteStarted name='TestA']\n" + "##teamcity[testStarted name='TestA.testName' locationHint='java:test://TestA.testName']\n" + "\n" + @@ -377,7 +378,8 @@ public class JUnitTreeByDescriptionHierarchyTest { final JUnit4TestListener sender = createListener(buf); sender.sendTree(root); - Assert.assertEquals("output: " + buf, "##teamcity[suiteTreeStarted name='TestA' locationHint='java:suite://TestA']\n" + + Assert.assertEquals("output: " + buf, "##teamcity[enteredTheMatrix]\n" + + "##teamcity[suiteTreeStarted name='TestA' locationHint='java:suite://TestA']\n" + "##teamcity[suiteTreeStarted name='param' locationHint='java:suite://param']\n" + "##teamcity[suiteTreeNode name='TestA.testName' locationHint='java:test://TestA.testName']\n" + "##teamcity[suiteTreeEnded name='param']\n" + @@ -392,8 +394,7 @@ public class JUnitTreeByDescriptionHierarchyTest { sender.testAssumptionFailure(new Failure(testA, exception)); sender.testRunFinished(new Result()); - Assert.assertEquals("output: " + buf, "##teamcity[enteredTheMatrix]\n" + - "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" + + Assert.assertEquals("output: " + buf, "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" + "##teamcity[testSuiteStarted name='TestA']\n" + "##teamcity[testSuiteStarted name='param']\n" + "##teamcity[testStarted name='TestA.testName' locationHint='java:test://TestA.testName']\n" + @@ -410,8 +411,7 @@ public class JUnitTreeByDescriptionHierarchyTest { sender.testAssumptionFailure(new Failure(testName, exception)); sender.testRunFinished(new Result()); - Assert.assertEquals("output: " + buf, "##teamcity[enteredTheMatrix]\n" + - "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" + + Assert.assertEquals("output: " + buf, "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" + "\n" + "##teamcity[testIgnored name='TestA.testName' details='java.lang.Exception|n' error='true' message='']\n", StringUtil.convertLineSeparators(buf.toString())); @@ -420,10 +420,10 @@ public class JUnitTreeByDescriptionHierarchyTest { @Test public void testSingleMethod() throws Exception { final Description rootDescription = Description.createTestDescription("TestA", "testName"); - doTest(rootDescription, Collections.singletonList(rootDescription), + doTest(rootDescription, Collections.singletonList(rootDescription), + "##teamcity[enteredTheMatrix]\n" + "##teamcity[suiteTreeNode name='TestA.testName' locationHint='java:test://TestA.testName']\n" + "##teamcity[treeEnded]\n", - "##teamcity[enteredTheMatrix]\n" + "##teamcity[rootName name = 'TestA' location = 'java:suite://TestA']\n" + "##teamcity[testStarted name='TestA.testName' locationHint='java:test://TestA.testName']\n" + "\n" + @@ -496,6 +496,7 @@ public class JUnitTreeByDescriptionHierarchyTest { testMethod.addChild(testDescription); } doTest(aTestClass, tests, + "##teamcity[enteredTheMatrix]\n" + "##teamcity[suiteTreeStarted name='testName' locationHint='java:suite://testName']\n" + "##teamcity[suiteTreeNode name='ATest.testName|[0|]' locationHint='java:test://ATest.testName|[0|]']\n" + "##teamcity[suiteTreeNode name='ATest.testName|[1|]' locationHint='java:test://ATest.testName|[1|]']\n" + @@ -503,7 +504,6 @@ public class JUnitTreeByDescriptionHierarchyTest { "##teamcity[treeEnded]\n", - "##teamcity[enteredTheMatrix]\n" + "##teamcity[rootName name = 'ATest' location = 'java:suite://ATest']\n" + "##teamcity[testSuiteStarted name='testName']\n" + "##teamcity[testStarted name='ATest.testName|[0|]' locationHint='java:test://ATest.testName|[0|]']\n" + @@ -530,6 +530,7 @@ public class JUnitTreeByDescriptionHierarchyTest { aTestClassWithJUnit3Test.addChild(testDescription); tests.add(testDescription); doTest(root, tests, + "##teamcity[enteredTheMatrix]\n" + "##teamcity[suiteTreeStarted name='ATest' locationHint='java:suite://ATest']\n" + "##teamcity[suiteTreeStarted name='|[0|]' locationHint='java:suite://ATest.|[0|]']\n" + "##teamcity[suiteTreeNode name='testName|[0|]' locationHint='java:test://ATest.testName|[0|]']\n" + @@ -546,7 +547,6 @@ public class JUnitTreeByDescriptionHierarchyTest { "##teamcity[treeEnded]\n", //start - "##teamcity[enteredTheMatrix]\n" + "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" + "##teamcity[testSuiteStarted name='ATest']\n" + "##teamcity[testSuiteStarted name='|[0|]']\n" + @@ -593,11 +593,10 @@ public class JUnitTreeByDescriptionHierarchyTest { final Description emptyDescription = Description.createTestDescription(JUnit4TestListener.EMPTY_SUITE_NAME, JUnit4TestListener.EMPTY_SUITE_WARNING); description.addChild(emptyDescription); doTest(description, Collections.singletonList(emptyDescription), + "##teamcity[enteredTheMatrix]\n" + "##teamcity[suiteTreeNode name='TestSuite$1.warning' locationHint='java:test://junit.framework.TestSuite$1.warning']\n" + "##teamcity[treeEnded]\n", - - "##teamcity[enteredTheMatrix]\n" + "##teamcity[rootName name = 'TestA' location = 'java:suite://TestA']\n" + "##teamcity[testStarted name='TestSuite$1.warning' locationHint='java:test://junit.framework.TestSuite$1.warning']\n" + "\n" + diff --git a/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestListener.java b/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestListener.java index d757df8370be..b93c0ab19131 100644 --- a/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestListener.java +++ b/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestListener.java @@ -50,11 +50,12 @@ public class JUnit4TestListener extends RunListener { private long myCurrentTestStart; public JUnit4TestListener() { - myPrintStream = System.out; + this(System.out); } public JUnit4TestListener(PrintStream printStream) { myPrintStream = printStream; + myPrintStream.println("##teamcity[enteredTheMatrix]"); } private static String escapeName(String str) { @@ -62,7 +63,6 @@ public class JUnit4TestListener extends RunListener { } public void testRunStarted(Description description) throws Exception { - myPrintStream.println("##teamcity[enteredTheMatrix]"); if (myRootName != null && !myRootName.startsWith("[")) { int lastPointIdx = myRootName.lastIndexOf('.'); String name = myRootName; diff --git a/plugins/testng/testSources/com/theoryinpractice/testng/configuration/TestNGTreeHierarchyTest.java b/plugins/testng/testSources/com/theoryinpractice/testng/configuration/TestNGTreeHierarchyTest.java index 3e1a36fb2217..814d0eeeb860 100644 --- a/plugins/testng/testSources/com/theoryinpractice/testng/configuration/TestNGTreeHierarchyTest.java +++ b/plugins/testng/testSources/com/theoryinpractice/testng/configuration/TestNGTreeHierarchyTest.java @@ -46,7 +46,8 @@ public class TestNGTreeHierarchyTest { test.getClasses().add(xmlClass); suite.getTests().add(test); - doTest(suite, "\n" + + doTest(suite,"##teamcity[enteredTheMatrix]\n" + + "\n" + "##teamcity[testSuiteStarted name ='ATest' locationHint = 'java:suite://a.ATest']\n" + "\n" + "##teamcity[testStarted name='ATest.test1|[0|]' locationHint='java:test://a.ATest.test1|[0|]']\n" + @@ -187,7 +188,8 @@ public class TestNGTreeHierarchyTest { test.getClasses().add(xmlClass); suite.getTests().add(test); - doTest(suite, "\n" + + doTest(suite, "##teamcity[enteredTheMatrix]\n" + + "\n" + "##teamcity[testSuiteStarted name ='ATest' locationHint = 'java:suite://a.ATest']\n" + "\n" + "##teamcity[testStarted name='ATest.test1|[0|]' locationHint='java:test://a.ATest.test1|[0|]']\n" + @@ -222,7 +224,8 @@ public class TestNGTreeHierarchyTest { } listener.onSuiteFinish(className); - Assert.assertEquals("output: " + buf, "\n" + + Assert.assertEquals("output: " + buf,"##teamcity[enteredTheMatrix]\n" + + "\n" + "##teamcity[testSuiteStarted name ='ATest' locationHint = 'java:suite://a.ATest']\n" + "\n" + "##teamcity[testStarted name='ATest.setUp' locationHint='java:test://a.ATest.setUp' config='true']\n" + @@ -262,7 +265,8 @@ public class TestNGTreeHierarchyTest { listener.onConfigurationFailure(setUp); listener.onSuiteFinish(className); - Assert.assertEquals("output: " + buf, "\n" + + Assert.assertEquals("output: " + buf, "##teamcity[enteredTheMatrix]\n" + + "\n" + "##teamcity[testSuiteStarted name ='ATest' locationHint = 'java:suite://a.ATest']\n" + "\n" + "##teamcity[testStarted name='ATest.setUp' locationHint='java:test://a.ATest.setUp' config='true']\n" + @@ -279,7 +283,8 @@ public class TestNGTreeHierarchyTest { final MockTestNGResult result = new MockTestNGResult("ATest", "testMe", null, new Object[]{null, null}); listener.onTestStart(result); listener.onTestFinished(result); - Assert.assertEquals("output: " + buf, "\n" + + Assert.assertEquals("output: " + buf, "##teamcity[enteredTheMatrix]\n" + + "\n" + "##teamcity[testSuiteStarted name ='ATest' locationHint = 'java:suite://ATest']\n" + "\n" + "##teamcity[testStarted name='ATest.testMe|[null, null|]' locationHint='java:test://ATest.testMe|[0|]']\n" + diff --git a/plugins/testng_rt/src/org/testng/IDEATestNGRemoteListener.java b/plugins/testng_rt/src/org/testng/IDEATestNGRemoteListener.java index 3553dfc4e34d..5664908788bf 100644 --- a/plugins/testng_rt/src/org/testng/IDEATestNGRemoteListener.java +++ b/plugins/testng_rt/src/org/testng/IDEATestNGRemoteListener.java @@ -21,15 +21,15 @@ public class IDEATestNGRemoteListener implements ISuiteListener, IResultListener private final Map myParamsMap = new HashMap(); public IDEATestNGRemoteListener() { - myPrintStream = System.out; + this(System.out); } public IDEATestNGRemoteListener(PrintStream printStream) { myPrintStream = printStream; + myPrintStream.println("##teamcity[enteredTheMatrix]"); } public synchronized void onStart(final ISuite suite) { - myPrintStream.println("##teamcity[enteredTheMatrix]"); if (suite != null) { final List allMethods = suite.getAllMethods(); if (allMethods != null) { From f5101a309a4e88777465b9c4608b0e4da38dd568 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 11 Sep 2015 19:47:51 +0300 Subject: [PATCH 15/21] fix java inplace introduce inside injections --- .../AbstractJavaInplaceIntroducer.java | 2 +- .../inplaceIntroduceVariable/insideInjectedString.java | 5 +++++ .../insideInjectedString_after.java | 5 +++++ .../refactoring/AbstractJavaInplaceIntroduceTest.java | 8 ++++++++ .../refactoring/InplaceIntroduceVariableTest.java | 9 +++++++++ .../refactoring/AbstractInplaceIntroduceTest.java | 3 ++- 6 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/refactoring/inplaceIntroduceVariable/insideInjectedString.java create mode 100644 java/java-tests/testData/refactoring/inplaceIntroduceVariable/insideInjectedString_after.java diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java index 92aedd951319..b803cf700364 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java @@ -38,7 +38,7 @@ public abstract class AbstractJavaInplaceIntroducer extends AbstractInplaceIntro PsiVariable localVariable, PsiExpression[] occurrences, TypeSelectorManagerImpl typeSelectorManager, String title) { - super(project, InjectedLanguageUtil.getTopLevelEditor(editor), expr, localVariable, occurrences, title, StdFileTypes.JAVA); + super(project, editor, expr, localVariable, occurrences, title, StdFileTypes.JAVA); myTypeSelectorManager = typeSelectorManager; } diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceVariable/insideInjectedString.java b/java/java-tests/testData/refactoring/inplaceIntroduceVariable/insideInjectedString.java new file mode 100644 index 000000000000..984b7b0aa298 --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceVariable/insideInjectedString.java @@ -0,0 +1,5 @@ +class C { + { + String java = "class ABC { {new ABC();}}"; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceVariable/insideInjectedString_after.java b/java/java-tests/testData/refactoring/inplaceIntroduceVariable/insideInjectedString_after.java new file mode 100644 index 000000000000..a646a5b7fb5a --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceVariable/insideInjectedString_after.java @@ -0,0 +1,5 @@ +class C { + { + String java = "class ABC { {ABC expr = new ABC();}}"; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/AbstractJavaInplaceIntroduceTest.java b/java/java-tests/testSrc/com/intellij/refactoring/AbstractJavaInplaceIntroduceTest.java index 37da84a67e2e..c7a6d9112f3c 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/AbstractJavaInplaceIntroduceTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/AbstractJavaInplaceIntroduceTest.java @@ -18,10 +18,12 @@ package com.intellij.refactoring; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.util.Pass; import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiLocalVariable; import com.intellij.psi.PsiMethodCallExpression; import com.intellij.psi.PsiReferenceExpression; +import com.intellij.psi.impl.source.tree.injected.MyTestInjector; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.introduce.inplace.AbstractInplaceIntroducer; import com.intellij.testFramework.IdeaTestCase; @@ -79,6 +81,12 @@ public abstract class AbstractJavaInplaceIntroduceTest extends AbstractInplaceIn } return introduceHandler.getInplaceIntroducer(); } + + protected void doTestInsideInjection(final Pass pass) { + MyTestInjector testInjector = new MyTestInjector(getPsiManager()); + testInjector.injectAll(myTestRootDisposable); + doTest(pass); + } public interface MyIntroduceHandler { boolean invokeImpl(Project project, @NotNull PsiExpression selectedExpr, Editor editor); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceVariableTest.java index 1b1449589230..0c6159d6d839 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceVariableTest.java @@ -55,6 +55,15 @@ public class InplaceIntroduceVariableTest extends AbstractJavaInplaceIntroduceTe }); } + public void testInsideInjectedString() throws Exception { + doTestInsideInjection(new Pass() { + @Override + public void pass(AbstractInplaceIntroducer inplaceIntroduceFieldPopup) { + type("expr"); + } + }); + } + public void testPlaceInsideLoopAndRename() throws Exception { doTest(new Pass() { @Override diff --git a/platform/testFramework/src/com/intellij/refactoring/AbstractInplaceIntroduceTest.java b/platform/testFramework/src/com/intellij/refactoring/AbstractInplaceIntroduceTest.java index b2d6620e22a7..deba4c6d9612 100644 --- a/platform/testFramework/src/com/intellij/refactoring/AbstractInplaceIntroduceTest.java +++ b/platform/testFramework/src/com/intellij/refactoring/AbstractInplaceIntroduceTest.java @@ -18,6 +18,7 @@ package com.intellij.refactoring; import com.intellij.codeInsight.template.impl.TemplateManagerImpl; import com.intellij.codeInsight.template.impl.TemplateState; import com.intellij.openapi.util.Pass; +import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.refactoring.introduce.inplace.AbstractInplaceIntroducer; import com.intellij.testFramework.LightPlatformCodeInsightTestCase; @@ -67,7 +68,7 @@ public abstract class AbstractInplaceIntroduceTest extends LightPlatformCodeInsi final AbstractInplaceIntroducer introducer = invokeRefactoring(); pass.pass(introducer); - TemplateState state = TemplateManagerImpl.getTemplateState(getEditor()); + TemplateState state = TemplateManagerImpl.getTemplateState(InjectedLanguageUtil.getTopLevelEditor(getEditor())); assert state != null; state.gotoEnd(false); checkResultByFile(getBasePath() + name + "_after" + getExtension()); From e7d0480644262ebe910a982328e09b9b824b1cd8 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 11 Sep 2015 19:44:13 +0300 Subject: [PATCH 16/21] cleanup --- .../src/com/intellij/lang/parser/GeneratedParserUtilBase.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java b/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java index fe6ce0840659..b3e708aaffa0 100644 --- a/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java +++ b/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java @@ -1104,9 +1104,7 @@ public class GeneratedParserUtilBase { tokenCount = 0; } } - if (marker != null) { - marker.drop(); - } + marker.drop(); for (Pair pair : parenList) { pair.first.drop(); } From 0d907dd377ffbaefd64c6b7f2d78b94121f80e60 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 11 Sep 2015 19:33:29 +0200 Subject: [PATCH 17/21] assert in tests that just created PsiAnchors can always be restored back fix java/drools case with classes physical for no good reason (EA-72352 - assert: SymbolCollectingProcessor$ResultWithContext.getElement) --- .../smartPointers/JavaAnchorProvider.java | 2 +- .../src/com/intellij/psi/PsiAnchor.java | 34 +++++++++++-------- .../impl/smartPointers/SelfElementInfo.java | 2 +- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/JavaAnchorProvider.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/JavaAnchorProvider.java index 17cb0d52175a..9597a68010aa 100644 --- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/JavaAnchorProvider.java +++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/JavaAnchorProvider.java @@ -26,7 +26,7 @@ import org.jetbrains.annotations.Nullable; public class JavaAnchorProvider extends SmartPointerAnchorProvider { @Override public PsiElement getAnchor(@NotNull PsiElement element) { - if (!element.getLanguage().isKindOf(JavaLanguage.INSTANCE)) { + if (!element.getLanguage().isKindOf(JavaLanguage.INSTANCE) || !element.isPhysical()) { return null; } diff --git a/platform/core-impl/src/com/intellij/psi/PsiAnchor.java b/platform/core-impl/src/com/intellij/psi/PsiAnchor.java index 51733b386fab..2d0d4e14dac9 100644 --- a/platform/core-impl/src/com/intellij/psi/PsiAnchor.java +++ b/platform/core-impl/src/com/intellij/psi/PsiAnchor.java @@ -19,6 +19,7 @@ package com.intellij.psi; import com.intellij.lang.ASTNode; import com.intellij.lang.Language; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; @@ -40,6 +41,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IStubFileElementType; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtilCore; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -51,6 +53,7 @@ import java.util.Set; * @author db */ public abstract class PsiAnchor { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.PsiAnchor"); @Nullable public abstract PsiElement retrieve(); public abstract PsiFile getFile(); @@ -59,10 +62,17 @@ public abstract class PsiAnchor { @NotNull public static PsiAnchor create(@NotNull final PsiElement element) { - if (!element.isValid()) { - throw new PsiInvalidElementAccessException(element); - } + PsiUtilCore.ensureValid(element); + PsiAnchor anchor = doCreateAnchor(element); + if (ApplicationManager.getApplication().isUnitTestMode() && !element.equals(anchor.retrieve())) { + LOG.error("Cannot restore element " + element + " of " + element.getClass() + " from anchor " + anchor); + } + return anchor; + } + + @NotNull + private static PsiAnchor doCreateAnchor(@NotNull PsiElement element) { if (element instanceof PsiFile) { VirtualFile virtualFile = ((PsiFile)element).getVirtualFile(); if (virtualFile != null) return new PsiFileReference(virtualFile, (PsiFile)element); @@ -83,7 +93,7 @@ public abstract class PsiAnchor { PsiAnchor stubRef = createStubReference(element, file); if (stubRef != null) return stubRef; - if (!element.isPhysical() && element instanceof PsiCompiledElement || element instanceof LightElement || element instanceof SyntheticElement) { + if (!element.isPhysical()) { return wrapperOrHardReference(element); } @@ -102,7 +112,10 @@ public abstract class PsiAnchor { } } - if (lang == null) lang = element.getLanguage(); + if (lang == null) { + return wrapperOrHardReference(element); + } + return new TreeRangeReference(file, textRange.getStartOffset(), textRange.getEndOffset(), element.getClass(), lang, virtualFile); } @@ -195,17 +208,8 @@ public abstract class PsiAnchor { public PsiElement retrieve() { PsiFile psiFile = getFile(); if (psiFile == null || !psiFile.isValid()) return null; - PsiElement element = psiFile.getViewProvider().findElementAt(myStartOffset, myLanguage); - if (element == null) return null; - while (!element.getClass().equals(myClass) || - element.getTextRange().getStartOffset() != myStartOffset || - element.getTextRange().getEndOffset() != myEndOffset) { - element = element.getParent(); - if (element == null || element.getTextRange() == null) return null; - } - - return element; + return SelfElementInfo.findElementInside(psiFile, myStartOffset, myEndOffset, myClass, myLanguage); } @Override diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java index 3a26df76c557..c1d58d624956 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java @@ -126,7 +126,7 @@ public class SelfElementInfo extends SmartPointerElementInfo { return restoreFileFromVirtual(getVirtualFile(), getProject(), myLanguage); } - static PsiElement findElementInside(@NotNull PsiFile file, + public static PsiElement findElementInside(@NotNull PsiFile file, int syncStartOffset, int syncEndOffset, @NotNull Class type, From 88208bc37256a0b1136fa3e2153bc65fdba61bde Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 11 Sep 2015 20:42:47 +0300 Subject: [PATCH 18/21] Cleanup (javadoc) --- platform/util/src/com/intellij/util/EnvironmentUtil.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/platform/util/src/com/intellij/util/EnvironmentUtil.java b/platform/util/src/com/intellij/util/EnvironmentUtil.java index 9dfa2f99c98d..7cb0a5216335 100644 --- a/platform/util/src/com/intellij/util/EnvironmentUtil.java +++ b/platform/util/src/com/intellij/util/EnvironmentUtil.java @@ -111,12 +111,20 @@ public class EnvironmentUtil { /** * Same as {@code getEnvironmentMap().get(name)}. * Returns value for the passed environment variable name, or null if no such variable found. + * + * @see #getEnvironmentMap() */ @Nullable public static String getValue(@NotNull String name) { return getEnvironmentMap().get(name); } + /** + * Same as {@code flattenEnvironment(getEnvironmentMap())}. + * Returns an environment as an array of "NAME=VALUE" strings. + * + * @see #getEnvironmentMap() + */ public static String[] getEnvironment() { return flattenEnvironment(getEnvironmentMap()); } From e757a9fb57af3844a788210fb6cbe015ed7b77f7 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Fri, 11 Sep 2015 19:59:38 +0200 Subject: [PATCH 19/21] support debugging for java scratches --- .../debugger/engine/PositionManagerImpl.java | 2 +- .../impl/JavaScratchPositionManager.java | 81 +++++++++++++++++++ .../JavaScratchRunConfigurationExtension.java | 37 +++++++-- 3 files changed, 113 insertions(+), 7 deletions(-) create mode 100644 java/execution/impl/src/com/intellij/execution/impl/JavaScratchPositionManager.java diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java index 91696653318b..a2cfbdad5c45 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java @@ -334,7 +334,7 @@ public class PositionManagerImpl implements PositionManager, MultiRequestPositio } @Nullable - private PsiFile getPsiFileByLocation(final Project project, final Location location) { + protected PsiFile getPsiFileByLocation(final Project project, final Location location) { if (location == null) { return null; } diff --git a/java/execution/impl/src/com/intellij/execution/impl/JavaScratchPositionManager.java b/java/execution/impl/src/com/intellij/execution/impl/JavaScratchPositionManager.java new file mode 100644 index 000000000000..86318a45ddf9 --- /dev/null +++ b/java/execution/impl/src/com/intellij/execution/impl/JavaScratchPositionManager.java @@ -0,0 +1,81 @@ +/* + * Copyright 2000-2015 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.impl; + +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.PositionManagerImpl; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.PsiManager; +import com.sun.jdi.Location; +import com.sun.jdi.ReferenceType; +import org.jetbrains.annotations.Nullable; + +/** + * @author Eugene Zhuravlev + * Date: 11-Sep-15 + */ +public class JavaScratchPositionManager extends PositionManagerImpl{ + private final VirtualFile myScratchFile; + + public JavaScratchPositionManager(DebugProcessImpl debugProcess, VirtualFile scratchFile) { + super(debugProcess); + myScratchFile = scratchFile; + } + + @Nullable + @Override + protected PsiFile getPsiFileByLocation(Project project, Location location) { + if (location == null) { + return null; + } + final ReferenceType refType = location.declaringType(); + if (refType == null) { + return null; + } + final PsiFile psiFile = PsiManager.getInstance(project).findFile(myScratchFile); + if (!(psiFile instanceof PsiJavaFile)) { + return null; + } + final PsiClass[] classes = ((PsiJavaFile)psiFile).getClasses(); + if (classes.length == 0) { + return null; + } + + final String originalQName = refType.name(); + for (PsiClass aClass : classes) { + if (StringUtil.equals(originalQName, aClass.getQualifiedName())) { + return psiFile; + } + } + + final int dollar = originalQName.indexOf('$'); + final String alternativeQName = dollar > 0? originalQName.substring(0, dollar) : null; + if (!StringUtil.isEmpty(alternativeQName)) { + for (PsiClass aClass : classes) { + if (StringUtil.equals(alternativeQName, aClass.getQualifiedName())) { + return psiFile; + } + } + } + + return null; + } +} diff --git a/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java b/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java index b63a3fd86a33..d8c1a40a14bb 100644 --- a/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java +++ b/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java @@ -15,14 +15,16 @@ */ package com.intellij.execution.impl; +import com.intellij.debugger.DebuggerManager; +import com.intellij.debugger.engine.DebugProcess; +import com.intellij.debugger.engine.DebugProcessAdapter; +import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.execution.ExecutionException; import com.intellij.execution.Location; import com.intellij.execution.RunConfigurationExtension; import com.intellij.execution.application.ApplicationConfiguration; -import com.intellij.execution.configurations.JavaParameters; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.configurations.RunConfigurationBase; -import com.intellij.execution.configurations.RunnerSettings; +import com.intellij.execution.configurations.*; +import com.intellij.execution.process.ProcessHandler; import com.intellij.ide.scratch.ScratchFileType; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.compiler.CompilerManager; @@ -80,6 +82,24 @@ public class JavaScratchRunConfigurationExtension extends RunConfigurationExtens } } + @Override + protected void attachToProcess(@NotNull final RunConfigurationBase configuration, @NotNull final ProcessHandler handler, @Nullable RunnerSettings runnerSettings) { + if (runnerSettings instanceof DebuggingRunnerData && getScratchFileId(configuration) >= 0) { + final VirtualFile vFile = getScratchVirtualFile(configuration); + if (vFile != null) { + DebuggerManager.getInstance(configuration.getProject()).addDebugProcessListener(handler, new DebugProcessAdapter() { + @Override + public void processAttached(DebugProcess process) { + if (vFile.isValid()) { + process.appendPositionManager(new JavaScratchPositionManager((DebugProcessImpl)process, vFile)); + } + process.removeDebugProcessListener(this); + } + }); + } + } + } + @NotNull protected String getSerializationId() { return "java-scratch-properties"; @@ -87,12 +107,17 @@ public class JavaScratchRunConfigurationExtension extends RunConfigurationExtens @Nullable public static String getScratchFileUrl(RunConfiguration configuration) { + final VirtualFile vFile = getScratchVirtualFile(configuration); + return vFile != null? vFile.getUrl() : null; + } + + @Nullable + private static VirtualFile getScratchVirtualFile(RunConfiguration configuration) { int id = getScratchFileId(configuration); if (id < 0) { return null; } - final VirtualFile vFile = ManagingFS.getInstance().findFileById(id); - return vFile != null? vFile.getUrl() : null; + return ManagingFS.getInstance().findFileById(id); } private static int getScratchFileId(RunConfiguration configuration) { From ab05d963c4b343bd4836a2d763863b34d8a50e93 Mon Sep 17 00:00:00 2001 From: "Vassiliy.Kudryashov" Date: Fri, 11 Sep 2015 21:06:01 +0300 Subject: [PATCH 20/21] IDEA-70943 Tooltip animations and buggy visibility are exceedingly frustrating --- .../com/intellij/ide/IdeTooltipManager.java | 29 +++++++++++++------ .../openapi/wm/impl/IdeGlassPaneImpl.java | 8 +++-- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java b/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java index 408bfd905093..31b842d65c04 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java @@ -197,7 +197,8 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener } private void queueShow(final JComponent c, final MouseEvent me, final boolean toCenter, int shift, int posChangeX, int posChangeY) { - final IdeTooltip tooltip = new IdeTooltip(c, me.getPoint(), null, new Object()) { + String aText = String.valueOf(c.getToolTipText(me)); + final IdeTooltip tooltip = new IdeTooltip(c, me.getPoint(), null, /*new Object()*/c, aText) { @Override protected boolean beforeShow() { myCurrentEvent = me; @@ -226,7 +227,7 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener public IdeTooltip show(final IdeTooltip tooltip, boolean now, final boolean animationEnabled) { myAlarm.cancelAllRequests(); - hideCurrent(null, null, null); + hideCurrent(null, tooltip, null, null); myQueuedComponent = tooltip.getComponent(); myQueuedTooltip = tooltip; @@ -239,7 +240,7 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener } if (myQueuedComponent != tooltip.getComponent() || !tooltip.getComponent().isShowing()) { - hideCurrent(null, null, null, animationEnabled); + hideCurrent(null, tooltip, null, null, animationEnabled); return; } @@ -247,7 +248,7 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener show(tooltip, null, animationEnabled); } else { - hideCurrent(null, null, null, animationEnabled); + hideCurrent(null, tooltip, null, null, animationEnabled); } } }; @@ -389,11 +390,22 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener return myCurrentTooltip != null; } - public boolean hideCurrent(@Nullable MouseEvent me, @Nullable AnAction action, @Nullable AnActionEvent event) { - return hideCurrent(me, action, event, myCurrentTipUi != null && myCurrentTipUi.isAnimationEnabled()); + public boolean hideCurrent(@Nullable MouseEvent me) { + return hideCurrent(me, null, null, null); } - public boolean hideCurrent(@Nullable MouseEvent me, @Nullable AnAction action, @Nullable AnActionEvent event, final boolean animationEnabled) { + private boolean hideCurrent(@Nullable MouseEvent me, @Nullable AnAction action, @Nullable AnActionEvent event) { + return hideCurrent(me, null, action, event, myCurrentTipUi != null && myCurrentTipUi.isAnimationEnabled()); + } + + private boolean hideCurrent(@Nullable MouseEvent me, + @Nullable IdeTooltip tooltipToShow, + @Nullable AnAction action, + @Nullable AnActionEvent event) { + return hideCurrent(me, tooltipToShow, action, event, myCurrentTipUi != null && myCurrentTipUi.isAnimationEnabled()); + } + + private boolean hideCurrent(@Nullable MouseEvent me, @Nullable IdeTooltip tooltipToShow, @Nullable AnAction action, @Nullable AnActionEvent event, final boolean animationEnabled) { if (myCurrentTooltip != null && me != null && myCurrentTooltip.isInside(RelativePoint.fromScreen(me.getLocationOnScreen()))) { if (me.getButton() == MouseEvent.NOBUTTON || myCurrentTipUi == null || myCurrentTipUi.isBlockClicks()) { return false; @@ -415,8 +427,7 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener (me.getID() == MouseEvent.MOUSE_MOVED || me.getID() == MouseEvent.MOUSE_EXITED || me.getID() == MouseEvent.MOUSE_ENTERED); - - if (!canAutoHide || myCurrentTooltip.isExplicitClose() && implicitMouseMove) { + if (!canAutoHide || myCurrentTooltip.isExplicitClose() && implicitMouseMove || Comparing.equal(myCurrentTooltip, tooltipToShow)) { if (myHideRunnable != null) { myHideRunnable = null; } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java index db8d3c53708d..19283895eeb9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java @@ -36,10 +36,12 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.event.MenuDragMouseEvent; import javax.swing.text.html.HTMLEditorKit; import java.awt.*; -import java.awt.event.*; +import java.awt.event.AWTEventListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; import java.util.*; import java.util.List; @@ -146,7 +148,7 @@ public class IdeGlassPaneImpl extends JPanel implements IdeGlassPaneEx, IdeEvent if (e.getID() == MouseEvent.MOUSE_DRAGGED) { if (ApplicationManager.getApplication() != null) { - IdeTooltipManager.getInstance().hideCurrent((MouseEvent)e, null, null); + IdeTooltipManager.getInstance().hideCurrent((MouseEvent)e); } } From ee78a3a8d8647cfc5d4dac83febe4468114679ce Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 11 Sep 2015 20:25:30 +0200 Subject: [PATCH 21/21] diagnostics for null references in IdentifierHighlighterPass (EA-72748 - IAE: ReferenceRange.getRanges) --- .../codeInsight/daemon/impl/IdentifierHighlighterPass.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java index 7684726ebb9d..7cefa33adf6c 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java @@ -139,6 +139,10 @@ public class IdentifierHighlighterPass extends TextEditorHighlightingPass { ? findUsagesHandler.findReferencesToHighlight(target, scope) : ReferencesSearch.search(target, scope).findAll(); for (PsiReference psiReference : refs) { + if (psiReference == null) { + LOG.error("Null reference returned, findUsagesHandler=" + findUsagesHandler + "; target=" + target + " of " + target.getClass()); + continue; + } final List textRanges = HighlightUsagesHandler.getRangesToHighlight(psiReference); if (detector == null || detector.getReferenceAccess(target, psiReference) == ReadWriteAccessDetector.Access.Read) { readRanges.addAll(textRanges);