Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1693,6 +1693,15 @@ private void applyTargetThisMapping() {
// apply name based mapping
applyPropertyNameBasedMapping( sourceRefs );

// the source of a target this mapping is only consumed when it actually contributed
// a property, so an unused target this still reports its source as unmapped
if ( !sourceRefs.isEmpty() ) {
String sourceName = targetThis.getSourceReference().getShallowestPropertyName();
if ( sourceName != null ) {
unprocessedSourceProperties.remove( sourceName );
}
}

// add handled target properties
handledTargetProperties.addAll( sourceRefs.stream()
.map( SourceReference::getDeepestPropertyName )
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.bugs._3839;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.ReportingPolicy;

@Mapper( unmappedSourcePolicy = ReportingPolicy.ERROR )
public interface ErroneousIssue3839UnusedTargetThisMapper {

@Mapping( target = ".", source = "record" )
Target map(Source source);

class Source {

private Record record;

public Record getRecord() {
return record;
}

public void setRecord(Record record) {
this.record = record;
}
}

class Record {

private String alpha;

public String getAlpha() {
return alpha;
}

public void setAlpha(String alpha) {
this.alpha = alpha;
}
}

class Target {

private String zulu;

public String getZulu() {
return zulu;
}

public void setZulu(String zulu) {
this.zulu = zulu;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.bugs._3839;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.ReportingPolicy;

/**
* The "target this" example from the reference documentation.
*/
@Mapper( unmappedSourcePolicy = ReportingPolicy.ERROR )
public interface Issue3839DocExampleMapper {

@Mapping( target = "name", source = "record.name" )
@Mapping( target = ".", source = "record" )
@Mapping( target = ".", source = "account" )
Customer map(CustomerDto customerDto);

class CustomerDto {

private Record record;

private Account account;

public Record getRecord() {
return record;
}

public void setRecord(Record record) {
this.record = record;
}

public Account getAccount() {
return account;
}

public void setAccount(Account account) {
this.account = account;
}
}

class Record {

private String name;

private String description;

public String getName() {
return name;
}

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

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}
}

class Account {

private String name;

private long number;

public String getName() {
return name;
}

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

public long getNumber() {
return number;
}

public void setNumber(long number) {
this.number = number;
}
}

class Customer {

private String name;

private String description;

private long number;

public String getName() {
return name;
}

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

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public long getNumber() {
return number;
}

public void setNumber(long number) {
this.number = number;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.bugs._3839;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.ReportingPolicy;

/**
* A single {@code target = "."} mapping whose source contributes both target properties.
*/
@Mapper( unmappedSourcePolicy = ReportingPolicy.ERROR )
public interface Issue3839Mapper {

@Mapping( target = ".", source = "record" )
Customer map(CustomerDto customerDto);

class CustomerDto {

private Record record;

public Record getRecord() {
return record;
}

public void setRecord(Record record) {
this.record = record;
}
}

class Record {

private String name;

private String description;

public String getName() {
return name;
}

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

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}
}

class Customer {

private String name;

private String description;

public String getName() {
return name;
}

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

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.bugs._3839;

import javax.tools.Diagnostic.Kind;

import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.ProcessorTest;
import org.mapstruct.ap.testutil.WithClasses;
import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult;
import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic;
import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome;

/**
* A source consumed by {@code @Mapping( target = "." )} should count as mapped for
* {@code unmappedSourcePolicy}, unless the target this mapping contributed nothing.
*/
@IssueKey( "3839" )
public class Issue3839Test {

@ProcessorTest
@WithClasses( Issue3839Mapper.class )
public void targetThisSourceIsNotReportedAsUnmapped() {
}

@ProcessorTest
@WithClasses( Issue3839DocExampleMapper.class )
public void documentedTargetThisExampleCompiles() {
}

@ProcessorTest
@WithClasses( ErroneousIssue3839UnusedTargetThisMapper.class )
@ExpectedCompilationOutcome(
value = CompilationResult.FAILED,
diagnostics = {
@Diagnostic(type = ErroneousIssue3839UnusedTargetThisMapper.class,
kind = Kind.WARNING,
line = 16,
message = "Unmapped target property: \"zulu\"."),
@Diagnostic(type = ErroneousIssue3839UnusedTargetThisMapper.class,
kind = Kind.ERROR,
line = 16,
message = "Unmapped source property: \"record\".")
}
)
public void unusedTargetThisStillReportsItsSource() {
}
}