mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-21 05:51:25 +07:00
[java] Improve support for multi-shred injections with guarded blocks in ModCommands
IDEA-333006 Language injection in String templates GitOrigin-RevId: 6b6bec62bd709cd0419139d8a78925ee3d59e249
This commit is contained in:
committed by
intellij-monorepo-bot
parent
108f842a27
commit
1813854fea
@@ -0,0 +1,16 @@
|
||||
// "Add on-demand static import for 'java.lang.System'" "true-preview"
|
||||
import org.intellij.lang.annotations.Language;
|
||||
|
||||
public class Hello {
|
||||
void test(String name, String message) {
|
||||
@Language("JAVA")
|
||||
String s = STR."""
|
||||
import static java.lang.System.*;
|
||||
|
||||
class \{name} {
|
||||
void main() {
|
||||
out.println("\{message}");
|
||||
}
|
||||
}""";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// "Add on-demand static import for 'java.lang.System'" "true-preview"
|
||||
import org.intellij.lang.annotations.Language;
|
||||
|
||||
public class Hello {
|
||||
void test(String name, String message) {
|
||||
@Language("JAVA")
|
||||
String s = STR."""
|
||||
class \{name} {
|
||||
void main() {
|
||||
<caret>System.out.println("\{message}");
|
||||
}
|
||||
}""";
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,17 @@
|
||||
package com.intellij.java.codeInsight.intention;
|
||||
|
||||
import com.intellij.codeInsight.daemon.LightIntentionActionTestCase;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase.JAVA_21;
|
||||
|
||||
public class AddOnDemandStaticImportActionTest extends LightIntentionActionTestCase {
|
||||
@Override
|
||||
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
|
||||
return JAVA_21;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/addOnDemandStaticImport";
|
||||
|
||||
@@ -65,7 +65,7 @@ final class PsiUpdateImpl {
|
||||
}
|
||||
|
||||
private static class FileTracker implements DocumentListener, Disposable {
|
||||
private final @Nullable PsiLanguageInjectionHost myHostCopy;
|
||||
private final @Nullable SmartPsiElementPointer<PsiLanguageInjectionHost> myHostCopy;
|
||||
private final @NotNull PsiFile myTargetFile;
|
||||
private final @NotNull Document myPositionDocument;
|
||||
private final @NotNull List<ModUpdateFileText.Fragment> myFragments = new ArrayList<>();
|
||||
@@ -91,7 +91,8 @@ final class PsiUpdateImpl {
|
||||
FileTracker hostTracker = changedFiles.get(hostFile);
|
||||
PsiFile hostFileCopy = hostTracker != null ? hostTracker.myTargetFile : (PsiFile)hostFile.copy();
|
||||
myInjectedFileCopy = getInjectedFileCopy(host, hostFileCopy, origFile.getLanguage());
|
||||
myHostCopy = injectionManager.getInjectionHost(myInjectedFileCopy);
|
||||
PsiLanguageInjectionHost injectionHost = injectionManager.getInjectionHost(myInjectedFileCopy);
|
||||
myHostCopy = injectionHost == null ? null : SmartPointerManager.createPointer(injectionHost);
|
||||
Disposable disposable = ApplicationManager.getApplication().getService(InjectionEditService.class)
|
||||
.synchronizeWithFragment(myInjectedFileCopy, myDocument);
|
||||
Disposer.register(this, disposable);
|
||||
@@ -112,6 +113,10 @@ final class PsiUpdateImpl {
|
||||
PostprocessReformattingAspect.getInstance(myProject).forcePostprocessFormat(myCopyFile, this);
|
||||
}
|
||||
|
||||
@Nullable PsiLanguageInjectionHost getHostCopy() {
|
||||
return myHostCopy == null ? null : myHostCopy.getElement();
|
||||
}
|
||||
|
||||
void unblock() {
|
||||
myManager.doPostponedOperationsAndUnblockDocument(myDocument);
|
||||
}
|
||||
@@ -417,7 +422,7 @@ final class PsiUpdateImpl {
|
||||
@Override
|
||||
public void moveCaretTo(int offset) {
|
||||
myPositionUpdated = true;
|
||||
PsiLanguageInjectionHost host = myTracker.myHostCopy;
|
||||
PsiLanguageInjectionHost host = myTracker.getHostCopy();
|
||||
if (host != null) {
|
||||
InjectedLanguageManager instance = InjectedLanguageManager.getInstance(myTracker.myProject);
|
||||
PsiFile file = findInjectedFile(instance, host);
|
||||
@@ -505,7 +510,7 @@ final class PsiUpdateImpl {
|
||||
}
|
||||
|
||||
private TextRange mapRange(@NotNull TextRange range) {
|
||||
PsiLanguageInjectionHost host = myTracker.myHostCopy;
|
||||
PsiLanguageInjectionHost host = myTracker.getHostCopy();
|
||||
if (host != null) {
|
||||
InjectedLanguageManager instance = InjectedLanguageManager.getInstance(myTracker.myProject);
|
||||
PsiFile file = findInjectedFile(instance, host);
|
||||
|
||||
@@ -25,7 +25,8 @@ public final class InjectionEditServiceImpl implements InjectionEditService {
|
||||
Place shreds = InjectedLanguageUtilBase.getShreds(injectedFile);
|
||||
Project project = injectedFile.getProject();
|
||||
PsiLanguageInjectionHost host = Objects.requireNonNull(InjectedLanguageManager.getInstance(project).getInjectionHost(injectedFile));
|
||||
Editor editor = new ImaginaryEditor(project, host.getContainingFile().getViewProvider().getDocument());
|
||||
Document origDocument = host.getContainingFile().getFileDocument();
|
||||
Editor editor = new ImaginaryEditor(project, origDocument);
|
||||
InjectedFileChangesHandler handler = QuickEditHandler.getHandler(injectedFile, editor, shreds, copyDocument);
|
||||
copyDocument.addDocumentListener(new DocumentListener() {
|
||||
@Override
|
||||
@@ -33,6 +34,7 @@ public final class InjectionEditServiceImpl implements InjectionEditService {
|
||||
handler.commitToOriginal(event);
|
||||
}
|
||||
});
|
||||
QuickEditHandler.initGuardedBlocks(copyDocument, origDocument, shreds);
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ public final class QuickEditHandler extends UserDataHolderBase implements Dispos
|
||||
Disposer.register(this, () -> finalEditHandlers.remove(this));
|
||||
});
|
||||
|
||||
initGuardedBlocks(shreds);
|
||||
initGuardedBlocks(myNewDocument, myOrigDocument, shreds);
|
||||
|
||||
myOrigDocument.addDocumentListener(this, this);
|
||||
myNewDocument.addDocumentListener(this, this);
|
||||
@@ -312,7 +312,7 @@ public final class QuickEditHandler extends UserDataHolderBase implements Dispos
|
||||
closeEditor();
|
||||
}
|
||||
|
||||
private void initGuardedBlocks(Place shreds) {
|
||||
static void initGuardedBlocks(@NotNull Document newDocument, @NotNull Document origDocument, Place shreds) {
|
||||
int origOffset = -1;
|
||||
int curOffset = 0;
|
||||
for (PsiLanguageInjectionHost.Shred shred : shreds) {
|
||||
@@ -320,16 +320,16 @@ public final class QuickEditHandler extends UserDataHolderBase implements Dispos
|
||||
int start = shred.getRange().getStartOffset() + shred.getPrefix().length();
|
||||
int end = shred.getRange().getEndOffset() - shred.getSuffix().length();
|
||||
if (curOffset < start) {
|
||||
RangeMarker guard = myNewDocument.createGuardedBlock(curOffset, start);
|
||||
RangeMarker guard = newDocument.createGuardedBlock(curOffset, start);
|
||||
if (curOffset == 0 && shred == shreds.get(0)) guard.setGreedyToLeft(true);
|
||||
String padding = origOffset < 0 ? "" : myOrigDocument.getText().substring(origOffset, hostRangeMarker.getStartOffset());
|
||||
String padding = origOffset < 0 ? "" : origDocument.getText().substring(origOffset, hostRangeMarker.getStartOffset());
|
||||
guard.putUserData(REPLACEMENT_KEY, fixQuotes(padding));
|
||||
}
|
||||
curOffset = end;
|
||||
origOffset = hostRangeMarker.getEndOffset();
|
||||
}
|
||||
if (curOffset < myNewDocument.getTextLength()) {
|
||||
RangeMarker guard = myNewDocument.createGuardedBlock(curOffset, myNewDocument.getTextLength());
|
||||
if (curOffset < newDocument.getTextLength()) {
|
||||
RangeMarker guard = newDocument.createGuardedBlock(curOffset, newDocument.getTextLength());
|
||||
guard.setGreedyToRight(true);
|
||||
guard.putUserData(REPLACEMENT_KEY, "");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user