mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 06:50:54 +07:00
IDEA-358678 Properly compute injection start
- First newline character - First non-space character - Any character after indentSize space characters GitOrigin-RevId: 80f413bb01cf784ed0f9266af35cc503a0f9f05f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
6c46345ea6
commit
fe9254efb5
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// 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.psi.impl.source.tree.injected
|
||||
|
||||
import com.intellij.codeInsight.intention.impl.QuickEditAction
|
||||
@@ -396,6 +396,67 @@ class JavaInjectedFileChangesHandlerTest : JavaCodeInsightFixtureTestCase() {
|
||||
|
||||
}
|
||||
|
||||
fun `test indented update`() {
|
||||
myFixture.configureByText("Test.java", """
|
||||
import org.intellij.lang.annotations.*;
|
||||
|
||||
class Hello {
|
||||
void test() {
|
||||
createClass(""${'"'}
|
||||
class Foo {
|
||||
static void foo(int a) {}<caret>
|
||||
static void foo(int a, int b) {}
|
||||
}""${'"'});
|
||||
}
|
||||
|
||||
private static void createClass(@Language("JAVA") String text){};
|
||||
}""".trimIndent())
|
||||
val originalEditor = injectionTestFixture.topLevelEditor
|
||||
|
||||
val quickEditHandler = QuickEditAction().invokeImpl(project, injectionTestFixture.topLevelEditor, injectionTestFixture.topLevelFile)
|
||||
val fragmentFile = quickEditHandler.newFile
|
||||
TestCase.assertEquals("""
|
||||
class Foo {
|
||||
static void foo(int a) {}
|
||||
static void foo(int a, int b) {}
|
||||
}
|
||||
""".trimIndent(), fragmentFile.text)
|
||||
|
||||
myFixture.openFileInEditor(fragmentFile.virtualFile)
|
||||
|
||||
myFixture.editor.caretModel.moveToOffset(fragmentFile.text.indexAfter("foo(int a) {}"))
|
||||
myFixture.type("\n\n\n")
|
||||
|
||||
TestCase.assertEquals("""
|
||||
class Foo {
|
||||
static void foo(int a) {}
|
||||
|
||||
|
||||
|
||||
static void foo(int a, int b) {}
|
||||
}
|
||||
""".trimIndent(), myFixture.editor.document.text.replace(Regex("[ \t]+\n"), "\n"))
|
||||
|
||||
TestCase.assertEquals("""
|
||||
import org.intellij.lang.annotations.*;
|
||||
|
||||
class Hello {
|
||||
void test() {
|
||||
createClass(""${'"'}
|
||||
|
||||
class Foo {
|
||||
static void foo(int a) {}
|
||||
\s
|
||||
\s
|
||||
\s
|
||||
static void foo(int a, int b) {}
|
||||
}""${'"'});
|
||||
}
|
||||
|
||||
private static void createClass(@Language("JAVA") String text){};
|
||||
}""".trimIndent(), originalEditor.document.text)
|
||||
}
|
||||
|
||||
fun `test suffix-prefix-edit-reformat`() {
|
||||
with(myFixture) {
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.intellij.plugins.intelliLang
|
||||
|
||||
import com.intellij.lang.Language
|
||||
@@ -351,6 +351,37 @@ class JavaLanguageInjectionSupportTest : AbstractLanguageInjectionTestCase() {
|
||||
}
|
||||
}""".trimIndent())
|
||||
}
|
||||
|
||||
fun testJavaInjectionWithLeadingNewLines() {
|
||||
myFixture.configureByText("Test.java", """
|
||||
import org.intellij.lang.annotations.*;
|
||||
|
||||
class Hello {
|
||||
void test() {
|
||||
createClass(""${'"'}
|
||||
|
||||
|
||||
|
||||
|
||||
class Foo {
|
||||
static void foo(int a) {}
|
||||
static void foo(int a, int b) {}
|
||||
}""${'"'});
|
||||
}
|
||||
|
||||
private static void createClass(@Language("JAVA") String text){};
|
||||
}""".trimIndent())
|
||||
myFixture.checkHighlighting()
|
||||
injectionTestFixture.assertInjectedContent("""
|
||||
|
||||
|
||||
|
||||
|
||||
class Foo {
|
||||
static void foo(int a) {}
|
||||
static void foo(int a, int b) {}
|
||||
}""".trimIndent())
|
||||
}
|
||||
|
||||
fun testRegexJsonNotSingle() {
|
||||
Configuration.getInstance().withInjections(listOf(jsonToPrintlnInjection().apply {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.intellij.plugins.intelliLang.inject.java;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
@@ -429,8 +429,7 @@ public final class ConcatenationInjector implements ConcatenationAwareInjector {
|
||||
}
|
||||
|
||||
final String text = host.getText();
|
||||
boolean noIndent = host instanceof PsiFragment fragment && fragment.getTokenType() != JavaTokenType.TEXT_BLOCK_TEMPLATE_BEGIN;
|
||||
int startOffset = textRange.getStartOffset() + (noIndent ? 0 : indent);
|
||||
var startOffset = computeInjectionStartOffset(host, textRange, indent, text);
|
||||
int endOffset = text.indexOf('\n', startOffset);
|
||||
final List<TextRange> result = new SmartList<>();
|
||||
while (endOffset > 0) {
|
||||
@@ -472,6 +471,33 @@ public final class ConcatenationInjector implements ConcatenationAwareInjector {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection starts from:<ul>
|
||||
* <li>First newline character</li>
|
||||
* <li>First non-space character</li>
|
||||
* <li>Any character after {@code indentSize} space characters</li>
|
||||
* </ul>
|
||||
*/
|
||||
private static int computeInjectionStartOffset(@NotNull PsiLanguageInjectionHost host,
|
||||
@NotNull TextRange textRange,
|
||||
int indentSize,
|
||||
@NotNull String hostText) {
|
||||
int startOffset = textRange.getStartOffset();
|
||||
boolean noIndent = host instanceof PsiFragment fragment && fragment.getTokenType() != JavaTokenType.TEXT_BLOCK_TEMPLATE_BEGIN;
|
||||
if (!noIndent) {
|
||||
int firstLineIndent = 0;
|
||||
while (startOffset < textRange.getEndOffset() && firstLineIndent < indentSize) {
|
||||
char currentCharacter = hostText.charAt(startOffset);
|
||||
if (currentCharacter == '\n' || !Character.isWhitespace(currentCharacter)) {
|
||||
break;
|
||||
}
|
||||
startOffset++;
|
||||
firstLineIndent++;
|
||||
}
|
||||
}
|
||||
return startOffset;
|
||||
}
|
||||
|
||||
private static boolean checkUnparsableReference(PsiExpression refExpression) {
|
||||
PsiElement parent = refExpression.getParent();
|
||||
if (parent instanceof PsiAssignmentExpression assignmentExpression) {
|
||||
|
||||
Reference in New Issue
Block a user