Skip to content

JSpecify: Missing null check before reusing non-nullable method #4077

Description

@RaniAgus

Expected behavior

When a non-nullable mapper method (under @NullMarked) is reused for a @Nullable source property, MapStruct should emit a null guard before the call.

Given:

@Mapper
@NullMarked
public interface Issue4077Mapper {
    Target map(Source source);
    Target.Nested mapNested(Source.Nested source); // non-null parameter
}

public class Source {
    private final @Nullable Nested nested;
    public @Nullable Nested getNested() { return nested; }
}

Expected:

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "0000-00-00T00:00:00+0000",
    comments = "version: , compiler: javac, environment: Java 21"
)
public class Issue4077MapperImpl implements Issue4077Mapper {

    @Override
    public Target map(Source source) {

        Target.Nested nested = null;

        if ( source.getNested() != null ) {
            nested = mapNested( source.getNested() );
        }

        Target target = new Target( nested );

        return target;
    }

    @Override
    public Target.Nested mapNested(Source.Nested source) {

        String foo = null;
        Integer bar = null;

        foo = source.getFoo();
        bar = source.getBar();

        Target.Nested nested = new Target.Nested( foo, bar );

        return nested;
    }
}

Actual behavior

The null check is missing, so null values will throw NullPointerException:

Changed content at line 22:
expecting:
  ["        if ( source.getNested() != null ) {",
   "            nested = mapNested( source.getNested() );",
   "        }"]
but was:
  ["        nested = mapNested( source.getNested() );"]

Steps to reproduce the problem

Can be reproduced in this branch: main...RaniAgus:mapstruct:issues/4077

MapStruct Version

1.7.0.Beta2

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions