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 + + + + + +