Skip to content

Commit

Permalink
Add support for java text-blocks for expression injection
Browse files Browse the repository at this point in the history
  • Loading branch information
hduelme committed Mar 30, 2024
1 parent 8e25048 commit 99d2043
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@
*/
public class JavaExpressionInjector implements MultiHostInjector {

public static final Pattern JAVA_EXPRESSION = Pattern.compile( "^\"\\s*java\\((.*)\\)\\s*\"$", Pattern.DOTALL );
public static final Pattern JAVA_EXPRESSION = Pattern.compile( "^(\"|\"{3})\\s*java\\((.*)\\)\\s*\\1$",
Pattern.DOTALL );

private static final ElementPattern<PsiElement> PATTERN =
StandardPatterns.or(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ private void inspectUnnecessaryWhitespaces(@NotNull ProblemsHolder problemsHolde
if ( !JAVA_EXPRESSION.matcher( text ).matches() ) {
return;
}
if ( text.charAt( 1 ) == '"') {
// Text-Block
return;
}
if ( text.indexOf( "java(" ) > 1 ) {
problemsHolder.registerProblem( property,
MapStructBundle.message( "inspection.java.expression.unnecessary.whitespace",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,43 @@ protected void withMapperToDtoWithoutAccessors(String attribute) {
assertThat( elementAt.getText() ).isEqualTo( ";" );
}

public void testWithTextBlockAndTargetDefined() {
withTextBlockAndTargetDefined( "expression" );
withTextBlockAndTargetDefined( "defaultExpression" );
withTextBlockAndTargetDefined( "conditionExpression" );
}

protected void withTextBlockAndTargetDefined(String attribute) {
String mapping = "@Mapping(target = \"manufacturingYear\", " + attribute
+ " = \"\"\"\njava(car.<caret>)\"\"\")\n";
@Language("java")
String mapper = formatMapper( CAR_MAPPER, mapping );
PsiFile file = configureMapperByText( mapper );

assertThat( myFixture.completeBasic() )
.extracting( LookupElementPresentation::renderElement )
.extracting( LookupElementPresentation::getItemText )
.contains(
"getMake",
"setMake",
"getManufacturingDate",
"setManufacturingDate",
"getNumberOfSeats",
"setNumberOfSeats"
);

assertThat( myFixture.complete( CompletionType.SMART ) )
.extracting( LookupElementPresentation::renderElement )
.extracting( LookupElementPresentation::getItemText )
.containsExactlyInAnyOrder( "getMake", "toString" );

PsiElement elementAt = file.findElementAt( myFixture.getCaretOffset() );
assertThat( elementAt )
.isNotNull()
.isInstanceOf( PsiJavaToken.class );
assertThat( elementAt.getText() ).isEqualTo( ";" );
}

private PsiFile configureMapperByText(@Language("java") String text) {
return myFixture.configureByText( JavaFileType.INSTANCE, text );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.pom.java.LanguageLevel;
import org.jetbrains.annotations.NotNull;

import java.util.List;
Expand Down Expand Up @@ -54,4 +55,17 @@ public void testJavaExpressionUnnecessaryWhitespacesInspectorWhitespaceAfter() {
allQuickFixes.forEach( myFixture::launchAction );
myFixture.checkResultByFile( testName + "_after.java" );
}

//Tests if inspection ignores Textblocks
public void testJavaExpressionUnnecessaryWhitespacesTextBlock() {
doTest();
String testName = getTestName( false );
List<IntentionAction> allQuickFixes = myFixture.getAllQuickFixes();
assertThat( allQuickFixes ).isEmpty();
}

@Override
protected LanguageLevel getLanguageLevel() {
return LanguageLevel.JDK_15;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at https://www.apache.org/licenses/LICENSE-2.0
*/

import org.mapstruct.BeanMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

class Source {

private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

class Target {

private String name;
private String lastName;
private String city;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}
}

@Mapper
interface SingleMappingMapper {

@Mapping(target = "name", source = "name", conditionExpression = """
java( !source.getName().length > 0 ) """)
@Mapping(target = "lastName", source = "name",defaultExpression = """
java( \" \" ) """)
@Mapping(target = "city", expression = """
java( \" \" ) """)
Target map(Source source);
}

0 comments on commit 99d2043

Please sign in to comment.