diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
index f28f743b041f..e291c92f2bcd 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
+++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
@@ -257,6 +257,8 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
}
public void setVarValue(DfaVariableValue var, DfaValue value) {
+ if (var == value) return;
+
flushVariable(var);
if (value instanceof DfaUnknownValue) return;
diff --git a/java/java-tests/testData/inspection/dataFlow/IDEADEV78370/expected.xml b/java/java-tests/testData/inspection/dataFlow/IDEADEV78370/expected.xml
new file mode 100644
index 000000000000..ec272abeaa3a
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/IDEADEV78370/expected.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/java/java-tests/testData/inspection/dataFlow/IDEADEV78370/src/NoWarnings.java b/java/java-tests/testData/inspection/dataFlow/IDEADEV78370/src/NoWarnings.java
new file mode 100644
index 000000000000..ace2d06e1df9
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/IDEADEV78370/src/NoWarnings.java
@@ -0,0 +1,8 @@
+import org.jetbrains.annotations.Nullable;
+
+public class NoWarnings {
+ int f(@Nullable String value) {
+ value = value == null ? "" : value;
+ return value.hashCode();
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
index c2b1a252839e..dc0428ae3fa8 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
@@ -81,6 +81,7 @@ public class DataFlowInspectionTest extends InspectionTestCase {
public void testIDEADEV74518() throws Exception { doTest(); }
public void testIDEADEV74518_2() throws Exception { doTest(); }
public void testIDEADEV77819() throws Exception { doTest(); }
+ public void testIDEADEV78370() throws Exception { doTest(); }
public void testRegressionByPti() throws Exception { doTest(); }
diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManagerEvent.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManagerEvent.java
index 390c16a32678..3509643e267d 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManagerEvent.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManagerEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,44 +16,78 @@
package com.intellij.openapi.fileEditor;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.EventObject;
public final class FileEditorManagerEvent extends EventObject {
- private final VirtualFile myOldFile;
- private final FileEditor myOldEditor;
- private final VirtualFile myNewFile;
- private final FileEditor myNewEditor;
- public FileEditorManagerEvent(FileEditorManager source,
- VirtualFile oldFile,
- FileEditor oldEditor,
- VirtualFile newFile,
- FileEditor newEditor) {
+ private final VirtualFile myOldFile;
+ private final FileEditor myOldEditor;
+ private final VirtualFile myNewFile;
+ private final FileEditor myNewEditor;
+ private final FileEditorProvider myOldProvider;
+ private final FileEditorProvider myNewProvider;
+
+ public FileEditorManagerEvent(@NotNull FileEditorManager source,
+ @Nullable VirtualFile oldFile,
+ @Nullable FileEditor oldEditor,
+ @Nullable VirtualFile newFile,
+ @Nullable FileEditor newEditor)
+ {
+ this(source, oldFile, oldEditor, null, newFile, newEditor, null);
+ }
+
+ public FileEditorManagerEvent(@NotNull FileEditorManager source,
+ @Nullable VirtualFile oldFile,
+ @Nullable FileEditor oldEditor,
+ @Nullable FileEditorProvider oldProvider,
+ @Nullable VirtualFile newFile,
+ @Nullable FileEditor newEditor,
+ @Nullable FileEditorProvider newProvider)
+ {
super(source);
myOldFile = oldFile;
myOldEditor = oldEditor;
myNewFile = newFile;
myNewEditor = newEditor;
+ myOldProvider = oldProvider;
+ myNewProvider = newProvider;
}
+ @NotNull
public FileEditorManager getManager(){
return (FileEditorManager)getSource();
}
+ @Nullable
public VirtualFile getOldFile() {
return myOldFile;
}
+ @Nullable
public VirtualFile getNewFile() {
return myNewFile;
}
+ @Nullable
public FileEditor getOldEditor() {
return myOldEditor;
}
+ @Nullable
public FileEditor getNewEditor() {
return myNewEditor;
}
+
+ @Nullable
+ public FileEditorProvider getOldProvider() {
+ return myOldProvider;
+ }
+
+ @Nullable
+ public FileEditorProvider getNewProvider() {
+ return myNewProvider;
+ }
}
\ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
index 238cc7a0472e..6ecddea85a1e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
@@ -590,10 +590,10 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
boolean softWrapsUsedBefore = mySoftWrapModel.isSoftWrappingEnabled();
+ mySettings.reinitSettings();
mySoftWrapModel.reinitSettings();
myCaretModel.reinitSettings();
mySelectionModel.reinitSettings();
- mySettings.reinitSettings();
ourCaretBlinkingCommand.setBlinkCaret(mySettings.isBlinkCaret());
ourCaretBlinkingCommand.setBlinkPeriod(mySettings.getCaretBlinkPeriod());
mySizeContainer.reset();
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java
index 934dff74cecd..74c0dc309a23 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java
@@ -25,6 +25,10 @@ import com.intellij.openapi.editor.ex.*;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.editor.impl.softwrap.*;
import com.intellij.openapi.editor.impl.softwrap.mapping.*;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.reference.SoftReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -92,6 +96,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
/** Holds number of 'active' calls, i.e. number of methods calls of the current object within the current call stack. */
private int myActive;
private boolean myUseSoftWraps;
+ private int myTabWidth = -1;
/**
* Standard IJ editor starts showing horizontal scroll bar event when text line ends couple of symbols before the right visual
@@ -191,7 +196,13 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
boolean softWrapsUsedBefore = myUseSoftWraps;
EditorSettings settings = myEditor.getSettings();
myUseSoftWraps = settings.isUseSoftWraps();
- if (myUseSoftWraps && (!softWrapsUsedBefore || settings.getAdditionalColumnsCount() > 0)) {
+
+ int tabWidthBefore = myTabWidth;
+ myTabWidth = getCurrentTabWidth();
+
+ if ((myUseSoftWraps && (!softWrapsUsedBefore || settings.getAdditionalColumnsCount() > 0))
+ || (tabWidthBefore >= 0 && myTabWidth != tabWidthBefore))
+ {
myApplianceManager.reset();
myDeferredFoldRegions.clear();
myAdditionalColumnsCount = settings.getAdditionalColumnsCount();
@@ -203,6 +214,20 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
myEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
}
+ /**
+ * @return tab width for the file used at the current editor (if it's possible to calculate the one);
+ * '-1' otherwise
+ */
+ private int getCurrentTabWidth() {
+ final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(myEditor.getProject());
+ final VirtualFile file = myEditor.getVirtualFile();
+ if (file == null) {
+ return -1;
+ }
+ final CommonCodeStyleSettings.IndentOptions indentOptions = settings.getIndentOptions(file.getFileType());
+ return indentOptions.TAB_SIZE;
+ }
+
@Override
public boolean isSoftWrappingEnabled() {
if (!myUseSoftWraps || myEditor.isOneLineMode()) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java
index c9126d1b3371..a6d987f4f0ff 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@ import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.ArrayUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
@@ -143,14 +144,28 @@ public final class EditorHistoryManager extends AbstractProjectComponent impleme
trimToSize();
}
}
-
- private void updateHistoryEntry(final VirtualFile file, final boolean changeEntryOrderOnly){
+
+ private void updateHistoryEntry(@Nullable final VirtualFile file, final boolean changeEntryOrderOnly) {
+ updateHistoryEntry(file, null, null, changeEntryOrderOnly);
+ }
+
+ private void updateHistoryEntry(@Nullable final VirtualFile file,
+ @Nullable final FileEditor fallbackEditor,
+ @Nullable FileEditorProvider fallbackProvider,
+ final boolean changeEntryOrderOnly)
+ {
if (file == null){
return;
}
final FileEditorManagerEx editorManager = FileEditorManagerEx.getInstanceEx(myProject);
final Pair editorsWithProviders = editorManager.getEditorsWithProviders(file);
- final FileEditor[] editors = editorsWithProviders.getFirst();
+ FileEditor[] editors = editorsWithProviders.getFirst();
+ FileEditorProvider[] providers = editorsWithProviders.getSecond();
+ if (editors.length <= 0 && fallbackEditor != null) {
+ editors = new FileEditor[] {fallbackEditor};
+ providers = new FileEditorProvider[] {fallbackProvider};
+ }
+
if (editors.length == 0) {
// obviously not opened in any editor at the moment,
// makes no sense to put the file in the history
@@ -167,7 +182,6 @@ public final class EditorHistoryManager extends AbstractProjectComponent impleme
}
if (!changeEntryOrderOnly) { // update entry state
- final FileEditorProvider [] providers = editorsWithProviders.getSecond();
//LOG.assertTrue(editors.length > 0);
for (int i = editors.length - 1; i >= 0; i--) {
final FileEditor editor = editors [i];
@@ -311,7 +325,7 @@ public final class EditorHistoryManager extends AbstractProjectComponent impleme
}
public void selectionChanged(final FileEditorManagerEvent event){
- updateHistoryEntry(event.getOldFile(), false);
+ updateHistoryEntry(event.getOldFile(), event.getOldEditor(), event.getOldProvider(), false);
updateHistoryEntry(event.getNewFile(), true);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
index e2877d3d6831..1406ba0523b2 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1318,26 +1318,20 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
}
public void fireSelectionChanged(final EditorComposite oldSelectedComposite, final EditorComposite newSelectedComposite) {
- final VirtualFile oldSelectedFile = oldSelectedComposite != null ? oldSelectedComposite.getFile() : null;
- final VirtualFile newSelectedFile = newSelectedComposite != null ? newSelectedComposite.getFile() : null;
-
- final FileEditor oldSelectedEditor =
- oldSelectedComposite != null && !oldSelectedComposite.isDisposed() ? oldSelectedComposite.getSelectedEditor() : null;
- final FileEditor newSelectedEditor =
- newSelectedComposite != null && !newSelectedComposite.isDisposed() ? newSelectedComposite.getSelectedEditor() : null;
-
- final boolean filesEqual = oldSelectedFile == null ? newSelectedFile == null : oldSelectedFile.equals(newSelectedFile);
- final boolean editorsEqual = oldSelectedEditor == null ? newSelectedEditor == null : oldSelectedEditor.equals(newSelectedEditor);
+ final Trinity oldData = extract(oldSelectedComposite);
+ final Trinity newData = extract(newSelectedComposite);
+ final boolean filesEqual = oldData.first == null ? newData.first == null : oldData.first.equals(newData.first);
+ final boolean editorsEqual = oldData.second == null ? newData.second == null : oldData.second.equals(newData.second);
if (!filesEqual || !editorsEqual) {
final FileEditorManagerEvent event =
- new FileEditorManagerEvent(this, oldSelectedFile, oldSelectedEditor, newSelectedFile, newSelectedEditor);
+ new FileEditorManagerEvent(this, oldData.first, oldData.second, oldData.third, newData.first, newData.second, newData.third);
final FileEditorManagerListener publisher = getProject().getMessageBus().syncPublisher(FileEditorManagerListener.FILE_EDITOR_MANAGER);
- if (newSelectedEditor != null) {
- final JComponent component = newSelectedEditor.getComponent();
+ if (newData.first != null) {
+ final JComponent component = newData.second.getComponent();
final EditorWindowHolder holder = UIUtil.getParentOfType(EditorWindowHolder.class, component);
if (holder != null) {
- addSelectionRecord(newSelectedFile, holder.getEditorWindow());
+ addSelectionRecord(newData.first, holder.getEditorWindow());
}
}
notifyPublisher(new Runnable() {
@@ -1348,7 +1342,26 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
});
}
}
-
+
+ @NotNull
+ private static Trinity extract(@Nullable EditorComposite composite) {
+ final VirtualFile file;
+ final FileEditor editor;
+ final FileEditorProvider provider;
+ if (composite == null || composite.isDisposed()) {
+ file = null;
+ editor = null;
+ provider = null;
+ }
+ else {
+ file = composite.getFile();
+ final Pair pair = composite.getSelectedEditorWithProvider();
+ editor = pair.first;
+ provider = pair.second;
+ }
+ return new Trinity(file, editor, provider);
+ }
+
public boolean isChanged(@NotNull final EditorComposite editor) {
final FileStatusManager fileStatusManager = FileStatusManager.getInstance(myProject);
if (fileStatusManager != null) {
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java
index 1f6a4865e5c4..28ffb0cbe25e 100644
--- a/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java
+++ b/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.editor.impl.AbstractEditorProcessingOnDocumentModifi
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.editor.impl.SoftWrapModelImpl;
import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.testFramework.TestFileType;
import gnu.trove.TIntHashSet;
import gnu.trove.TIntProcedure;
@@ -848,6 +849,28 @@ public class SoftWrapApplianceOnDocumentModificationTest extends AbstractEditorP
assertEquals(visualPosition, getEditor().logicalToVisualPosition(logicalPosition));
assertEquals(logicalPosition, getEditor().visualToLogicalPosition(visualPosition));
}
+
+ public void testSoftWrapsRecalculationOnTabWidthChange() throws IOException {
+ // Inspired by IDEA-78616 - the point is to recalculate soft wraps when tab width is changed.
+ String text =
+ "\t my text";
+
+ // Build soft wraps cache.
+ init(300, text);
+
+ VisualPosition caretPositionBefore = getEditor().getCaretModel().getVisualPosition();
+
+ // Change tab size.
+ final CommonCodeStyleSettings.IndentOptions indentOptions = getCurrentCodeStyleSettings().getIndentOptions();
+ assertNotNull(indentOptions);
+ indentOptions.TAB_SIZE++;
+
+ ((EditorImpl)getEditor()).reinitSettings();
+ assertEquals(
+ new VisualPosition(caretPositionBefore.line, caretPositionBefore.column + 1),
+ getEditor().getCaretModel().getVisualPosition()
+ );
+ }
private void init(final int visibleWidth, @NotNull String fileText) throws IOException {
init(visibleWidth, fileText, TestFileType.TEXT);