mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
[vcs] IJPL-157627 Added ability to load inner fragments when 'Highlight lines' mode is enabled.
GitOrigin-RevId: 992ae38f51a3cf97157605dc63d1529cd5821644
This commit is contained in:
committed by
intellij-monorepo-bot
parent
2dc32e7977
commit
75d4f86f62
@@ -640,6 +640,12 @@ a:com.intellij.diff.lang.LangDiffIgnoredRangeProvider
|
||||
- pa:accepts(com.intellij.openapi.project.Project,com.intellij.lang.Language):Z
|
||||
- pa:computeIgnoredRanges(com.intellij.openapi.project.Project,java.lang.CharSequence,com.intellij.lang.Language):java.util.List
|
||||
- getIgnoredRanges(com.intellij.openapi.project.Project,java.lang.CharSequence,com.intellij.diff.contents.DiffContent):java.util.List
|
||||
f:com.intellij.diff.merge.ChangeReferenceProcessor
|
||||
- sf:Companion:com.intellij.diff.merge.ChangeReferenceProcessor$Companion
|
||||
- <init>(com.intellij.openapi.project.Project,com.intellij.openapi.editor.Editor,java.util.List,java.util.List):V
|
||||
- f:process(com.intellij.diff.util.ThreeSide,java.util.List,java.util.List):V
|
||||
f:com.intellij.diff.merge.ChangeReferenceProcessor$Companion
|
||||
- f:getLOG():com.intellij.openapi.diagnostic.Logger
|
||||
a:com.intellij.diff.merge.MergeContextEx
|
||||
- com.intellij.diff.merge.MergeContext
|
||||
- <init>():V
|
||||
|
||||
@@ -4,18 +4,26 @@ package com.intellij.diff.merge
|
||||
import com.intellij.codeInsight.editorActions.CopyPastePostProcessor
|
||||
import com.intellij.codeInsight.editorActions.ReferenceCopyPasteProcessor
|
||||
import com.intellij.codeInsight.editorActions.TextBlockTransferableData
|
||||
import com.intellij.diff.comparison.ComparisonPolicy
|
||||
import com.intellij.diff.tools.util.text.MergeInnerDifferences
|
||||
import com.intellij.diff.util.DiffUtil
|
||||
import com.intellij.diff.util.Side
|
||||
import com.intellij.diff.util.ThreeSide
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.RangeMarker
|
||||
import com.intellij.openapi.progress.DumbProgressIndicator
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiFile
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class ChangeReferenceProcessor(val project: Project, private val editor: Editor, val files: List<PsiFile>) {
|
||||
class ChangeReferenceProcessor(private val project: Project, private val editor: Editor, private val files: List<PsiFile>, private val documents: List<Document>) {
|
||||
|
||||
private val innerDifferencesCache: MutableMap<TextMergeChange, MergeInnerDifferences?> = ConcurrentHashMap()
|
||||
|
||||
fun process(
|
||||
side: ThreeSide,
|
||||
@@ -51,39 +59,59 @@ class ChangeReferenceProcessor(val project: Project, private val editor: Editor,
|
||||
processInnerFragments: Boolean,
|
||||
) {
|
||||
val sourceThreeSide = sourceSide.select(ThreeSide.LEFT, ThreeSide.RIGHT) ?: return
|
||||
val sourceDocument = sourceThreeSide.select(documents) ?: return
|
||||
val psiFile = sourceSide.select(files[0], files[2]) ?: return
|
||||
val sourceDocument = psiFile.fileDocument
|
||||
val startOffset = sourceDocument.getLineStartOffset(change.getStartLine(sourceThreeSide))
|
||||
val endOffset = sourceDocument.getLineEndOffset(change.getEndLine(sourceThreeSide) - 1)
|
||||
val sourceRange = DiffUtil.getLinesRange(sourceDocument, change.getStartLine(sourceThreeSide), change.getEndLine(sourceThreeSide))
|
||||
|
||||
if (!processInnerFragments) {
|
||||
val data = createReferenceData(psiFile, startOffset, endOffset)
|
||||
if (change.getStartLine(sourceThreeSide) == change.getEndLine(sourceThreeSide)) return
|
||||
|
||||
if (processInnerFragments) {
|
||||
val innerDifferences = change.innerFragments ?: compareInner(change) ?: return
|
||||
|
||||
innerDifferences.get(sourceThreeSide)?.forEach {
|
||||
if (it.isEmpty) return@forEach
|
||||
|
||||
val text = editor.document.getText(rangeMarker.textRange)
|
||||
val fragmentStartOffset = sourceRange.startOffset + it.startOffset
|
||||
val rangeInDocument = TextRange(fragmentStartOffset, fragmentStartOffset + it.length)
|
||||
val fragmentText = sourceDocument.getText(rangeInDocument)
|
||||
|
||||
if (fragmentText.isBlank()) return@forEach
|
||||
|
||||
val offset = text.indexOf(fragmentText)
|
||||
if (offset == -1) return@forEach
|
||||
|
||||
val data = createReferenceData(psiFile, rangeInDocument.startOffset, rangeInDocument.endOffset)
|
||||
val marker = sourceDocument.createRangeMarker(
|
||||
rangeMarker.startOffset + offset,
|
||||
rangeMarker.startOffset + offset + fragmentText.length
|
||||
)
|
||||
data.forEach { processorData ->
|
||||
processorData.process(project, editor, marker, 0, Ref(false))
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
val data = createReferenceData(psiFile, sourceRange.startOffset, sourceRange.endOffset)
|
||||
data.forEach { processorData ->
|
||||
processorData.process(project, editor, rangeMarker, 0, Ref(false))
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
val innerFragments = change.innerFragments
|
||||
innerFragments?.get(sourceThreeSide)?.forEach {
|
||||
if (it.isEmpty) return@forEach
|
||||
private fun getSequences(change: TextMergeChange): List<CharSequence?> {
|
||||
return ThreeSide.map {
|
||||
if (!change.isChange(it)) return@map null
|
||||
val startLine = change.getStartLine(it)
|
||||
val endLine = change.getEndLine(it)
|
||||
if (startLine == endLine) return@map null
|
||||
return@map DiffUtil.getLinesContent(it.select(documents), startLine, endLine)
|
||||
}
|
||||
}
|
||||
|
||||
val text = editor.document.getText(rangeMarker.textRange)
|
||||
val fragmentStartOffset = startOffset + it.startOffset
|
||||
val rangeInDocument = TextRange(fragmentStartOffset, fragmentStartOffset + it.length)
|
||||
val fragmentText = sourceDocument.getText(rangeInDocument)
|
||||
val offset = text.indexOf(fragmentText)
|
||||
|
||||
if (offset == -1) return@forEach
|
||||
|
||||
val data = createReferenceData(psiFile, rangeInDocument.startOffset, rangeInDocument.endOffset)
|
||||
val marker = sourceDocument.createRangeMarker(
|
||||
rangeMarker.startOffset + offset,
|
||||
rangeInDocument.startOffset + offset + it.length
|
||||
)
|
||||
data.forEach { processorData ->
|
||||
processorData.process(project, editor, marker, 0, Ref(false))
|
||||
}
|
||||
private fun compareInner(change: TextMergeChange): MergeInnerDifferences? {
|
||||
return innerDifferencesCache.computeIfAbsent(change) {
|
||||
return@computeIfAbsent DiffUtil.compareThreesideInner(getSequences(change), ComparisonPolicy.DEFAULT, DumbProgressIndicator.INSTANCE)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.diff.merge;
|
||||
|
||||
import com.intellij.codeInsight.editorActions.CopyPastePostProcessor;
|
||||
import com.intellij.codeInsight.editorActions.ReferenceCopyPasteProcessor;
|
||||
import com.intellij.codeInsight.editorActions.TextBlockTransferableData;
|
||||
import com.intellij.diff.DiffContext;
|
||||
import com.intellij.diff.DiffDialogHints;
|
||||
import com.intellij.diff.DiffManager;
|
||||
@@ -59,7 +56,10 @@ import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageDialogBuilder;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.NlsSafe;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.LineTokenizer;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.ex.Range;
|
||||
@@ -409,7 +409,6 @@ public class MergeThreesideViewer extends ThreesideTextDiffViewerEx {
|
||||
sequences.addAll(ContainerUtil.map(contents, content -> content.getDocument().getImmutableCharSequence()));
|
||||
if (getTextSettings().isAutoResolveImportConflicts()) {
|
||||
initPsiFiles();
|
||||
myChangeReferenceProcessor = new ChangeReferenceProcessor(myProject, getEditor(), myPsiFiles);
|
||||
return MergeImportUtil.getImportMergeRange(myProject, myPsiFiles);
|
||||
}
|
||||
return null;
|
||||
@@ -535,6 +534,9 @@ public class MergeThreesideViewer extends ThreesideTextDiffViewerEx {
|
||||
);
|
||||
|
||||
if (myResolveImportConflicts) {
|
||||
myChangeReferenceProcessor =
|
||||
new ChangeReferenceProcessor(myProject, getEditor(), myPsiFiles,
|
||||
ContainerUtil.map(myMergeRequest.getContents(), content -> content.getDocument()));
|
||||
List<TextMergeChange> importChanges = ContainerUtil.filter(getChanges(), change -> change.isImportChange());
|
||||
if (importChanges.size() != fragmentsWithMetadata.getFragments().size()) {
|
||||
for (TextMergeChange importChange : importChanges) {
|
||||
@@ -1104,8 +1106,9 @@ public class MergeThreesideViewer extends ThreesideTextDiffViewerEx {
|
||||
if (myResolveImportConflicts && myPsiFiles.size() == 3) {
|
||||
Document document = getContent(ThreeSide.BASE).getDocument();
|
||||
List<RangeMarker> markers = ContainerUtil.map(newRanges, range ->
|
||||
document.createRangeMarker(document.getLineStartOffset(range.start), document.getLineEndOffset(range.end)));
|
||||
document.createRangeMarker(DiffUtil.getLinesRange(document, range.start, range.end)));
|
||||
myChangeReferenceProcessor.process(side, changes, markers);
|
||||
markers.forEach(RangeMarker::dispose);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user