diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/JavaProblemHighlightFilter.java b/java/java-impl/src/com/intellij/codeInsight/daemon/JavaProblemHighlightFilter.java
index 922c8a4e0ca4..1582a8ca9ada 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/JavaProblemHighlightFilter.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/JavaProblemHighlightFilter.java
@@ -16,7 +16,7 @@
package com.intellij.codeInsight.daemon;
import com.intellij.ide.highlighter.JavaFileType;
-import com.intellij.ide.scratch.ScratchFileType;
+import com.intellij.openapi.fileTypes.PeripheralFileType;
import com.intellij.openapi.roots.JavaProjectRootsUtil;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
@@ -28,7 +28,9 @@ import org.jetbrains.annotations.NotNull;
public class JavaProblemHighlightFilter extends ProblemHighlightFilter {
@Override
public boolean shouldHighlight(@NotNull PsiFile psiFile) {
- return psiFile.getFileType() != JavaFileType.INSTANCE || !JavaProjectRootsUtil.isOutsideJavaSourceRoot(psiFile) || (psiFile.getViewProvider().getFileType() == ScratchFileType.INSTANCE);
+ return psiFile.getFileType() != JavaFileType.INSTANCE ||
+ !JavaProjectRootsUtil.isOutsideJavaSourceRoot(psiFile) ||
+ psiFile.getViewProvider().getFileType() instanceof PeripheralFileType;
}
@Override
diff --git a/platform/core-api/src/com/intellij/openapi/fileTypes/PeripheralFileType.java b/platform/core-api/src/com/intellij/openapi/fileTypes/PeripheralFileType.java
new file mode 100644
index 000000000000..3f0a85c3463f
--- /dev/null
+++ b/platform/core-api/src/com/intellij/openapi/fileTypes/PeripheralFileType.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2016 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.openapi.fileTypes;
+
+/**
+ * Marker interface for files that should be highlighted in a project context, despite of them not being part of it.
+ * Example: content from VCS, scratch files
+ *
+ * This file cannot be referenced from the rest of a project and might depend on no longer existent files.
+ * But we still can use project context to provide highlighting and code navigation in assumption, that local references are valid
+ * and non-local references still point at the right location.
+ */
+public interface PeripheralFileType extends FileType {
+}
diff --git a/platform/diff-impl/diff-impl.iml b/platform/diff-impl/diff-impl.iml
index 186e74c7578c..6897d1d50aad 100644
--- a/platform/diff-impl/diff-impl.iml
+++ b/platform/diff-impl/diff-impl.iml
@@ -13,5 +13,6 @@
+
\ No newline at end of file
diff --git a/platform/diff-impl/src/com/intellij/diff/contents/DiffPsiFileType.java b/platform/diff-impl/src/com/intellij/diff/contents/DiffPsiFileType.java
new file mode 100644
index 000000000000..83d0ee6f84fe
--- /dev/null
+++ b/platform/diff-impl/src/com/intellij/diff/contents/DiffPsiFileType.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2000-2016 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.diff.contents;
+
+import com.intellij.codeInsight.daemon.impl.HighlightInfo;
+import com.intellij.codeInsight.daemon.impl.HighlightInfoFilter;
+import com.intellij.codeInsight.daemon.impl.IntentionActionFilter;
+import com.intellij.codeInsight.daemon.impl.analysis.DefaultHighlightingSettingProvider;
+import com.intellij.codeInsight.daemon.impl.analysis.FileHighlightingSetting;
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.icons.AllIcons;
+import com.intellij.lang.Language;
+import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.openapi.fileTypes.*;
+import com.intellij.openapi.fileTypes.ex.FileTypeIdentifiableByVirtualFile;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.LanguageSubstitutor;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+public class DiffPsiFileType extends LanguageFileType implements FileTypeIdentifiableByVirtualFile, PeripheralFileType {
+ public static final Key ORIGINAL_FILE_TYPE_KEY = Key.create("Diff.DiffPsiFileType.OriginalFileTypeKey");
+ public static final LanguageFileType INSTANCE = new DiffPsiFileType();
+
+ DiffPsiFileType() {
+ super(PlainTextLanguage.INSTANCE);
+ }
+
+ @Override
+ public boolean isMyFileType(@NotNull VirtualFile file) {
+ return isDiffFile(file);
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return "Diff";
+ }
+
+ @NotNull
+ @Override
+ public String getDescription() {
+ return "Diff";
+ }
+
+ @NotNull
+ @Override
+ public String getDefaultExtension() {
+ return "";
+ }
+
+ @Nullable
+ @Override
+ public Icon getIcon() {
+ return AllIcons.Diff.Diff;
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public String getCharset(@NotNull VirtualFile file, @NotNull byte[] content) {
+ return null;
+ }
+
+
+ public static class TypeFactory extends FileTypeFactory {
+ @Override
+ public void createFileTypes(@NotNull FileTypeConsumer consumer) {
+ consumer.consume(INSTANCE);
+ }
+ }
+
+ public static class Substitutor extends LanguageSubstitutor {
+ @Nullable
+ @Override
+ public Language getLanguage(@NotNull VirtualFile file, @NotNull Project project) {
+ FileType originalType = getOriginalFileType(file);
+ if (originalType instanceof LanguageFileType) {
+ return ((LanguageFileType)originalType).getLanguage();
+ }
+ return null;
+ }
+ }
+
+ public static class HighlightFilter implements HighlightInfoFilter {
+ @Override
+ public boolean accept(@NotNull HighlightInfo info, @Nullable PsiFile file) {
+ if (!isDiffFile(file)) return true;
+ if (info.getSeverity() == HighlightSeverity.ERROR) return false;
+ return true;
+ }
+ }
+
+ public static class IntentionFilter implements IntentionActionFilter {
+ @Override
+ public boolean accept(@NotNull IntentionAction intentionAction, @Nullable PsiFile file) {
+ return !isDiffFile(file);
+ }
+ }
+
+ public static class HighlightingSettingProvider extends DefaultHighlightingSettingProvider {
+ @Nullable
+ @Override
+ public FileHighlightingSetting getDefaultSetting(@NotNull Project project, @NotNull VirtualFile file) {
+ if (!isDiffFile(file)) return null;
+ return FileHighlightingSetting.SKIP_INSPECTION;
+ }
+ }
+
+
+ private static boolean isDiffFile(@Nullable PsiFile file) {
+ return file != null && isDiffFile(file.getVirtualFile());
+ }
+
+ private static boolean isDiffFile(@Nullable VirtualFile file) {
+ return file != null && getOriginalFileType(file) != null;
+ }
+
+ @Nullable
+ private static FileType getOriginalFileType(@NotNull VirtualFile file) {
+ FileType fileType = file.getUserData(ORIGINAL_FILE_TYPE_KEY);
+ return fileType instanceof DiffPsiFileType ? null : fileType;
+ }
+}
diff --git a/platform/diff-impl/src/com/intellij/diff/contents/FileAwareDocumentContent.java b/platform/diff-impl/src/com/intellij/diff/contents/FileAwareDocumentContent.java
index 47bbe6718368..45a3062eae11 100644
--- a/platform/diff-impl/src/com/intellij/diff/contents/FileAwareDocumentContent.java
+++ b/platform/diff-impl/src/com/intellij/diff/contents/FileAwareDocumentContent.java
@@ -4,6 +4,7 @@ import com.intellij.diff.tools.util.DiffNotifications;
import com.intellij.diff.util.DiffUserDataKeysEx;
import com.intellij.diff.util.DiffUtil;
import com.intellij.diff.util.LineCol;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.fileEditor.FileDocumentManager;
@@ -12,11 +13,14 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.fileTypes.PlainTextFileType;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.Navigatable;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.testFramework.LightVirtualFile;
import com.intellij.ui.LightColors;
import com.intellij.util.LineSeparator;
import com.intellij.util.diff.Diff;
@@ -107,7 +111,27 @@ public class FileAwareDocumentContent extends DocumentContentImpl {
@NotNull
private Builder create(@NotNull String content) {
mySeparator = StringUtil.detectSeparators(content);
- myDocument = EditorFactory.getInstance().createDocument(StringUtil.convertLineSeparators(content));
+ String correctedContent = StringUtil.convertLineSeparators(content);
+
+ if (myProject != null && Registry.is("diff.enable.psi.highlighting")) {
+ ApplicationManager.getApplication().runReadAction(() -> {
+ LightVirtualFile file = new LightVirtualFile(myFileName, DiffPsiFileType.INSTANCE, correctedContent);
+ file.setWritable(false);
+
+ file.putUserData(DiffPsiFileType.ORIGINAL_FILE_TYPE_KEY, myFileType);
+
+ myDocument = FileDocumentManager.getInstance().getDocument(file);
+ if (myDocument == null) {
+ myDocument = EditorFactory.getInstance().createDocument(correctedContent);
+ }
+
+ PsiDocumentManager.getInstance(myProject).getPsiFile(myDocument);
+ });
+ }
+ else {
+ myDocument = EditorFactory.getInstance().createDocument(correctedContent);
+ }
+
myDocument.setReadOnly(true);
return this;
}
diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/side/TwosideTextDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/util/side/TwosideTextDiffViewer.java
index 9a2cd57a63cb..c9fe5d66e636 100644
--- a/platform/diff-impl/src/com/intellij/diff/tools/util/side/TwosideTextDiffViewer.java
+++ b/platform/diff-impl/src/com/intellij/diff/tools/util/side/TwosideTextDiffViewer.java
@@ -36,6 +36,7 @@ import com.intellij.diff.util.LineCol;
import com.intellij.diff.util.Side;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
@@ -43,6 +44,9 @@ import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.VisibleAreaEvent;
import com.intellij.openapi.editor.event.VisibleAreaListener;
import com.intellij.openapi.editor.ex.EditorEx;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.pom.Navigatable;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.CalledInAwt;
@@ -350,8 +354,23 @@ public abstract class TwosideTextDiffViewer extends TwosideDiffViewer
+
+
+
+
+
+