Skip to content

Unnecessary reflection when one constructor is used more than once #1353

Closed
@volivan239

Description

@volivan239

Description

In some cases, generated tests will have to call one constructor more then once. In this case, second and following calls may use reflection even though it is unnecessary.

To Reproduce

Launch action on class UnnecessaryReflection from below:

class MyPoint {
    public final int x, y;
    public MyPoint(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

class ClassWithPoint {
    public MyPoint p;
    public ClassWithPoint(MyPoint p) {
        this.p = p;
    }
}

public class UnnecessaryReflection {
    public ClassWithPoint f(ClassWithPoint c) {
        if (c.p.x == 1)
            return new ClassWithPoint(new MyPoint(2, 3));
        return c;
    }
}

Expected behavior

Tests are generated correctly and without reflection.

Actual behavior

In some tests, some UtBot doesn't instantiate Point with constructor and uses reflection instead.

Visual proofs (screenshots, logs, images)

@Test
public void testF2() throws Exception {
    UnnecessaryReflection unnecessaryReflection = new UnnecessaryReflection();
    MyPoint myPoint = new MyPoint(1, -1464141532);
    ClassWithPoint c = new ClassWithPoint(myPoint);

    ClassWithPoint actual = unnecessaryReflection.f(c);

    ClassWithPoint expected = new ClassWithPoint(null);
    MyPoint myPoint1 = ((MyPoint) createInstance("testpackage.MyPoint"));
    setField(myPoint1, "testpackage.MyPoint", "x", 2);
    setField(myPoint1, "testpackage.MyPoint", "y", 3);
    expected.p = myPoint1;
    MyPoint expectedP = expected.p;
    MyPoint actualP = actual.p;
    int expectedPX = expectedP.x;
    int actualPX = actualP.x;
    assertEquals(expectedPX, actualPX);

    int expectedPY = expectedP.y;
    int actualPY = actualP.y;
    assertEquals(expectedPY, actualPY);

}

Environment

Fuzzing 25% Symbolic execution 75%

Additional context

Seems like problem is in ConstructorAnalyzer.analyze() method which does nothing when called more then once. However, we can't just remove visited checks from there, because this would lead to infinite recursion in examples like org.utbot.examples.codegen.deepequals.ClassWithCrossReferenceRelationshipTest#testClassWithCrossReferenceRelationship -- see failed attempt to fix issue this way

Metadata

Metadata

Assignees

Labels

comp-codegenIssue is related to code generatorctg-bugIssue is a bugpriority-top-focusTop priority chosen by dev team

Type

No type

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions