diff --git a/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/expression/ListOperationTest.java b/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/expression/ListOperationTest.java index 631569dba1..6bf7481905 100644 --- a/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/expression/ListOperationTest.java +++ b/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/expression/ListOperationTest.java @@ -53,70 +53,68 @@ filteredFoos Foo (0..*) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.CardinalityOperator; - import com.rosetta.model.lib.functions.ModelObjectValidator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.test.model.Foo; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - import java.util.Optional; - import java.util.stream.Collectors; - import javax.inject.Inject; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - - /** - * @param foos\s - * @return filteredFoos\s - */ - public List evaluate(List foos) { - List filteredFoosBuilder = doEvaluate(foos); - \t\t - final List filteredFoos; - if (filteredFoosBuilder == null) { - filteredFoos = null; - } else { - filteredFoos = filteredFoosBuilder.stream().map(Foo::build).collect(Collectors.toList()); - objectValidator.validate(Foo.class, filteredFoos); - } - \t\t - return filteredFoos; - } - - protected abstract List doEvaluate(List foos); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List foos) { - if (foos == null) { - foos = Collections.emptyList(); - } - List filteredFoos = new ArrayList<>(); - return assignOutput(filteredFoos, foos); - } - \t\t - protected List assignOutput(List filteredFoos, List foos) { - filteredFoos = toBuilder(MapperC.of(foos) - .filterItemNullSafe(item -> areEqual(item.map("getInclude", foo -> foo.getInclude()), MapperS.of(true), CardinalityOperator.All).get()).getMulti()); - \t\t\t - return Optional.ofNullable(filteredFoos) - .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) - .orElse(null); - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.CardinalityOperator; + import com.rosetta.model.lib.functions.ModelObjectValidator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.test.model.Foo; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + import java.util.Optional; + import java.util.stream.Collectors; + import javax.inject.Inject; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + @Inject protected ModelObjectValidator objectValidator; + + /** + * @param foos + * @return filteredFoos + */ + public List evaluate(List foos) { + List filteredFoosBuilder = doEvaluate(foos); + + final List filteredFoos; + if (filteredFoosBuilder == null) { + filteredFoos = null; + } else { + filteredFoos = filteredFoosBuilder.stream().map(Foo::build).collect(Collectors.toList()); + objectValidator.validate(Foo.class, filteredFoos); + } + return filteredFoos; + } + + protected abstract List doEvaluate(List foos); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List foos) { + if (foos == null) { + foos = Collections.emptyList(); + } + List filteredFoos = new ArrayList<>(); + return assignOutput(filteredFoos, foos); + } + + protected List assignOutput(List filteredFoos, List foos) { + filteredFoos = toBuilder(MapperC.of(foos) + .filterItemNullSafe(item -> areEqual(item.map("getInclude", foo -> foo.getInclude()), MapperS.of(true), CardinalityOperator.All).get()).getMulti()); + return Optional.ofNullable(filteredFoos) + .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) + .orElse(null); + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); @@ -154,70 +152,68 @@ filteredFoos Foo (0..*) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.CardinalityOperator; - import com.rosetta.model.lib.functions.ModelObjectValidator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.test.model.Foo; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - import java.util.Optional; - import java.util.stream.Collectors; - import javax.inject.Inject; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - - /** - * @param foos\s - * @return filteredFoos\s - */ - public List evaluate(List foos) { - List filteredFoosBuilder = doEvaluate(foos); - \t\t - final List filteredFoos; - if (filteredFoosBuilder == null) { - filteredFoos = null; - } else { - filteredFoos = filteredFoosBuilder.stream().map(Foo::build).collect(Collectors.toList()); - objectValidator.validate(Foo.class, filteredFoos); - } - \t\t - return filteredFoos; - } - - protected abstract List doEvaluate(List foos); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List foos) { - if (foos == null) { - foos = Collections.emptyList(); - } - List filteredFoos = new ArrayList<>(); - return assignOutput(filteredFoos, foos); - } - \t\t - protected List assignOutput(List filteredFoos, List foos) { - filteredFoos = toBuilder(MapperC.of(foos) - .filterItemNullSafe(fooItem -> areEqual(fooItem.map("getInclude", foo -> foo.getInclude()), MapperS.of(true), CardinalityOperator.All).get()).getMulti()); - \t\t\t - return Optional.ofNullable(filteredFoos) - .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) - .orElse(null); - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.CardinalityOperator; + import com.rosetta.model.lib.functions.ModelObjectValidator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.test.model.Foo; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + import java.util.Optional; + import java.util.stream.Collectors; + import javax.inject.Inject; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + @Inject protected ModelObjectValidator objectValidator; + + /** + * @param foos + * @return filteredFoos + */ + public List evaluate(List foos) { + List filteredFoosBuilder = doEvaluate(foos); + + final List filteredFoos; + if (filteredFoosBuilder == null) { + filteredFoos = null; + } else { + filteredFoos = filteredFoosBuilder.stream().map(Foo::build).collect(Collectors.toList()); + objectValidator.validate(Foo.class, filteredFoos); + } + return filteredFoos; + } + + protected abstract List doEvaluate(List foos); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List foos) { + if (foos == null) { + foos = Collections.emptyList(); + } + List filteredFoos = new ArrayList<>(); + return assignOutput(filteredFoos, foos); + } + + protected List assignOutput(List filteredFoos, List foos) { + filteredFoos = toBuilder(MapperC.of(foos) + .filterItemNullSafe(fooItem -> areEqual(fooItem.map("getInclude", foo -> foo.getInclude()), MapperS.of(true), CardinalityOperator.All).get()).getMulti()); + return Optional.ofNullable(filteredFoos) + .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) + .orElse(null); + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); @@ -293,72 +289,70 @@ filteredFoos Foo2 (0..*) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.CardinalityOperator; - import com.rosetta.model.lib.functions.ModelObjectValidator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.test.model.Foo2; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - import java.util.Optional; - import java.util.stream.Collectors; - import javax.inject.Inject; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - - /** - * @param foos\s - * @return filteredFoos\s - */ - public List evaluate(List foos) { - List filteredFoosBuilder = doEvaluate(foos); - \t\t - final List filteredFoos; - if (filteredFoosBuilder == null) { - filteredFoos = null; - } else { - filteredFoos = filteredFoosBuilder.stream().map(Foo2::build).collect(Collectors.toList()); - objectValidator.validate(Foo2.class, filteredFoos); - } - \t\t - return filteredFoos; - } - - protected abstract List doEvaluate(List foos); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List foos) { - if (foos == null) { - foos = Collections.emptyList(); - } - List filteredFoos = new ArrayList<>(); - return assignOutput(filteredFoos, foos); - } - \t\t - protected List assignOutput(List filteredFoos, List foos) { - final MapperC thenArg = MapperC.of(foos) - .filterItemNullSafe(item -> areEqual(item.map("getInclude", foo2 -> foo2.getInclude()), MapperS.of(true), CardinalityOperator.All).get()); - filteredFoos = toBuilder(thenArg - .filterItemNullSafe(item -> areEqual(item.map("getInclude2", foo2 -> foo2.getInclude2()), MapperS.of(true), CardinalityOperator.All).get()).getMulti()); - \t\t\t - return Optional.ofNullable(filteredFoos) - .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) - .orElse(null); - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.CardinalityOperator; + import com.rosetta.model.lib.functions.ModelObjectValidator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.test.model.Foo2; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + import java.util.Optional; + import java.util.stream.Collectors; + import javax.inject.Inject; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + @Inject protected ModelObjectValidator objectValidator; + + /** + * @param foos + * @return filteredFoos + */ + public List evaluate(List foos) { + List filteredFoosBuilder = doEvaluate(foos); + + final List filteredFoos; + if (filteredFoosBuilder == null) { + filteredFoos = null; + } else { + filteredFoos = filteredFoosBuilder.stream().map(Foo2::build).collect(Collectors.toList()); + objectValidator.validate(Foo2.class, filteredFoos); + } + return filteredFoos; + } + + protected abstract List doEvaluate(List foos); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List foos) { + if (foos == null) { + foos = Collections.emptyList(); + } + List filteredFoos = new ArrayList<>(); + return assignOutput(filteredFoos, foos); + } + + protected List assignOutput(List filteredFoos, List foos) { + final MapperC thenArg = MapperC.of(foos) + .filterItemNullSafe(item -> areEqual(item.map("getInclude", foo2 -> foo2.getInclude()), MapperS.of(true), CardinalityOperator.All).get()); + filteredFoos = toBuilder(thenArg + .filterItemNullSafe(item -> areEqual(item.map("getInclude2", foo2 -> foo2.getInclude2()), MapperS.of(true), CardinalityOperator.All).get()).getMulti()); + return Optional.ofNullable(filteredFoos) + .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) + .orElse(null); + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); @@ -396,71 +390,69 @@ filteredFoos FooWithScheme (0..*) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.CardinalityOperator; - import com.rosetta.model.lib.functions.ModelObjectValidator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.model.metafields.FieldWithMetaString; - import com.rosetta.test.model.FooWithScheme; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - import java.util.Optional; - import java.util.stream.Collectors; - import javax.inject.Inject; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - - /** - * @param foos\s - * @return filteredFoos\s - */ - public List evaluate(List foos) { - List filteredFoosBuilder = doEvaluate(foos); - \t\t - final List filteredFoos; - if (filteredFoosBuilder == null) { - filteredFoos = null; - } else { - filteredFoos = filteredFoosBuilder.stream().map(FooWithScheme::build).collect(Collectors.toList()); - objectValidator.validate(FooWithScheme.class, filteredFoos); - } - \t\t - return filteredFoos; - } - - protected abstract List doEvaluate(List foos); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List foos) { - if (foos == null) { - foos = Collections.emptyList(); - } - List filteredFoos = new ArrayList<>(); - return assignOutput(filteredFoos, foos); - } - \t\t - protected List assignOutput(List filteredFoos, List foos) { - filteredFoos = toBuilder(MapperC.of(foos) - .filterItemNullSafe(item -> areEqual(item.map("getAttr", fooWithScheme -> fooWithScheme.getAttr()).map("getMeta", a->a.getMeta()).map("getScheme", a->a.getScheme()), MapperS.of("foo-scheme"), CardinalityOperator.All).get()).getMulti()); - \t\t\t - return Optional.ofNullable(filteredFoos) - .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) - .orElse(null); - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.CardinalityOperator; + import com.rosetta.model.lib.functions.ModelObjectValidator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.model.metafields.FieldWithMetaString; + import com.rosetta.test.model.FooWithScheme; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + import java.util.Optional; + import java.util.stream.Collectors; + import javax.inject.Inject; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + @Inject protected ModelObjectValidator objectValidator; + + /** + * @param foos + * @return filteredFoos + */ + public List evaluate(List foos) { + List filteredFoosBuilder = doEvaluate(foos); + + final List filteredFoos; + if (filteredFoosBuilder == null) { + filteredFoos = null; + } else { + filteredFoos = filteredFoosBuilder.stream().map(FooWithScheme::build).collect(Collectors.toList()); + objectValidator.validate(FooWithScheme.class, filteredFoos); + } + return filteredFoos; + } + + protected abstract List doEvaluate(List foos); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List foos) { + if (foos == null) { + foos = Collections.emptyList(); + } + List filteredFoos = new ArrayList<>(); + return assignOutput(filteredFoos, foos); + } + + protected List assignOutput(List filteredFoos, List foos) { + filteredFoos = toBuilder(MapperC.of(foos) + .filterItemNullSafe(item -> areEqual(item.map("getAttr", fooWithScheme -> fooWithScheme.getAttr()).map("getMeta", a->a.getMeta()).map("getScheme", a->a.getScheme()), MapperS.of("foo-scheme"), CardinalityOperator.All).get()).getMulti()); + return Optional.ofNullable(filteredFoos) + .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) + .orElse(null); + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); @@ -578,53 +570,51 @@ filteredFoos boolean (0..*) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.CardinalityOperator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.mapper.MapperS; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param foos\s - * @return filteredFoos\s - */ - public List evaluate(List foos) { - List filteredFoos = doEvaluate(foos); - \t\t - return filteredFoos; - } - - protected abstract List doEvaluate(List foos); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List foos) { - if (foos == null) { - foos = Collections.emptyList(); - } - List filteredFoos = new ArrayList<>(); - return assignOutput(filteredFoos, foos); - } - \t\t - protected List assignOutput(List filteredFoos, List foos) { - filteredFoos = MapperC.of(foos) - .filterItemNullSafe(item -> areEqual(item, MapperS.of(true), CardinalityOperator.All).get()).getMulti(); - \t\t\t - return filteredFoos; - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.CardinalityOperator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.mapper.MapperS; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param foos + * @return filteredFoos + */ + public List evaluate(List foos) { + List filteredFoos = doEvaluate(foos); + return filteredFoos; + } + + protected abstract List doEvaluate(List foos); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List foos) { + if (foos == null) { + foos = Collections.emptyList(); + } + List filteredFoos = new ArrayList<>(); + return assignOutput(filteredFoos, foos); + } + + protected List assignOutput(List filteredFoos, List foos) { + filteredFoos = MapperC.of(foos) + .filterItemNullSafe(item -> areEqual(item, MapperS.of(true), CardinalityOperator.All).get()).getMulti(); + return filteredFoos; + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); @@ -949,75 +939,73 @@ foos Foo (0..*) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.CardinalityOperator; - import com.rosetta.model.lib.expression.MapperMaths; - import com.rosetta.model.lib.functions.ModelObjectValidator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.test.model.Bar; - import com.rosetta.test.model.Foo; - import java.util.ArrayList; - import java.util.List; - import java.util.Optional; - import java.util.stream.Collectors; - import javax.inject.Inject; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - - /** - * @param bar\s - * @return foos\s - */ - public List evaluate(Bar bar) { - List foosBuilder = doEvaluate(bar); - \t\t - final List foos; - if (foosBuilder == null) { - foos = null; - } else { - foos = foosBuilder.stream().map(Foo::build).collect(Collectors.toList()); - objectValidator.validate(Foo.class, foos); - } - \t\t - return foos; - } - - protected abstract List doEvaluate(Bar bar); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(Bar bar) { - List foos = new ArrayList<>(); - return assignOutput(foos, bar); - } - \t\t - protected List assignOutput(List foos, Bar bar) { - foos = toBuilder(MapperS.of(bar).mapC("getFoos", _bar -> _bar.getFoos()) - .mapItem(item -> { - if (areEqual(item.map("getInclude", foo -> foo.getInclude()), MapperS.of(true), CardinalityOperator.All).getOrDefault(false)) { - return MapperS.of(Foo.builder() - .setInclude(item.map("getInclude", foo -> foo.getInclude()).get()) - .setAttr(MapperMaths.add(item.map("getAttr", foo -> foo.getAttr()), MapperS.of("_bar")).get()) - .build()); - } - return item; - }).getMulti()); - \t\t\t - return Optional.ofNullable(foos) - .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) - .orElse(null); - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.CardinalityOperator; + import com.rosetta.model.lib.expression.MapperMaths; + import com.rosetta.model.lib.functions.ModelObjectValidator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.test.model.Bar; + import com.rosetta.test.model.Foo; + import java.util.ArrayList; + import java.util.List; + import java.util.Optional; + import java.util.stream.Collectors; + import javax.inject.Inject; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + @Inject protected ModelObjectValidator objectValidator; + + /** + * @param bar + * @return foos + */ + public List evaluate(Bar bar) { + List foosBuilder = doEvaluate(bar); + + final List foos; + if (foosBuilder == null) { + foos = null; + } else { + foos = foosBuilder.stream().map(Foo::build).collect(Collectors.toList()); + objectValidator.validate(Foo.class, foos); + } + return foos; + } + + protected abstract List doEvaluate(Bar bar); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(Bar bar) { + List foos = new ArrayList<>(); + return assignOutput(foos, bar); + } + + protected List assignOutput(List foos, Bar bar) { + foos = toBuilder(MapperS.of(bar).mapC("getFoos", _bar -> _bar.getFoos()) + .mapItem(item -> { + if (areEqual(item.map("getInclude", foo -> foo.getInclude()), MapperS.of(true), CardinalityOperator.All).getOrDefault(false)) { + return MapperS.of(Foo.builder() + .setInclude(item.map("getInclude", foo -> foo.getInclude()).get()) + .setAttr(MapperMaths.add(item.map("getAttr", foo -> foo.getAttr()), MapperS.of("_bar")).get()) + .build()); + } + return item; + }).getMulti()); + return Optional.ofNullable(foos) + .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) + .orElse(null); + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); @@ -1263,51 +1251,49 @@ strings string (0..*) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.test.model.Foo; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param foos\s - * @return strings\s - */ - public List evaluate(List foos) { - List strings = doEvaluate(foos); - \t\t - return strings; - } - - protected abstract List doEvaluate(List foos); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List foos) { - if (foos == null) { - foos = Collections.emptyList(); - } - List strings = new ArrayList<>(); - return assignOutput(strings, foos); - } - \t\t - protected List assignOutput(List strings, List foos) { - strings = MapperC.of(foos) - .mapItem(item -> item.map("getAttr", foo -> foo.getAttr())).getMulti(); - \t\t\t - return strings; - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.test.model.Foo; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param foos + * @return strings + */ + public List evaluate(List foos) { + List strings = doEvaluate(foos); + return strings; + } + + protected abstract List doEvaluate(List foos); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List foos) { + if (foos == null) { + foos = Collections.emptyList(); + } + List strings = new ArrayList<>(); + return assignOutput(strings, foos); + } + + protected List assignOutput(List strings, List foos) { + strings = MapperC.of(foos) + .mapItem(item -> item.map("getAttr", foo -> foo.getAttr())).getMulti(); + return strings; + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); @@ -1382,56 +1368,54 @@ fooCounts int (0..*) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.mapper.MapperListOfLists; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.test.model.Bar; - import com.rosetta.test.model.Foo; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param bars\s - * @return fooCounts\s - */ - public List evaluate(List bars) { - List fooCounts = doEvaluate(bars); - \t\t - return fooCounts; - } - - protected abstract List doEvaluate(List bars); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List bars) { - if (bars == null) { - bars = Collections.emptyList(); - } - List fooCounts = new ArrayList<>(); - return assignOutput(fooCounts, bars); - } - \t\t - protected List assignOutput(List fooCounts, List bars) { - final MapperListOfLists thenArg = MapperC.of(bars) - .mapItemToList(bar -> bar.mapC("getFoos", _bar -> _bar.getFoos())); - fooCounts = thenArg - .mapListToItem(fooListItem -> MapperS.of(fooListItem.resultCount())).getMulti(); - \t\t\t - return fooCounts; - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.mapper.MapperListOfLists; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.test.model.Bar; + import com.rosetta.test.model.Foo; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param bars + * @return fooCounts + */ + public List evaluate(List bars) { + List fooCounts = doEvaluate(bars); + return fooCounts; + } + + protected abstract List doEvaluate(List bars); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List bars) { + if (bars == null) { + bars = Collections.emptyList(); + } + List fooCounts = new ArrayList<>(); + return assignOutput(fooCounts, bars); + } + + protected List assignOutput(List fooCounts, List bars) { + final MapperListOfLists thenArg = MapperC.of(bars) + .mapItemToList(bar -> bar.mapC("getFoos", _bar -> _bar.getFoos())); + fooCounts = thenArg + .mapListToItem(fooListItem -> MapperS.of(fooListItem.resultCount())).getMulti(); + return fooCounts; + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); @@ -1584,71 +1568,69 @@ foos Foo (0..*) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.ModelObjectValidator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.mapper.MapperListOfLists; - import com.rosetta.test.model.Bar; - import com.rosetta.test.model.Foo; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - import java.util.Optional; - import java.util.stream.Collectors; - import javax.inject.Inject; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - - /** - * @param bars\s - * @return foos\s - */ - public List evaluate(List bars) { - List foosBuilder = doEvaluate(bars); - \t\t - final List foos; - if (foosBuilder == null) { - foos = null; - } else { - foos = foosBuilder.stream().map(Foo::build).collect(Collectors.toList()); - objectValidator.validate(Foo.class, foos); - } - \t\t - return foos; - } - - protected abstract List doEvaluate(List bars); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List bars) { - if (bars == null) { - bars = Collections.emptyList(); - } - List foos = new ArrayList<>(); - return assignOutput(foos, bars); - } - \t\t - protected List assignOutput(List foos, List bars) { - final MapperListOfLists thenArg = MapperC.of(bars) - .mapItemToList(bar -> bar.mapC("getFoos", _bar -> _bar.getFoos())); - foos = toBuilder(thenArg - .flattenList().getMulti()); - \t\t\t - return Optional.ofNullable(foos) - .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) - .orElse(null); - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.ModelObjectValidator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.mapper.MapperListOfLists; + import com.rosetta.test.model.Bar; + import com.rosetta.test.model.Foo; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + import java.util.Optional; + import java.util.stream.Collectors; + import javax.inject.Inject; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + @Inject protected ModelObjectValidator objectValidator; + + /** + * @param bars + * @return foos + */ + public List evaluate(List bars) { + List foosBuilder = doEvaluate(bars); + + final List foos; + if (foosBuilder == null) { + foos = null; + } else { + foos = foosBuilder.stream().map(Foo::build).collect(Collectors.toList()); + objectValidator.validate(Foo.class, foos); + } + return foos; + } + + protected abstract List doEvaluate(List bars); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List bars) { + if (bars == null) { + bars = Collections.emptyList(); + } + List foos = new ArrayList<>(); + return assignOutput(foos, bars); + } + + protected List assignOutput(List foos, List bars) { + final MapperListOfLists thenArg = MapperC.of(bars) + .mapItemToList(bar -> bar.mapC("getFoos", _bar -> _bar.getFoos())); + foos = toBuilder(thenArg + .flattenList().getMulti()); + return Optional.ofNullable(foos) + .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) + .orElse(null); + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); @@ -1732,57 +1714,55 @@ attrs string (0..*) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.mapper.MapperListOfLists; - import com.rosetta.test.model.Bar; - import com.rosetta.test.model.Foo; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param bars\s - * @return attrs\s - */ - public List evaluate(List bars) { - List attrs = doEvaluate(bars); - \t\t - return attrs; - } - - protected abstract List doEvaluate(List bars); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List bars) { - if (bars == null) { - bars = Collections.emptyList(); - } - List attrs = new ArrayList<>(); - return assignOutput(attrs, bars); - } - \t\t - protected List assignOutput(List attrs, List bars) { - final MapperListOfLists thenArg0 = MapperC.of(bars) - .mapItemToList(item -> item.mapC("getFoos", bar -> bar.getFoos())); - final MapperC thenArg1 = thenArg0 - .flattenList(); - attrs = thenArg1 - .mapItem(item -> item.map("getAttr", foo -> foo.getAttr())).getMulti(); - \t\t\t - return attrs; - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.mapper.MapperListOfLists; + import com.rosetta.test.model.Bar; + import com.rosetta.test.model.Foo; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param bars + * @return attrs + */ + public List evaluate(List bars) { + List attrs = doEvaluate(bars); + return attrs; + } + + protected abstract List doEvaluate(List bars); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List bars) { + if (bars == null) { + bars = Collections.emptyList(); + } + List attrs = new ArrayList<>(); + return assignOutput(attrs, bars); + } + + protected List assignOutput(List attrs, List bars) { + final MapperListOfLists thenArg0 = MapperC.of(bars) + .mapItemToList(item -> item.mapC("getFoos", bar -> bar.getFoos())); + final MapperC thenArg1 = thenArg0 + .flattenList(); + attrs = thenArg1 + .mapItem(item -> item.map("getAttr", foo -> foo.getAttr())).getMulti(); + return attrs; + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); @@ -1917,79 +1897,77 @@ foo Foo (0..1) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.MapperMaths; - import com.rosetta.model.lib.functions.ModelObjectValidator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.mapper.MapperListOfLists; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.test.model.Bar; - import com.rosetta.test.model.Foo; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - import java.util.Optional; - import java.util.stream.Collectors; - import javax.inject.Inject; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - \t - // RosettaFunction dependencies - // - @Inject protected NewBar newBar; - @Inject protected NewFoo newFoo; - - /** - * @param bars\s - * @return updatedBars\s - */ - public List evaluate(List bars) { - List updatedBarsBuilder = doEvaluate(bars); - \t\t - final List updatedBars; - if (updatedBarsBuilder == null) { - updatedBars = null; - } else { - updatedBars = updatedBarsBuilder.stream().map(Bar::build).collect(Collectors.toList()); - objectValidator.validate(Bar.class, updatedBars); - } - \t\t - return updatedBars; - } - - protected abstract List doEvaluate(List bars); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List bars) { - if (bars == null) { - bars = Collections.emptyList(); - } - List updatedBars = new ArrayList<>(); - return assignOutput(updatedBars, bars); - } - \t\t - protected List assignOutput(List updatedBars, List bars) { - final MapperListOfLists thenArg = MapperC.of(bars) - .mapItemToList(bar -> bar.mapC("getFoos", _bar -> _bar.getFoos()) - .mapItem(foo -> MapperS.of(newFoo.evaluate(MapperMaths.add(foo.map("getAttr", _foo -> _foo.getAttr()), MapperS.of("_bar")).get())))); - updatedBars = toBuilder(thenArg - .mapListToItem(updatedFoos -> MapperS.of(newBar.evaluate(updatedFoos.getMulti()))).getMulti()); - \t\t\t - return Optional.ofNullable(updatedBars) - .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) - .orElse(null); - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.MapperMaths; + import com.rosetta.model.lib.functions.ModelObjectValidator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.mapper.MapperListOfLists; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.test.model.Bar; + import com.rosetta.test.model.Foo; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + import java.util.Optional; + import java.util.stream.Collectors; + import javax.inject.Inject; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + @Inject protected ModelObjectValidator objectValidator; + + // RosettaFunction dependencies + // + @Inject protected NewBar newBar; + @Inject protected NewFoo newFoo; + + /** + * @param bars + * @return updatedBars + */ + public List evaluate(List bars) { + List updatedBarsBuilder = doEvaluate(bars); + + final List updatedBars; + if (updatedBarsBuilder == null) { + updatedBars = null; + } else { + updatedBars = updatedBarsBuilder.stream().map(Bar::build).collect(Collectors.toList()); + objectValidator.validate(Bar.class, updatedBars); + } + return updatedBars; + } + + protected abstract List doEvaluate(List bars); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List bars) { + if (bars == null) { + bars = Collections.emptyList(); + } + List updatedBars = new ArrayList<>(); + return assignOutput(updatedBars, bars); + } + + protected List assignOutput(List updatedBars, List bars) { + final MapperListOfLists thenArg = MapperC.of(bars) + .mapItemToList(bar -> bar.mapC("getFoos", _bar -> _bar.getFoos()) + .mapItem(foo -> MapperS.of(newFoo.evaluate(MapperMaths.add(foo.map("getAttr", _foo -> _foo.getAttr()), MapperS.of("_bar")).get())))); + updatedBars = toBuilder(thenArg + .mapListToItem(updatedFoos -> MapperS.of(newBar.evaluate(updatedFoos.getMulti()))).getMulti()); + return Optional.ofNullable(updatedBars) + .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) + .orElse(null); + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); @@ -2058,76 +2036,74 @@ foo Foo (0..1) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.MapperMaths; - import com.rosetta.model.lib.functions.ModelObjectValidator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.test.model.Bar; - import com.rosetta.test.model.Foo; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - import java.util.Optional; - import java.util.stream.Collectors; - import javax.inject.Inject; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - \t - // RosettaFunction dependencies - // - @Inject protected NewBar newBar; - @Inject protected NewFoo newFoo; - - /** - * @param bars\s - * @return updatedBars\s - */ - public List evaluate(List bars) { - List updatedBarsBuilder = doEvaluate(bars); - \t\t - final List updatedBars; - if (updatedBarsBuilder == null) { - updatedBars = null; - } else { - updatedBars = updatedBarsBuilder.stream().map(Bar::build).collect(Collectors.toList()); - objectValidator.validate(Bar.class, updatedBars); - } - \t\t - return updatedBars; - } - - protected abstract List doEvaluate(List bars); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List bars) { - if (bars == null) { - bars = Collections.emptyList(); - } - List updatedBars = new ArrayList<>(); - return assignOutput(updatedBars, bars); - } - \t\t - protected List assignOutput(List updatedBars, List bars) { - updatedBars = toBuilder(MapperC.of(bars) - .mapItem(bar -> MapperS.of(newBar.evaluate(bar.mapC("getFoos", _bar -> _bar.getFoos()) - .mapItem(foo -> MapperS.of(newFoo.evaluate(MapperMaths.add(foo.map("getAttr", _foo -> _foo.getAttr()), MapperS.of("_bar")).get()))).getMulti()))).getMulti()); - \t\t\t - return Optional.ofNullable(updatedBars) - .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) - .orElse(null); - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.MapperMaths; + import com.rosetta.model.lib.functions.ModelObjectValidator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.test.model.Bar; + import com.rosetta.test.model.Foo; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + import java.util.Optional; + import java.util.stream.Collectors; + import javax.inject.Inject; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + @Inject protected ModelObjectValidator objectValidator; + + // RosettaFunction dependencies + // + @Inject protected NewBar newBar; + @Inject protected NewFoo newFoo; + + /** + * @param bars + * @return updatedBars + */ + public List evaluate(List bars) { + List updatedBarsBuilder = doEvaluate(bars); + + final List updatedBars; + if (updatedBarsBuilder == null) { + updatedBars = null; + } else { + updatedBars = updatedBarsBuilder.stream().map(Bar::build).collect(Collectors.toList()); + objectValidator.validate(Bar.class, updatedBars); + } + return updatedBars; + } + + protected abstract List doEvaluate(List bars); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List bars) { + if (bars == null) { + bars = Collections.emptyList(); + } + List updatedBars = new ArrayList<>(); + return assignOutput(updatedBars, bars); + } + + protected List assignOutput(List updatedBars, List bars) { + updatedBars = toBuilder(MapperC.of(bars) + .mapItem(bar -> MapperS.of(newBar.evaluate(bar.mapC("getFoos", _bar -> _bar.getFoos()) + .mapItem(foo -> MapperS.of(newFoo.evaluate(MapperMaths.add(foo.map("getAttr", _foo -> _foo.getAttr()), MapperS.of("_bar")).get()))).getMulti()))).getMulti()); + return Optional.ofNullable(updatedBars) + .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) + .orElse(null); + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); @@ -2223,56 +2199,54 @@ foos Foo (0..*) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.CardinalityOperator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.test.model.Foo; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param foos\s - * @return newFoos\s - */ - public List evaluate(List foos) { - List newFoos = doEvaluate(foos); - \t\t - return newFoos; - } - - protected abstract List doEvaluate(List foos); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List foos) { - if (foos == null) { - foos = Collections.emptyList(); - } - List newFoos = new ArrayList<>(); - return assignOutput(newFoos, foos); - } - \t\t - protected List assignOutput(List newFoos, List foos) { - final MapperC thenArg = MapperC.of(foos) - .filterItemNullSafe(item -> areEqual(item.map("getInclude", foo -> foo.getInclude()), MapperS.of(true), CardinalityOperator.All).get()); - newFoos = thenArg - .mapItem(item -> item.map("getAttr", foo -> foo.getAttr())).getMulti(); - \t\t\t - return newFoos; - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.CardinalityOperator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.test.model.Foo; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param foos + * @return newFoos + */ + public List evaluate(List foos) { + List newFoos = doEvaluate(foos); + return newFoos; + } + + protected abstract List doEvaluate(List foos); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List foos) { + if (foos == null) { + foos = Collections.emptyList(); + } + List newFoos = new ArrayList<>(); + return assignOutput(newFoos, foos); + } + + protected List assignOutput(List newFoos, List foos) { + final MapperC thenArg = MapperC.of(foos) + .filterItemNullSafe(item -> areEqual(item.map("getInclude", foo -> foo.getInclude()), MapperS.of(true), CardinalityOperator.All).get()); + newFoos = thenArg + .mapItem(item -> item.map("getAttr", foo -> foo.getAttr())).getMulti(); + return newFoos; + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); @@ -2321,60 +2295,58 @@ strings string (0..*) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("ns1.functions.FuncFoo"); assertEquals(""" - package ns1.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.mapper.MapperS; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - import javax.inject.Inject; - import ns1.Bar; - import ns1.Foo; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - \t - // RosettaFunction dependencies - // - @Inject protected GetFoo getFoo; - - /** - * @param bars\s - * @return strings\s - */ - public List evaluate(List bars) { - List strings = doEvaluate(bars); - \t\t - return strings; - } - - protected abstract List doEvaluate(List bars); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List bars) { - if (bars == null) { - bars = Collections.emptyList(); - } - List strings = new ArrayList<>(); - return assignOutput(strings, bars); - } - \t\t - protected List assignOutput(List strings, List bars) { - final MapperC thenArg = MapperC.of(bars) - .mapItem(item -> MapperS.of(getFoo.evaluate(item.map("getBarAttr", bar -> bar.getBarAttr()).get()))); - strings = thenArg - .mapItem(item -> item.map("getFooAttr", foo -> foo.getFooAttr())).getMulti(); - \t\t\t - return strings; - } - } - } - """, f); + package ns1.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.mapper.MapperS; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + import javax.inject.Inject; + import ns1.Bar; + import ns1.Foo; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + // RosettaFunction dependencies + // + @Inject protected GetFoo getFoo; + + /** + * @param bars + * @return strings + */ + public List evaluate(List bars) { + List strings = doEvaluate(bars); + return strings; + } + + protected abstract List doEvaluate(List bars); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List bars) { + if (bars == null) { + bars = Collections.emptyList(); + } + List strings = new ArrayList<>(); + return assignOutput(strings, bars); + } + + protected List assignOutput(List strings, List bars) { + final MapperC thenArg = MapperC.of(bars) + .mapItem(item -> MapperS.of(getFoo.evaluate(item.map("getBarAttr", bar -> bar.getBarAttr()).get()))); + strings = thenArg + .mapItem(item -> item.map("getFooAttr", foo -> foo.getFooAttr())).getMulti(); + return strings; + } + } + } + """, f); codeGeneratorTestHelper.compileToClasses(code); } @@ -2409,57 +2381,55 @@ strings string (0..*) var code = codeGeneratorTestHelper.generateCode(model0, model1); String f = code.get("ns2.functions.FuncFoo"); assertEquals(""" - package ns2.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.mapper.MapperListOfLists; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - import ns1.Bar; - import ns1.Foo; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param bars\s - * @return strings\s - */ - public List evaluate(List bars) { - List strings = doEvaluate(bars); - \t\t - return strings; - } - - protected abstract List doEvaluate(List bars); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List bars) { - if (bars == null) { - bars = Collections.emptyList(); - } - List strings = new ArrayList<>(); - return assignOutput(strings, bars); - } - \t\t - protected List assignOutput(List strings, List bars) { - final MapperListOfLists thenArg0 = MapperC.of(bars) - .mapItemToList(item -> item.mapC("getFoos", bar -> bar.getFoos())); - final MapperC thenArg1 = thenArg0 - .flattenList(); - strings = thenArg1 - .mapItem(item -> item.map("getAttr", foo -> foo.getAttr())).getMulti(); - \t\t\t - return strings; - } - } - } - """, f); + package ns2.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.mapper.MapperListOfLists; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + import ns1.Bar; + import ns1.Foo; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param bars + * @return strings + */ + public List evaluate(List bars) { + List strings = doEvaluate(bars); + return strings; + } + + protected abstract List doEvaluate(List bars); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List bars) { + if (bars == null) { + bars = Collections.emptyList(); + } + List strings = new ArrayList<>(); + return assignOutput(strings, bars); + } + + protected List assignOutput(List strings, List bars) { + final MapperListOfLists thenArg0 = MapperC.of(bars) + .mapItemToList(item -> item.mapC("getFoos", bar -> bar.getFoos())); + final MapperC thenArg1 = thenArg0 + .flattenList(); + strings = thenArg1 + .mapItem(item -> item.map("getAttr", foo -> foo.getAttr())).getMulti(); + return strings; + } + } + } + """, f); codeGeneratorTestHelper.compileToClasses(code); } @@ -2499,61 +2469,59 @@ strings string (0..*) var code = codeGeneratorTestHelper.generateCode(model0, model1); String f = code.get("ns2.functions.FuncFoo"); assertEquals(""" - package ns2.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.mapper.MapperS; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - import javax.inject.Inject; - import ns1.Bar; - import ns1.Foo; - import ns1.functions.GetFoo; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - \t - // RosettaFunction dependencies - // - @Inject protected GetFoo getFoo; - - /** - * @param bars\s - * @return strings\s - */ - public List evaluate(List bars) { - List strings = doEvaluate(bars); - \t\t - return strings; - } - - protected abstract List doEvaluate(List bars); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List bars) { - if (bars == null) { - bars = Collections.emptyList(); - } - List strings = new ArrayList<>(); - return assignOutput(strings, bars); - } - \t\t - protected List assignOutput(List strings, List bars) { - final MapperC thenArg = MapperC.of(bars) - .mapItem(item -> MapperS.of(getFoo.evaluate(item.map("getBarAttr", bar -> bar.getBarAttr()).get()))); - strings = thenArg - .mapItem(item -> item.map("getFooAttr", foo -> foo.getFooAttr())).getMulti(); - \t\t\t - return strings; - } - } - } - """, f); + package ns2.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.mapper.MapperS; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + import javax.inject.Inject; + import ns1.Bar; + import ns1.Foo; + import ns1.functions.GetFoo; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + // RosettaFunction dependencies + // + @Inject protected GetFoo getFoo; + + /** + * @param bars + * @return strings + */ + public List evaluate(List bars) { + List strings = doEvaluate(bars); + return strings; + } + + protected abstract List doEvaluate(List bars); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List bars) { + if (bars == null) { + bars = Collections.emptyList(); + } + List strings = new ArrayList<>(); + return assignOutput(strings, bars); + } + + protected List assignOutput(List strings, List bars) { + final MapperC thenArg = MapperC.of(bars) + .mapItem(item -> MapperS.of(getFoo.evaluate(item.map("getBarAttr", bar -> bar.getBarAttr()).get()))); + strings = thenArg + .mapItem(item -> item.map("getFooAttr", foo -> foo.getFooAttr())).getMulti(); + return strings; + } + } + } + """, f); codeGeneratorTestHelper.compileToClasses(code); } @@ -2602,63 +2570,61 @@ strings string (0..*) var code = codeGeneratorTestHelper.generateCode(model0, model1); String f = code.get("ns2.functions.FuncFoo"); assertEquals(""" - package ns2.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.mapper.MapperS; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - import javax.inject.Inject; - import ns1.Bar; - import ns1.Foo; - import ns1.functions.GetBaz; - import ns1.functions.GetFoo; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - \t - // RosettaFunction dependencies - // - @Inject protected GetBaz getBaz; - @Inject protected GetFoo getFoo; - - /** - * @param bars\s - * @return strings\s - */ - public List evaluate(List bars) { - List strings = doEvaluate(bars); - \t\t - return strings; - } - - protected abstract List doEvaluate(List bars); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List bars) { - if (bars == null) { - bars = Collections.emptyList(); - } - List strings = new ArrayList<>(); - return assignOutput(strings, bars); - } - \t\t - protected List assignOutput(List strings, List bars) { - final MapperC thenArg = MapperC.of(bars) - .mapItem(item -> MapperS.of(getFoo.evaluate(getBaz.evaluate(item.map("getBarAttr", bar -> bar.getBarAttr()).get())))); - strings = thenArg - .mapItem(item -> item.map("getFooAttr", foo -> foo.getFooAttr())).getMulti(); - \t\t\t - return strings; - } - } - } - """, f); + package ns2.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.mapper.MapperS; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + import javax.inject.Inject; + import ns1.Bar; + import ns1.Foo; + import ns1.functions.GetBaz; + import ns1.functions.GetFoo; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + // RosettaFunction dependencies + // + @Inject protected GetBaz getBaz; + @Inject protected GetFoo getFoo; + + /** + * @param bars + * @return strings + */ + public List evaluate(List bars) { + List strings = doEvaluate(bars); + return strings; + } + + protected abstract List doEvaluate(List bars); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List bars) { + if (bars == null) { + bars = Collections.emptyList(); + } + List strings = new ArrayList<>(); + return assignOutput(strings, bars); + } + + protected List assignOutput(List strings, List bars) { + final MapperC thenArg = MapperC.of(bars) + .mapItem(item -> MapperS.of(getFoo.evaluate(getBaz.evaluate(item.map("getBarAttr", bar -> bar.getBarAttr()).get())))); + strings = thenArg + .mapItem(item -> item.map("getFooAttr", foo -> foo.getFooAttr())).getMulti(); + return strings; + } + } + } + """, f); codeGeneratorTestHelper.compileToClasses(code); } @@ -2687,66 +2653,64 @@ strings string (0..*) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.CardinalityOperator; - import com.rosetta.model.lib.expression.MapperMaths; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.test.model.Foo; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param foos\s - * @param test\s - * @return strings\s - */ - public List evaluate(List foos, String test) { - List strings = doEvaluate(foos, test); - \t\t - return strings; - } - - protected abstract List doEvaluate(List foos, String test); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List foos, String test) { - if (foos == null) { - foos = Collections.emptyList(); - } - List strings = new ArrayList<>(); - return assignOutput(strings, foos, test); - } - \t\t - protected List assignOutput(List strings, List foos, String test) { - if (areEqual(MapperS.of(test), MapperS.of("a"), CardinalityOperator.All).getOrDefault(false)) { - strings = MapperC.of(foos) - .mapItem(item -> MapperMaths.add(item.map("getAttr", foo -> foo.getAttr()), MapperS.of("_a"))).getMulti(); - } else if (areEqual(MapperS.of(test), MapperS.of("b"), CardinalityOperator.All).getOrDefault(false)) { - strings = MapperC.of(foos) - .mapItem(item -> MapperMaths.add(item.map("getAttr", foo -> foo.getAttr()), MapperS.of("_b"))).getMulti(); - } else if (areEqual(MapperS.of(test), MapperS.of("c"), CardinalityOperator.All).getOrDefault(false)) { - strings = MapperC.of(foos) - .mapItem(item -> MapperMaths.add(item.map("getAttr", foo -> foo.getAttr()), MapperS.of("_c"))).getMulti(); - } else { - strings = Collections.emptyList(); - } - \t\t\t - return strings; - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.CardinalityOperator; + import com.rosetta.model.lib.expression.MapperMaths; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.test.model.Foo; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param foos + * @param test + * @return strings + */ + public List evaluate(List foos, String test) { + List strings = doEvaluate(foos, test); + return strings; + } + + protected abstract List doEvaluate(List foos, String test); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List foos, String test) { + if (foos == null) { + foos = Collections.emptyList(); + } + List strings = new ArrayList<>(); + return assignOutput(strings, foos, test); + } + + protected List assignOutput(List strings, List foos, String test) { + if (areEqual(MapperS.of(test), MapperS.of("a"), CardinalityOperator.All).getOrDefault(false)) { + strings = MapperC.of(foos) + .mapItem(item -> MapperMaths.add(item.map("getAttr", foo -> foo.getAttr()), MapperS.of("_a"))).getMulti(); + } else if (areEqual(MapperS.of(test), MapperS.of("b"), CardinalityOperator.All).getOrDefault(false)) { + strings = MapperC.of(foos) + .mapItem(item -> MapperMaths.add(item.map("getAttr", foo -> foo.getAttr()), MapperS.of("_b"))).getMulti(); + } else if (areEqual(MapperS.of(test), MapperS.of("c"), CardinalityOperator.All).getOrDefault(false)) { + strings = MapperC.of(foos) + .mapItem(item -> MapperMaths.add(item.map("getAttr", foo -> foo.getAttr()), MapperS.of("_c"))).getMulti(); + } else { + strings = Collections.emptyList(); + } + return strings; + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); @@ -2836,50 +2800,48 @@ concatenatedString string (1..1) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.MapperMaths; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import java.util.Collections; - import java.util.List; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param stringList\s - * @return concatenatedString\s - */ - public String evaluate(List stringList) { - String concatenatedString = doEvaluate(stringList); - \t\t - return concatenatedString; - } - - protected abstract String doEvaluate(List stringList); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected String doEvaluate(List stringList) { - if (stringList == null) { - stringList = Collections.emptyList(); - } - String concatenatedString = null; - return assignOutput(concatenatedString, stringList); - } - \t\t - protected String assignOutput(String concatenatedString, List stringList) { - concatenatedString = MapperC.of(stringList) - .reduce((a, b) -> MapperMaths.add(a, b)).get(); - \t\t\t - return concatenatedString; - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.MapperMaths; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import java.util.Collections; + import java.util.List; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param stringList + * @return concatenatedString + */ + public String evaluate(List stringList) { + String concatenatedString = doEvaluate(stringList); + return concatenatedString; + } + + protected abstract String doEvaluate(List stringList); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected String doEvaluate(List stringList) { + if (stringList == null) { + stringList = Collections.emptyList(); + } + String concatenatedString = null; + return assignOutput(concatenatedString, stringList); + } + + protected String assignOutput(String concatenatedString, List stringList) { + concatenatedString = MapperC.of(stringList) + .reduce((a, b) -> MapperMaths.add(a, b)).get(); + return concatenatedString; + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); @@ -3310,71 +3272,69 @@ foo Foo (1..1) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.MapperMaths; - import com.rosetta.model.lib.functions.ModelObjectValidator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.test.model.Foo; - import java.util.Collections; - import java.util.List; - import java.util.Optional; - import javax.inject.Inject; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - \t - // RosettaFunction dependencies - // - @Inject protected Create_Foo create_Foo; - - /** - * @param foos\s - * @return foo\s - */ - public Foo evaluate(List foos) { - Foo.FooBuilder fooBuilder = doEvaluate(foos); - \t\t - final Foo foo; - if (fooBuilder == null) { - foo = null; - } else { - foo = fooBuilder.build(); - objectValidator.validate(Foo.class, foo); - } - \t\t - return foo; - } - - protected abstract Foo.FooBuilder doEvaluate(List foos); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected Foo.FooBuilder doEvaluate(List foos) { - if (foos == null) { - foos = Collections.emptyList(); - } - Foo.FooBuilder foo = Foo.builder(); - return assignOutput(foo, foos); - } - \t\t - protected Foo.FooBuilder assignOutput(Foo.FooBuilder foo, List foos) { - foo = toBuilder(MapperC.of(foos) - .reduce((foo1, foo2) -> MapperS.of(create_Foo.evaluate(MapperMaths.add(foo1.map("getAttr", _foo -> _foo.getAttr()), foo2.map("getAttr", _foo -> _foo.getAttr())).get()))).get()); - \t\t\t - return Optional.ofNullable(foo) - .map(o -> o.prune()) - .orElse(null); - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.MapperMaths; + import com.rosetta.model.lib.functions.ModelObjectValidator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.test.model.Foo; + import java.util.Collections; + import java.util.List; + import java.util.Optional; + import javax.inject.Inject; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + @Inject protected ModelObjectValidator objectValidator; + + // RosettaFunction dependencies + // + @Inject protected Create_Foo create_Foo; + + /** + * @param foos + * @return foo + */ + public Foo evaluate(List foos) { + Foo.FooBuilder fooBuilder = doEvaluate(foos); + + final Foo foo; + if (fooBuilder == null) { + foo = null; + } else { + foo = fooBuilder.build(); + objectValidator.validate(Foo.class, foo); + } + return foo; + } + + protected abstract Foo.FooBuilder doEvaluate(List foos); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected Foo.FooBuilder doEvaluate(List foos) { + if (foos == null) { + foos = Collections.emptyList(); + } + Foo.FooBuilder foo = Foo.builder(); + return assignOutput(foo, foos); + } + + protected Foo.FooBuilder assignOutput(Foo.FooBuilder foo, List foos) { + foo = toBuilder(MapperC.of(foos) + .reduce((foo1, foo2) -> MapperS.of(create_Foo.evaluate(MapperMaths.add(foo1.map("getAttr", _foo -> _foo.getAttr()), foo2.map("getAttr", _foo -> _foo.getAttr())).get()))).get()); + return Optional.ofNullable(foo) + .map(o -> o.prune()) + .orElse(null); + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); @@ -3628,50 +3588,48 @@ sortedNumbers int (0..*) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param numbers\s - * @return sortedNumbers\s - */ - public List evaluate(List numbers) { - List sortedNumbers = doEvaluate(numbers); - \t\t - return sortedNumbers; - } - - protected abstract List doEvaluate(List numbers); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List numbers) { - if (numbers == null) { - numbers = Collections.emptyList(); - } - List sortedNumbers = new ArrayList<>(); - return assignOutput(sortedNumbers, numbers); - } - \t\t - protected List assignOutput(List sortedNumbers, List numbers) { - sortedNumbers = MapperC.of(numbers) - .sort().getMulti(); - \t\t\t - return sortedNumbers; - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param numbers + * @return sortedNumbers + */ + public List evaluate(List numbers) { + List sortedNumbers = doEvaluate(numbers); + return sortedNumbers; + } + + protected abstract List doEvaluate(List numbers); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List numbers) { + if (numbers == null) { + numbers = Collections.emptyList(); + } + List sortedNumbers = new ArrayList<>(); + return assignOutput(sortedNumbers, numbers); + } + + protected List assignOutput(List sortedNumbers, List numbers) { + sortedNumbers = MapperC.of(numbers) + .sort().getMulti(); + return sortedNumbers; + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); @@ -3747,67 +3705,65 @@ sortedFoos Foo (0..*) var code = codeGeneratorTestHelper.generateCode(model); String f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals(""" - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.ModelObjectValidator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.test.model.Foo; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - import java.util.Optional; - import java.util.stream.Collectors; - import javax.inject.Inject; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - - /** - * @param foos\s - * @return sortedFoos\s - */ - public List evaluate(List foos) { - List sortedFoosBuilder = doEvaluate(foos); - \t\t - final List sortedFoos; - if (sortedFoosBuilder == null) { - sortedFoos = null; - } else { - sortedFoos = sortedFoosBuilder.stream().map(Foo::build).collect(Collectors.toList()); - objectValidator.validate(Foo.class, sortedFoos); - } - \t\t - return sortedFoos; - } - - protected abstract List doEvaluate(List foos); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(List foos) { - if (foos == null) { - foos = Collections.emptyList(); - } - List sortedFoos = new ArrayList<>(); - return assignOutput(sortedFoos, foos); - } - \t\t - protected List assignOutput(List sortedFoos, List foos) { - sortedFoos = toBuilder(MapperC.of(foos) - .sort(item -> item.map("getAttr", foo -> foo.getAttr())).getMulti()); - \t\t\t - return Optional.ofNullable(sortedFoos) - .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) - .orElse(null); - } - } - } - """, f); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.ModelObjectValidator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.test.model.Foo; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + import java.util.Optional; + import java.util.stream.Collectors; + import javax.inject.Inject; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + @Inject protected ModelObjectValidator objectValidator; + + /** + * @param foos + * @return sortedFoos + */ + public List evaluate(List foos) { + List sortedFoosBuilder = doEvaluate(foos); + + final List sortedFoos; + if (sortedFoosBuilder == null) { + sortedFoos = null; + } else { + sortedFoos = sortedFoosBuilder.stream().map(Foo::build).collect(Collectors.toList()); + objectValidator.validate(Foo.class, sortedFoos); + } + return sortedFoos; + } + + protected abstract List doEvaluate(List foos); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(List foos) { + if (foos == null) { + foos = Collections.emptyList(); + } + List sortedFoos = new ArrayList<>(); + return assignOutput(sortedFoos, foos); + } + + protected List assignOutput(List sortedFoos, List foos) { + sortedFoos = toBuilder(MapperC.of(foos) + .sort(item -> item.map("getAttr", foo -> foo.getAttr())).getMulti()); + return Optional.ofNullable(sortedFoos) + .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) + .orElse(null); + } + } + } + """, f); var classes = codeGeneratorTestHelper.compileToClasses(code); var func = functionGeneratorHelper.createFunc(classes, "FuncFoo"); diff --git a/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/expression/RosettaBinaryOperationTest.java b/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/expression/RosettaBinaryOperationTest.java index 922c9dc314..614271736e 100644 --- a/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/expression/RosettaBinaryOperationTest.java +++ b/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/expression/RosettaBinaryOperationTest.java @@ -362,49 +362,49 @@ attrNumber number (1..1) Map code = generatorTestHelper.generateCode(model); String funcFoo = code.get("com.rosetta.test.model.functions.FuncFoo"); String expected = """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.CardinalityOperator; - import com.rosetta.model.lib.expression.ComparisonResult; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.test.model.Foo; - import java.math.BigDecimal; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param foo\s - * @return result\s - */ - public Boolean evaluate(Foo foo) { - Boolean result = doEvaluate(foo); - \t\t - return result; - } - - protected abstract Boolean doEvaluate(Foo foo); - - public static class FuncFooDefault extends FuncFoo { - @Override - protected Boolean doEvaluate(Foo foo) { - Boolean result = null; - return assignOutput(result, foo); - } - \t\t - protected Boolean assignOutput(Boolean result, Foo foo) { - result = ComparisonResult.ofNullSafe(MapperS.of(foo).map("getAttrBoolean", _foo -> _foo.getAttrBoolean())).orNullSafe(areEqual(MapperS.of(foo).map("getAttrNumber", _foo -> _foo.getAttrNumber()), MapperS.of(BigDecimal.valueOf(5)), CardinalityOperator.All)).get(); - \t\t\t - return result; - } - } - } - """; - assertEquals(expected, funcFoo); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.CardinalityOperator; + import com.rosetta.model.lib.expression.ComparisonResult; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.test.model.Foo; + import java.math.BigDecimal; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param foo + * @return result + */ + public Boolean evaluate(Foo foo) { + Boolean result = doEvaluate(foo); + return result; + } + + protected abstract Boolean doEvaluate(Foo foo); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected Boolean doEvaluate(Foo foo) { + Boolean result = null; + return assignOutput(result, foo); + } + + protected Boolean assignOutput(Boolean result, Foo foo) { + result = ComparisonResult.ofNullSafe(MapperS.of(foo).map("getAttrBoolean", _foo -> _foo.getAttrBoolean())).orNullSafe(areEqual(MapperS.of(foo).map("getAttrNumber", _foo -> _foo.getAttrNumber()), MapperS.of(BigDecimal.valueOf(5)), CardinalityOperator.All)).get(); + return result; + } + } + } + """; + // Normalize line endings so the comparison holds on Windows, where the generator + // emits '\r\n' but the expected value is built with '\n'. + assertEquals(expected, funcFoo.replace("\r\n", "\n")); generatorTestHelper.compileToClasses(code); } diff --git a/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/function/CalculationFunctionGeneratorTest.xtend b/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/function/CalculationFunctionGeneratorTest.xtend index 6b01c98294..eecc50dcdd 100644 --- a/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/function/CalculationFunctionGeneratorTest.xtend +++ b/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/function/CalculationFunctionGeneratorTest.xtend @@ -70,56 +70,53 @@ class CalculationFunctionGeneratorTest { * @version test */ public class PeriodEnumFunc implements RosettaFunction { - - @Inject protected PeriodEnumFunc.PeriodEnumFuncMONTH periodEnumFuncMONTH; - - public BigDecimal evaluate(PeriodEnum in1, Period in2) { - switch (in1) { - case MONTH: - return periodEnumFuncMONTH.evaluate(in1, in2); - default: - throw new IllegalArgumentException("Enum value not implemented: " + in1); - } - } - - @ImplementedBy(PeriodEnumFunc.PeriodEnumFuncMONTH.PeriodEnumFuncMONTHDefault.class) - public static abstract class PeriodEnumFuncMONTH implements RosettaFunction { - - /** - * @param in1 - * @param in2 - * @return out - */ - public BigDecimal evaluate(PeriodEnum in1, Period in2) { - BigDecimal out = doEvaluate(in1, in2); - - return out; - } - - protected abstract BigDecimal doEvaluate(PeriodEnum in1, Period in2); - - protected abstract MapperS i(PeriodEnum in1, Period in2); - - public static class PeriodEnumFuncMONTHDefault extends PeriodEnumFunc.PeriodEnumFuncMONTH { - @Override - protected BigDecimal doEvaluate(PeriodEnum in1, Period in2) { - BigDecimal out = null; - return assignOutput(out, in1, in2); - } - - protected BigDecimal assignOutput(BigDecimal out, PeriodEnum in1, Period in2) { - out = MapperMaths.multiply(i(in1, in2).map("Type coercion", integer -> integer == null ? null : BigDecimal.valueOf(integer)), MapperS.of(new BigDecimal("30.0"))).get(); - - return out; - } - - @Override - protected MapperS i(PeriodEnum in1, Period in2) { - return MapperS.of(in2).map("getFrequency", period -> period.getFrequency()); - } - } - } - } + + @Inject protected PeriodEnumFunc.PeriodEnumFuncMONTH periodEnumFuncMONTH; + + public BigDecimal evaluate(PeriodEnum in1, Period in2) { + switch (in1) { + case MONTH: + return periodEnumFuncMONTH.evaluate(in1, in2); + default: + throw new IllegalArgumentException("Enum value not implemented: " + in1); + } + } + + @ImplementedBy(PeriodEnumFunc.PeriodEnumFuncMONTH.PeriodEnumFuncMONTHDefault.class) + public static abstract class PeriodEnumFuncMONTH implements RosettaFunction { + + /** + * @param in1 + * @param in2 + * @return out + */ + public BigDecimal evaluate(PeriodEnum in1, Period in2) { + BigDecimal out = doEvaluate(in1, in2); + return out; + } + + protected abstract BigDecimal doEvaluate(PeriodEnum in1, Period in2); + + protected abstract MapperS i(PeriodEnum in1, Period in2); + + public static class PeriodEnumFuncMONTHDefault extends PeriodEnumFunc.PeriodEnumFuncMONTH { + @Override + protected BigDecimal doEvaluate(PeriodEnum in1, Period in2) { + BigDecimal out = null; + return assignOutput(out, in1, in2); + } + + protected BigDecimal assignOutput(BigDecimal out, PeriodEnum in1, Period in2) { + out = MapperMaths.multiply(i(in1, in2).map("Type coercion", integer -> integer == null ? null : BigDecimal.valueOf(integer)), MapperS.of(new BigDecimal("30.0"))).get(); + return out; + } + + @Override + protected MapperS i(PeriodEnum in1, Period in2) { + return MapperS.of(in2).map("getFrequency", period -> period.getFrequency()); + } + } + }} '''.toString.lf, generated ) @@ -150,38 +147,36 @@ class CalculationFunctionGeneratorTest { @ImplementedBy(Calc.CalcDefault.class) public abstract class Calc implements RosettaFunction { - /** - * @param one - * @return out - */ - public Integer evaluate(Integer one) { - Integer out = doEvaluate(one); - - return out; - } - - protected abstract Integer doEvaluate(Integer one); - - protected abstract MapperS oneA(Integer one); - - public static class CalcDefault extends Calc { - @Override - protected Integer doEvaluate(Integer one) { - Integer out = null; - return assignOutput(out, one); - } - - protected Integer assignOutput(Integer out, Integer one) { - out = MapperMaths.add(oneA(one), oneA(one)).get(); - - return out; - } - - @Override - protected MapperS oneA(Integer one) { - return MapperS.of(1); - } - } + /** + * @param one + * @return out + */ + public Integer evaluate(Integer one) { + Integer out = doEvaluate(one); + return out; + } + + protected abstract Integer doEvaluate(Integer one); + + protected abstract MapperS oneA(Integer one); + + public static class CalcDefault extends Calc { + @Override + protected Integer doEvaluate(Integer one) { + Integer out = null; + return assignOutput(out, one); + } + + protected Integer assignOutput(Integer out, Integer one) { + out = MapperMaths.add(oneA(one), oneA(one)).get(); + return out; + } + + @Override + protected MapperS oneA(Integer one) { + return MapperS.of(1); + } + } } ''' ) @@ -215,46 +210,44 @@ class CalculationFunctionGeneratorTest { @ImplementedBy(Calc.CalcDefault.class) public abstract class Calc implements RosettaFunction { - /** - * @param arg1 - * @param arg2 - * @return res - */ - public Integer evaluate(Integer arg1, Integer arg2) { - Integer res = doEvaluate(arg1, arg2); - - return res; - } - - protected abstract Integer doEvaluate(Integer arg1, Integer arg2); - - protected abstract MapperS a1(Integer arg1, Integer arg2); - - protected abstract MapperS a2(Integer arg1, Integer arg2); - - public static class CalcDefault extends Calc { - @Override - protected Integer doEvaluate(Integer arg1, Integer arg2) { - Integer res = null; - return assignOutput(res, arg1, arg2); - } - - protected Integer assignOutput(Integer res, Integer arg1, Integer arg2) { - res = MapperMaths.add(a1(arg1, arg2), MapperMaths.multiply(a2(arg1, arg2), MapperS.of(215))).get(); - - return res; - } - - @Override - protected MapperS a1(Integer arg1, Integer arg2) { - return MapperS.of(new Min().execute(1, 2)); - } - - @Override - protected MapperS a2(Integer arg1, Integer arg2) { - return MapperS.of(new Max().execute(1, 2)); - } - } + /** + * @param arg1 + * @param arg2 + * @return res + */ + public Integer evaluate(Integer arg1, Integer arg2) { + Integer res = doEvaluate(arg1, arg2); + return res; + } + + protected abstract Integer doEvaluate(Integer arg1, Integer arg2); + + protected abstract MapperS a1(Integer arg1, Integer arg2); + + protected abstract MapperS a2(Integer arg1, Integer arg2); + + public static class CalcDefault extends Calc { + @Override + protected Integer doEvaluate(Integer arg1, Integer arg2) { + Integer res = null; + return assignOutput(res, arg1, arg2); + } + + protected Integer assignOutput(Integer res, Integer arg1, Integer arg2) { + res = MapperMaths.add(a1(arg1, arg2), MapperMaths.multiply(a2(arg1, arg2), MapperS.of(215))).get(); + return res; + } + + @Override + protected MapperS a1(Integer arg1, Integer arg2) { + return MapperS.of(new Min().execute(1, 2)); + } + + @Override + protected MapperS a2(Integer arg1, Integer arg2) { + return MapperS.of(new Max().execute(1, 2)); + } + } } ''' ) @@ -302,62 +295,59 @@ class CalculationFunctionGeneratorTest { @ImplementedBy(Calc.CalcDefault.class) public abstract class Calc implements RosettaFunction { - - @Inject protected ModelObjectValidator objectValidator; - - /** - * @param funIn - * @return res - */ - public FoncOut evaluate(FuncIn funIn) { - FoncOut.FoncOutBuilder resBuilder = doEvaluate(funIn); - - final FoncOut res; - if (resBuilder == null) { - res = null; - } else { - res = resBuilder.build(); - objectValidator.validate(FoncOut.class, res); - } - - return res; - } - - protected abstract FoncOut.FoncOutBuilder doEvaluate(FuncIn funIn); - protected abstract MapperS arg1(FuncIn funIn); - - protected abstract MapperS arg2(FuncIn funIn); - - public static class CalcDefault extends Calc { - @Override - protected FoncOut.FoncOutBuilder doEvaluate(FuncIn funIn) { - FoncOut.FoncOutBuilder res = FoncOut.builder(); - return assignOutput(res, funIn); - } - - protected FoncOut.FoncOutBuilder assignOutput(FoncOut.FoncOutBuilder res, FuncIn funIn) { - res - .setRes1(MapperMaths.add(arg1(funIn), arg2(funIn)).get()); - - res - .setRes2(MapperMaths.add(arg1(funIn), arg2(funIn)).get()); - - return Optional.ofNullable(res) - .map(o -> o.prune()) - .orElse(null); - } - - @Override - protected MapperS arg1(FuncIn funIn) { - return MapperS.of(funIn).map("getVal1", funcIn -> funcIn.getVal1()); - } - - @Override - protected MapperS arg2(FuncIn funIn) { - return MapperS.of(funIn).map("getVal2", funcIn -> funcIn.getVal2()); - } - } + @Inject protected ModelObjectValidator objectValidator; + + /** + * @param funIn + * @return res + */ + public FoncOut evaluate(FuncIn funIn) { + FoncOut.FoncOutBuilder resBuilder = doEvaluate(funIn); + + final FoncOut res; + if (resBuilder == null) { + res = null; + } else { + res = resBuilder.build(); + objectValidator.validate(FoncOut.class, res); + } + return res; + } + + protected abstract FoncOut.FoncOutBuilder doEvaluate(FuncIn funIn); + + protected abstract MapperS arg1(FuncIn funIn); + + protected abstract MapperS arg2(FuncIn funIn); + + public static class CalcDefault extends Calc { + @Override + protected FoncOut.FoncOutBuilder doEvaluate(FuncIn funIn) { + FoncOut.FoncOutBuilder res = FoncOut.builder(); + return assignOutput(res, funIn); + } + + protected FoncOut.FoncOutBuilder assignOutput(FoncOut.FoncOutBuilder res, FuncIn funIn) { + res + .setRes1(MapperMaths.add(arg1(funIn), arg2(funIn)).get()); + res + .setRes2(MapperMaths.add(arg1(funIn), arg2(funIn)).get()); + return Optional.ofNullable(res) + .map(o -> o.prune()) + .orElse(null); + } + + @Override + protected MapperS arg1(FuncIn funIn) { + return MapperS.of(funIn).map("getVal1", funcIn -> funcIn.getVal1()); + } + + @Override + protected MapperS arg2(FuncIn funIn) { + return MapperS.of(funIn).map("getVal2", funcIn -> funcIn.getVal2()); + } + } } ''' assertEquals(expected.lf, calcJava) @@ -409,69 +399,66 @@ class CalculationFunctionGeneratorTest { @ImplementedBy(RTS_22_Fields.RTS_22_FieldsDefault.class) public abstract class RTS_22_Fields implements RosettaFunction { - - @Inject protected ModelObjectValidator objectValidator; - - /** - * @param funcIn - * @return out - */ - public FuncOut evaluate(FuncIn funcIn) { - FuncOut.FuncOutBuilder outBuilder = doEvaluate(funcIn); - - final FuncOut out; - if (outBuilder == null) { - out = null; - } else { - out = outBuilder.build(); - objectValidator.validate(FuncOut.class, out); - } - - return out; - } - - protected abstract FuncOut.FuncOutBuilder doEvaluate(FuncIn funcIn); - - protected abstract MapperS linkId(FuncIn funcIn); - - protected abstract MapperS tradeDate(FuncIn funcIn); - protected abstract MapperS tradeTime(FuncIn funcIn); - - public static class RTS_22_FieldsDefault extends RTS_22_Fields { - @Override - protected FuncOut.FuncOutBuilder doEvaluate(FuncIn funcIn) { - FuncOut.FuncOutBuilder out = FuncOut.builder(); - return assignOutput(out, funcIn); - } - - protected FuncOut.FuncOutBuilder assignOutput(FuncOut.FuncOutBuilder out, FuncIn funcIn) { - out - .setTransactionReferenceNumber(MapperMaths.add(MapperS.of("SPH"), linkId(funcIn)).get()); - - out - .setTradingDateTime(MapperMaths.add(tradeDate(funcIn), tradeTime(funcIn)).get()); - - return Optional.ofNullable(out) - .map(o -> o.prune()) - .orElse(null); - } - - @Override - protected MapperS linkId(FuncIn funcIn) { - return MapperS.of(funcIn).map("getValS", _funcIn -> _funcIn.getValS()); - } - - @Override - protected MapperS tradeDate(FuncIn funcIn) { - return MapperS.of(funcIn).map("getVal1", _funcIn -> _funcIn.getVal1()); - } - - @Override - protected MapperS tradeTime(FuncIn funcIn) { - return MapperS.of(funcIn).map("getVal2", _funcIn -> _funcIn.getVal2()); - } - } + @Inject protected ModelObjectValidator objectValidator; + + /** + * @param funcIn + * @return out + */ + public FuncOut evaluate(FuncIn funcIn) { + FuncOut.FuncOutBuilder outBuilder = doEvaluate(funcIn); + + final FuncOut out; + if (outBuilder == null) { + out = null; + } else { + out = outBuilder.build(); + objectValidator.validate(FuncOut.class, out); + } + return out; + } + + protected abstract FuncOut.FuncOutBuilder doEvaluate(FuncIn funcIn); + + protected abstract MapperS linkId(FuncIn funcIn); + + protected abstract MapperS tradeDate(FuncIn funcIn); + + protected abstract MapperS tradeTime(FuncIn funcIn); + + public static class RTS_22_FieldsDefault extends RTS_22_Fields { + @Override + protected FuncOut.FuncOutBuilder doEvaluate(FuncIn funcIn) { + FuncOut.FuncOutBuilder out = FuncOut.builder(); + return assignOutput(out, funcIn); + } + + protected FuncOut.FuncOutBuilder assignOutput(FuncOut.FuncOutBuilder out, FuncIn funcIn) { + out + .setTransactionReferenceNumber(MapperMaths.add(MapperS.of("SPH"), linkId(funcIn)).get()); + out + .setTradingDateTime(MapperMaths.add(tradeDate(funcIn), tradeTime(funcIn)).get()); + return Optional.ofNullable(out) + .map(o -> o.prune()) + .orElse(null); + } + + @Override + protected MapperS linkId(FuncIn funcIn) { + return MapperS.of(funcIn).map("getValS", _funcIn -> _funcIn.getValS()); + } + + @Override + protected MapperS tradeDate(FuncIn funcIn) { + return MapperS.of(funcIn).map("getVal1", _funcIn -> _funcIn.getVal1()); + } + + @Override + protected MapperS tradeTime(FuncIn funcIn) { + return MapperS.of(funcIn).map("getVal2", _funcIn -> _funcIn.getVal2()); + } + } } ''' assertEquals(expected.lf, calcJava) @@ -516,69 +503,64 @@ class CalculationFunctionGeneratorTest { @ImplementedBy(asKeyUsage.asKeyUsageDefault.class) public abstract class asKeyUsage implements RosettaFunction { - - @Inject protected ModelObjectValidator objectValidator; - /** - * @param withMeta - * @return out - */ - public OtherType evaluate(List withMeta) { - OtherType.OtherTypeBuilder outBuilder = doEvaluate(withMeta); - - final OtherType out; - if (outBuilder == null) { - out = null; - } else { - out = outBuilder.build(); - objectValidator.validate(OtherType.class, out); - } - - return out; - } + @Inject protected ModelObjectValidator objectValidator; - protected abstract OtherType.OtherTypeBuilder doEvaluate(List withMeta); + /** + * @param withMeta + * @return out + */ + public OtherType evaluate(List withMeta) { + OtherType.OtherTypeBuilder outBuilder = doEvaluate(withMeta); - public static class asKeyUsageDefault extends asKeyUsage { - @Override - protected OtherType.OtherTypeBuilder doEvaluate(List withMeta) { - if (withMeta == null) { - withMeta = Collections.emptyList(); - } - OtherType.OtherTypeBuilder out = OtherType.builder(); - return assignOutput(out, withMeta); - } - - protected OtherType.OtherTypeBuilder assignOutput(OtherType.OtherTypeBuilder out, List withMeta) { - out - .addAttrMulti(MapperC.of(withMeta) - .getItems() - .map(item -> ReferenceWithMetaWithMeta.builder() - .setExternalReference(item.getMappedObject().getMeta().getExternalKey()) - .setGlobalReference(item.getMappedObject().getMeta().getGlobalKey()) - .build()) - .collect(Collectors.toList()) - ); - - final WithMeta outAttrSingle = MapperC.of(withMeta).get(); - out - .setAttrSingle(ReferenceWithMetaWithMeta.builder() - .setGlobalReference(Optional.ofNullable(outAttrSingle) - .map(r -> r.getMeta()) - .map(m -> m.getGlobalKey()) - .orElse(null)) - .setExternalReference(Optional.ofNullable(outAttrSingle) - .map(r -> r.getMeta()) - .map(m -> m.getExternalKey()) - .orElse(null)) - .build() - ); - - return Optional.ofNullable(out) - .map(o -> o.prune()) - .orElse(null); - } - } + final OtherType out; + if (outBuilder == null) { + out = null; + } else { + out = outBuilder.build(); + objectValidator.validate(OtherType.class, out); + } + return out; + } + + protected abstract OtherType.OtherTypeBuilder doEvaluate(List withMeta); + + public static class asKeyUsageDefault extends asKeyUsage { + @Override + protected OtherType.OtherTypeBuilder doEvaluate(List withMeta) { + if (withMeta == null) { + withMeta = Collections.emptyList(); + } + OtherType.OtherTypeBuilder out = OtherType.builder(); + return assignOutput(out, withMeta); + } + + protected OtherType.OtherTypeBuilder assignOutput(OtherType.OtherTypeBuilder out, List withMeta) { + out + .addAttrMulti(MapperC.of(withMeta) + .getItems() + .map(item -> ReferenceWithMetaWithMeta.builder() + .setExternalReference(item.getMappedObject().getMeta().getExternalKey()) + .setGlobalReference(item.getMappedObject().getMeta().getGlobalKey()) + .build()) + .collect(Collectors.toList())); + final WithMeta outAttrSingle = MapperC.of(withMeta).get(); + out + .setAttrSingle(ReferenceWithMetaWithMeta.builder() + .setGlobalReference(Optional.ofNullable(outAttrSingle) + .map(r -> r.getMeta()) + .map(m -> m.getGlobalKey()) + .orElse(null)) + .setExternalReference(Optional.ofNullable(outAttrSingle) + .map(r -> r.getMeta()) + .map(m -> m.getExternalKey()) + .orElse(null)) + .build()); + return Optional.ofNullable(out) + .map(o -> o.prune()) + .orElse(null); + } + } } ''' ) @@ -608,42 +590,40 @@ class CalculationFunctionGeneratorTest { @ImplementedBy(Adder.AdderDefault.class) public abstract class Adder implements RosettaFunction { - - // RosettaFunction dependencies - // - @Inject protected AddOne addOne; - - /** - * @return res - */ - public Integer evaluate() { - Integer res = doEvaluate(); - - return res; - } - - protected abstract Integer doEvaluate(); - protected abstract MapperS arg1(); - - public static class AdderDefault extends Adder { - @Override - protected Integer doEvaluate() { - Integer res = null; - return assignOutput(res); - } - - protected Integer assignOutput(Integer res) { - res = arg1().get(); - - return res; - } - - @Override - protected MapperS arg1() { - return MapperS.of(addOne.evaluate(1)); - } - } + // RosettaFunction dependencies + // + @Inject protected AddOne addOne; + + /** + * @return res + */ + public Integer evaluate() { + Integer res = doEvaluate(); + return res; + } + + protected abstract Integer doEvaluate(); + + protected abstract MapperS arg1(); + + public static class AdderDefault extends Adder { + @Override + protected Integer doEvaluate() { + Integer res = null; + return assignOutput(res); + } + + protected Integer assignOutput(Integer res) { + res = arg1().get(); + return res; + } + + @Override + protected MapperS arg1() { + return MapperS.of(addOne.evaluate(1)); + } + } } ''' ) @@ -699,90 +679,85 @@ class CalculationFunctionGeneratorTest { * @version test */ public class MathFunc implements RosettaFunction { - - @Inject protected MathFunc.MathFuncINCR mathFuncINCR; - @Inject protected MathFunc.MathFuncDECR mathFuncDECR; - - public String evaluate(com.rosetta.test.model.Math in1, MathInput in2) { - switch (in1) { - case INCR: - return mathFuncINCR.evaluate(in1, in2); - case DECR: - return mathFuncDECR.evaluate(in1, in2); - default: - throw new IllegalArgumentException("Enum value not implemented: " + in1); - } - } - - @ImplementedBy(MathFunc.MathFuncINCR.MathFuncINCRDefault.class) - public static abstract class MathFuncINCR implements RosettaFunction { - - // RosettaFunction dependencies - // - @Inject protected AddOne addOne; - - /** - * @param in1 - * @param in2 - * @return arg1 - */ - public String evaluate(com.rosetta.test.model.Math in1, MathInput in2) { - String arg1 = doEvaluate(in1, in2); - - return arg1; - } - - protected abstract String doEvaluate(com.rosetta.test.model.Math in1, MathInput in2); - - public static class MathFuncINCRDefault extends MathFunc.MathFuncINCR { - @Override - protected String doEvaluate(com.rosetta.test.model.Math in1, MathInput in2) { - String arg1 = null; - return assignOutput(arg1, in1, in2); - } - - protected String assignOutput(String arg1, com.rosetta.test.model.Math in1, MathInput in2) { - arg1 = addOne.evaluate(MapperS.of(in2).map("getMathInput", mathInput -> mathInput.getMathInput()).get()); - - return arg1; - } - } - } - @ImplementedBy(MathFunc.MathFuncDECR.MathFuncDECRDefault.class) - public static abstract class MathFuncDECR implements RosettaFunction { - - // RosettaFunction dependencies - // - @Inject protected SubOne subOne; - - /** - * @param in1 - * @param in2 - * @return arg1 - */ - public String evaluate(com.rosetta.test.model.Math in1, MathInput in2) { - String arg1 = doEvaluate(in1, in2); - - return arg1; - } - - protected abstract String doEvaluate(com.rosetta.test.model.Math in1, MathInput in2); - - public static class MathFuncDECRDefault extends MathFunc.MathFuncDECR { - @Override - protected String doEvaluate(com.rosetta.test.model.Math in1, MathInput in2) { - String arg1 = null; - return assignOutput(arg1, in1, in2); - } - - protected String assignOutput(String arg1, com.rosetta.test.model.Math in1, MathInput in2) { - arg1 = subOne.evaluate(MapperS.of(in2).map("getMathInput", mathInput -> mathInput.getMathInput()).get()); - - return arg1; - } - } - } - } + + @Inject protected MathFunc.MathFuncINCR mathFuncINCR; + @Inject protected MathFunc.MathFuncDECR mathFuncDECR; + + public String evaluate(com.rosetta.test.model.Math in1, MathInput in2) { + switch (in1) { + case INCR: + return mathFuncINCR.evaluate(in1, in2); + case DECR: + return mathFuncDECR.evaluate(in1, in2); + default: + throw new IllegalArgumentException("Enum value not implemented: " + in1); + } + } + + @ImplementedBy(MathFunc.MathFuncINCR.MathFuncINCRDefault.class) + public static abstract class MathFuncINCR implements RosettaFunction { + + // RosettaFunction dependencies + // + @Inject protected AddOne addOne; + + /** + * @param in1 + * @param in2 + * @return arg1 + */ + public String evaluate(com.rosetta.test.model.Math in1, MathInput in2) { + String arg1 = doEvaluate(in1, in2); + return arg1; + } + + protected abstract String doEvaluate(com.rosetta.test.model.Math in1, MathInput in2); + + public static class MathFuncINCRDefault extends MathFunc.MathFuncINCR { + @Override + protected String doEvaluate(com.rosetta.test.model.Math in1, MathInput in2) { + String arg1 = null; + return assignOutput(arg1, in1, in2); + } + + protected String assignOutput(String arg1, com.rosetta.test.model.Math in1, MathInput in2) { + arg1 = addOne.evaluate(MapperS.of(in2).map("getMathInput", mathInput -> mathInput.getMathInput()).get()); + return arg1; + } + } + } + @ImplementedBy(MathFunc.MathFuncDECR.MathFuncDECRDefault.class) + public static abstract class MathFuncDECR implements RosettaFunction { + + // RosettaFunction dependencies + // + @Inject protected SubOne subOne; + + /** + * @param in1 + * @param in2 + * @return arg1 + */ + public String evaluate(com.rosetta.test.model.Math in1, MathInput in2) { + String arg1 = doEvaluate(in1, in2); + return arg1; + } + + protected abstract String doEvaluate(com.rosetta.test.model.Math in1, MathInput in2); + + public static class MathFuncDECRDefault extends MathFunc.MathFuncDECR { + @Override + protected String doEvaluate(com.rosetta.test.model.Math in1, MathInput in2) { + String arg1 = null; + return assignOutput(arg1, in1, in2); + } + + protected String assignOutput(String arg1, com.rosetta.test.model.Math in1, MathInput in2) { + arg1 = subOne.evaluate(MapperS.of(in2).map("getMathInput", mathInput -> mathInput.getMathInput()).get()); + return arg1; + } + } + }} '''.toString.lf, generated) generatedCode.compileToClasses @@ -813,43 +788,41 @@ class CalculationFunctionGeneratorTest { @ImplementedBy(Adder.AdderDefault.class) public abstract class Adder implements RosettaFunction { - - // RosettaFunction dependencies - // - @Inject protected AddOne addOne; - - /** - * @param arg1 - * @return res - */ - public Integer evaluate(Integer arg1) { - Integer res = doEvaluate(arg1); - - return res; - } - - protected abstract Integer doEvaluate(Integer arg1); - - protected abstract MapperS addedOne(Integer arg1); - public static class AdderDefault extends Adder { - @Override - protected Integer doEvaluate(Integer arg1) { - Integer res = null; - return assignOutput(res, arg1); - } - - protected Integer assignOutput(Integer res, Integer arg1) { - res = addedOne(arg1).get(); - - return res; - } - - @Override - protected MapperS addedOne(Integer arg1) { - return MapperS.of(addOne.evaluate(1)); - } - } + // RosettaFunction dependencies + // + @Inject protected AddOne addOne; + + /** + * @param arg1 + * @return res + */ + public Integer evaluate(Integer arg1) { + Integer res = doEvaluate(arg1); + return res; + } + + protected abstract Integer doEvaluate(Integer arg1); + + protected abstract MapperS addedOne(Integer arg1); + + public static class AdderDefault extends Adder { + @Override + protected Integer doEvaluate(Integer arg1) { + Integer res = null; + return assignOutput(res, arg1); + } + + protected Integer assignOutput(Integer res, Integer arg1) { + res = addedOne(arg1).get(); + return res; + } + + @Override + protected MapperS addedOne(Integer arg1) { + return MapperS.of(addOne.evaluate(1)); + } + } } ''' ) diff --git a/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/function/FunctionGeneratorHelper.java b/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/function/FunctionGeneratorHelper.java index 948d9b5d7b..704d7a576b 100644 --- a/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/function/FunctionGeneratorHelper.java +++ b/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/function/FunctionGeneratorHelper.java @@ -3,9 +3,10 @@ import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; +import com.regnosys.rosetta.codegen.api.CodeRenderer; import com.regnosys.rosetta.generator.java.scoping.JavaClassScope; import com.regnosys.rosetta.generator.java.types.RGeneratedJavaClass; -import com.regnosys.rosetta.generator.java.util.ImportManagerExtension; +import com.regnosys.rosetta.generator.java.util.FluentImportManager; import com.regnosys.rosetta.rosetta.RosettaModel; import com.regnosys.rosetta.tests.util.CodeGeneratorTestHelper; import com.regnosys.rosetta.tests.util.ModelHelper; @@ -16,7 +17,6 @@ import com.rosetta.model.lib.functions.NoOpModelObjectValidator; import com.rosetta.model.lib.functions.RosettaFunction; import com.rosetta.util.DottedPath; -import org.eclipse.xtend2.lib.StringConcatenationClient; import org.eclipse.xtext.xbase.testing.RegisteringFileSystemAccess; import javax.inject.Inject; @@ -35,13 +35,13 @@ public class FunctionGeneratorHelper { @Inject private FunctionGenerator generator; @Inject + private FluentImportManager importManager; + @Inject private ModelHelper modelHelper; @Inject private CodeGeneratorTestHelper codeGeneratorTestHelper; @Inject private RegisteringFileSystemAccess fsa; - @Inject - private ImportManagerExtension importManager; private final Injector injector; @@ -106,7 +106,7 @@ public void assertToGeneratedCalculation(CharSequence actualModel, CharSequence private void generate(RFunction func) { RGeneratedJavaClass typeRepresentation = generator.createTypeRepresentation(func); JavaClassScope classScope = JavaClassScope.createAndRegisterIdentifier(typeRepresentation); - StringConcatenationClient classCode = generator.generateClass(func, typeRepresentation, "test", classScope); + CodeRenderer classCode = generator.generateClass(func, typeRepresentation, "test", classScope); String javaFileCode = importManager.buildClass(typeRepresentation.getPackageName(), classCode, classScope.getFileScope()); fsa.generateFile(typeRepresentation.getCanonicalName().withForwardSlashes() + ".java", javaFileCode); } diff --git a/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/function/FunctionGeneratorTest.java b/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/function/FunctionGeneratorTest.java index 3135e35163..58424f593b 100644 --- a/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/function/FunctionGeneratorTest.java +++ b/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/function/FunctionGeneratorTest.java @@ -1120,42 +1120,40 @@ void canEscapeIdentifiers() { var funcCode = code.get("com.rosetta.test.model.functions.Foo"); assertEquals( """ - package com.rosetta.test.model.functions; + package com.rosetta.test.model.functions; - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; - @ImplementedBy(Foo.FooDefault.class) - public abstract class Foo implements RosettaFunction { + @ImplementedBy(Foo.FooDefault.class) + public abstract class Foo implements RosettaFunction { - /** - * @param func\s - * @return result\s - */ - public Integer evaluate(Integer func) { - Integer result = doEvaluate(func); - \t\t - return result; - } + /** + * @param func + * @return result + */ + public Integer evaluate(Integer func) { + Integer result = doEvaluate(func); + return result; + } - protected abstract Integer doEvaluate(Integer func); + protected abstract Integer doEvaluate(Integer func); - public static class FooDefault extends Foo { - @Override - protected Integer doEvaluate(Integer func) { - Integer result = null; - return assignOutput(result, func); - } - \t\t - protected Integer assignOutput(Integer result, Integer func) { - result = func; - \t\t\t - return result; - } - } - } - """, + public static class FooDefault extends Foo { + @Override + protected Integer doEvaluate(Integer func) { + Integer result = null; + return assignOutput(result, func); + } + + protected Integer assignOutput(Integer result, Integer func) { + result = func; + return result; + } + } + } + """, funcCode ); @@ -2214,41 +2212,40 @@ result string (0..1) var generatedCode = generatorTestHelper.generateCode(code); assertEquals( """ - package com.rosetta.test.model.functions; + package com.rosetta.test.model.functions; - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { - /** - * @param name\s - * @param name2\s - * @return result\s - */ - public String evaluate(String name, String name2) { - String result = doEvaluate(name, name2); - \t\t - return result; - } + /** + * @param name + * @param name2 + * @return result + */ + public String evaluate(String name, String name2) { + String result = doEvaluate(name, name2); + return result; + } - protected abstract String doEvaluate(String name, String name2); + protected abstract String doEvaluate(String name, String name2); - public static class FuncFooDefault extends FuncFoo { - @Override - protected String doEvaluate(String name, String name2) { - String result = null; - return assignOutput(result, name, name2); - } - \t\t - protected String assignOutput(String result, String name, String name2) { - return result; - } - } - } - """, + public static class FuncFooDefault extends FuncFoo { + @Override + protected String doEvaluate(String name, String name2) { + String result = null; + return assignOutput(result, name, name2); + } + + protected String assignOutput(String result, String name, String name2) { + return result; + } + } + } + """, generatedCode.get("com.rosetta.test.model.functions.FuncFoo")); generatorTestHelper.compileToClasses(generatorTestHelper.generateCode(code)); } @@ -2266,43 +2263,42 @@ result string (0..*) var generatedCode = generatorTestHelper.generateCode(code); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import java.util.ArrayList; - import java.util.List; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param name\s - * @param name2\s - * @return result\s - */ - public List evaluate(String name, String name2) { - List result = doEvaluate(name, name2); - \t\t - return result; - } - - protected abstract List doEvaluate(String name, String name2); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import java.util.ArrayList; + import java.util.List; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param name + * @param name2 + * @return result + */ + public List evaluate(String name, String name2) { + List result = doEvaluate(name, name2); + return result; + } + + protected abstract List doEvaluate(String name, String name2); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(String name, String name2) { + List result = new ArrayList<>(); + return assignOutput(result, name, name2); + } - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(String name, String name2) { - List result = new ArrayList<>(); - return assignOutput(result, name, name2); - } - \t\t - protected List assignOutput(List result, String name, String name2) { - return result; - } - } - } - """, + protected List assignOutput(List result, String name, String name2) { + return result; + } + } + } + """, generatedCode.get("com.rosetta.test.model.functions.FuncFoo")); generatorTestHelper.compileToClasses(generatorTestHelper.generateCode(code)); } @@ -2320,44 +2316,43 @@ result number (0..*) var generatedCode = generatorTestHelper.generateCode(code); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import java.math.BigDecimal; - import java.util.ArrayList; - import java.util.List; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param name\s - * @param name2\s - * @return result\s - */ - public List evaluate(String name, String name2) { - List result = doEvaluate(name, name2); - \t\t - return result; - } - - protected abstract List doEvaluate(String name, String name2); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import java.math.BigDecimal; + import java.util.ArrayList; + import java.util.List; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param name + * @param name2 + * @return result + */ + public List evaluate(String name, String name2) { + List result = doEvaluate(name, name2); + return result; + } + + protected abstract List doEvaluate(String name, String name2); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(String name, String name2) { + List result = new ArrayList<>(); + return assignOutput(result, name, name2); + } - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(String name, String name2) { - List result = new ArrayList<>(); - return assignOutput(result, name, name2); - } - \t\t - protected List assignOutput(List result, String name, String name2) { - return result; - } - } - } - """, + protected List assignOutput(List result, String name, String name2) { + return result; + } + } + } + """, generatedCode.get("com.rosetta.test.model.functions.FuncFoo")); generatorTestHelper.compileToClasses(generatorTestHelper.generateCode(code)); } @@ -2375,43 +2370,42 @@ result int (0..*) var generatedCode = generatorTestHelper.generateCode(code); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import java.util.ArrayList; - import java.util.List; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param name\s - * @param name2\s - * @return result\s - */ - public List evaluate(String name, String name2) { - List result = doEvaluate(name, name2); - \t\t - return result; - } - - protected abstract List doEvaluate(String name, String name2); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import java.util.ArrayList; + import java.util.List; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param name + * @param name2 + * @return result + */ + public List evaluate(String name, String name2) { + List result = doEvaluate(name, name2); + return result; + } + + protected abstract List doEvaluate(String name, String name2); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(String name, String name2) { + List result = new ArrayList<>(); + return assignOutput(result, name, name2); + } - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(String name, String name2) { - List result = new ArrayList<>(); - return assignOutput(result, name, name2); - } - \t\t - protected List assignOutput(List result, String name, String name2) { - return result; - } - } - } - """, + protected List assignOutput(List result, String name, String name2) { + return result; + } + } + } + """, generatedCode.get("com.rosetta.test.model.functions.FuncFoo")); generatorTestHelper.compileToClasses(generatorTestHelper.generateCode(code)); } @@ -2429,44 +2423,43 @@ result date (0..*) var generatedCode = generatorTestHelper.generateCode(code); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.records.Date; - import java.util.ArrayList; - import java.util.List; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param name\s - * @param name2\s - * @return result\s - */ - public List evaluate(String name, String name2) { - List result = doEvaluate(name, name2); - \t\t - return result; - } - - protected abstract List doEvaluate(String name, String name2); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.records.Date; + import java.util.ArrayList; + import java.util.List; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param name + * @param name2 + * @return result + */ + public List evaluate(String name, String name2) { + List result = doEvaluate(name, name2); + return result; + } + + protected abstract List doEvaluate(String name, String name2); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(String name, String name2) { + List result = new ArrayList<>(); + return assignOutput(result, name, name2); + } - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(String name, String name2) { - List result = new ArrayList<>(); - return assignOutput(result, name, name2); - } - \t\t - protected List assignOutput(List result, String name, String name2) { - return result; - } - } - } - """, + protected List assignOutput(List result, String name, String name2) { + return result; + } + } + } + """, generatedCode.get("com.rosetta.test.model.functions.FuncFoo")); generatorTestHelper.compileToClasses(generatorTestHelper.generateCode(code)); } @@ -2839,73 +2832,70 @@ id number (1..1) var extractBar = code.get("com.rosetta.test.model.agreement.functions.ExtractBar"); assertEquals( """ - package com.rosetta.test.model.agreement.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.ModelObjectValidator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.test.model.agreement.Bar; - import com.rosetta.test.model.agreement.Foo; - import com.rosetta.test.model.agreement.Top; - import java.util.Optional; - import javax.inject.Inject; + package com.rosetta.test.model.agreement.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.ModelObjectValidator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.test.model.agreement.Bar; + import com.rosetta.test.model.agreement.Foo; + import com.rosetta.test.model.agreement.Top; + import java.util.Optional; + import javax.inject.Inject; + + + @ImplementedBy(ExtractBar.ExtractBarDefault.class) + public abstract class ExtractBar implements RosettaFunction { + + @Inject protected ModelObjectValidator objectValidator; + + /** + * @param top + * @return topOut + */ + public Top evaluate(Top top) { + Top.TopBuilder topOutBuilder = doEvaluate(top); + + final Top topOut; + if (topOutBuilder == null) { + topOut = null; + } else { + topOut = topOutBuilder.build(); + objectValidator.validate(Top.class, topOut); + } + return topOut; + } + protected abstract Top.TopBuilder doEvaluate(Top top); - @ImplementedBy(ExtractBar.ExtractBarDefault.class) - public abstract class ExtractBar implements RosettaFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - - /** - * @param top\s - * @return topOut\s - */ - public Top evaluate(Top top) { - Top.TopBuilder topOutBuilder = doEvaluate(top); - \t\t - final Top topOut; - if (topOutBuilder == null) { - topOut = null; - } else { - topOut = topOutBuilder.build(); - objectValidator.validate(Top.class, topOut); - } - \t\t - return topOut; - } + protected abstract Foo.FooBuilder fooAlias(Top.TopBuilder topOut, Top top); - protected abstract Top.TopBuilder doEvaluate(Top top); + public static class ExtractBarDefault extends ExtractBar { + @Override + protected Top.TopBuilder doEvaluate(Top top) { + Top.TopBuilder topOut = Top.builder(); + return assignOutput(topOut, top); + } - protected abstract Foo.FooBuilder fooAlias(Top.TopBuilder topOut, Top top); + protected Top.TopBuilder assignOutput(Top.TopBuilder topOut, Top top) { + topOut.getOrCreateFoo() + .setBar1(MapperS.of(top).map("getFoo", _top -> _top.getFoo()).map("getBar1", foo -> foo.getBar1()).get()); + topOut + .getOrCreateFoo() + .setBar2(MapperS.of(top).map("getFoo", _top -> _top.getFoo()).map("getBar2", foo -> foo.getBar2()).get()); + return Optional.ofNullable(topOut) + .map(o -> o.prune()) + .orElse(null); + } - public static class ExtractBarDefault extends ExtractBar { - @Override - protected Top.TopBuilder doEvaluate(Top top) { - Top.TopBuilder topOut = Top.builder(); - return assignOutput(topOut, top); - } - \t\t - protected Top.TopBuilder assignOutput(Top.TopBuilder topOut, Top top) { - topOut.getOrCreateFoo() - .setBar1(MapperS.of(top).map("getFoo", _top -> _top.getFoo()).map("getBar1", foo -> foo.getBar1()).get()); - \t\t\t - topOut - .getOrCreateFoo() - .setBar2(MapperS.of(top).map("getFoo", _top -> _top.getFoo()).map("getBar2", foo -> foo.getBar2()).get()); - \t\t\t - return Optional.ofNullable(topOut) - .map(o -> o.prune()) - .orElse(null); - } - \t\t - @Override - protected Foo.FooBuilder fooAlias(Top.TopBuilder topOut, Top top) { - return toBuilder(MapperS.of(topOut).map("getFoo", _top -> _top.getFoo()).get()); - } - } - } - """, + @Override + protected Foo.FooBuilder fooAlias(Top.TopBuilder topOut, Top top) { + return toBuilder(MapperS.of(topOut).map("getFoo", _top -> _top.getFoo()).get()); + } + } + } + """, extractBar); generatorTestHelper.compileToClasses(code); } @@ -3084,49 +3074,47 @@ void funcCallingMultipleFunc() { var f3 = code.get("com.rosetta.test.model.functions.F3"); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.records.Date; - import javax.inject.Inject; - - - @ImplementedBy(F3.F3Default.class) - public abstract class F3 implements RosettaFunction { - \t - // RosettaFunction dependencies - // - @Inject protected F1 f1; - @Inject protected F2 f2; - - /** - * @param f3Input\s - * @return f3Output\s - */ - public Date evaluate(Date f3Input) { - Date f3Output = doEvaluate(f3Input); - \t\t - return f3Output; - } - - protected abstract Date doEvaluate(Date f3Input); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.records.Date; + import javax.inject.Inject; + + + @ImplementedBy(F3.F3Default.class) + public abstract class F3 implements RosettaFunction { + + // RosettaFunction dependencies + // + @Inject protected F1 f1; + @Inject protected F2 f2; + + /** + * @param f3Input + * @return f3Output + */ + public Date evaluate(Date f3Input) { + Date f3Output = doEvaluate(f3Input); + return f3Output; + } + + protected abstract Date doEvaluate(Date f3Input); + + public static class F3Default extends F3 { + @Override + protected Date doEvaluate(Date f3Input) { + Date f3Output = null; + return assignOutput(f3Output, f3Input); + } - public static class F3Default extends F3 { - @Override - protected Date doEvaluate(Date f3Input) { - Date f3Output = null; - return assignOutput(f3Output, f3Input); - } - \t\t - protected Date assignOutput(Date f3Output, Date f3Input) { - f3Output = f2.evaluate(f1.evaluate(f3Input)); - \t\t\t - return f3Output; - } - } - } - """, + protected Date assignOutput(Date f3Output, Date f3Input) { + f3Output = f2.evaluate(f1.evaluate(f3Input)); + return f3Output; + } + } + } + """, f3 ); generatorTestHelper.compileToClasses(code); @@ -3149,94 +3137,91 @@ void testDelegateFunctionCallWithInputAlias() { var f1 = code.get("com.rosetta.test.model.functions.F1"); assertEquals( """ - package com.rosetta.test.model.functions; + package com.rosetta.test.model.functions; - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; - @ImplementedBy(F1.F1Default.class) - public abstract class F1 implements RosettaFunction { + @ImplementedBy(F1.F1Default.class) + public abstract class F1 implements RosettaFunction { - /** - * @param f1Input\s - * @return f1Output\s - */ - public String evaluate(String f1Input) { - String f1Output = doEvaluate(f1Input); - \t\t - return f1Output; - } + /** + * @param f1Input + * @return f1Output + */ + public String evaluate(String f1Input) { + String f1Output = doEvaluate(f1Input); + return f1Output; + } - protected abstract String doEvaluate(String f1Input); + protected abstract String doEvaluate(String f1Input); - public static class F1Default extends F1 { - @Override - protected String doEvaluate(String f1Input) { - String f1Output = null; - return assignOutput(f1Output, f1Input); - } - \t\t - protected String assignOutput(String f1Output, String f1Input) { - return f1Output; - } - } - } - """, + public static class F1Default extends F1 { + @Override + protected String doEvaluate(String f1Input) { + String f1Output = null; + return assignOutput(f1Output, f1Input); + } + + protected String assignOutput(String f1Output, String f1Input) { + return f1Output; + } + } + } + """, f1 ); var f2 = code.get("com.rosetta.test.model.functions.F2"); assertEquals( """ - package com.rosetta.test.model.functions; + package com.rosetta.test.model.functions; - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperS; - import javax.inject.Inject; + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperS; + import javax.inject.Inject; - @ImplementedBy(F2.F2Default.class) - public abstract class F2 implements RosettaFunction { - \t - // RosettaFunction dependencies - // - @Inject protected F1 f1; - - /** - * @param f2Input\s - * @return f2Output\s - */ - public String evaluate(String f2Input) { - String f2Output = doEvaluate(f2Input); - \t\t - return f2Output; - } + @ImplementedBy(F2.F2Default.class) + public abstract class F2 implements RosettaFunction { - protected abstract String doEvaluate(String f2Input); + // RosettaFunction dependencies + // + @Inject protected F1 f1; - protected abstract MapperS foo(String f2Input); + /** + * @param f2Input + * @return f2Output + */ + public String evaluate(String f2Input) { + String f2Output = doEvaluate(f2Input); + return f2Output; + } - public static class F2Default extends F2 { - @Override - protected String doEvaluate(String f2Input) { - String f2Output = null; - return assignOutput(f2Output, f2Input); - } - \t\t - protected String assignOutput(String f2Output, String f2Input) { - f2Output = foo(f2Input).get(); - \t\t\t - return f2Output; - } - \t\t - @Override - protected MapperS foo(String f2Input) { - return MapperS.of(f1.evaluate(f2Input)); - } - } - } - """, + protected abstract String doEvaluate(String f2Input); + + protected abstract MapperS foo(String f2Input); + + public static class F2Default extends F2 { + @Override + protected String doEvaluate(String f2Input) { + String f2Output = null; + return assignOutput(f2Output, f2Input); + } + + protected String assignOutput(String f2Output, String f2Input) { + f2Output = foo(f2Input).get(); + return f2Output; + } + + @Override + protected MapperS foo(String f2Input) { + return MapperS.of(f1.evaluate(f2Input)); + } + } + } + """, f2 ); generatorTestHelper.compileToClasses(code); @@ -3263,144 +3248,140 @@ void funcCallingMultipleFunc2() { var f1 = code.get("com.rosetta.test.model.functions.F1"); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.records.Date; - import java.util.ArrayList; - import java.util.List; - - - @ImplementedBy(F1.F1Default.class) - public abstract class F1 implements RosettaFunction { - - /** - * @param f1Input\s - * @return f1OutputList\s - */ - public List evaluate(Date f1Input) { - List f1OutputList = doEvaluate(f1Input); - \t\t - return f1OutputList; - } - - protected abstract List doEvaluate(Date f1Input); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.records.Date; + import java.util.ArrayList; + import java.util.List; + + + @ImplementedBy(F1.F1Default.class) + public abstract class F1 implements RosettaFunction { + + /** + * @param f1Input + * @return f1OutputList + */ + public List evaluate(Date f1Input) { + List f1OutputList = doEvaluate(f1Input); + return f1OutputList; + } + + protected abstract List doEvaluate(Date f1Input); + + public static class F1Default extends F1 { + @Override + protected List doEvaluate(Date f1Input) { + List f1OutputList = new ArrayList<>(); + return assignOutput(f1OutputList, f1Input); + } - public static class F1Default extends F1 { - @Override - protected List doEvaluate(Date f1Input) { - List f1OutputList = new ArrayList<>(); - return assignOutput(f1OutputList, f1Input); - } - \t\t - protected List assignOutput(List f1OutputList, Date f1Input) { - return f1OutputList; - } - } - } - """, + protected List assignOutput(List f1OutputList, Date f1Input) { + return f1OutputList; + } + } + } + """, f1 ); var f2 = code.get("com.rosetta.test.model.functions.F2"); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.records.Date; - import java.util.Collections; - import java.util.List; - - - @ImplementedBy(F2.F2Default.class) - public abstract class F2 implements RosettaFunction { - - /** - * @param f2InputList\s - * @return f2Output\s - */ - public Date evaluate(List f2InputList) { - Date f2Output = doEvaluate(f2InputList); - \t\t - return f2Output; - } - - protected abstract Date doEvaluate(List f2InputList); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.records.Date; + import java.util.Collections; + import java.util.List; + + + @ImplementedBy(F2.F2Default.class) + public abstract class F2 implements RosettaFunction { + + /** + * @param f2InputList + * @return f2Output + */ + public Date evaluate(List f2InputList) { + Date f2Output = doEvaluate(f2InputList); + return f2Output; + } + + protected abstract Date doEvaluate(List f2InputList); + + public static class F2Default extends F2 { + @Override + protected Date doEvaluate(List f2InputList) { + if (f2InputList == null) { + f2InputList = Collections.emptyList(); + } + Date f2Output = null; + return assignOutput(f2Output, f2InputList); + } - public static class F2Default extends F2 { - @Override - protected Date doEvaluate(List f2InputList) { - if (f2InputList == null) { - f2InputList = Collections.emptyList(); - } - Date f2Output = null; - return assignOutput(f2Output, f2InputList); - } - \t\t - protected Date assignOutput(Date f2Output, List f2InputList) { - return f2Output; - } - } - } - """, + protected Date assignOutput(Date f2Output, List f2InputList) { + return f2Output; + } + } + } + """, f2 ); var f3 = code.get("com.rosetta.test.model.functions.F3"); assertEquals( """ - package com.rosetta.test.model.functions; + package com.rosetta.test.model.functions; - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.model.lib.records.Date; - import javax.inject.Inject; + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.model.lib.records.Date; + import javax.inject.Inject; - @ImplementedBy(F3.F3Default.class) - public abstract class F3 implements RosettaFunction { - \t - // RosettaFunction dependencies - // - @Inject protected F1 f1; - @Inject protected F2 f2; - - /** - * @param f3Input\s - * @return f3Output\s - */ - public Date evaluate(Date f3Input) { - Date f3Output = doEvaluate(f3Input); - \t\t - return f3Output; - } + @ImplementedBy(F3.F3Default.class) + public abstract class F3 implements RosettaFunction { - protected abstract Date doEvaluate(Date f3Input); + // RosettaFunction dependencies + // + @Inject protected F1 f1; + @Inject protected F2 f2; - protected abstract MapperC f1OutList(Date f3Input); + /** + * @param f3Input + * @return f3Output + */ + public Date evaluate(Date f3Input) { + Date f3Output = doEvaluate(f3Input); + return f3Output; + } - public static class F3Default extends F3 { - @Override - protected Date doEvaluate(Date f3Input) { - Date f3Output = null; - return assignOutput(f3Output, f3Input); - } - \t\t - protected Date assignOutput(Date f3Output, Date f3Input) { - f3Output = f2.evaluate(f1OutList(f3Input).getMulti()); - \t\t\t - return f3Output; - } - \t\t - @Override - protected MapperC f1OutList(Date f3Input) { - return MapperC.of(f1.evaluate(f3Input)); - } - } - } - """, + protected abstract Date doEvaluate(Date f3Input); + + protected abstract MapperC f1OutList(Date f3Input); + + public static class F3Default extends F3 { + @Override + protected Date doEvaluate(Date f3Input) { + Date f3Output = null; + return assignOutput(f3Output, f3Input); + } + + protected Date assignOutput(Date f3Output, Date f3Input) { + f3Output = f2.evaluate(f1OutList(f3Input).getMulti()); + return f3Output; + } + + @Override + protected MapperC f1OutList(Date f3Input) { + return MapperC.of(f1.evaluate(f3Input)); + } + } + } + """, f3 ); generatorTestHelper.compileToClasses(code); @@ -3827,56 +3808,54 @@ res int (0..*) var f = code.get("com.rosetta.test.model.functions.DistinctFunc"); assertEquals( """ - package com.rosetta.test.model.functions; + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.test.model.Foo; + import java.util.ArrayList; + import java.util.List; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(DistinctFunc.DistinctFuncDefault.class) + public abstract class DistinctFunc implements RosettaFunction { + + /** + * @param foo + * @return res + */ + public List evaluate(Foo foo) { + List res = doEvaluate(foo); + return res; + } + + protected abstract List doEvaluate(Foo foo); + + public static class DistinctFuncDefault extends DistinctFunc { + @Override + protected List doEvaluate(Foo foo) { + List res = new ArrayList<>(); + return assignOutput(res, foo); + } - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.test.model.Foo; - import java.util.ArrayList; - import java.util.List; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(DistinctFunc.DistinctFuncDefault.class) - public abstract class DistinctFunc implements RosettaFunction { - - /** - * @param foo\s - * @return res\s - */ - public List evaluate(Foo foo) { - List res = doEvaluate(foo); - \t\t - return res; - } - - protected abstract List doEvaluate(Foo foo); - - public static class DistinctFuncDefault extends DistinctFunc { - @Override - protected List doEvaluate(Foo foo) { - List res = new ArrayList<>(); - return assignOutput(res, foo); - } - \t\t - protected List assignOutput(List res, Foo foo) { - res = distinctIgnoringPrecision(MapperS.of(foo).mapC("getN", _foo -> _foo.getN())).getMulti(); - \t\t\t - return res; - } - } - } - """, - f - ); - var classes = generatorTestHelper.compileToClasses(code); - var func = functionGeneratorHelper.createFunc(classes, "DistinctFunc"); - var foo = generatorTestHelper.createInstanceUsingBuilder(classes, "Foo", Map.of(), Map.of("n", ImmutableList.of(1, 1, 1, 2, 2, 3))); - List res = functionGeneratorHelper.invokeFunc(func, List.class, foo); - assertEquals(3, res.size()); - assertThat(res, hasItems((Object) 1, 2, 3)); - } + protected List assignOutput(List res, Foo foo) { + res = distinctIgnoringPrecision(MapperS.of(foo).mapC("getN", _foo -> _foo.getN())).getMulti(); + return res; + } + } + } + """, + f + ); + var classes = generatorTestHelper.compileToClasses(code); + var func = functionGeneratorHelper.createFunc(classes, "DistinctFunc"); + var foo = generatorTestHelper.createInstanceUsingBuilder(classes, "Foo", Map.of(), Map.of("n", ImmutableList.of(1, 1, 1, 2, 2, 3))); + List res = functionGeneratorHelper.invokeFunc(func, List.class, foo); + assertEquals(3, res.size()); + assertThat(res, hasItems((Object) 1, 2, 3)); + } @Test void funcWithListOfIntDistinct2() { @@ -3895,50 +3874,48 @@ res int (0..*) var f = code.get("com.rosetta.test.model.functions.DistinctFunc"); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(DistinctFunc.DistinctFuncDefault.class) - public abstract class DistinctFunc implements RosettaFunction { - - /** - * @param n\s - * @return res\s - */ - public List evaluate(List n) { - List res = doEvaluate(n); - \t\t - return res; - } - - protected abstract List doEvaluate(List n); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(DistinctFunc.DistinctFuncDefault.class) + public abstract class DistinctFunc implements RosettaFunction { + + /** + * @param n + * @return res + */ + public List evaluate(List n) { + List res = doEvaluate(n); + return res; + } + + protected abstract List doEvaluate(List n); + + public static class DistinctFuncDefault extends DistinctFunc { + @Override + protected List doEvaluate(List n) { + if (n == null) { + n = Collections.emptyList(); + } + List res = new ArrayList<>(); + return assignOutput(res, n); + } - public static class DistinctFuncDefault extends DistinctFunc { - @Override - protected List doEvaluate(List n) { - if (n == null) { - n = Collections.emptyList(); - } - List res = new ArrayList<>(); - return assignOutput(res, n); - } - \t\t - protected List assignOutput(List res, List n) { - res = distinctIgnoringPrecision(MapperC.of(n)).getMulti(); - \t\t\t - return res; - } - } - } - """, + protected List assignOutput(List res, List n) { + res = distinctIgnoringPrecision(MapperC.of(n)).getMulti(); + return res; + } + } + } + """, f ); var classes = generatorTestHelper.compileToClasses(code); @@ -4015,64 +3992,62 @@ res Bar (0..*) var f = code.get("com.rosetta.test.model.functions.DistinctFunc"); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.ModelObjectValidator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.test.model.Bar; - import com.rosetta.test.model.Foo; - import java.util.ArrayList; - import java.util.List; - import java.util.Optional; - import java.util.stream.Collectors; - import javax.inject.Inject; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.ModelObjectValidator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.test.model.Bar; + import com.rosetta.test.model.Foo; + import java.util.ArrayList; + import java.util.List; + import java.util.Optional; + import java.util.stream.Collectors; + import javax.inject.Inject; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(DistinctFunc.DistinctFuncDefault.class) + public abstract class DistinctFunc implements RosettaFunction { + + @Inject protected ModelObjectValidator objectValidator; + + /** + * @param foo + * @return res + */ + public List evaluate(Foo foo) { + List resBuilder = doEvaluate(foo); + + final List res; + if (resBuilder == null) { + res = null; + } else { + res = resBuilder.stream().map(Bar::build).collect(Collectors.toList()); + objectValidator.validate(Bar.class, res); + } + return res; + } - @ImplementedBy(DistinctFunc.DistinctFuncDefault.class) - public abstract class DistinctFunc implements RosettaFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - - /** - * @param foo\s - * @return res\s - */ - public List evaluate(Foo foo) { - List resBuilder = doEvaluate(foo); - \t\t - final List res; - if (resBuilder == null) { - res = null; - } else { - res = resBuilder.stream().map(Bar::build).collect(Collectors.toList()); - objectValidator.validate(Bar.class, res); - } - \t\t - return res; - } + protected abstract List doEvaluate(Foo foo); - protected abstract List doEvaluate(Foo foo); + public static class DistinctFuncDefault extends DistinctFunc { + @Override + protected List doEvaluate(Foo foo) { + List res = new ArrayList<>(); + return assignOutput(res, foo); + } - public static class DistinctFuncDefault extends DistinctFunc { - @Override - protected List doEvaluate(Foo foo) { - List res = new ArrayList<>(); - return assignOutput(res, foo); - } - \t\t - protected List assignOutput(List res, Foo foo) { - res.addAll(toBuilder(distinctIgnoringPrecision(MapperS.of(foo).mapC("getBarList", _foo -> _foo.getBarList())).getMulti())); - \t\t\t - return Optional.ofNullable(res) - .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) - .orElse(null); - } - } - } - """, + protected List assignOutput(List res, Foo foo) { + res.addAll(toBuilder(distinctIgnoringPrecision(MapperS.of(foo).mapC("getBarList", _foo -> _foo.getBarList())).getMulti())); + return Optional.ofNullable(res) + .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) + .orElse(null); + } + } + } + """, f ); var classes = generatorTestHelper.compileToClasses(code); @@ -4117,67 +4092,65 @@ res Bar (0..*) var f = code.get("com.rosetta.test.model.functions.DistinctFunc"); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.ModelObjectValidator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperC; - import com.rosetta.test.model.Bar; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - import java.util.Optional; - import java.util.stream.Collectors; - import javax.inject.Inject; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(DistinctFunc.DistinctFuncDefault.class) - public abstract class DistinctFunc implements RosettaFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - - /** - * @param barList\s - * @return res\s - */ - public List evaluate(List barList) { - List resBuilder = doEvaluate(barList); - \t\t - final List res; - if (resBuilder == null) { - res = null; - } else { - res = resBuilder.stream().map(Bar::build).collect(Collectors.toList()); - objectValidator.validate(Bar.class, res); - } - \t\t - return res; - } - - protected abstract List doEvaluate(List barList); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.ModelObjectValidator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperC; + import com.rosetta.test.model.Bar; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + import java.util.Optional; + import java.util.stream.Collectors; + import javax.inject.Inject; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(DistinctFunc.DistinctFuncDefault.class) + public abstract class DistinctFunc implements RosettaFunction { + + @Inject protected ModelObjectValidator objectValidator; + + /** + * @param barList + * @return res + */ + public List evaluate(List barList) { + List resBuilder = doEvaluate(barList); + + final List res; + if (resBuilder == null) { + res = null; + } else { + res = resBuilder.stream().map(Bar::build).collect(Collectors.toList()); + objectValidator.validate(Bar.class, res); + } + return res; + } + + protected abstract List doEvaluate(List barList); + + public static class DistinctFuncDefault extends DistinctFunc { + @Override + protected List doEvaluate(List barList) { + if (barList == null) { + barList = Collections.emptyList(); + } + List res = new ArrayList<>(); + return assignOutput(res, barList); + } - public static class DistinctFuncDefault extends DistinctFunc { - @Override - protected List doEvaluate(List barList) { - if (barList == null) { - barList = Collections.emptyList(); - } - List res = new ArrayList<>(); - return assignOutput(res, barList); - } - \t\t - protected List assignOutput(List res, List barList) { - res.addAll(toBuilder(distinctIgnoringPrecision(MapperC.of(barList)).getMulti())); - \t\t\t - return Optional.ofNullable(res) - .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) - .orElse(null); - } - } - } - """, + protected List assignOutput(List res, List barList) { + res.addAll(toBuilder(distinctIgnoringPrecision(MapperC.of(barList)).getMulti())); + return Optional.ofNullable(res) + .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) + .orElse(null); + } + } + } + """, f ); var classes = generatorTestHelper.compileToClasses(code); @@ -4435,51 +4408,49 @@ result string (1..1) var f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.CardinalityOperator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperS; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param test\s - * @param t1\s - * @param t2\s - * @return result\s - */ - public String evaluate(Boolean test, String t1, String t2) { - String result = doEvaluate(test, t1, t2); - \t\t - return result; - } - - protected abstract String doEvaluate(Boolean test, String t1, String t2); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.CardinalityOperator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperS; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param test + * @param t1 + * @param t2 + * @return result + */ + public String evaluate(Boolean test, String t1, String t2) { + String result = doEvaluate(test, t1, t2); + return result; + } + + protected abstract String doEvaluate(Boolean test, String t1, String t2); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected String doEvaluate(Boolean test, String t1, String t2) { + String result = null; + return assignOutput(result, test, t1, t2); + } - public static class FuncFooDefault extends FuncFoo { - @Override - protected String doEvaluate(Boolean test, String t1, String t2) { - String result = null; - return assignOutput(result, test, t1, t2); - } - \t\t - protected String assignOutput(String result, Boolean test, String t1, String t2) { - if (areEqual(MapperS.of(test), MapperS.of(true), CardinalityOperator.All).getOrDefault(false)) { - result = t1; - } else { - result = t2; - } - \t\t\t - return result; - } - } - } - """, + protected String assignOutput(String result, Boolean test, String t1, String t2) { + if (areEqual(MapperS.of(test), MapperS.of(true), CardinalityOperator.All).getOrDefault(false)) { + result = t1; + } else { + result = t2; + } + return result; + } + } + } + """, f ); generatorTestHelper.compileToClasses(code); @@ -4505,60 +4476,58 @@ result string (1..*) var f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.CardinalityOperator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperS; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param test\s - * @param t1\s - * @param t2\s - * @return result\s - */ - public List evaluate(Boolean test, List t1, List t2) { - List result = doEvaluate(test, t1, t2); - \t\t - return result; - } - - protected abstract List doEvaluate(Boolean test, List t1, List t2); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.CardinalityOperator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperS; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param test + * @param t1 + * @param t2 + * @return result + */ + public List evaluate(Boolean test, List t1, List t2) { + List result = doEvaluate(test, t1, t2); + return result; + } + + protected abstract List doEvaluate(Boolean test, List t1, List t2); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(Boolean test, List t1, List t2) { + if (t1 == null) { + t1 = Collections.emptyList(); + } + if (t2 == null) { + t2 = Collections.emptyList(); + } + List result = new ArrayList<>(); + return assignOutput(result, test, t1, t2); + } - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(Boolean test, List t1, List t2) { - if (t1 == null) { - t1 = Collections.emptyList(); - } - if (t2 == null) { - t2 = Collections.emptyList(); - } - List result = new ArrayList<>(); - return assignOutput(result, test, t1, t2); - } - \t\t - protected List assignOutput(List result, Boolean test, List t1, List t2) { - if (areEqual(MapperS.of(test), MapperS.of(true), CardinalityOperator.All).getOrDefault(false)) { - result.addAll(t1); - } else { - result.addAll(t2); - } - \t\t\t - return result; - } - } - } - """, + protected List assignOutput(List result, Boolean test, List t1, List t2) { + if (areEqual(MapperS.of(test), MapperS.of(true), CardinalityOperator.All).getOrDefault(false)) { + result.addAll(t1); + } else { + result.addAll(t2); + } + return result; + } + } + } + """, f ); generatorTestHelper.compileToClasses(code); @@ -4584,52 +4553,50 @@ result number (1..1) var f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.CardinalityOperator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperS; - import java.math.BigDecimal; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param test\s - * @param t1\s - * @param t2\s - * @return result\s - */ - public BigDecimal evaluate(Boolean test, BigDecimal t1, BigDecimal t2) { - BigDecimal result = doEvaluate(test, t1, t2); - \t\t - return result; - } - - protected abstract BigDecimal doEvaluate(Boolean test, BigDecimal t1, BigDecimal t2); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.CardinalityOperator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperS; + import java.math.BigDecimal; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param test + * @param t1 + * @param t2 + * @return result + */ + public BigDecimal evaluate(Boolean test, BigDecimal t1, BigDecimal t2) { + BigDecimal result = doEvaluate(test, t1, t2); + return result; + } + + protected abstract BigDecimal doEvaluate(Boolean test, BigDecimal t1, BigDecimal t2); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected BigDecimal doEvaluate(Boolean test, BigDecimal t1, BigDecimal t2) { + BigDecimal result = null; + return assignOutput(result, test, t1, t2); + } - public static class FuncFooDefault extends FuncFoo { - @Override - protected BigDecimal doEvaluate(Boolean test, BigDecimal t1, BigDecimal t2) { - BigDecimal result = null; - return assignOutput(result, test, t1, t2); - } - \t\t - protected BigDecimal assignOutput(BigDecimal result, Boolean test, BigDecimal t1, BigDecimal t2) { - if (areEqual(MapperS.of(test), MapperS.of(true), CardinalityOperator.All).getOrDefault(false)) { - result = t1; - } else { - result = t2; - } - \t\t\t - return result; - } - } - } - """, + protected BigDecimal assignOutput(BigDecimal result, Boolean test, BigDecimal t1, BigDecimal t2) { + if (areEqual(MapperS.of(test), MapperS.of(true), CardinalityOperator.All).getOrDefault(false)) { + result = t1; + } else { + result = t2; + } + return result; + } + } + } + """, f ); generatorTestHelper.compileToClasses(code); @@ -4655,61 +4622,59 @@ result number (1..*) var f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.CardinalityOperator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperS; - import java.math.BigDecimal; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param test\s - * @param t1\s - * @param t2\s - * @return result\s - */ - public List evaluate(Boolean test, List t1, List t2) { - List result = doEvaluate(test, t1, t2); - \t\t - return result; - } - - protected abstract List doEvaluate(Boolean test, List t1, List t2); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.CardinalityOperator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperS; + import java.math.BigDecimal; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param test + * @param t1 + * @param t2 + * @return result + */ + public List evaluate(Boolean test, List t1, List t2) { + List result = doEvaluate(test, t1, t2); + return result; + } + + protected abstract List doEvaluate(Boolean test, List t1, List t2); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(Boolean test, List t1, List t2) { + if (t1 == null) { + t1 = Collections.emptyList(); + } + if (t2 == null) { + t2 = Collections.emptyList(); + } + List result = new ArrayList<>(); + return assignOutput(result, test, t1, t2); + } - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(Boolean test, List t1, List t2) { - if (t1 == null) { - t1 = Collections.emptyList(); - } - if (t2 == null) { - t2 = Collections.emptyList(); - } - List result = new ArrayList<>(); - return assignOutput(result, test, t1, t2); - } - \t\t - protected List assignOutput(List result, Boolean test, List t1, List t2) { - if (areEqual(MapperS.of(test), MapperS.of(true), CardinalityOperator.All).getOrDefault(false)) { - result.addAll(t1); - } else { - result.addAll(t2); - } - \t\t\t - return result; - } - } - } - """, + protected List assignOutput(List result, Boolean test, List t1, List t2) { + if (areEqual(MapperS.of(test), MapperS.of(true), CardinalityOperator.All).getOrDefault(false)) { + result.addAll(t1); + } else { + result.addAll(t2); + } + return result; + } + } + } + """, f ); generatorTestHelper.compileToClasses(code); @@ -4738,67 +4703,65 @@ s1 string (1..1) var f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals( """ - package com.rosetta.test.model.functions; + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.CardinalityOperator; + import com.rosetta.model.lib.functions.ModelObjectValidator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.test.model.Bar; + import java.util.Optional; + import javax.inject.Inject; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + @Inject protected ModelObjectValidator objectValidator; + + /** + * @param test + * @param b1 + * @param b2 + * @return result + */ + public Bar evaluate(Boolean test, Bar b1, Bar b2) { + Bar.BarBuilder resultBuilder = doEvaluate(test, b1, b2); + + final Bar result; + if (resultBuilder == null) { + result = null; + } else { + result = resultBuilder.build(); + objectValidator.validate(Bar.class, result); + } + return result; + } - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.CardinalityOperator; - import com.rosetta.model.lib.functions.ModelObjectValidator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.test.model.Bar; - import java.util.Optional; - import javax.inject.Inject; + protected abstract Bar.BarBuilder doEvaluate(Boolean test, Bar b1, Bar b2); - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - - /** - * @param test\s - * @param b1\s - * @param b2\s - * @return result\s - */ - public Bar evaluate(Boolean test, Bar b1, Bar b2) { - Bar.BarBuilder resultBuilder = doEvaluate(test, b1, b2); - \t\t - final Bar result; - if (resultBuilder == null) { - result = null; - } else { - result = resultBuilder.build(); - objectValidator.validate(Bar.class, result); - } - \t\t - return result; - } - - protected abstract Bar.BarBuilder doEvaluate(Boolean test, Bar b1, Bar b2); + public static class FuncFooDefault extends FuncFoo { + @Override + protected Bar.BarBuilder doEvaluate(Boolean test, Bar b1, Bar b2) { + Bar.BarBuilder result = Bar.builder(); + return assignOutput(result, test, b1, b2); + } - public static class FuncFooDefault extends FuncFoo { - @Override - protected Bar.BarBuilder doEvaluate(Boolean test, Bar b1, Bar b2) { - Bar.BarBuilder result = Bar.builder(); - return assignOutput(result, test, b1, b2); - } - \t\t - protected Bar.BarBuilder assignOutput(Bar.BarBuilder result, Boolean test, Bar b1, Bar b2) { - if (areEqual(MapperS.of(test), MapperS.of(true), CardinalityOperator.All).getOrDefault(false)) { - result = toBuilder(b1); - } else { - result = toBuilder(b2); - } - \t\t\t - return Optional.ofNullable(result) - .map(o -> o.prune()) - .orElse(null); - } - } - } - """, + protected Bar.BarBuilder assignOutput(Bar.BarBuilder result, Boolean test, Bar b1, Bar b2) { + if (areEqual(MapperS.of(test), MapperS.of(true), CardinalityOperator.All).getOrDefault(false)) { + result = toBuilder(b1); + } else { + result = toBuilder(b2); + } + return Optional.ofNullable(result) + .map(o -> o.prune()) + .orElse(null); + } + } + } + """, f ); generatorTestHelper.compileToClasses(code); @@ -4827,77 +4790,75 @@ s1 string (1..1) var f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.CardinalityOperator; - import com.rosetta.model.lib.functions.ModelObjectValidator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.test.model.Bar; - import java.util.ArrayList; - import java.util.Collections; - import java.util.List; - import java.util.Optional; - import java.util.stream.Collectors; - import javax.inject.Inject; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - - /** - * @param test\s - * @param b1\s - * @param b2\s - * @return result\s - */ - public List evaluate(Boolean test, List b1, List b2) { - List resultBuilder = doEvaluate(test, b1, b2); - \t\t - final List result; - if (resultBuilder == null) { - result = null; - } else { - result = resultBuilder.stream().map(Bar::build).collect(Collectors.toList()); - objectValidator.validate(Bar.class, result); - } - \t\t - return result; - } - - protected abstract List doEvaluate(Boolean test, List b1, List b2); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.CardinalityOperator; + import com.rosetta.model.lib.functions.ModelObjectValidator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.test.model.Bar; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; + import java.util.Optional; + import java.util.stream.Collectors; + import javax.inject.Inject; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + @Inject protected ModelObjectValidator objectValidator; + + /** + * @param test + * @param b1 + * @param b2 + * @return result + */ + public List evaluate(Boolean test, List b1, List b2) { + List resultBuilder = doEvaluate(test, b1, b2); + + final List result; + if (resultBuilder == null) { + result = null; + } else { + result = resultBuilder.stream().map(Bar::build).collect(Collectors.toList()); + objectValidator.validate(Bar.class, result); + } + return result; + } + + protected abstract List doEvaluate(Boolean test, List b1, List b2); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected List doEvaluate(Boolean test, List b1, List b2) { + if (b1 == null) { + b1 = Collections.emptyList(); + } + if (b2 == null) { + b2 = Collections.emptyList(); + } + List result = new ArrayList<>(); + return assignOutput(result, test, b1, b2); + } - public static class FuncFooDefault extends FuncFoo { - @Override - protected List doEvaluate(Boolean test, List b1, List b2) { - if (b1 == null) { - b1 = Collections.emptyList(); - } - if (b2 == null) { - b2 = Collections.emptyList(); - } - List result = new ArrayList<>(); - return assignOutput(result, test, b1, b2); - } - \t\t - protected List assignOutput(List result, Boolean test, List b1, List b2) { - if (areEqual(MapperS.of(test), MapperS.of(true), CardinalityOperator.All).getOrDefault(false)) { - result.addAll(toBuilder(b1)); - } else { - result.addAll(toBuilder(b2)); - } - \t\t\t - return Optional.ofNullable(result) - .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) - .orElse(null); - } - } - } - """, + protected List assignOutput(List result, Boolean test, List b1, List b2) { + if (areEqual(MapperS.of(test), MapperS.of(true), CardinalityOperator.All).getOrDefault(false)) { + result.addAll(toBuilder(b1)); + } else { + result.addAll(toBuilder(b2)); + } + return Optional.ofNullable(result) + .map(o -> o.stream().map(i -> i.prune()).collect(Collectors.toList())) + .orElse(null); + } + } + } + """, f ); generatorTestHelper.compileToClasses(code); @@ -4920,46 +4881,44 @@ res number (1..1) var f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.MapperMaths; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperS; - import java.math.BigDecimal; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - - /** - * @param n1\s - * @param n2\s - * @return res\s - */ - public BigDecimal evaluate(BigDecimal n1, BigDecimal n2) { - BigDecimal res = doEvaluate(n1, n2); - \t\t - return res; - } - - protected abstract BigDecimal doEvaluate(BigDecimal n1, BigDecimal n2); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.MapperMaths; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperS; + import java.math.BigDecimal; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + /** + * @param n1 + * @param n2 + * @return res + */ + public BigDecimal evaluate(BigDecimal n1, BigDecimal n2) { + BigDecimal res = doEvaluate(n1, n2); + return res; + } + + protected abstract BigDecimal doEvaluate(BigDecimal n1, BigDecimal n2); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected BigDecimal doEvaluate(BigDecimal n1, BigDecimal n2) { + BigDecimal res = null; + return assignOutput(res, n1, n2); + } - public static class FuncFooDefault extends FuncFoo { - @Override - protected BigDecimal doEvaluate(BigDecimal n1, BigDecimal n2) { - BigDecimal res = null; - return assignOutput(res, n1, n2); - } - \t\t - protected BigDecimal assignOutput(BigDecimal res, BigDecimal n1, BigDecimal n2) { - res = MapperMaths.multiply(MapperS.of(n1), MapperS.of(n2)).get(); - \t\t\t - return res; - } - } - } - """, + protected BigDecimal assignOutput(BigDecimal res, BigDecimal n1, BigDecimal n2) { + res = MapperMaths.multiply(MapperS.of(n1), MapperS.of(n2)).get(); + return res; + } + } + } + """, f ); generatorTestHelper.compileToClasses(code); @@ -4984,64 +4943,62 @@ foo Foo (1..1) var f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.ModelObjectValidator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.test.model.Foo; - import java.util.Collections; - import java.util.List; - import java.util.Optional; - import javax.inject.Inject; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - - /** - * @param inList\s - * @return foo\s - */ - public Foo evaluate(List inList) { - Foo.FooBuilder fooBuilder = doEvaluate(inList); - \t\t - final Foo foo; - if (fooBuilder == null) { - foo = null; - } else { - foo = fooBuilder.build(); - objectValidator.validate(Foo.class, foo); - } - \t\t - return foo; - } - - protected abstract Foo.FooBuilder doEvaluate(List inList); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.ModelObjectValidator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.test.model.Foo; + import java.util.Collections; + import java.util.List; + import java.util.Optional; + import javax.inject.Inject; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + @Inject protected ModelObjectValidator objectValidator; + + /** + * @param inList + * @return foo + */ + public Foo evaluate(List inList) { + Foo.FooBuilder fooBuilder = doEvaluate(inList); + + final Foo foo; + if (fooBuilder == null) { + foo = null; + } else { + foo = fooBuilder.build(); + objectValidator.validate(Foo.class, foo); + } + return foo; + } + + protected abstract Foo.FooBuilder doEvaluate(List inList); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected Foo.FooBuilder doEvaluate(List inList) { + if (inList == null) { + inList = Collections.emptyList(); + } + Foo.FooBuilder foo = Foo.builder(); + return assignOutput(foo, inList); + } - public static class FuncFooDefault extends FuncFoo { - @Override - protected Foo.FooBuilder doEvaluate(List inList) { - if (inList == null) { - inList = Collections.emptyList(); - } - Foo.FooBuilder foo = Foo.builder(); - return assignOutput(foo, inList); - } - \t\t - protected Foo.FooBuilder assignOutput(Foo.FooBuilder foo, List inList) { - foo - .setOutList(inList); - \t\t\t - return Optional.ofNullable(foo) - .map(o -> o.prune()) - .orElse(null); - } - } - } - """, + protected Foo.FooBuilder assignOutput(Foo.FooBuilder foo, List inList) { + foo + .setOutList(inList); + return Optional.ofNullable(foo) + .map(o -> o.prune()) + .orElse(null); + } + } + } + """, f ); generatorTestHelper.compileToClasses(code); @@ -5066,64 +5023,62 @@ foo Foo (1..1) var f = code.get("com.rosetta.test.model.functions.FuncFoo"); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.ModelObjectValidator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.test.model.Foo; - import java.util.Collections; - import java.util.List; - import java.util.Optional; - import javax.inject.Inject; - - - @ImplementedBy(FuncFoo.FuncFooDefault.class) - public abstract class FuncFoo implements RosettaFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - - /** - * @param inList\s - * @return foo\s - */ - public Foo evaluate(List inList) { - Foo.FooBuilder fooBuilder = doEvaluate(inList); - \t\t - final Foo foo; - if (fooBuilder == null) { - foo = null; - } else { - foo = fooBuilder.build(); - objectValidator.validate(Foo.class, foo); - } - \t\t - return foo; - } - - protected abstract Foo.FooBuilder doEvaluate(List inList); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.ModelObjectValidator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.test.model.Foo; + import java.util.Collections; + import java.util.List; + import java.util.Optional; + import javax.inject.Inject; + + + @ImplementedBy(FuncFoo.FuncFooDefault.class) + public abstract class FuncFoo implements RosettaFunction { + + @Inject protected ModelObjectValidator objectValidator; + + /** + * @param inList + * @return foo + */ + public Foo evaluate(List inList) { + Foo.FooBuilder fooBuilder = doEvaluate(inList); + + final Foo foo; + if (fooBuilder == null) { + foo = null; + } else { + foo = fooBuilder.build(); + objectValidator.validate(Foo.class, foo); + } + return foo; + } + + protected abstract Foo.FooBuilder doEvaluate(List inList); + + public static class FuncFooDefault extends FuncFoo { + @Override + protected Foo.FooBuilder doEvaluate(List inList) { + if (inList == null) { + inList = Collections.emptyList(); + } + Foo.FooBuilder foo = Foo.builder(); + return assignOutput(foo, inList); + } - public static class FuncFooDefault extends FuncFoo { - @Override - protected Foo.FooBuilder doEvaluate(List inList) { - if (inList == null) { - inList = Collections.emptyList(); - } - Foo.FooBuilder foo = Foo.builder(); - return assignOutput(foo, inList); - } - \t\t - protected Foo.FooBuilder assignOutput(Foo.FooBuilder foo, List inList) { - foo - .addOutList(inList); - \t\t\t - return Optional.ofNullable(foo) - .map(o -> o.prune()) - .orElse(null); - } - } - } - """, + protected Foo.FooBuilder assignOutput(Foo.FooBuilder foo, List inList) { + foo + .addOutList(inList); + return Optional.ofNullable(foo) + .map(o -> o.prune()) + .orElse(null); + } + } + } + """, f ); generatorTestHelper.compileToClasses(code); @@ -5709,54 +5664,52 @@ result boolean (1..1) var f = code.get("com.rosetta.test.model.functions.B"); assertEquals( """ - package com.rosetta.test.model.functions; + package com.rosetta.test.model.functions; - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.functions.RosettaFunction; - import javax.inject.Inject; + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.functions.RosettaFunction; + import javax.inject.Inject; - @ImplementedBy(B.BDefault.class) - public abstract class B implements RosettaFunction { - \t - // RosettaFunction dependencies - // - @Inject protected A a; - - /** - * @return result\s - */ - public Boolean evaluate() { - Boolean result = doEvaluate(); - \t\t - return result; - } + @ImplementedBy(B.BDefault.class) + public abstract class B implements RosettaFunction { - protected abstract Boolean doEvaluate(); + // RosettaFunction dependencies + // + @Inject protected A a; - public static class BDefault extends B { - @Override - protected Boolean doEvaluate() { - Boolean result = null; - return assignOutput(result); - } - \t\t - protected Boolean assignOutput(Boolean result) { - final Boolean ifThenElseResult; - if (true) { - ifThenElseResult = true; - } else if (false) { - ifThenElseResult = true; - } else { - ifThenElseResult = null; - } - result = a.evaluate(ifThenElseResult); - \t\t\t - return result; - } - } - } - """, + /** + * @return result + */ + public Boolean evaluate() { + Boolean result = doEvaluate(); + return result; + } + + protected abstract Boolean doEvaluate(); + + public static class BDefault extends B { + @Override + protected Boolean doEvaluate() { + Boolean result = null; + return assignOutput(result); + } + + protected Boolean assignOutput(Boolean result) { + final Boolean ifThenElseResult; + if (true) { + ifThenElseResult = true; + } else if (false) { + ifThenElseResult = true; + } else { + ifThenElseResult = null; + } + result = a.evaluate(ifThenElseResult); + return result; + } + } + } + """, f ); generatorTestHelper.compileToClasses(code); @@ -5779,48 +5732,46 @@ result boolean (1..1) var f = code.get("com.rosetta.test.model.functions.IsDateGreaterThan"); assertEquals( """ - package com.rosetta.test.model.functions; - - import com.google.inject.ImplementedBy; - import com.rosetta.model.lib.expression.CardinalityOperator; - import com.rosetta.model.lib.functions.RosettaFunction; - import com.rosetta.model.lib.mapper.MapperS; - import com.rosetta.model.lib.records.Date; - import java.time.ZonedDateTime; - - import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - - @ImplementedBy(IsDateGreaterThan.IsDateGreaterThanDefault.class) - public abstract class IsDateGreaterThan implements RosettaFunction { - - /** - * @param date\s - * @param zonedDateTime\s - * @return result\s - */ - public Boolean evaluate(Date date, ZonedDateTime zonedDateTime) { - Boolean result = doEvaluate(date, zonedDateTime); - \t\t - return result; - } - - protected abstract Boolean doEvaluate(Date date, ZonedDateTime zonedDateTime); + package com.rosetta.test.model.functions; + + import com.google.inject.ImplementedBy; + import com.rosetta.model.lib.expression.CardinalityOperator; + import com.rosetta.model.lib.functions.RosettaFunction; + import com.rosetta.model.lib.mapper.MapperS; + import com.rosetta.model.lib.records.Date; + import java.time.ZonedDateTime; + + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; + + @ImplementedBy(IsDateGreaterThan.IsDateGreaterThanDefault.class) + public abstract class IsDateGreaterThan implements RosettaFunction { + + /** + * @param date + * @param zonedDateTime + * @return result + */ + public Boolean evaluate(Date date, ZonedDateTime zonedDateTime) { + Boolean result = doEvaluate(date, zonedDateTime); + return result; + } + + protected abstract Boolean doEvaluate(Date date, ZonedDateTime zonedDateTime); + + public static class IsDateGreaterThanDefault extends IsDateGreaterThan { + @Override + protected Boolean doEvaluate(Date date, ZonedDateTime zonedDateTime) { + Boolean result = null; + return assignOutput(result, date, zonedDateTime); + } - public static class IsDateGreaterThanDefault extends IsDateGreaterThan { - @Override - protected Boolean doEvaluate(Date date, ZonedDateTime zonedDateTime) { - Boolean result = null; - return assignOutput(result, date, zonedDateTime); - } - \t\t - protected Boolean assignOutput(Boolean result, Date date, ZonedDateTime zonedDateTime) { - result = lessThanEquals(MapperS.of(date), MapperS.of(zonedDateTime).map("Date", zdt -> Date.of(zdt.toLocalDate())), CardinalityOperator.All).get(); - \t\t\t - return result; - } - } - } - """, + protected Boolean assignOutput(Boolean result, Date date, ZonedDateTime zonedDateTime) { + result = lessThanEquals(MapperS.of(date), MapperS.of(zonedDateTime).map("Date", zdt -> Date.of(zdt.toLocalDate())), CardinalityOperator.All).get(); + return result; + } + } + } + """, f ); generatorTestHelper.compileToClasses(code); diff --git a/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/rule/RosettaRuleGeneratorTest.java b/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/rule/RosettaRuleGeneratorTest.java index b9bb2ac026..fb0b3ed01f 100644 --- a/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/rule/RosettaRuleGeneratorTest.java +++ b/rune-integration-tests/src/test/java/com/regnosys/rosetta/generator/java/rule/RosettaRuleGeneratorTest.java @@ -149,7 +149,7 @@ bazQux2 string (1..1) assertThat(reportJava, CoreMatchers.notNullValue()); var expected = """ package com.rosetta.test.model.reports; - + import com.google.inject.ImplementedBy; import com.rosetta.model.lib.annotations.RosettaReport; import com.rosetta.model.lib.annotations.RuneLabelProvider; @@ -160,15 +160,15 @@ bazQux2 string (1..1) import com.rosetta.test.model.labels.TEST_REGMiFIRLabelProvider; import java.util.Optional; import javax.inject.Inject; - - + + @RosettaReport(namespace="com.rosetta.test.model", body="TEST_REG", corpusList={"MiFIR"}) @RuneLabelProvider(labelProvider=TEST_REGMiFIRLabelProvider.class) @ImplementedBy(TEST_REGMiFIRReportFunction.TEST_REGMiFIRReportFunctionDefault.class) public abstract class TEST_REGMiFIRReportFunction implements ReportFunction { - \t + @Inject protected ModelObjectValidator objectValidator; - \t + // RosettaFunction dependencies // @Inject protected BarBarOneRule barBarOneRule; @@ -176,15 +176,15 @@ public abstract class TEST_REGMiFIRReportFunction implements ReportFunction o.prune()) .orElse(null); @@ -294,7 +288,7 @@ bazQux2 string (1..1) assertThat(reportJava, CoreMatchers.notNullValue()); var expected = """ package com.rosetta.test.model.reports; - + import com.google.inject.ImplementedBy; import com.rosetta.model.lib.annotations.RosettaReport; import com.rosetta.model.lib.annotations.RuneLabelProvider; @@ -305,15 +299,15 @@ bazQux2 string (1..1) import com.rosetta.test.model.labels.TEST_REGMiFIRLabelProvider; import java.util.Optional; import javax.inject.Inject; - - + + @RosettaReport(namespace="com.rosetta.test.model", body="TEST_REG", corpusList={"MiFIR"}) @RuneLabelProvider(labelProvider=TEST_REGMiFIRLabelProvider.class) @ImplementedBy(TEST_REGMiFIRReportFunction.TEST_REGMiFIRReportFunctionDefault.class) public abstract class TEST_REGMiFIRReportFunction implements ReportFunction { - \t + @Inject protected ModelObjectValidator objectValidator; - \t + // RosettaFunction dependencies // @Inject protected BarBarOneRule barBarOneRule; @@ -321,15 +315,15 @@ public abstract class TEST_REGMiFIRReportFunction implements ReportFunction o.prune()) .orElse(null); @@ -432,7 +420,7 @@ bazQux2 string (1..1) assertThat(reportJava, CoreMatchers.notNullValue()); var expected = """ package com.rosetta.test.model.reports; - + import com.google.inject.ImplementedBy; import com.rosetta.model.lib.annotations.RosettaReport; import com.rosetta.model.lib.annotations.RuneLabelProvider; @@ -443,30 +431,30 @@ bazQux2 string (1..1) import com.rosetta.test.model.labels.TEST_REGMiFIRLabelProvider; import java.util.Optional; import javax.inject.Inject; - - + + @RosettaReport(namespace="com.rosetta.test.model", body="TEST_REG", corpusList={"MiFIR"}) @RuneLabelProvider(labelProvider=TEST_REGMiFIRLabelProvider.class) @ImplementedBy(TEST_REGMiFIRReportFunction.TEST_REGMiFIRReportFunctionDefault.class) public abstract class TEST_REGMiFIRReportFunction implements ReportFunction { - \t + @Inject protected ModelObjectValidator objectValidator; - \t + // RosettaFunction dependencies // @Inject protected BarBarTwoRule barBarTwoRule; @Inject protected BarBazRule barBazRule; @Inject protected BarQuxListRule barQuxListRule; @Inject protected New_BarBarOneRule new_BarBarOneRule; - + /** - * @param input\s - * @return output\s - */ + * @param input + * @return output + */ @Override public BarReport evaluate(Bar input) { BarReport.BarReportBuilder outputBuilder = doEvaluate(input); - \t\t + final BarReport output; if (outputBuilder == null) { output = null; @@ -474,33 +462,28 @@ public BarReport evaluate(Bar input) { output = outputBuilder.build(); objectValidator.validate(BarReport.class, output); } - \t\t return output; } - + protected abstract BarReport.BarReportBuilder doEvaluate(Bar input); - + public static class TEST_REGMiFIRReportFunctionDefault extends TEST_REGMiFIRReportFunction { @Override protected BarReport.BarReportBuilder doEvaluate(Bar input) { BarReport.BarReportBuilder output = BarReport.builder(); return assignOutput(output, input); } - \t\t + protected BarReport.BarReportBuilder assignOutput(BarReport.BarReportBuilder output, Bar input) { output .setBarBarOne(new_BarBarOneRule.evaluate(input)); - \t\t\t output .setBarBarTwo(barBarTwoRule.evaluate(input)); - \t\t\t output .getOrCreateBarBaz() .setBarBaz1(barBazRule.evaluate(input)); - \t\t\t output .setBarQuxList(barQuxListRule.evaluate(input)); - \t\t\t return Optional.ofNullable(output) .map(o -> o.prune()) .orElse(null); @@ -561,7 +544,7 @@ bazQux2 string (1..1) assertThat(reportJava, CoreMatchers.notNullValue()); var expected = """ package com.rosetta.test.model.reports; - + import com.google.inject.ImplementedBy; import com.rosetta.model.lib.annotations.RosettaReport; import com.rosetta.model.lib.annotations.RuneLabelProvider; @@ -572,29 +555,29 @@ bazQux2 string (1..1) import com.rosetta.test.model.labels.TEST_REGMiFIRLabelProvider; import java.util.Optional; import javax.inject.Inject; - - + + @RosettaReport(namespace="com.rosetta.test.model", body="TEST_REG", corpusList={"MiFIR"}) @RuneLabelProvider(labelProvider=TEST_REGMiFIRLabelProvider.class) @ImplementedBy(TEST_REGMiFIRReportFunction.TEST_REGMiFIRReportFunctionDefault.class) public abstract class TEST_REGMiFIRReportFunction implements ReportFunction { - \t + @Inject protected ModelObjectValidator objectValidator; - \t + // RosettaFunction dependencies // @Inject protected BarBarTwoRule barBarTwoRule; @Inject protected BarBazRule barBazRule; @Inject protected BarQuxListRule barQuxListRule; - + /** - * @param input\s - * @return output\s - */ + * @param input + * @return output + */ @Override public BarReport evaluate(Bar input) { BarReport.BarReportBuilder outputBuilder = doEvaluate(input); - \t\t + final BarReport output; if (outputBuilder == null) { output = null; @@ -602,30 +585,26 @@ public BarReport evaluate(Bar input) { output = outputBuilder.build(); objectValidator.validate(BarReport.class, output); } - \t\t return output; } - + protected abstract BarReport.BarReportBuilder doEvaluate(Bar input); - + public static class TEST_REGMiFIRReportFunctionDefault extends TEST_REGMiFIRReportFunction { @Override protected BarReport.BarReportBuilder doEvaluate(Bar input) { BarReport.BarReportBuilder output = BarReport.builder(); return assignOutput(output, input); } - \t\t + protected BarReport.BarReportBuilder assignOutput(BarReport.BarReportBuilder output, Bar input) { output .setBarBarTwo(barBarTwoRule.evaluate(input)); - \t\t\t output .getOrCreateBarBaz() .setBarBaz1(barBazRule.evaluate(input)); - \t\t\t output .setBarQuxList(barQuxListRule.evaluate(input)); - \t\t\t return Optional.ofNullable(output) .map(o -> o.prune()) .orElse(null); @@ -700,7 +679,7 @@ attr string (1..1) var expected = """ package com.rosetta.test.model.reports; - + import com.google.inject.ImplementedBy; import com.rosetta.model.lib.annotations.RosettaReport; import com.rosetta.model.lib.annotations.RuneLabelProvider; @@ -711,27 +690,27 @@ attr string (1..1) import com.rosetta.test.model.labels.TEST_REGMiFIRLabelProvider; import java.util.Optional; import javax.inject.Inject; - - + + @RosettaReport(namespace="com.rosetta.test.model", body="TEST_REG", corpusList={"MiFIR"}) @RuneLabelProvider(labelProvider=TEST_REGMiFIRLabelProvider.class) @ImplementedBy(TEST_REGMiFIRReportFunction.TEST_REGMiFIRReportFunctionDefault.class) public abstract class TEST_REGMiFIRReportFunction implements ReportFunction { - \t + @Inject protected ModelObjectValidator objectValidator; - \t + // RosettaFunction dependencies // @Inject protected BarToBazReportRule barToBazReportRule; - + /** - * @param input\s - * @return output\s - */ + * @param input + * @return output + */ @Override public BarReport evaluate(Bar input) { BarReport.BarReportBuilder outputBuilder = doEvaluate(input); - \t\t + final BarReport output; if (outputBuilder == null) { output = null; @@ -739,23 +718,21 @@ public BarReport evaluate(Bar input) { output = outputBuilder.build(); objectValidator.validate(BarReport.class, output); } - \t\t return output; } - + protected abstract BarReport.BarReportBuilder doEvaluate(Bar input); - + public static class TEST_REGMiFIRReportFunctionDefault extends TEST_REGMiFIRReportFunction { @Override protected BarReport.BarReportBuilder doEvaluate(Bar input) { BarReport.BarReportBuilder output = BarReport.builder(); return assignOutput(output, input); } - \t\t + protected BarReport.BarReportBuilder assignOutput(BarReport.BarReportBuilder output, Bar input) { output .setBaz(barToBazReportRule.evaluate(input)); - \t\t\t return Optional.ofNullable(output) .map(o -> o.prune()) .orElse(null); @@ -808,7 +785,7 @@ bar1 string (0..1) assertThat(reportJava, CoreMatchers.notNullValue()); var expected = """ package com.rosetta.test.model.reports; - + import com.google.inject.ImplementedBy; import com.rosetta.model.lib.annotations.RosettaReport; import com.rosetta.model.lib.annotations.RuneLabelProvider; @@ -819,23 +796,23 @@ bar1 string (0..1) import com.rosetta.test.model.labels.TEST_REGMiFIRLabelProvider; import java.util.Optional; import javax.inject.Inject; - - + + @RosettaReport(namespace="com.rosetta.test.model", body="TEST_REG", corpusList={"MiFIR"}) @RuneLabelProvider(labelProvider=TEST_REGMiFIRLabelProvider.class) @ImplementedBy(TEST_REGMiFIRReportFunction.TEST_REGMiFIRReportFunctionDefault.class) public abstract class TEST_REGMiFIRReportFunction implements ReportFunction { - \t + @Inject protected ModelObjectValidator objectValidator; - + /** - * @param input\s - * @return output\s - */ + * @param input + * @return output + */ @Override public BarReport evaluate(Bar input) { BarReport.BarReportBuilder outputBuilder = doEvaluate(input); - \t\t + final BarReport output; if (outputBuilder == null) { output = null; @@ -843,19 +820,18 @@ public BarReport evaluate(Bar input) { output = outputBuilder.build(); objectValidator.validate(BarReport.class, output); } - \t\t return output; } - + protected abstract BarReport.BarReportBuilder doEvaluate(Bar input); - + public static class TEST_REGMiFIRReportFunctionDefault extends TEST_REGMiFIRReportFunction { @Override protected BarReport.BarReportBuilder doEvaluate(Bar input) { BarReport.BarReportBuilder output = BarReport.builder(); return assignOutput(output, input); } - \t\t + protected BarReport.BarReportBuilder assignOutput(BarReport.BarReportBuilder output, Bar input) { return Optional.ofNullable(output) .map(o -> o.prune()) @@ -895,46 +871,44 @@ baz string (1..1) assertThat(ruleJava, CoreMatchers.notNullValue()); var expected = """ package com.rosetta.test.model.reports; - + import com.google.inject.ImplementedBy; import com.rosetta.model.lib.mapper.MapperS; import com.rosetta.model.lib.reports.ReportFunction; import com.rosetta.test.model.Bar; import com.rosetta.test.model.Foo; - - + + @ImplementedBy(Rule1Rule.Rule1RuleDefault.class) public abstract class Rule1Rule implements ReportFunction { - - /** - * @param input\s - * @return output\s - */ - @Override - public String evaluate(Foo input) { - String output = doEvaluate(input); - \t\t - return output; - } - - protected abstract String doEvaluate(Foo input); - - public static class Rule1RuleDefault extends Rule1Rule { - @Override - protected String doEvaluate(Foo input) { - String output = null; - return assignOutput(output, input); - } - \t\t - protected String assignOutput(String output, Foo input) { - final MapperS thenArg = MapperS.of(input) - .mapSingleToItem(item -> item.map("getBar", foo -> foo.getBar())); - output = thenArg - .mapSingleToItem(item -> item.map("getBaz", bar -> bar.getBaz())).get(); - \t\t\t - return output; - } - } + + /** + * @param input + * @return output + */ + @Override + public String evaluate(Foo input) { + String output = doEvaluate(input); + return output; + } + + protected abstract String doEvaluate(Foo input); + + public static class Rule1RuleDefault extends Rule1Rule { + @Override + protected String doEvaluate(Foo input) { + String output = null; + return assignOutput(output, input); + } + + protected String assignOutput(String output, Foo input) { + final MapperS thenArg = MapperS.of(input) + .mapSingleToItem(item -> item.map("getBar", foo -> foo.getBar())); + output = thenArg + .mapSingleToItem(item -> item.map("getBaz", bar -> bar.getBaz())).get(); + return output; + } + } } """; assertJavaEquals(expected, ruleJava); @@ -966,50 +940,48 @@ val string (1..1) assertThat(rule, CoreMatchers.notNullValue()); var expected = """ package com.rosetta.test.model.reports; - + import com.google.inject.ImplementedBy; import com.rosetta.model.lib.mapper.MapperS; import com.rosetta.model.lib.reports.ReportFunction; import com.rosetta.test.model.Bar; import com.rosetta.test.model.Foo; import javax.inject.Inject; - - + + @ImplementedBy(Rule1Rule.Rule1RuleDefault.class) public abstract class Rule1Rule implements ReportFunction { - \t - // RosettaFunction dependencies - // - @Inject protected Rule2Rule rule2Rule; - - /** - * @param input\s - * @return output\s - */ - @Override - public String evaluate(Foo input) { - String output = doEvaluate(input); - \t\t - return output; - } - - protected abstract String doEvaluate(Foo input); - - public static class Rule1RuleDefault extends Rule1Rule { - @Override - protected String doEvaluate(Foo input) { - String output = null; - return assignOutput(output, input); - } - \t\t - protected String assignOutput(String output, Foo input) { - final MapperS thenArg = MapperS.of(rule2Rule.evaluate(input)); - output = thenArg - .mapSingleToItem(item -> item.map("getVal", bar -> bar.getVal())).get(); - \t\t\t - return output; - } - } + + // RosettaFunction dependencies + // + @Inject protected Rule2Rule rule2Rule; + + /** + * @param input + * @return output + */ + @Override + public String evaluate(Foo input) { + String output = doEvaluate(input); + return output; + } + + protected abstract String doEvaluate(Foo input); + + public static class Rule1RuleDefault extends Rule1Rule { + @Override + protected String doEvaluate(Foo input) { + String output = null; + return assignOutput(output, input); + } + + protected String assignOutput(String output, Foo input) { + final MapperS thenArg = MapperS.of(rule2Rule.evaluate(input)); + output = thenArg + .mapSingleToItem(item -> item.map("getVal", bar -> bar.getVal())).get(); + return output; + } + } } """; assertJavaEquals(expected, rule); @@ -1033,7 +1005,7 @@ traderef string (1..1) assertThat(ruleJava, CoreMatchers.notNullValue()); var expected = """ package com.rosetta.test.model.reports; - + import com.google.inject.ImplementedBy; import com.rosetta.model.lib.expression.CardinalityOperator; import com.rosetta.model.lib.functions.ModelObjectValidator; @@ -1042,51 +1014,49 @@ traderef string (1..1) import com.rosetta.test.model.Input; import java.util.Optional; import javax.inject.Inject; - + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - + @ImplementedBy(SimpleRuleRule.SimpleRuleRuleDefault.class) public abstract class SimpleRuleRule implements ReportFunction { - \t - @Inject protected ModelObjectValidator objectValidator; - - /** - * @param input\s - * @return output\s - */ - @Override - public Input evaluate(Input input) { - Input.InputBuilder outputBuilder = doEvaluate(input); - \t\t - final Input output; - if (outputBuilder == null) { - output = null; - } else { - output = outputBuilder.build(); - objectValidator.validate(Input.class, output); - } - \t\t - return output; - } - - protected abstract Input.InputBuilder doEvaluate(Input input); - - public static class SimpleRuleRuleDefault extends SimpleRuleRule { - @Override - protected Input.InputBuilder doEvaluate(Input input) { - Input.InputBuilder output = Input.builder(); - return assignOutput(output, input); - } - \t\t - protected Input.InputBuilder assignOutput(Input.InputBuilder output, Input input) { - output = toBuilder(MapperS.of(input) - .filterSingleNullSafe(item -> areEqual(item.map("getTraderef", _input -> _input.getTraderef()), MapperS.of("Hello"), CardinalityOperator.All).get()).get()); - \t\t\t - return Optional.ofNullable(output) - .map(o -> o.prune()) - .orElse(null); - } - } + + @Inject protected ModelObjectValidator objectValidator; + + /** + * @param input + * @return output + */ + @Override + public Input evaluate(Input input) { + Input.InputBuilder outputBuilder = doEvaluate(input); + + final Input output; + if (outputBuilder == null) { + output = null; + } else { + output = outputBuilder.build(); + objectValidator.validate(Input.class, output); + } + return output; + } + + protected abstract Input.InputBuilder doEvaluate(Input input); + + public static class SimpleRuleRuleDefault extends SimpleRuleRule { + @Override + protected Input.InputBuilder doEvaluate(Input input) { + Input.InputBuilder output = Input.builder(); + return assignOutput(output, input); + } + + protected Input.InputBuilder assignOutput(Input.InputBuilder output, Input input) { + output = toBuilder(MapperS.of(input) + .filterSingleNullSafe(item -> areEqual(item.map("getTraderef", _input -> _input.getTraderef()), MapperS.of("Hello"), CardinalityOperator.All).get()).get()); + return Optional.ofNullable(output) + .map(o -> o.prune()) + .orElse(null); + } + } } """; assertJavaEquals(expected, ruleJava); @@ -1148,45 +1118,43 @@ floating string (0..*) assertThat(ruleJava, CoreMatchers.notNullValue()); var expected = """ package com.rosetta.test.model.reports; - + import com.google.inject.ImplementedBy; import com.rosetta.model.lib.expression.CardinalityOperator; import com.rosetta.model.lib.mapper.MapperS; import com.rosetta.model.lib.reports.ReportFunction; import com.rosetta.test.model.Foo; - + import static com.rosetta.model.lib.expression.ExpressionOperatorsNullSafe.*; - + @ImplementedBy(IsFixedFloatRule.IsFixedFloatRuleDefault.class) public abstract class IsFixedFloatRule implements ReportFunction { - - /** - * @param input\s - * @return output\s - */ - @Override - public Boolean evaluate(Foo input) { - Boolean output = doEvaluate(input); - \t\t - return output; - } - - protected abstract Boolean doEvaluate(Foo input); - - public static class IsFixedFloatRuleDefault extends IsFixedFloatRule { - @Override - protected Boolean doEvaluate(Foo input) { - Boolean output = null; - return assignOutput(output, input); - } - \t\t - protected Boolean assignOutput(Boolean output, Foo input) { - output = MapperS.of(input) - .mapSingleToItem(item -> areEqual(MapperS.of(item.mapC("getFixed", foo -> foo.getFixed()).resultCount()), MapperS.of(12), CardinalityOperator.All).asMapper()).get(); - \t\t\t - return output; - } - } + + /** + * @param input + * @return output + */ + @Override + public Boolean evaluate(Foo input) { + Boolean output = doEvaluate(input); + return output; + } + + protected abstract Boolean doEvaluate(Foo input); + + public static class IsFixedFloatRuleDefault extends IsFixedFloatRule { + @Override + protected Boolean doEvaluate(Foo input) { + Boolean output = null; + return assignOutput(output, input); + } + + protected Boolean assignOutput(Boolean output, Foo input) { + output = MapperS.of(input) + .mapSingleToItem(item -> areEqual(MapperS.of(item.mapC("getFixed", foo -> foo.getFixed()).resultCount()), MapperS.of(12), CardinalityOperator.All).asMapper()).get(); + return output; + } + } } """; codeGeneratorTestHelper.compileToClasses(code); @@ -1561,41 +1529,39 @@ enum FooEnum: var expectedRule = """ package com.rosetta.test.model.reports; - + import com.google.inject.ImplementedBy; import com.rosetta.model.lib.reports.ReportFunction; import com.rosetta.test.model.FooEnum; - - + + @ImplementedBy(ReturnEnumValueRule.ReturnEnumValueRuleDefault.class) public abstract class ReturnEnumValueRule implements ReportFunction { - - /** - * @param input\s - * @return output\s - */ - @Override - public FooEnum evaluate(String input) { - FooEnum output = doEvaluate(input); - \t\t - return output; - } - - protected abstract FooEnum doEvaluate(String input); - - public static class ReturnEnumValueRuleDefault extends ReturnEnumValueRule { - @Override - protected FooEnum doEvaluate(String input) { - FooEnum output = null; - return assignOutput(output, input); - } - \t\t - protected FooEnum assignOutput(FooEnum output, String input) { - output = FooEnum.BAR; - \t\t\t - return output; - } - } + + /** + * @param input + * @return output + */ + @Override + public FooEnum evaluate(String input) { + FooEnum output = doEvaluate(input); + return output; + } + + protected abstract FooEnum doEvaluate(String input); + + public static class ReturnEnumValueRuleDefault extends ReturnEnumValueRule { + @Override + protected FooEnum doEvaluate(String input) { + FooEnum output = null; + return assignOutput(output, input); + } + + protected FooEnum assignOutput(FooEnum output, String input) { + output = FooEnum.BAR; + return output; + } + } } """; diff --git a/rune-integration-tests/src/test/resources/generation-regression-tests/name-escaping/expected/test/escaping/importoverlap/dep/functions/MyFunc.java b/rune-integration-tests/src/test/resources/generation-regression-tests/name-escaping/expected/test/escaping/importoverlap/dep/functions/MyFunc.java index fcf17d38f9..05bd8beab9 100644 --- a/rune-integration-tests/src/test/resources/generation-regression-tests/name-escaping/expected/test/escaping/importoverlap/dep/functions/MyFunc.java +++ b/rune-integration-tests/src/test/resources/generation-regression-tests/name-escaping/expected/test/escaping/importoverlap/dep/functions/MyFunc.java @@ -7,26 +7,25 @@ @ImplementedBy(MyFunc.MyFuncDefault.class) public abstract class MyFunc implements RosettaFunction { - /** - * @return result - */ - public Integer evaluate() { - Integer result = doEvaluate(); - - return result; - } + /** + * @return result + */ + public Integer evaluate() { + Integer result = doEvaluate(); + return result; + } - protected abstract Integer doEvaluate(); + protected abstract Integer doEvaluate(); - public static class MyFuncDefault extends MyFunc { - @Override - protected Integer doEvaluate() { - Integer result = null; - return assignOutput(result); - } - - protected Integer assignOutput(Integer result) { - return result; - } - } + public static class MyFuncDefault extends MyFunc { + @Override + protected Integer doEvaluate() { + Integer result = null; + return assignOutput(result); + } + + protected Integer assignOutput(Integer result) { + return result; + } + } } diff --git a/rune-integration-tests/src/test/resources/generation-regression-tests/name-escaping/expected/test/escaping/importoverlap/functions/MyFunc.java b/rune-integration-tests/src/test/resources/generation-regression-tests/name-escaping/expected/test/escaping/importoverlap/functions/MyFunc.java index 49371ca12d..6e57cf0f97 100644 --- a/rune-integration-tests/src/test/resources/generation-regression-tests/name-escaping/expected/test/escaping/importoverlap/functions/MyFunc.java +++ b/rune-integration-tests/src/test/resources/generation-regression-tests/name-escaping/expected/test/escaping/importoverlap/functions/MyFunc.java @@ -7,26 +7,25 @@ @ImplementedBy(MyFunc.MyFuncDefault.class) public abstract class MyFunc implements RosettaFunction { - /** - * @return result - */ - public Integer evaluate() { - Integer result = doEvaluate(); - - return result; - } + /** + * @return result + */ + public Integer evaluate() { + Integer result = doEvaluate(); + return result; + } - protected abstract Integer doEvaluate(); + protected abstract Integer doEvaluate(); - public static class MyFuncDefault extends MyFunc { - @Override - protected Integer doEvaluate() { - Integer result = null; - return assignOutput(result); - } - - protected Integer assignOutput(Integer result) { - return result; - } - } + public static class MyFuncDefault extends MyFunc { + @Override + protected Integer doEvaluate() { + Integer result = null; + return assignOutput(result); + } + + protected Integer assignOutput(Integer result) { + return result; + } + } } diff --git a/rune-integration-tests/src/test/resources/generation-regression-tests/name-escaping/expected/test/escaping/importoverlap/functions/UseFunctions.java b/rune-integration-tests/src/test/resources/generation-regression-tests/name-escaping/expected/test/escaping/importoverlap/functions/UseFunctions.java index 065e761df7..36400f4025 100644 --- a/rune-integration-tests/src/test/resources/generation-regression-tests/name-escaping/expected/test/escaping/importoverlap/functions/UseFunctions.java +++ b/rune-integration-tests/src/test/resources/generation-regression-tests/name-escaping/expected/test/escaping/importoverlap/functions/UseFunctions.java @@ -10,34 +10,32 @@ @ImplementedBy(UseFunctions.UseFunctionsDefault.class) public abstract class UseFunctions implements RosettaFunction { - - // RosettaFunction dependencies - // - @Inject protected MyFunc myFunc0; - @Inject protected test.escaping.importoverlap.functions.MyFunc myFunc1; - - /** - * @return result - */ - public Integer evaluate() { - Integer result = doEvaluate(); - - return result; - } - - protected abstract Integer doEvaluate(); - - public static class UseFunctionsDefault extends UseFunctions { - @Override - protected Integer doEvaluate() { - Integer result = null; - return assignOutput(result); - } - - protected Integer assignOutput(Integer result) { - result = MapperMaths.add(MapperS.of(myFunc1.evaluate()), MapperS.of(myFunc0.evaluate())).get(); - - return result; - } - } + + // RosettaFunction dependencies + // + @Inject protected MyFunc myFunc0; + @Inject protected test.escaping.importoverlap.functions.MyFunc myFunc1; + + /** + * @return result + */ + public Integer evaluate() { + Integer result = doEvaluate(); + return result; + } + + protected abstract Integer doEvaluate(); + + public static class UseFunctionsDefault extends UseFunctions { + @Override + protected Integer doEvaluate() { + Integer result = null; + return assignOutput(result); + } + + protected Integer assignOutput(Integer result) { + result = MapperMaths.add(MapperS.of(myFunc1.evaluate()), MapperS.of(myFunc0.evaluate())).get(); + return result; + } + } } diff --git a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/FluentJavaClassGenerator.java b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/FluentJavaClassGenerator.java index 67662f022c..c737456426 100644 --- a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/FluentJavaClassGenerator.java +++ b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/FluentJavaClassGenerator.java @@ -17,13 +17,13 @@ package com.regnosys.rosetta.generator.java; import com.regnosys.rosetta.codegen.api.CodeRenderer; -import com.regnosys.rosetta.codegen.support.StringCodeWriter; import com.regnosys.rosetta.generator.java.scoping.JavaClassScope; -import com.regnosys.rosetta.generator.java.scoping.JavaFileScope; +import com.regnosys.rosetta.generator.java.util.FluentImportManager; import com.regnosys.rosetta.generator.java.util.RecordingCodeWriter; -import com.rosetta.util.DottedPath; import com.rosetta.util.types.JavaTypeDeclaration; +import jakarta.inject.Inject; + /** * Base class for generators that produce a Java class using the fluent * {@link CodeRenderer} API. This is the fluent counterpart of @@ -37,36 +37,14 @@ * while rendering. */ public abstract class FluentJavaClassGenerator> extends JavaClassGenerator { + @Inject + private FluentImportManager importManager; + protected abstract CodeRenderer generateClass(T object, C typeRepresentation, String version, JavaClassScope scope); @Override protected String generate(T object, C typeRepresentation, String version, JavaClassScope scope) { CodeRenderer classCode = generateClass(object, typeRepresentation, version, scope); - return buildClass(typeRepresentation.getPackageName(), classCode, scope.getFileScope()); - } - - /** - * Given the body of a Java class represented as a {@link CodeRenderer}, - * generate a full Java class file by adding imports and resolving identifiers. - */ - protected String buildClass(DottedPath packageName, CodeRenderer classCode, JavaFileScope fileScope) { - if (fileScope.isClosed()) { - throw new IllegalStateException("The top scope may not be closed, as imports will be added to it."); - } - RecordingCodeWriter recording = new RecordingCodeWriter(fileScope); - classCode.render(recording); - - StringCodeWriter result = new StringCodeWriter(); - result.writeln("package ", packageName, ";"); - result.newline(); - recording.getImports().forEach(imp -> result.writeln("import ", imp, ";")); - result.newline(); - recording.getStaticImports().forEach(imp -> result.writeln("import static ", imp, ";")); - result.newline(); - recording.replay(result); - if (!result.toString().endsWith("\n")) { - result.newline(); - } - return result.toString(); + return importManager.buildClass(typeRepresentation.getPackageName(), classCode, scope.getFileScope()); } } diff --git a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/expression/DeepPathUtilGenerator.java b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/expression/DeepPathUtilGenerator.java index 827ac400c5..75e8770d10 100644 --- a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/expression/DeepPathUtilGenerator.java +++ b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/expression/DeepPathUtilGenerator.java @@ -101,7 +101,7 @@ protected CodeRenderer generateClass(RDataType choiceType, JavaClass javaClas .map(deepFeature -> createMethod(choiceType, deepFeature, recursiveDeepFeatures, classScope)) .toList(); - return out -> renderClass(out, javaClass, classScope, dependencies, methods); + return renderClass(javaClass, classScope, dependencies, methods); } private Map> computeRecursiveDeepFeatures(RDataType choiceType, Collection deepFeatures, Set> dependencies) { @@ -172,19 +172,21 @@ private JavaStatementBuilder deepFeatureValue(JavaStatementBuilder attrVar, RAtt return expressionGenerator.attributeCall(attrVar, attrMetaType, actualFeature, needsToGoDownDeeper, deepFeatureType, scope); } - private void renderClass(CodeWriter out, JavaClass javaClass, JavaClassScope classScope, Set> dependencies, List methods) { - out.writeln("public class ", javaClass, " {"); - out.indented(() -> { - if (!dependencies.isEmpty()) { - renderDependencies(out, javaClass, classScope, dependencies); - out.newline(); - } - for (DeepFeatureMethod method : methods) { - out.writeln("public ", method.returnType(), " ", method.name(), "(", method.inputParameter().getExpressionType(), " ", method.inputParameter(), ") ", method.body()); - out.newline(); - } - }); - out.write("}"); + private CodeRenderer renderClass(JavaClass javaClass, JavaClassScope classScope, Set> dependencies, List methods) { + return out -> { + out.writeln("public class ", javaClass, " {"); + out.indented(() -> { + if (!dependencies.isEmpty()) { + renderDependencies(out, javaClass, classScope, dependencies); + out.newline(); + } + for (DeepFeatureMethod method : methods) { + out.writeln("public ", method.returnType(), " ", method.name(), "(", method.inputParameter().getExpressionType(), " ", method.inputParameter(), ") ", method.body()); + out.newline(); + } + }); + out.write("}"); + }; } private void renderDependencies(CodeWriter out, JavaClass javaClass, JavaClassScope classScope, Set> dependencies) { diff --git a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/function/FunctionGenerator.java b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/function/FunctionGenerator.java new file mode 100644 index 0000000000..0266aa3875 --- /dev/null +++ b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/function/FunctionGenerator.java @@ -0,0 +1,895 @@ +package com.regnosys.rosetta.generator.java.function; + +import static com.regnosys.rosetta.generator.java.enums.EnumHelper.formatEnumName; +import static org.apache.commons.lang3.StringUtils.capitalize; +import static org.apache.commons.lang3.StringUtils.uncapitalize; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.google.inject.ImplementedBy; +import com.regnosys.rosetta.codegen.api.CodeRenderer; +import com.regnosys.rosetta.codegen.api.CodeWriter; +import com.regnosys.rosetta.generator.GeneratedIdentifier; +import com.regnosys.rosetta.generator.java.FluentRObjectJavaClassGenerator; +import com.regnosys.rosetta.generator.java.expression.ExpressionGenerator; +import com.regnosys.rosetta.generator.java.expression.JavaDependencyProvider; +import com.regnosys.rosetta.generator.java.expression.TypeCoercionService; +import com.regnosys.rosetta.generator.java.labels.LabelProviderGeneratorUtil; +import com.regnosys.rosetta.generator.java.scoping.JavaClassScope; +import com.regnosys.rosetta.generator.java.scoping.JavaIdentifierRepresentationService; +import com.regnosys.rosetta.generator.java.scoping.JavaMethodScope; +import com.regnosys.rosetta.generator.java.scoping.JavaStatementScope; +import com.regnosys.rosetta.generator.java.statement.JavaStatement; +import com.regnosys.rosetta.generator.java.statement.builder.JavaExpression; +import com.regnosys.rosetta.generator.java.statement.builder.JavaStatementBuilder; +import com.regnosys.rosetta.generator.java.statement.builder.JavaVariable; +import com.regnosys.rosetta.generator.java.types.JavaPojoInterface; +import com.regnosys.rosetta.generator.java.types.JavaPojoProperty; +import com.regnosys.rosetta.generator.java.types.JavaPojoPropertyOperationType; +import com.regnosys.rosetta.generator.java.types.JavaTypeTranslator; +import com.regnosys.rosetta.generator.java.types.JavaTypeUtil; +import com.regnosys.rosetta.generator.java.types.RGeneratedJavaClass; +import com.regnosys.rosetta.generator.java.types.RJavaFieldWithMeta; +import com.regnosys.rosetta.generator.java.types.RJavaPojoInterface; +import com.regnosys.rosetta.generator.java.types.RJavaReferenceWithMeta; +import com.regnosys.rosetta.generator.java.types.RJavaWithMetaValue; +import com.regnosys.rosetta.generator.java.util.CodeWriterTargetStringConcatenation; +import com.regnosys.rosetta.generator.java.util.ModelGeneratorUtil; +import com.regnosys.rosetta.generator.util.RosettaFunctionExtensions; +import com.regnosys.rosetta.rosetta.RosettaCallableWithArgs; +import com.regnosys.rosetta.rosetta.RosettaEnumeration; +import com.regnosys.rosetta.rosetta.RosettaFeature; +import com.regnosys.rosetta.rosetta.RosettaModel; +import com.regnosys.rosetta.rosetta.RosettaSymbol; +import com.regnosys.rosetta.rosetta.expression.AsKeyOperation; +import com.regnosys.rosetta.rosetta.expression.RosettaExpression; +import com.regnosys.rosetta.rosetta.expression.RosettaFeatureCall; +import com.regnosys.rosetta.rosetta.expression.RosettaSymbolReference; +import com.regnosys.rosetta.rosetta.expression.RosettaUnaryOperation; +import com.regnosys.rosetta.rosetta.simple.Attribute; +import com.regnosys.rosetta.rosetta.simple.Condition; +import com.regnosys.rosetta.rosetta.simple.Function; +import com.regnosys.rosetta.rosetta.simple.FunctionDispatch; +import com.regnosys.rosetta.rosetta.simple.ShortcutDeclaration; +import com.regnosys.rosetta.rosetta.simple.TransformAnnotation; +import com.regnosys.rosetta.types.CardinalityProvider; +import com.regnosys.rosetta.types.RAttribute; +import com.regnosys.rosetta.types.RFeature; +import com.regnosys.rosetta.types.RFunction; +import com.regnosys.rosetta.types.RFunctionOrigin; +import com.regnosys.rosetta.types.RMetaAnnotatedType; +import com.regnosys.rosetta.types.RMetaAttribute; +import com.regnosys.rosetta.types.RObjectFactory; +import com.regnosys.rosetta.types.ROperation; +import com.regnosys.rosetta.types.ROperationType; +import com.regnosys.rosetta.types.RShortcut; +import com.regnosys.rosetta.types.RosettaTypeProvider; +import com.regnosys.rosetta.utils.ExpressionHelper; +import com.regnosys.rosetta.utils.ImplicitVariableUtil; +import com.regnosys.rosetta.utils.ModelIdProvider; +import com.regnosys.rosetta.utils.PojoPropertyUtil; +import com.regnosys.rosetta.utils.TransformAnnotationHelper; +import com.rosetta.model.lib.ModelSymbolId; +import com.rosetta.model.lib.annotations.RuneLabelProvider; +import com.rosetta.model.lib.functions.ConditionValidator; +import com.rosetta.model.lib.functions.IQualifyFunctionExtension; +import com.rosetta.model.lib.functions.ModelObjectValidator; +import com.rosetta.model.lib.functions.RosettaFunction; +import com.rosetta.model.lib.transform.SerializationFormat; +import com.rosetta.util.types.JavaClass; +import com.rosetta.util.types.JavaParameterizedType; +import com.rosetta.util.types.JavaPrimitiveType; +import com.rosetta.util.types.JavaReferenceType; +import com.rosetta.util.types.JavaType; + +import jakarta.inject.Inject; + +public class FunctionGenerator extends FluentRObjectJavaClassGenerator> { + + @Inject + private ExpressionGenerator expressionGenerator; + @Inject + private JavaDependencyProvider dependencyProvider; + @Inject + private RosettaTypeProvider typeProvider; + @Inject + private RosettaFunctionExtensions functionExtensions; + @Inject + private ModelGeneratorUtil modelGeneratorUtil; + @Inject + private ExpressionHelper exprHelper; + @Inject + private CardinalityProvider cardinality; + @Inject + private JavaIdentifierRepresentationService identifierService; + @Inject + private JavaTypeTranslator typeTranslator; + @Inject + private RObjectFactory rObjectFactory; + @Inject + private ImplicitVariableUtil implicitVariableUtil; + @Inject + private JavaTypeUtil typeUtil; + @Inject + private TypeCoercionService coercionService; + @Inject + private ModelIdProvider modelIdProvider; + @Inject + private LabelProviderGeneratorUtil labelProviderUtil; + @Inject + private AliasUtil aliasUtil; + @Inject + private TransformAnnotationHelper transformAnnotationHelper; + + @Override + protected Stream streamObjects(RosettaModel model) { + return model.getElements().stream() + .filter(e -> e instanceof Function && !(e instanceof FunctionDispatch)) + .map(Function.class::cast) + .map(rObjectFactory::buildRFunction); + } + + @Override + protected RGeneratedJavaClass createTypeRepresentation(RFunction rFunction) { + return typeTranslator.toFunctionJavaClass(rFunction); + } + + @Override + protected CodeRenderer generateClass(RFunction rFunction, RGeneratedJavaClass javaFunctionClass, String version, JavaClassScope scope) { + if (rFunction.getEObject() instanceof Function origin && functionExtensions.handleAsEnumFunction(origin)) { + return dispatchClassBody(origin, javaFunctionClass, scope, version); + } + boolean overridesEvaluate = false; + List functionInterfaces = new ArrayList<>(); + functionInterfaces.add(JavaClass.from(RosettaFunction.class)); + if (functionExtensions.isQualifierFunction(rFunction)) { + overridesEvaluate = true; + functionInterfaces.add(getQualifyingFunctionInterface(rFunction.getInputs())); + } + Map, CodeRenderer> annotations = new LinkedHashMap<>(); + if (rFunction.getEObject() instanceof Function origin && labelProviderUtil.shouldGenerateLabelProvider(origin)) { + JavaClass labelProviderClass = typeTranslator.toLabelProviderJavaClass(rFunction); + annotations.put(RuneLabelProvider.class, out -> out.write("labelProvider=", labelProviderClass, ".class")); + } + if (rFunction.getEObject() instanceof Function origin && !origin.getTransform().isEmpty()) { + addTransformAnnotation(origin.getTransform().get(0), annotations); + } + return rBuildClass(rFunction, javaFunctionClass, false, functionInterfaces, annotations, overridesEvaluate, scope); + } + + public CodeRenderer rBuildClass(RFunction rFunction, RGeneratedJavaClass javaFunctionClass, boolean isStatic, List functionInterfaces, Map, CodeRenderer> annotations, boolean overridesEvaluate, JavaClassScope classScope) { + List> dependencies = collectFunctionDependencies(rFunction); + return classBody(rFunction, javaFunctionClass, isStatic, overridesEvaluate, dependencies, functionInterfaces, annotations, classScope); + } + + private void addTransformAnnotation(TransformAnnotation transform, Map, CodeRenderer> annotations) { + Class annotationClass = typeTranslator.toTransformAnnotationClass(transform.getKind()); + String id = transformAnnotationHelper.getSchemaId(transform).orElse(null); + SerializationFormat format = transformAnnotationHelper.getFormat(transform).orElse(null); + String configPath = transformAnnotationHelper.getConfigPath(transform).orElse(null); + annotations.put(annotationClass, out -> { + boolean needsSeparator = false; + if (id != null) { + out.write("id = \"", id, "\""); + needsSeparator = true; + } + if (format != null) { + if (needsSeparator) { + out.write(", "); + } + out.write("format = ", SerializationFormat.class, ".", format.name()); + } + if (configPath != null) { + out.write(", configPath = \"", configPath, "\""); + } + }); + } + + private JavaType getQualifyingFunctionInterface(List inputs) { + RAttribute first = inputs.get(0); + JavaClass parameterVariable = typeTranslator.toListOrSingleJavaType(first.getRMetaAnnotatedType(), first.isMulti()); + return JavaParameterizedType.from(new TypeReference>() {}, parameterVariable); + } + + private List> collectFunctionDependencies(RFunction func) { + List expressions = new ArrayList<>(); + func.getPreConditions().forEach(c -> expressions.add(c.getExpression())); + func.getPostConditions().forEach(c -> expressions.add(c.getExpression())); + func.getOperations().forEach(o -> expressions.add(o.getExpression())); + func.getShortcuts().forEach(s -> expressions.add(s.getExpression())); + return dependencyProvider.javaDependencies(expressions); + } + + private CodeRenderer classBody( + RFunction function, + RGeneratedJavaClass javaFunctionClass, + boolean isStatic, + boolean overridesEvaluate, + List> dependencies, + List functionInterfaces, + Map, CodeRenderer> annotations, + JavaClassScope classScope) { + return out -> { + List inputs = function.getInputs(); + RAttribute output = function.getOutput(); + List shortcuts = function.getShortcuts(); + List operations = function.getOperations(); + List preConditions = function.getPreConditions(); + List postConditions = function.getPostConditions(); + + dependencies.forEach(dep -> classScope.createIdentifier(identifierService.toDependencyInstance(dep), uncapitalize(dep.getSimpleName()))); + + RGeneratedJavaClass defaultClass = javaFunctionClass.createNestedClassWithSuperclass(javaFunctionClass.getSimpleName() + "Default", javaFunctionClass); + JavaClassScope defaultClassScope = classScope.createNestedClassScopeAndRegisterIdentifier(defaultClass); + JavaType outputType = typeTranslator.toMetaJavaType(output); + Map aliasOut = shortcuts.stream() + .collect(Collectors.toMap(s -> s, s -> exprHelper.usesOutputParameter(s.getExpression()))); + + GeneratedIdentifier conditionValidatorId = classScope.createUniqueIdentifier("conditionValidator"); + GeneratedIdentifier objectValidatorId = classScope.createUniqueIdentifier("objectValidator"); + + JavaMethodScope evaluateScope = classScope.createMethodScope("evaluate"); + inputs.forEach(input -> evaluateScope.createIdentifier(input, input.getName())); + JavaStatementScope evaluateBodyScope = evaluateScope.getBodyScope(); + evaluateBodyScope.createIdentifier(output, output.getName()); + GeneratedIdentifier outputBuilderId = needsBuilder(output) + ? evaluateBodyScope.createUniqueIdentifier(output.getName() + "Builder") + : null; + + JavaMethodScope doEvaluateScope = classScope.createMethodScope("doEvaluate"); + inputs.forEach(input -> doEvaluateScope.createIdentifier(input, input.getName())); + doEvaluateScope.createIdentifier(output, output.getName()); + + JavaMethodScope defaultDoEvaluateScope = defaultClassScope.createMethodScope("doEvaluate"); + inputs.forEach(input -> defaultDoEvaluateScope.createIdentifier(input, input.getName())); + defaultDoEvaluateScope.createIdentifier(output, output.getName()); + JavaStatementScope defaultDoEvaluateBodyScope = defaultDoEvaluateScope.getBodyScope(); + + JavaMethodScope assignOutputScope = defaultClassScope.createMethodScope("assignOutput"); + inputs.forEach(input -> assignOutputScope.createIdentifier(input, input.getName())); + assignOutputScope.createIdentifier(output, output.getName()); + operations.stream() + .map(ROperation::getExpression) + .filter(e -> implicitVariableUtil.implicitVariableExistsInContext(e)) + .map(e -> identifierService.getImplicitVarInContext(e)) + .distinct() + .forEach(v -> assignOutputScope.createKeySynonym(v, inputs.get(0))); + JavaStatementScope assignOutputBodyScope = assignOutputScope.getBodyScope(); + + Map aliasScopes = new java.util.HashMap<>(); + Map defaultClassAliasScopes = new java.util.HashMap<>(); + shortcuts.forEach(alias -> { + classScope.createIdentifier(alias, alias.getName()); + + JavaMethodScope aliasScope = classScope.createMethodScope(alias.getName()); + aliasScopes.put(alias, aliasScope); + + JavaMethodScope defaultClassAliasScope = defaultClassScope.createMethodScope(alias.getName()); + defaultClassAliasScopes.put(alias, defaultClassAliasScope); + + if (aliasUtil.requiresOutput(alias)) { + aliasScope.createIdentifier(output, output.getName()); + defaultClassAliasScope.createIdentifier(output, output.getName()); + } + inputs.forEach(input -> { + aliasScope.createIdentifier(input, input.getName()); + defaultClassAliasScope.createIdentifier(input, input.getName()); + }); + }); + + annotations.forEach((annotationClass, annotationBody) -> { + out.write("@", annotationClass, "("); + out.write(annotationBody); + out.writeln(")"); + }); + out.writeln("@", ImplementedBy.class, "(", defaultClass, ".class)"); + out.write("public ", isStatic ? "static " : "", "abstract class ", javaFunctionClass.getSimpleName()); + if (!functionInterfaces.isEmpty()) { + out.write(" implements "); + out.join(functionInterfaces, ","); + } + out.writeln(" {"); + out.indented(() -> { + if (!preConditions.isEmpty() || !postConditions.isEmpty()) { + out.newline(); + out.writeln("@", javax.inject.Inject.class, " protected ", ConditionValidator.class, " ", conditionValidatorId, ";"); + } + if (needsBuilder(output)) { + out.newline(); + out.writeln("@", javax.inject.Inject.class, " protected ", ModelObjectValidator.class, " ", objectValidatorId, ";"); + } + if (!dependencies.isEmpty()) { + out.newline(); + out.writeln("// RosettaFunction dependencies"); + out.writeln("//"); + dependencies.forEach(dep -> out.writeln("@", javax.inject.Inject.class, " protected ", dep, " ", classScope.getIdentifierOrThrow(identifierService.toDependencyInstance(dep)), ";")); + } + out.newline(); + + out.writeln("/**"); + inputs.forEach(input -> renderJavadocTag(out, "@param", evaluateScope.getIdentifierOrThrow(input), input.getDefinition())); + renderJavadocTag(out, "@return", evaluateBodyScope.getIdentifierOrThrow(output), output.getDefinition()); + out.writeln(" */"); + if (overridesEvaluate) { + out.writeln("@Override"); + } + out.write("public ", outputType, " evaluate("); + renderInputsAsParameters(out, inputs, evaluateScope); + out.writeln(") {"); + out.indented(() -> { + if (!preConditions.isEmpty()) { + out.writeln("// pre-conditions"); + preConditions.forEach(cond -> { + renderContributeCondition(out, cond, conditionValidatorId, evaluateBodyScope); + out.newline(); + }); + } + out.write(toBuilderType(output), " ", needsBuilder(output) ? outputBuilderId : evaluateBodyScope.getIdentifierOrThrow(output), " = doEvaluate("); + renderInputsAsArguments(out, inputs, evaluateBodyScope); + out.writeln(");"); + if (needsBuilder(output)) { + out.newline(); + out.writeln("final ", outputType, " ", evaluateBodyScope.getIdentifierOrThrow(output), ";"); + out.writeln("if (", outputBuilderId, " == null) {"); + out.indented(() -> out.writeln(evaluateBodyScope.getIdentifierOrThrow(output), " = null;")); + out.writeln("} else {"); + out.indented(() -> { + out.write(evaluateBodyScope.getIdentifierOrThrow(output), " = ", outputBuilderId); + if (output.isMulti()) { + out.write(".stream().map(", typeTranslator.toJavaReferenceType(output.getRMetaAnnotatedType()), "::build).collect(", Collectors.class, ".toList())"); + } else { + out.write(".build()"); + } + out.writeln(";"); + out.writeln(objectValidatorId, ".validate(", typeTranslator.toJavaReferenceType(output.getRMetaAnnotatedType()), ".class, ", evaluateBodyScope.getIdentifierOrThrow(output), ");"); + }); + out.writeln("}"); + } + if (!postConditions.isEmpty()) { + out.newline(); + out.writeln("// post-conditions"); + postConditions.forEach(cond -> { + renderContributeCondition(out, cond, conditionValidatorId, evaluateBodyScope); + out.newline(); + }); + } + out.writeln("return ", evaluateBodyScope.getIdentifierOrThrow(output), ";"); + }); + out.writeln("}"); + out.newline(); + + out.write("protected abstract ", toBuilderType(output), " doEvaluate("); + renderInputsAsParameters(out, inputs, doEvaluateScope); + out.writeln(");"); + + shortcuts.forEach(alias -> { + JavaMethodScope aliasScope = aliasScopes.get(alias); + out.newline(); + out.write("protected abstract ", aliasUtil.getReturnType(alias), " ", classScope.getIdentifierOrThrow(alias), "("); + out.write(CodeWriterTargetStringConcatenation.asCodeRenderer(aliasUtil.getParameters(alias, aliasScope))); + out.writeln(");"); + }); + out.newline(); + + out.write("public static ", defaultClass.asClassDeclaration()); + out.writeln(" {"); + out.indented(() -> { + out.writeln("@Override"); + out.write("protected ", toBuilderType(output), " doEvaluate("); + renderInputsAsParameters(out, inputs, defaultDoEvaluateScope); + out.writeln(") {"); + out.indented(() -> { + inputs.stream().filter(RAttribute::isMulti).forEach(input -> { + out.writeln("if (", defaultDoEvaluateBodyScope.getIdentifierOrThrow(input), " == null) {"); + out.indented(() -> out.writeln(defaultDoEvaluateBodyScope.getIdentifierOrThrow(input), " = ", Collections.class, ".emptyList();")); + out.writeln("}"); + }); + out.write(toBuilderType(output), " ", defaultDoEvaluateBodyScope.getIdentifierOrThrow(output), " = "); + if (output.isMulti()) { + out.write("new ", ArrayList.class, "<>()"); + } else if (needsBuilder(output)) { + out.write(typeTranslator.toListOrSingleJavaType(output.getRMetaAnnotatedType(), output.isMulti()), ".builder()"); + } else { + out.write("null"); + } + out.writeln(";"); + out.write("return assignOutput(", defaultDoEvaluateBodyScope.getIdentifierOrThrow(output)); + if (!inputs.isEmpty()) { + out.write(", "); + } + renderInputsAsArguments(out, inputs, defaultDoEvaluateBodyScope); + out.writeln(");"); + }); + out.writeln("}"); + out.newline(); + + out.write("protected ", toBuilderType(output), " assignOutput(", toBuilderType(output), " ", assignOutputScope.getIdentifierOrThrow(output)); + if (!inputs.isEmpty()) { + out.write(", "); + } + renderInputsAsParameters(out, inputs, assignOutputScope); + out.writeln(") {"); + boolean functionHasDeepOperations = operations.stream().anyMatch(o -> o.getPathTail().size() > 0); + out.indented(() -> { + operations.forEach(operation -> { + out.write(assign(assignOutputBodyScope, operation, function, aliasOut, output, functionHasDeepOperations).asStatementList()); + out.newline(); + }); + if (!needsBuilder(output)) { + out.writeln("return ", assignOutputBodyScope.getIdentifierOrThrow(output), ";"); + } else { + out.write("return ", Optional.class, ".ofNullable(", assignOutputBodyScope.getIdentifierOrThrow(output), ")"); + out.newline(); + if (output.isMulti()) { + out.write(" .map(o -> o.stream().map(i -> i.prune()).collect(", Collectors.class, ".toList()))"); + } else { + out.write(" .map(o -> o.prune())"); + } + out.newline(); + out.writeln(" .orElse(null);"); + } + }); + out.writeln("}"); + + shortcuts.forEach(alias -> { + JavaMethodScope aliasScope = defaultClassAliasScopes.get(alias); + JavaType returnType = aliasUtil.getReturnType(alias); + JavaStatementBuilder body = expressionGenerator.javaCode(alias.getExpression(), returnType, aliasScope.getBodyScope()); + JavaStatementBuilder safeBody = aliasUtil.requiresOutput(alias) + ? body.mapExpressionIfNotNull(it -> JavaExpression.from(o -> o.write("toBuilder(", it, ")"), returnType)) + : body; + out.newline(); + out.writeln("@Override"); + out.write("protected ", returnType, " ", defaultClassScope.getIdentifierOrThrow(alias), "("); + out.write(CodeWriterTargetStringConcatenation.asCodeRenderer(aliasUtil.getParameters(alias, aliasScope))); + out.write(") "); + out.writeln(safeBody.completeAsReturn().toBlock()); + }); + }); + out.writeln("}"); + + if (functionExtensions.isQualifierFunction(function)) { + out.newline(); + out.writeln("@Override"); + out.writeln("public String getNamePrefix() {"); + out.indented(() -> out.writeln("return \"", functionExtensions.getQualifierAnnotations(function.getAnnotations()).get(0).getAnnotation().getPrefix(), "\";")); + out.writeln("}"); + } + }); + out.write("}"); + }; + } + + private CodeRenderer dispatchClassBody(Function function, RGeneratedJavaClass javaFunctionClass, JavaClassScope classScope, String version) { + return out -> { + RFunction rfunc = rObjectFactory.buildRFunction(function); + List dispatchingFuncs = new ArrayList<>(); + functionExtensions.getDispatchingFunctions(function).forEach(dispatchingFuncs::add); + dispatchingFuncs.sort(java.util.Comparator.comparing(FunctionDispatch::getName)); + String enumParam = function.getInputs().stream() + .filter(i -> i.getTypeCall().getType() instanceof RosettaEnumeration) + .findFirst().orElseThrow().getName(); + JavaType outputType = outputTypeOrVoid(function); + + dispatchingFuncs.forEach(f -> classScope.createIdentifier(f, uncapitalize(function.getName() + capitalize(f.getValue().getValue().getName())))); + + Map enumFuncToRFunc = new java.util.HashMap<>(); + Map> enumFuncToClass = new java.util.HashMap<>(); + Map enumFuncToScope = new java.util.HashMap<>(); + dispatchingFuncs.forEach(enumFunc -> { + List allShortcuts = new ArrayList<>(); + function.getShortcuts().forEach(s -> allShortcuts.add(rObjectFactory.buildRShortcut(s))); + enumFunc.getShortcuts().forEach(s -> allShortcuts.add(rObjectFactory.buildRShortcut(s))); + RFunction rFunction = new RFunction( + enumFunc, + null, + null, + new ModelSymbolId(modelIdProvider.toDottedPath(function.getModel()), function.getName() + formatEnumName(enumFunc.getValue().getValue().getName())), + enumFunc.getDefinition(), + function.getInputs().stream().map(i -> rObjectFactory.buildRAttributeWithEnclosingType(null, i)).collect(Collectors.toList()), + rObjectFactory.buildRAttributeWithEnclosingType(null, function.getOutput()), + RFunctionOrigin.FUNCTION, + enumFunc.getConditions(), + enumFunc.getPostConditions(), + allShortcuts, + enumFunc.getOperations().stream().map(o -> rObjectFactory.buildROperation(o)).collect(Collectors.toList()), + enumFunc.getAnnotations()); + RGeneratedJavaClass nestedClass = javaFunctionClass.createNestedClass(rFunction.getAlphanumericName(), RosettaFunction.class); + JavaClassScope scope = classScope.createNestedClassScopeAndRegisterIdentifier(nestedClass); + enumFuncToRFunc.put(enumFunc, rFunction); + enumFuncToClass.put(enumFunc, nestedClass); + enumFuncToScope.put(enumFunc, scope); + }); + + JavaMethodScope evaluateScope = classScope.createMethodScope("evaluate"); + rfunc.getInputs().forEach(input -> evaluateScope.createIdentifier(input, input.getName())); + JavaStatementScope evaluateBodyScope = evaluateScope.getBodyScope(); + + out.write(modelGeneratorUtil.javadoc(function.getDefinition(), function.getReferences(), version)); + out.writeln("public class ", javaFunctionClass, " implements ", RosettaFunction.class, " {"); + out.indented(() -> { + out.newline(); + dispatchingFuncs.forEach(enumFunc -> out.writeln("@", javax.inject.Inject.class, " protected ", enumFuncToClass.get(enumFunc), " ", classScope.getIdentifierOrThrow(enumFunc), ";")); + out.newline(); + out.write("public ", outputType, " evaluate("); + renderInputsAsParameters(out, rfunc.getInputs(), evaluateScope); + out.writeln(") {"); + out.indented(() -> { + out.writeln("switch (", enumParam, ") {"); + out.indented(() -> { + dispatchingFuncs.forEach(enumFunc -> { + out.writeln("case ", formatEnumName(enumFunc.getValue().getValue().getName()), ":"); + out.indented(() -> { + out.write("return ", evaluateBodyScope.getIdentifierOrThrow(enumFunc), ".evaluate("); + renderInputsAsArguments(out, rfunc.getInputs(), evaluateBodyScope); + out.writeln(");"); + }); + }); + out.writeln("default:"); + out.indented(() -> out.writeln("throw new IllegalArgumentException(\"Enum value not implemented: \" + ", enumParam, ");")); + }); + out.writeln("}"); + }); + out.writeln("}"); + + dispatchingFuncs.forEach(enumFunc -> { + RFunction rFunction = enumFuncToRFunc.get(enumFunc); + RGeneratedJavaClass nestedClass = enumFuncToClass.get(enumFunc); + JavaClassScope scope = enumFuncToScope.get(enumFunc); + out.newline(); + out.write(rBuildClass(rFunction, nestedClass, true, List.of(JavaClass.from(RosettaFunction.class)), Collections.emptyMap(), false, scope)); + }); + }); + out.write("}"); + }; + } + + private boolean assignAsKey(ROperation op) { + return op.getExpression() instanceof AsKeyOperation; + } + + private JavaStatement assign(JavaStatementScope scope, ROperation op, RFunction function, Map outs, RAttribute attribute, boolean functionHasDeepOperations) { + if (op.getPathTail().isEmpty()) { + // assign function output object + JavaType expressionType = typeTranslator.toMetaJavaType(attribute); + JavaStatementBuilder javaExpr = expressionGenerator.javaCode(op.getExpression(), expressionType, scope); + JavaType effectiveExprType = javaExpr.getExpressionType(); + if (needsBuilder(attribute)) { + javaExpr = javaExpr.mapExpressionIfNotNull(it -> JavaExpression.from(o -> { + o.write("toBuilder(", it); + if (functionHasDeepOperations) { + o.write(", () -> ", effectiveExprType, ".builder()"); + } + o.write(")"); + }, toBuilderType(attribute))); + } else { + boolean needsToCopy = + op.getROperationType() == ROperationType.SET + && typeUtil.isList(effectiveExprType) + && function.getOperations().stream().anyMatch(o -> o.getROperationType() == ROperationType.ADD); + if (needsToCopy) { + javaExpr = javaExpr.mapExpressionIfNotNull(it -> JavaExpression.from( + o -> o.write("new ", ArrayList.class, "<>(", it, ")"), + typeUtil.wrap(typeUtil.LIST, typeUtil.getItemType(effectiveExprType)))); + } + } + switch (op.getROperationType()) { + case ADD: { + JavaStatementBuilder coerced = coercionService.addCoercions(javaExpr, attribute.isMulti() ? typeUtil.wrapExtends(typeUtil.LIST, toBuilderItemType(attribute)) : toBuilderItemType(attribute), scope); + return coerced + .mapExpression(it -> JavaExpression.from( + o -> { o.write(assignTarget(op, function, outs, scope)); o.write(".addAll(", it, ")"); }, + JavaPrimitiveType.VOID)) + .completeAsExpressionStatement(); + } + case SET: { + JavaStatementBuilder coerced = coercionService.addCoercions(javaExpr, toBuilderType(attribute), scope); + return coerced + .mapExpression(it -> JavaExpression.from( + o -> { o.write(assignTarget(op, function, outs, scope)); o.write(" = ", it); }, + JavaPrimitiveType.VOID)) + .completeAsExpressionStatement(); + } + default: + throw new IllegalStateException("Unexpected operation type: " + op.getROperationType()); + } + } + // assign an attribute of the function output object + return assignValue(scope, op, assignAsKey(op)) + .collapseToSingleExpression(scope) + .mapExpression(it -> { + JavaExpression expr = assignTarget(op, function, outs, scope); + + // path intermediary + int intermediarySegmentSize = op.getPathTail().size() - 1; + for (int pathIndex = 0; pathIndex < intermediarySegmentSize; pathIndex++) { + RFeature seg = op.getPathTail().get(pathIndex); + + if (typeUtil.getItemType(expr.getExpressionType()) instanceof RJavaWithMetaValue withMeta) { + JavaExpression metaExpr = expr; + expr = JavaExpression.from(o -> o.write(metaExpr, ".getOrCreateValue()"), withMeta.getValueType()); + } + + JavaPojoProperty prop = getPojoProperty(seg, typeUtil.getItemType(expr.getExpressionType())); + JavaExpression oldExpr = expr; + JavaType itemType = typeUtil.getItemType(prop.getType()); + expr = JavaExpression.from(o -> { + o.write(oldExpr); + o.newline(); + o.write(" .", prop.getOperationName(JavaPojoPropertyOperationType.GET_OR_CREATE), "(", typeUtil.isList(prop.getType()) ? "0" : "", ")"); + }, itemType); + } + + // end of path + RFeature seg = op.getPathTail().get(op.getPathTail().size() - 1); + JavaExpression oldExpr = expr; + JavaType outputExpressionType = typeUtil.getItemType(expr.getExpressionType()); + JavaPojoProperty prop = getPojoProperty(seg, outputExpressionType); + + boolean requiresValueSetter = requiresValueSetter(outputExpressionType, prop, seg, op); + String propertySetterName = getPropertySetterName(outputExpressionType, prop, seg, op.getROperationType(), requiresValueSetter); + expr = JavaExpression.from(o -> { + o.write(oldExpr); + o.newline(); + o.write(" "); + o.write(generateMetaWrapperCreator(seg, prop, outputExpressionType)); + o.write(".", propertySetterName, "(", it, ")"); + }, JavaPrimitiveType.VOID); + + return expr; + }) + .completeAsExpressionStatement(); + } + + private String getPropertySetterName(JavaType outputExpressionType, JavaPojoProperty prop, RFeature segment, ROperationType operationType, boolean requiresValueSetter) { + if (outputExpressionType instanceof RJavaWithMetaValue || (segment instanceof RMetaAttribute && outputExpressionType instanceof RJavaPojoInterface)) { + String prefix = operationType == ROperationType.ADD ? "add" : "set"; + String segmentPropName = capitalize(PojoPropertyUtil.toPojoPropertyName(segment)); + if (requiresValueSetter) { + return prefix + segmentPropName + "Value"; + } + return prefix + segmentPropName; + } + if (requiresValueSetter) { + if (operationType == ROperationType.ADD) { + return prop.getOperationName(JavaPojoPropertyOperationType.ADD_VALUE); + } + return prop.getOperationName(JavaPojoPropertyOperationType.SET_VALUE); + } + if (operationType == ROperationType.ADD) { + return prop.getOperationName(JavaPojoPropertyOperationType.ADD); + } + return prop.getOperationName(JavaPojoPropertyOperationType.SET); + } + + private boolean requiresValueSetter(JavaType outputExpressionType, JavaPojoProperty outerPojoProperty, RFeature segment, ROperation op) { + JavaType outerPropertyType = typeUtil.getItemType(outerPojoProperty.getType()); + JavaPojoProperty innerProp = (outputExpressionType instanceof RJavaWithMetaValue && outerPropertyType instanceof JavaPojoInterface) + ? getPojoProperty(segment, outerPropertyType) + : outerPojoProperty; + + JavaType innerPropType = typeUtil.getItemType(innerProp.getType()); + + boolean isMetaSegment = segment instanceof RAttribute attr && attr.getRMetaAnnotatedType().hasAttributeMeta(); + + return innerPropType instanceof RJavaWithMetaValue && !isMetaSegment && !assignAsKey(op); + } + + private CodeRenderer generateMetaWrapperCreator(RFeature seg, JavaPojoProperty prop, JavaType expressionType) { + if (expressionType instanceof RJavaFieldWithMeta) { + return out -> { + if (seg instanceof RMetaAttribute) { + out.write(".getOrCreateMeta()"); + } else { + out.write(".", prop.getOperationName(JavaPojoPropertyOperationType.GET_OR_CREATE), "()"); + } + }; + } + if (expressionType instanceof RJavaReferenceWithMeta && seg instanceof RMetaAttribute && "address".equals(seg.getName())) { + return out -> out.write(".", prop.getOperationName(JavaPojoPropertyOperationType.GET_OR_CREATE), "()"); + } + if (expressionType instanceof RJavaReferenceWithMeta && !(seg instanceof RMetaAttribute)) { + return out -> out.write(".getOrCreateValue()"); + } + if (expressionType instanceof RJavaPojoInterface && seg instanceof RMetaAttribute) { + return out -> out.write(".", prop.getOperationName(JavaPojoPropertyOperationType.GET_OR_CREATE), "()"); + } + return out -> {}; + } + + // The type of the output expression to be set and the pojo property type are not the same when working with meta + private JavaPojoProperty getPojoProperty(RFeature seg, JavaType outputExpressionType) { + if (seg instanceof RMetaAttribute && (outputExpressionType instanceof RJavaFieldWithMeta || outputExpressionType instanceof RJavaPojoInterface)) { + return ((JavaPojoInterface) outputExpressionType).findProperty("meta"); + } else if (seg instanceof RMetaAttribute && outputExpressionType instanceof RJavaReferenceWithMeta) { + return ((JavaPojoInterface) outputExpressionType).findProperty("reference"); + } else if (outputExpressionType instanceof RJavaWithMetaValue) { + return ((JavaPojoInterface) outputExpressionType).findProperty("value"); + } else { + return ((JavaPojoInterface) outputExpressionType).findProperty(seg.getName()); + } + } + + private JavaStatementBuilder assignValue(JavaStatementScope scope, ROperation op, boolean assignAsKey) { + if (assignAsKey) { + JavaClass metaClass = typeTranslator.operationToReferenceWithMetaType(op); + if (cardinality.isMulti(op.getExpression())) { + JavaStatementScope lambdaScope = scope.lambdaScope(); + GeneratedIdentifier item = lambdaScope.createUniqueIdentifier("item"); + return expressionGenerator.javaCode(op.getExpression(), typeUtil.wrapExtendsWithoutMeta(typeUtil.MAPPER_C, op.getExpression()), scope) + .collapseToSingleExpression(scope) + .mapExpression(it -> JavaExpression.from(o -> { + o.write(it); + o.newline(); + o.write(" .getItems()"); + o.newline(); + o.write(" .map(", item, " -> ", metaClass, ".builder()"); + o.newline(); + o.write(" .setExternalReference(", item, ".getMappedObject().getMeta().getExternalKey())"); + o.newline(); + o.write(" .setGlobalReference(", item, ".getMappedObject().getMeta().getGlobalKey())"); + o.newline(); + o.write(" .build())"); + o.newline(); + o.write(" .collect(", Collectors.class, ".toList())"); + }, typeUtil.wrap(typeUtil.LIST, metaClass))); + } + JavaStatementScope lambdaScope = scope.lambdaScope(); + GeneratedIdentifier r = lambdaScope.createUniqueIdentifier("r"); + GeneratedIdentifier m = lambdaScope.createUniqueIdentifier("m"); + return expressionGenerator.javaCode(op.getExpression(), typeTranslator.toJavaReferenceType(RMetaAnnotatedType.withNoMeta(typeProvider.getRMetaAnnotatedType(op.getExpression()).getRType())), scope) + .declareAsVariable(true, op.getPathHead().getName() + pathTailSuffix(op), scope) + .mapExpression(it -> JavaExpression.from(o -> { + o.write(metaClass, ".builder()"); + o.newline(); + o.write(" .setGlobalReference(", Optional.class, ".ofNullable(", it, ")"); + o.newline(); + o.write(" .map(", r, " -> ", r, ".getMeta())"); + o.newline(); + o.write(" .map(", m, " -> ", m, ".getGlobalKey())"); + o.newline(); + o.write(" .orElse(null))"); + o.newline(); + o.write(" .setExternalReference(", Optional.class, ".ofNullable(", it, ")"); + o.newline(); + o.write(" .map(", r, " -> ", r, ".getMeta())"); + o.newline(); + o.write(" .map(", m, " -> ", m, ".getExternalKey())"); + o.newline(); + o.write(" .orElse(null))"); + o.newline(); + o.write(" .build()"); + }, metaClass)); + } + return expressionGenerator.javaCode(op.getExpression(), typeTranslator.operationToMetaJavaType(op), scope); + } + + private String pathTailSuffix(ROperation op) { + return op.getPathTail().stream().map(f -> capitalize(f.getName())).collect(Collectors.joining()); + } + + private JavaExpression assignTarget(ROperation operation, RFunction function, Map outs, JavaStatementScope scope) { + Object root = operation.getPathHead(); + if (root instanceof RAttribute attr) { + return new JavaVariable(scope.getIdentifierOrThrow(attr), typeTranslator.toJavaReferenceType(attr.getRMetaAnnotatedType())); + } + if (root instanceof RShortcut shortcut) { + return unfoldLHSShortcut(shortcut, function, scope); + } + throw new IllegalStateException("Unexpected assign target: " + root); + } + + private JavaExpression unfoldLHSShortcut(RShortcut shortcut, RFunction function, JavaStatementScope scope) { + RosettaExpression e = shortcut.getExpression(); + if (e instanceof RosettaSymbolReference ref && ref.getSymbol() instanceof RosettaCallableWithArgs) { + // assign-output for an alias + return JavaExpression.from( + o -> { o.write(scope.getIdentifierOrThrow(shortcut), "("); o.write(CodeWriterTargetStringConcatenation.asCodeRenderer(expressionGenerator.aliasCallArgs(shortcut, function, scope))); o.write(")"); }, + shortcutExpressionJavaType(shortcut)); + } + return lhsExpand(e, scope); + } + + private JavaExpression lhsExpand(Object f, JavaStatementScope scope) { + if (f instanceof RosettaFeatureCall fc) { + return lhsFeature(lhsExpand(fc.getReceiver(), scope), fc.getFeature()); + } + if (f instanceof RosettaSymbolReference ref) { + return lhsExpand(ref.getSymbol(), scope); + } + if (f instanceof ShortcutDeclaration sd) { + return lhsExpand(sd.getExpression(), scope); + } + if (f instanceof RosettaUnaryOperation uo) { + return lhsExpand(uo.getArgument(), scope); + } + if (f instanceof Attribute attribute) { + RAttribute rAttribute = rObjectFactory.buildRAttribute(attribute); + return new JavaVariable(scope.getIdentifierOrThrow(rAttribute), typeTranslator.toJavaReferenceType(rAttribute.getRMetaAnnotatedType())); + } + throw new IllegalStateException("No implementation for lhsExpand for " + f.getClass()); + } + + private JavaExpression lhsFeature(JavaExpression receiver, RosettaFeature f) { + if (f instanceof Attribute attribute) { + JavaPojoInterface t = (JavaPojoInterface) receiver.getExpressionType(); + JavaPojoProperty prop = t.findProperty(attribute.getName()); + return JavaExpression.from( + o -> o.write(receiver, ".", prop.getOperationName(JavaPojoPropertyOperationType.GET_OR_CREATE), "(", typeUtil.isList(prop.getType()) ? "0" : "", ")"), + typeUtil.getItemType(prop.getType())); + } + throw new IllegalStateException("No implementation for lhsFeature for " + f.getClass()); + } + + private void renderContributeCondition(CodeWriter out, Condition condition, GeneratedIdentifier conditionValidator, JavaStatementScope scope) { + JavaStatementBuilder conditionBody = expressionGenerator.javaCode(condition.getExpression(), typeUtil.COMPARISON_RESULT, scope.lambdaScope()); + out.writeln(conditionValidator, ".validate(() -> ", conditionBody.toLambdaBody(), ","); + out.writeln(" \"", condition.getDefinition(), "\");"); + } + + private JavaType outputTypeOrVoid(Function function) { + Attribute out = functionExtensions.getOutput(function); + if (out == null) { + return JavaPrimitiveType.VOID; + } + if (functionExtensions.needsBuilder(out.getTypeCall().getType())) { + return typeTranslator.toPolymorphicListOrSingleJavaType(typeProvider.getRTypeOfSymbol(out).getRType(), out.getCard().isIsMany()); + } + return typeTranslator.toListOrSingleJavaType(typeProvider.getRTypeOfSymbol(out).getRType(), out.getCard().isIsMany()); + } + + private void renderJavadocTag(CodeWriter out, String tag, GeneratedIdentifier name, String definition) { + String escaped = modelGeneratorUtil.escape(definition).toString(); + out.write(" * ", tag, " ", name); + if (!escaped.isEmpty()) { + out.write(" ", escaped); + } + out.newline(); + } + + private void renderInputsAsArguments(CodeWriter out, List inputs, JavaStatementScope scope) { + out.join(inputs, ", ", input -> out.write(scope.getIdentifierOrThrow(input))); + } + + private void renderInputsAsParameters(CodeWriter out, List inputs, JavaMethodScope scope) { + out.join(inputs, ", ", input -> out.write(typeTranslator.toMetaJavaType(input), " ", scope.getIdentifierOrThrow(input))); + } + + private JavaReferenceType shortcutExpressionJavaType(RShortcut feature) { + RMetaAnnotatedType metaRType = typeProvider.getRMetaAnnotatedType(feature.getExpression()); + return typeTranslator.toJavaReferenceType(metaRType); + } + + private JavaType toBuilderItemType(RAttribute rAttribute) { + JavaClass javaType = (JavaClass) typeTranslator.toJavaReferenceType(rAttribute.getRMetaAnnotatedType()); + if (needsBuilder(javaType)) { + return ((JavaPojoInterface) javaType).toBuilderInterface(); + } + return javaType; + } + + private JavaType toBuilderType(RAttribute rAttribute) { + JavaType javaType = toBuilderItemType(rAttribute); + if (rAttribute.isMulti()) { + return typeUtil.wrap(typeUtil.LIST, javaType); + } + return javaType; + } + + private boolean needsBuilder(RAttribute rAttribute) { + JavaClass javaType = (JavaClass) typeTranslator.toJavaReferenceType(rAttribute.getRMetaAnnotatedType()); + return needsBuilder(javaType); + } + + private boolean needsBuilder(JavaClass javaClass) { + return javaClass instanceof JavaPojoInterface; + } +} diff --git a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/function/FunctionGenerator.xtend b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/function/FunctionGenerator.xtend deleted file mode 100644 index 11ffcaeea7..0000000000 --- a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/function/FunctionGenerator.xtend +++ /dev/null @@ -1,751 +0,0 @@ -package com.regnosys.rosetta.generator.java.function - -import com.fasterxml.jackson.core.type.TypeReference -import com.google.inject.ImplementedBy -import com.regnosys.rosetta.generator.GeneratedIdentifier -import com.regnosys.rosetta.generator.java.expression.ExpressionGenerator -import com.regnosys.rosetta.generator.java.expression.JavaDependencyProvider -import com.regnosys.rosetta.generator.java.expression.TypeCoercionService -import com.regnosys.rosetta.generator.java.labels.LabelProviderGeneratorUtil -import com.regnosys.rosetta.generator.java.statement.JavaStatement -import com.regnosys.rosetta.generator.java.statement.builder.JavaExpression -import com.regnosys.rosetta.generator.java.statement.builder.JavaStatementBuilder -import com.regnosys.rosetta.generator.java.statement.builder.JavaVariable -import com.regnosys.rosetta.generator.java.types.JavaPojoInterface -import com.regnosys.rosetta.generator.java.types.JavaPojoProperty -import com.regnosys.rosetta.generator.java.types.JavaTypeTranslator -import com.regnosys.rosetta.generator.java.types.JavaTypeUtil -import com.regnosys.rosetta.generator.java.types.RJavaFieldWithMeta -import com.regnosys.rosetta.generator.java.types.RJavaPojoInterface -import com.regnosys.rosetta.generator.java.types.RJavaReferenceWithMeta -import com.regnosys.rosetta.generator.java.types.RJavaWithMetaValue -import com.regnosys.rosetta.generator.java.util.ModelGeneratorUtil -import com.regnosys.rosetta.generator.util.RosettaFunctionExtensions -import com.regnosys.rosetta.rosetta.RosettaCallableWithArgs -import com.regnosys.rosetta.rosetta.RosettaEnumeration -import com.regnosys.rosetta.rosetta.RosettaFeature -import com.regnosys.rosetta.rosetta.RosettaSymbol -import com.regnosys.rosetta.rosetta.expression.AsKeyOperation -import com.regnosys.rosetta.rosetta.expression.RosettaExpression -import com.regnosys.rosetta.rosetta.expression.RosettaFeatureCall -import com.regnosys.rosetta.rosetta.expression.RosettaSymbolReference -import com.regnosys.rosetta.rosetta.expression.RosettaUnaryOperation -import com.regnosys.rosetta.rosetta.simple.Attribute -import com.regnosys.rosetta.rosetta.simple.Condition -import com.regnosys.rosetta.rosetta.simple.Function -import com.regnosys.rosetta.rosetta.simple.FunctionDispatch -import com.regnosys.rosetta.rosetta.simple.ShortcutDeclaration -import com.regnosys.rosetta.rosetta.simple.TransformAnnotation -import com.regnosys.rosetta.utils.TransformAnnotationHelper -import com.rosetta.model.lib.transform.SerializationFormat -import com.regnosys.rosetta.types.CardinalityProvider -import com.regnosys.rosetta.types.RAttribute -import com.regnosys.rosetta.types.RFeature -import com.regnosys.rosetta.types.RFunction -import com.regnosys.rosetta.types.RFunctionOrigin -import com.regnosys.rosetta.types.RMetaAttribute -import com.regnosys.rosetta.types.RObjectFactory -import com.regnosys.rosetta.types.ROperation -import com.regnosys.rosetta.types.ROperationType -import com.regnosys.rosetta.types.RShortcut -import com.regnosys.rosetta.types.RosettaTypeProvider -import com.regnosys.rosetta.utils.ExpressionHelper -import com.regnosys.rosetta.utils.ImplicitVariableUtil -import com.regnosys.rosetta.utils.ModelIdProvider -import com.rosetta.model.lib.ModelSymbolId -import com.rosetta.model.lib.annotations.RuneLabelProvider -import com.rosetta.model.lib.functions.ConditionValidator -import com.rosetta.model.lib.functions.IQualifyFunctionExtension -import com.rosetta.model.lib.functions.ModelObjectValidator -import com.rosetta.model.lib.functions.RosettaFunction -import com.rosetta.util.types.JavaClass -import com.rosetta.util.types.JavaParameterizedType -import com.rosetta.util.types.JavaPrimitiveType -import com.rosetta.util.types.JavaReferenceType -import com.rosetta.util.types.JavaType -import java.util.ArrayList -import java.util.Collections -import java.util.List -import java.util.Map -import java.util.Optional -import java.util.stream.Collectors -import jakarta.inject.Inject -import org.eclipse.xtend2.lib.StringConcatenationClient - -import static com.regnosys.rosetta.generator.java.enums.EnumHelper.* - -import static extension com.regnosys.rosetta.types.RMetaAnnotatedType.withNoMeta -import static extension com.regnosys.rosetta.utils.PojoPropertyUtil.* -import com.regnosys.rosetta.generator.java.scoping.JavaIdentifierRepresentationService -import com.regnosys.rosetta.generator.java.scoping.JavaStatementScope -import com.regnosys.rosetta.generator.java.types.RGeneratedJavaClass -import com.regnosys.rosetta.generator.java.RObjectJavaClassGenerator -import com.regnosys.rosetta.generator.java.scoping.JavaClassScope -import com.regnosys.rosetta.rosetta.RosettaModel -import com.regnosys.rosetta.generator.java.scoping.JavaMethodScope -import static com.regnosys.rosetta.generator.java.types.JavaPojoPropertyOperationType.* - -class FunctionGenerator extends RObjectJavaClassGenerator> { - - @Inject ExpressionGenerator expressionGenerator - @Inject JavaDependencyProvider dependencyProvider - @Inject RosettaTypeProvider typeProvider - @Inject extension RosettaFunctionExtensions - @Inject extension ModelGeneratorUtil - - @Inject ExpressionHelper exprHelper - @Inject CardinalityProvider cardinality - @Inject extension JavaIdentifierRepresentationService - @Inject extension JavaTypeTranslator - @Inject RObjectFactory rTypeBuilderFactory - @Inject ImplicitVariableUtil implicitVariableUtil - @Inject extension JavaTypeUtil - @Inject TypeCoercionService coercionService - @Inject extension ModelIdProvider - @Inject LabelProviderGeneratorUtil labelProviderUtil - @Inject AliasUtil aliasUtil - @Inject TransformAnnotationHelper transformAnnotationHelper - - override protected streamObjects(RosettaModel model) { - model.elements.stream.filter[it instanceof Function && !(it instanceof FunctionDispatch)].map[it as Function].map[rTypeBuilderFactory.buildRFunction(it)] - } - override protected createTypeRepresentation(RFunction rFunction) { - rFunction.toFunctionJavaClass - } - override protected generateClass(RFunction rFunction, RGeneratedJavaClass javaFunctionClass, String version, JavaClassScope scope) { - val origin = rFunction.EObject - if (origin instanceof Function && (origin as Function).handleAsEnumFunction) { - (origin as Function).dispatchClassBody(javaFunctionClass, scope, version) - } else { - var overridesEvaluate = false - val List functionInterfaces = newArrayList(JavaClass.from(RosettaFunction)) - if (isQualifierFunction(rFunction)) { - overridesEvaluate = true - functionInterfaces.add(getQualifyingFunctionInterface(rFunction.inputs)) - } - val Map, StringConcatenationClient> annotations = newLinkedHashMap - if (origin instanceof Function && labelProviderUtil.shouldGenerateLabelProvider(origin as Function)) { - val labelProviderClass = rFunction.toLabelProviderJavaClass - annotations.put(RuneLabelProvider, '''labelProvider=«labelProviderClass».class''' ) - } - if (origin instanceof Function && !(origin as Function).transform.empty) { - addTransformAnnotation((origin as Function).transform.head, annotations) - } - rBuildClass(rFunction, javaFunctionClass, false, functionInterfaces, annotations, overridesEvaluate, scope) - } - } - - def rBuildClass(RFunction rFunction, RGeneratedJavaClass javaFunctionClass, boolean isStatic, List functionInterfaces, Map, StringConcatenationClient> annotations, boolean overridesEvaluate, JavaClassScope classScope) { - val dependencies = collectFunctionDependencies(rFunction) - rFunction.classBody(javaFunctionClass, isStatic, overridesEvaluate, dependencies, functionInterfaces, annotations, classScope) - } - - private def void addTransformAnnotation(TransformAnnotation transform, Map, StringConcatenationClient> annotations) { - val annotationClass = transform.kind.toTransformAnnotationClass - val id = transformAnnotationHelper.getSchemaId(transform).orElse(null) - val format = transformAnnotationHelper.getFormat(transform).orElse(null) - val configPath = transformAnnotationHelper.getConfigPath(transform).orElse(null) - val StringConcatenationClient attributes = '''«IF id !== null»id = "«id»", «ENDIF»«IF format !== null»format = «SerializationFormat».«format.name»«ENDIF»«IF configPath !== null», configPath = "«configPath»"«ENDIF»''' - annotations.put(annotationClass, attributes) - } - - private def getQualifyingFunctionInterface(List inputs) { - val parameterVariable = inputs.head.RMetaAnnotatedType.toListOrSingleJavaType(inputs.head.multi) - JavaParameterizedType.from(new TypeReference>() {}, parameterVariable) - } - - private def collectFunctionDependencies(RFunction func) { - val expressions = func.preConditions.map[it.expression] + - func.postConditions.map[it.expression] + - func.operations.map[it.expression] + - func.shortcuts.map[it.expression] - return dependencyProvider.javaDependencies(expressions) - } - - private def StringConcatenationClient classBody( - RFunction function, - RGeneratedJavaClass javaFunctionClass, - boolean isStatic, - boolean overridesEvaluate, - List> dependencies, - List functionInterfaces, - Map, StringConcatenationClient> annotations, - JavaClassScope classScope - ) { - val inputs = function.inputs - val output = function.output - val shortcuts = function.shortcuts - val operations = function.operations - val preConditions = function.preConditions - val postConditions = function.postConditions - - dependencies.forEach[classScope.createIdentifier(it.toDependencyInstance, it.simpleName.toFirstLower)] - - val defaultClass = javaFunctionClass.createNestedClassWithSuperclass(javaFunctionClass.simpleName + "Default", javaFunctionClass) - val defaultClassScope = classScope.createNestedClassScopeAndRegisterIdentifier(defaultClass) - val outputType = output.toMetaJavaType - val aliasOut = shortcuts.toMap([it], [exprHelper.usesOutputParameter(it.expression)]) - - - val conditionValidatorId = classScope.createUniqueIdentifier("conditionValidator") - val objectValidatorId = classScope.createUniqueIdentifier("objectValidator") - - val evaluateScope = classScope.createMethodScope("evaluate") - inputs.forEach[evaluateScope.createIdentifier(it, it.name)] - val evaluateBodyScope = evaluateScope.bodyScope - evaluateBodyScope.createIdentifier(output, output.name) - val outputBuilderId = if (output.needsBuilder) { - evaluateBodyScope.createUniqueIdentifier(output.name + "Builder") - } - - val doEvaluateScope = classScope.createMethodScope("doEvaluate") - inputs.forEach[doEvaluateScope.createIdentifier(it, it.name)] - doEvaluateScope.createIdentifier(output, output.name) - - val defaultDoEvaluateScope = defaultClassScope.createMethodScope("doEvaluate") - inputs.forEach[defaultDoEvaluateScope.createIdentifier(it, it.name)] - defaultDoEvaluateScope.createIdentifier(output, output.name) - val defaultDoEvaluateBodyScope = defaultDoEvaluateScope.bodyScope - - val assignOutputScope = defaultClassScope.createMethodScope("assignOutput") - inputs.forEach[assignOutputScope.createIdentifier(it, it.name)] - assignOutputScope.createIdentifier(output, output.name) - function.operations - .map[it.expression] - .filter[implicitVariableUtil.implicitVariableExistsInContext(it)] - .map[it.implicitVarInContext] - .toSet - .forEach[assignOutputScope.createKeySynonym(it, inputs.head)] - val assignOutputBodyScope = assignOutputScope.bodyScope - - // TODO: try break things with clever alias names - val aliasScopes = newHashMap - val defaultClassAliasScopes = newHashMap - shortcuts.forEach[ - classScope.createIdentifier(it, it.name) - - val aliasScope = classScope.createMethodScope(it.name) - aliasScopes.put(it, aliasScope) - - val defaultClassAliasScope = defaultClassScope.createMethodScope(it.name) - defaultClassAliasScopes.put(it, defaultClassAliasScope) - - if (aliasUtil.requiresOutput(it)) { - aliasScope.createIdentifier(output, output.name) - defaultClassAliasScope.createIdentifier(output, output.name) - } - inputs.forEach[ - aliasScope.createIdentifier(it, it.name) - defaultClassAliasScope.createIdentifier(it, it.name) - ] - ] - - ''' - «FOR entry: annotations.entrySet» - @«entry.key»(«entry.value») - «ENDFOR» - @«ImplementedBy»(«defaultClass».class) - public «IF isStatic»static «ENDIF»abstract class «javaFunctionClass.simpleName»«IF !functionInterfaces.empty» implements «FOR fInterface : functionInterfaces SEPARATOR ","»«fInterface»«ENDFOR»«ENDIF» { - «IF !preConditions.empty || !postConditions.empty» - - @«javax.inject.Inject» protected «ConditionValidator» «conditionValidatorId»; - «ENDIF» - «IF output.needsBuilder» - - @«javax.inject.Inject» protected «ModelObjectValidator» «objectValidatorId»; - «ENDIF» - «IF !dependencies.empty» - - // RosettaFunction dependencies - // - «ENDIF» - «FOR dep : dependencies» - @«javax.inject.Inject» protected «dep» «classScope.getIdentifierOrThrow(dep.toDependencyInstance)»; - «ENDFOR» - - /** - «FOR input : inputs» - * @param «evaluateScope.getIdentifierOrThrow(input)» «escape(input.definition)» - «ENDFOR» - * @return «evaluateBodyScope.getIdentifierOrThrow(output)» «escape(output.definition)» - */ - «IF overridesEvaluate» - @Override - «ENDIF» - public «outputType» evaluate(«inputs.inputsAsParameters(evaluateScope)») { - «IF !preConditions.empty» - // pre-conditions - «FOR cond:preConditions» - «cond.contributeCondition(conditionValidatorId, evaluateBodyScope)» - - «ENDFOR» - «ENDIF» - «output.toBuilderType» «IF output.needsBuilder»«outputBuilderId»«ELSE»«evaluateBodyScope.getIdentifierOrThrow(output)»«ENDIF» = doEvaluate(«inputs.inputsAsArguments(evaluateBodyScope)»); - - «IF output.needsBuilder» - final «outputType» «evaluateBodyScope.getIdentifierOrThrow(output)»; - if («outputBuilderId» == null) { - «evaluateBodyScope.getIdentifierOrThrow(output)» = null; - } else { - «evaluateBodyScope.getIdentifierOrThrow(output)» = «outputBuilderId»«IF output.isMulti».stream().map(«output.RMetaAnnotatedType.toJavaReferenceType»::build).collect(«Collectors».toList())«ELSE».build()«ENDIF»; - «objectValidatorId».validate(«output.RMetaAnnotatedType.toJavaReferenceType».class, «evaluateBodyScope.getIdentifierOrThrow(output)»); - } - - «ENDIF» - «IF !postConditions.empty» - // post-conditions - «FOR cond:postConditions» - «cond.contributeCondition(conditionValidatorId, evaluateBodyScope)» - - «ENDFOR» - «ENDIF» - return «evaluateBodyScope.getIdentifierOrThrow(output)»; - } - - protected abstract «output.toBuilderType» doEvaluate(«inputs.inputsAsParameters(doEvaluateScope)»); - «FOR alias : shortcuts» - «val aliasScope = aliasScopes.get(alias)» - - protected abstract «aliasUtil.getReturnType(alias)» «classScope.getIdentifierOrThrow(alias)»(«aliasUtil.getParameters(alias, aliasScope)»); - «ENDFOR» - - public static «defaultClass.asClassDeclaration» { - @Override - protected «output.toBuilderType» doEvaluate(«inputs.inputsAsParameters(defaultDoEvaluateScope)») { - «FOR input : inputs.filter[isMulti]» - if («defaultDoEvaluateBodyScope.getIdentifierOrThrow(input)» == null) { - «defaultDoEvaluateBodyScope.getIdentifierOrThrow(input)» = «Collections».emptyList(); - } - «ENDFOR» - «output.toBuilderType» «defaultDoEvaluateBodyScope.getIdentifierOrThrow(output)» = «IF output.multi»new «ArrayList»<>()«ELSEIF output.needsBuilder»«output.RMetaAnnotatedType.toListOrSingleJavaType(output.multi)».builder()«ELSE»null«ENDIF»; - return assignOutput(«defaultDoEvaluateBodyScope.getIdentifierOrThrow(output)»«IF !inputs.empty», «ENDIF»«inputs.inputsAsArguments(defaultDoEvaluateBodyScope)»); - } - - protected «output.toBuilderType» assignOutput(«output.toBuilderType» «assignOutputScope.getIdentifierOrThrow(output)»«IF !inputs.empty», «ENDIF»«inputs.inputsAsParameters(assignOutputScope)») { - «val functionHasDeepOperations = operations.filter[o|o.pathTail.size > 0].size > 0» - «FOR operation : operations» - «assign(assignOutputBodyScope, operation, function, aliasOut, output, functionHasDeepOperations).asStatementList» - - «ENDFOR» - return «IF !needsBuilder(output)»«assignOutputBodyScope.getIdentifierOrThrow(output)»«ELSE»«Optional».ofNullable(«assignOutputBodyScope.getIdentifierOrThrow(output)») - .map(«IF output.multi»o -> o.stream().map(i -> i.prune()).collect(«Collectors».toList())«ELSE»o -> o.prune()«ENDIF») - .orElse(null)«ENDIF»; - } - «FOR alias : shortcuts» - «val aliasScope = defaultClassAliasScopes.get(alias)» - «val returnType = aliasUtil.getReturnType(alias)» - «val body = expressionGenerator.javaCode(alias.expression, returnType, aliasScope.bodyScope)» - «val safeBody = aliasUtil.requiresOutput(alias) ? body.mapExpressionIfNotNull[JavaExpression.from('''toBuilder(«it»)''', returnType)] : body» - - @Override - protected «returnType» «defaultClassScope.getIdentifierOrThrow(alias)»(«aliasUtil.getParameters(alias, aliasScope)») «safeBody.completeAsReturn.toBlock» - «ENDFOR» - } - «IF isQualifierFunction(function)» - - @Override - public String getNamePrefix() { - return "«getQualifierAnnotations(function.annotations).head.annotation.prefix»"; - } - «ENDIF» - } - ''' - } - - private def StringConcatenationClient dispatchClassBody(Function function, RGeneratedJavaClass javaFunctionClass, JavaClassScope classScope, String version) { - val rfunc = rTypeBuilderFactory.buildRFunction(function) - val dispatchingFuncs = function.dispatchingFunctions.sortBy[name].toList - val enumParam = function.inputs.filter[typeCall.type instanceof RosettaEnumeration].head.name - val outputType = function.outputTypeOrVoid - - dispatchingFuncs.forEach[classScope.createIdentifier(it, (function.name + value.value.name.toFirstUpper).toFirstLower)] - - val enumFuncToRFunc = newHashMap - val enumFuncToClass = newHashMap - val enumFuncToScope = newHashMap - dispatchingFuncs.forEach[enumFunc| - val rFunction = new RFunction( - enumFunc, - null, - null, - new ModelSymbolId(function.model.toDottedPath, function.name + formatEnumName(enumFunc.value.value.name)), - enumFunc.definition, - function.inputs.map[rTypeBuilderFactory.buildRAttributeWithEnclosingType(null, it)], - rTypeBuilderFactory.buildRAttributeWithEnclosingType(null, function.output), - RFunctionOrigin.FUNCTION, - enumFunc.conditions, - enumFunc.postConditions, - (function.shortcuts + enumFunc.shortcuts).toList.map[rTypeBuilderFactory.buildRShortcut(it)], - enumFunc.operations.map[rTypeBuilderFactory.buildROperation(it)], - enumFunc.annotations - ) - val nestedClass = javaFunctionClass.createNestedClass(rFunction.alphanumericName, RosettaFunction) - val scope = classScope.createNestedClassScopeAndRegisterIdentifier(nestedClass) - enumFuncToRFunc.put(enumFunc, rFunction) - enumFuncToClass.put(enumFunc, nestedClass) - enumFuncToScope.put(enumFunc, scope) - ] - - val evaluateScope = classScope.createMethodScope("evaluate") - rfunc.inputs.forEach[evaluateScope.createIdentifier(it, it.name)] - val evaluateBodyScope = evaluateScope.bodyScope - ''' - «javadoc(function.definition, function.references, version)» - public class «javaFunctionClass» implements «RosettaFunction» { - - «FOR enumFunc : dispatchingFuncs» - @«javax.inject.Inject» protected «enumFuncToClass.get(enumFunc)» «classScope.getIdentifierOrThrow(enumFunc)»; - «ENDFOR» - - public «outputType» evaluate(«rfunc.inputs.inputsAsParameters(evaluateScope)») { - switch («enumParam») { - «FOR enumFunc : dispatchingFuncs» - case «formatEnumName(enumFunc.value.value.name)»: - return «evaluateBodyScope.getIdentifierOrThrow(enumFunc)».evaluate(«rfunc.inputs.inputsAsArguments(evaluateBodyScope)»); - «ENDFOR» - default: - throw new IllegalArgumentException("Enum value not implemented: " + «enumParam»); - } - } - - «FOR enumFunc : dispatchingFuncs» - «val rFunction = enumFuncToRFunc.get(enumFunc)» - «val nestedClass = enumFuncToClass.get(enumFunc)» - «val scope = enumFuncToScope.get(enumFunc)» - «rFunction.rBuildClass(nestedClass, true, #[JavaClass.from(RosettaFunction)], emptyMap, false, scope)» - «ENDFOR» - }''' - } - - private def boolean assignAsKey(ROperation op) { - return op.expression instanceof AsKeyOperation - } - - private def JavaStatement assign(JavaStatementScope scope, ROperation op, RFunction function, Map outs, RAttribute attribute, boolean functionHasDeepOperations) { - if (op.pathTail.isEmpty) { - // assign function output object - val expressionType = attribute.toMetaJavaType - var javaExpr = expressionGenerator.javaCode(op.expression, expressionType, scope) - val effectiveExprType = javaExpr.expressionType - if (needsBuilder(attribute)) { - javaExpr = javaExpr.mapExpressionIfNotNull[JavaExpression.from('''toBuilder(«it»«IF functionHasDeepOperations», () -> «effectiveExprType».builder()«ENDIF»)''', attribute.toBuilderType)] - } else { - val needsToCopy = - op.ROperationType == ROperationType.SET - && effectiveExprType.isList - && function.operations.exists[o| o.ROperationType == ROperationType.ADD] - if (needsToCopy) { - javaExpr = - javaExpr - .mapExpressionIfNotNull[JavaExpression.from('''new «ArrayList»<>(«it»)''', LIST.wrap(effectiveExprType.itemType))] - } - } - switch(op.ROperationType) { - case ADD: { - javaExpr = coercionService.addCoercions(javaExpr, attribute.isMulti ? LIST.wrapExtends(attribute.toBuilderItemType) : attribute.toBuilderItemType, scope) - javaExpr - .mapExpression[ - JavaExpression.from( - '''«op.assignTarget(function, outs, scope)».addAll(«it»)''', - JavaPrimitiveType.VOID - ) - ].completeAsExpressionStatement - } - case SET: { - javaExpr = coercionService.addCoercions(javaExpr, attribute.toBuilderType, scope) - javaExpr - .mapExpression[ - JavaExpression.from( - '''«op.assignTarget(function, outs, scope)» = «it»''', - JavaPrimitiveType.VOID - ) - ].completeAsExpressionStatement - } - } - - } else { // assign an attribute of the function output object - assignValue(scope, op, op.assignAsKey) - .collapseToSingleExpression(scope) - .mapExpression[ - var expr = op.assignTarget(function, outs, scope) - - // path intermediary - val intermediarySegmentSize = op.pathTail.length - 1 - for (var pathIndex=0; pathIndex < intermediarySegmentSize; pathIndex++) { - - val seg = op.pathTail.get(pathIndex) - - if (expr.expressionType.itemType instanceof RJavaWithMetaValue) { - val metaExpr = expr - expr = JavaExpression.from('''«metaExpr».getOrCreateValue()''', (expr.expressionType.itemType as RJavaWithMetaValue).valueType) - } - - val prop = getPojoProperty(seg, expr.expressionType.itemType) - val oldExpr = expr - val itemType = prop.type.itemType - expr = JavaExpression.from( - ''' - «oldExpr» - .«prop.getOperationName(GET_OR_CREATE)»(«IF prop.type.isList»0«ENDIF»)''', - itemType - ) - } - - //end of path - val seg = op.pathTail.get(op.pathTail.length - 1) - val oldExpr = expr - val outputExpressionType = expr.expressionType.itemType - val prop = getPojoProperty(seg, outputExpressionType) - - val requiresValueSetter = requiresValueSetter(outputExpressionType, prop, seg, op) - val propertySetterName = getPropertySetterName(outputExpressionType, prop, seg, op.ROperationType, requiresValueSetter) - expr = JavaExpression.from( - ''' - «oldExpr» - «generateMetaWrapperCreator(seg, prop, outputExpressionType)».«propertySetterName»(«it»)''', - JavaPrimitiveType.VOID - ) - - expr - ].completeAsExpressionStatement - } - } - - private def String getPropertySetterName(JavaType outputExpressionType, JavaPojoProperty prop, RFeature segment, ROperationType operationType, boolean requiresValueSetter) { - if (outputExpressionType instanceof RJavaWithMetaValue || (segment instanceof RMetaAttribute && outputExpressionType instanceof RJavaPojoInterface)) { - val prefix = operationType == ROperationType.ADD ? "add" : "set" - val segmentPropName = segment.toPojoPropertyName.toFirstUpper - if (requiresValueSetter) { - prefix + segmentPropName + "Value" - } else { - prefix + segmentPropName - } - } else { - if (requiresValueSetter) { - if (operationType == ROperationType.ADD) { - prop.getOperationName(ADD_VALUE) - } else { - prop.getOperationName(SET_VALUE) - } - } else { - if (operationType == ROperationType.ADD) { - prop.getOperationName(ADD) - } else { - prop.getOperationName(SET) - } - } - } - } - - private def boolean requiresValueSetter(JavaType outputExpressionType, JavaPojoProperty outerPojoProperty, RFeature segment, ROperation op) { - val outerPropertyType = outerPojoProperty.type.itemType - val innerProp = if (outputExpressionType instanceof RJavaWithMetaValue && outerPropertyType instanceof JavaPojoInterface) { - getPojoProperty(segment, outerPropertyType) - } else { - outerPojoProperty - } - - val innerPropType = innerProp.type.itemType - - val isMetaSegment = if (segment instanceof RAttribute) { - segment.RMetaAnnotatedType.hasAttributeMeta - } else { - false - } - - innerPropType instanceof RJavaWithMetaValue && !isMetaSegment && !op.assignAsKey - } - - private def StringConcatenationClient generateMetaWrapperCreator(RFeature seg, JavaPojoProperty prop, JavaType expressionType) { - switch (expressionType) { - RJavaFieldWithMeta: '''«IF seg instanceof RMetaAttribute».getOrCreateMeta()«ELSE».«prop.getOperationName(GET_OR_CREATE)»()«ENDIF»''' - RJavaReferenceWithMeta case seg instanceof RMetaAttribute && seg.name == "address": '''.«prop.getOperationName(GET_OR_CREATE)»()''' - RJavaReferenceWithMeta case !(seg instanceof RMetaAttribute): '''.getOrCreateValue()''' - RJavaPojoInterface case seg instanceof RMetaAttribute: '''.«prop.getOperationName(GET_OR_CREATE)»()''' - default: '''''' - } - } - - //The type of the output expression to be set and the pojo property type are not the same when working with meta - private def JavaPojoProperty getPojoProperty(RFeature seg, JavaType outputExpressionType) { - if (seg instanceof RMetaAttribute && (outputExpressionType instanceof RJavaFieldWithMeta || outputExpressionType instanceof RJavaPojoInterface)) { - (outputExpressionType as JavaPojoInterface).findProperty("meta") - } else if (seg instanceof RMetaAttribute && outputExpressionType instanceof RJavaReferenceWithMeta) { - (outputExpressionType as JavaPojoInterface).findProperty("reference") - } else if (outputExpressionType instanceof RJavaWithMetaValue) { - (outputExpressionType as JavaPojoInterface).findProperty("value") - } else { - (outputExpressionType as JavaPojoInterface).findProperty(seg.name) - } - } - - - - private def JavaStatementBuilder assignValue(JavaStatementScope scope, ROperation op, boolean assignAsKey) { - if (assignAsKey) { - val metaClass = op.operationToReferenceWithMetaType - if (cardinality.isMulti(op.expression)) { - val lambdaScope = scope.lambdaScope - val item = lambdaScope.createUniqueIdentifier("item") - expressionGenerator.javaCode(op.expression, MAPPER_C.wrapExtendsWithoutMeta(op.expression), scope) - .collapseToSingleExpression(scope) - .mapExpression[ - JavaExpression.from( - ''' - «it» - .getItems() - .map(«item» -> «metaClass».builder() - .setExternalReference(«item».getMappedObject().getMeta().getExternalKey()) - .setGlobalReference(«item».getMappedObject().getMeta().getGlobalKey()) - .build()) - .collect(«Collectors».toList()) - ''', - LIST.wrap(metaClass) - ) - ] - } else { - val lambdaScope = scope.lambdaScope - val r = lambdaScope.createUniqueIdentifier("r") - val m = lambdaScope.createUniqueIdentifier("m") - expressionGenerator.javaCode(op.expression, typeProvider.getRMetaAnnotatedType(op.expression).RType.withNoMeta.toJavaReferenceType, scope) - .declareAsVariable(true, op.pathHead.name + op.pathTail.map[name.toFirstUpper].join, scope) - .mapExpression[ - JavaExpression.from( - ''' - «metaClass».builder() - .setGlobalReference(«Optional».ofNullable(«it») - .map(«r» -> «r».getMeta()) - .map(«m» -> «m».getGlobalKey()) - .orElse(null)) - .setExternalReference(«Optional».ofNullable(«it») - .map(«r» -> «r».getMeta()) - .map(«m» -> «m».getExternalKey()) - .orElse(null)) - .build() - ''', - metaClass - ) - ] - } - } else { - expressionGenerator.javaCode(op.expression, op.operationToMetaJavaType, scope) - } - } - - private def JavaExpression assignTarget(ROperation operation, RFunction function, Map outs, - JavaStatementScope scope) { - val root = operation.pathHead - switch (root) { - RAttribute: new JavaVariable(scope.getIdentifierOrThrow(root), root.RMetaAnnotatedType.toJavaReferenceType) - RShortcut: - unfoldLHSShortcut(root, function, scope) - } - } - - private def JavaExpression unfoldLHSShortcut(RShortcut shortcut, RFunction function, JavaStatementScope scope) { - val e = shortcut.expression - if (e instanceof RosettaSymbolReference) { - if (e.symbol instanceof RosettaCallableWithArgs) { - // assign-output for an alias - return JavaExpression.from('''«scope.getIdentifierOrThrow(shortcut)»(«expressionGenerator.aliasCallArgs(shortcut, function, scope)»)''', shortcut.shortcutExpressionJavaType) - } - } - return lhsExpand(e, scope) - } - - private def dispatch JavaExpression lhsExpand(RosettaExpression f, JavaStatementScope scope) { - throw new IllegalStateException("No implementation for lhsExpand for " + f.class) - } - - private def dispatch JavaExpression lhsExpand(RosettaFeatureCall f, - JavaStatementScope scope) { lhsExpand(f.receiver, scope).lhsFeature(f.feature) } - - private def dispatch JavaExpression lhsExpand(RosettaSymbolReference f, - JavaStatementScope scope) { f.symbol.lhsExpand(scope) } - - private def dispatch JavaExpression lhsExpand(ShortcutDeclaration f, - JavaStatementScope scope) { f.expression.lhsExpand(scope) } - - private def dispatch JavaExpression lhsExpand(RosettaUnaryOperation f, - JavaStatementScope scope) { f.argument.lhsExpand(scope) } - - private def dispatch JavaExpression lhsFeature(JavaExpression receiver, RosettaFeature f) { - throw new IllegalStateException("No implementation for lhsFeature for " + f.class) - } - - private def dispatch JavaExpression lhsFeature(JavaExpression receiver, Attribute f) { - val t = receiver.expressionType as JavaPojoInterface - val prop = t.findProperty(f.name) - JavaExpression.from('''«receiver».«prop.getOperationName(GET_OR_CREATE)»(«IF prop.type.isList»0«ENDIF»)''', prop.type.itemType) - } - - private def dispatch JavaExpression lhsExpand(RosettaSymbol c, JavaStatementScope scope) { - throw new IllegalStateException("No implementation for lhsExpand for " + c.class) - } - - private def dispatch JavaExpression lhsExpand(Attribute c, JavaStatementScope scope) { - val rAttribute = rTypeBuilderFactory.buildRAttribute(c) - new JavaVariable(scope.getIdentifierOrThrow(rAttribute), rAttribute.RMetaAnnotatedType.toJavaReferenceType) - } - - private def StringConcatenationClient contributeCondition(Condition condition, - GeneratedIdentifier conditionValidator, JavaStatementScope scope) { - val conditionBody = expressionGenerator.javaCode(condition.expression, COMPARISON_RESULT, scope.lambdaScope).toLambdaBody - ''' - «conditionValidator».validate(() -> «conditionBody», - "«condition.definition»"); - ''' - } - - private def JavaType outputTypeOrVoid(Function function) { - val out = getOutput(function) - if (out === null) { - JavaPrimitiveType.VOID - } else { - if (out.typeCall.type.needsBuilder) { - typeProvider.getRTypeOfSymbol(out).RType.toPolymorphicListOrSingleJavaType(out.card.isMany) - } else { - typeProvider.getRTypeOfSymbol(out).RType.toListOrSingleJavaType(out.card.isMany) - } - } - } - - private def StringConcatenationClient inputsAsArguments(List inputs, JavaStatementScope scope) { - '''«FOR input : inputs SEPARATOR ', '»«scope.getIdentifierOrThrow(input)»«ENDFOR»''' - } - - private def StringConcatenationClient inputsAsParameters(List inputs, JavaMethodScope scope) { - '''«FOR input : inputs SEPARATOR ', '»«input.toMetaJavaType» «scope.getIdentifierOrThrow(input)»«ENDFOR»''' - } - - private def JavaReferenceType shortcutExpressionJavaType(RShortcut feature) { - val metaRType = typeProvider.getRMetaAnnotatedType(feature.expression) - metaRType.toJavaReferenceType - } - - private def JavaType toBuilderItemType(RAttribute rAttribute) { - var javaType = rAttribute.RMetaAnnotatedType.toJavaReferenceType as JavaClass - if(javaType.needsBuilder) javaType = (javaType as JavaPojoInterface).toBuilderInterface - javaType - } - private def JavaType toBuilderType(RAttribute rAttribute) { - val javaType = rAttribute.toBuilderItemType - if (rAttribute.multi) { - return LIST.wrap(javaType) - } else { - return javaType - } - } - - private def needsBuilder(RAttribute rAttribute) { - var javaType = rAttribute.RMetaAnnotatedType.toJavaReferenceType as JavaClass - javaType.needsBuilder - } - - private def boolean needsBuilder(JavaClass javaClass) { - switch (javaClass) { - JavaPojoInterface: true - default: false - } - } -} diff --git a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/reports/ReportGenerator.java b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/reports/ReportGenerator.java new file mode 100644 index 0000000000..34f6a4085e --- /dev/null +++ b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/reports/ReportGenerator.java @@ -0,0 +1,96 @@ +package com.regnosys.rosetta.generator.java.reports; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.regnosys.rosetta.codegen.api.CodeRenderer; +import com.regnosys.rosetta.generator.java.FluentRObjectJavaClassGenerator; +import com.regnosys.rosetta.generator.java.function.FunctionGenerator; +import com.regnosys.rosetta.generator.java.scoping.JavaClassScope; +import com.regnosys.rosetta.generator.java.types.JavaTypeTranslator; +import com.regnosys.rosetta.generator.java.types.RGeneratedJavaClass; +import com.regnosys.rosetta.rosetta.RosettaCorpus; +import com.regnosys.rosetta.rosetta.RosettaModel; +import com.regnosys.rosetta.rosetta.RosettaReport; +import com.regnosys.rosetta.types.RFunction; +import com.regnosys.rosetta.types.RObjectFactory; +import com.regnosys.rosetta.utils.ModelIdProvider; +import com.rosetta.model.lib.annotations.RuneLabelProvider; +import com.rosetta.model.lib.functions.RosettaFunction; +import com.rosetta.model.lib.reports.ReportFunction; +import com.rosetta.util.types.JavaClass; +import com.rosetta.util.types.JavaParameterizedType; +import com.rosetta.util.types.JavaType; + +import jakarta.inject.Inject; + +public class ReportGenerator extends FluentRObjectJavaClassGenerator> { + @Inject + private RObjectFactory rObjectFactory; + @Inject + private FunctionGenerator functionGenerator; + @Inject + private JavaTypeTranslator typeTranslator; + @Inject + private ModelIdProvider modelIdProvider; + + @Override + protected Stream streamObjects(RosettaModel model) { + return model.getElements().stream() + .filter(RosettaReport.class::isInstance) + .map(RosettaReport.class::cast) + .map(rObjectFactory::buildRFunction); + } + + @Override + protected RGeneratedJavaClass createTypeRepresentation(RFunction rFunction) { + return typeTranslator.toFunctionJavaClass(rFunction); + } + + @Override + protected CodeRenderer generateClass(RFunction rFunction, RGeneratedJavaClass clazz, String version, JavaClassScope scope) { + RosettaReport report = (RosettaReport) rFunction.getEObject(); + JavaType baseInterface = JavaParameterizedType.from( + new TypeReference>() {}, + typeTranslator.toMetaJavaType(rFunction.getInputs().get(0)), + typeTranslator.toMetaJavaType(rFunction.getOutput())); + + Map, CodeRenderer> annotations = new LinkedHashMap<>(); + annotations.put(com.rosetta.model.lib.annotations.RosettaReport.class, reportAnnotation(report)); + JavaClass labelProviderClass = typeTranslator.toLabelProviderJavaClass(rFunction); + annotations.put(RuneLabelProvider.class, labelProviderAnnotation(labelProviderClass)); + + return functionGenerator.rBuildClass(rFunction, clazz, false, List.of(baseInterface), annotations, true, scope); + } + + private CodeRenderer reportAnnotation(RosettaReport report) { + return out -> { + out.write("namespace=\""); + out.write(modelIdProvider.toDottedPath(report.getModel())); + out.write("\", body=\""); + out.write(report.getRegulatoryBody().getBody().getName()); + out.write("\", corpusList={"); + List corpusList = report.getRegulatoryBody().getCorpusList(); + for (int i = 0; i < corpusList.size(); i++) { + if (i > 0) { + out.write(", "); + } + out.write("\""); + out.write(corpusList.get(i).getName()); + out.write("\""); + } + out.write("}"); + }; + } + + private CodeRenderer labelProviderAnnotation(JavaClass labelProviderClass) { + return out -> { + out.write("labelProvider="); + out.write(labelProviderClass); + out.write(".class"); + }; + } +} diff --git a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/reports/ReportGenerator.xtend b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/reports/ReportGenerator.xtend deleted file mode 100644 index 01159cfbd6..0000000000 --- a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/reports/ReportGenerator.xtend +++ /dev/null @@ -1,45 +0,0 @@ -package com.regnosys.rosetta.generator.java.reports - -import com.regnosys.rosetta.generator.java.function.FunctionGenerator -import com.regnosys.rosetta.generator.java.types.JavaTypeTranslator -import com.regnosys.rosetta.types.RObjectFactory -import com.rosetta.model.lib.reports.ReportFunction -import com.rosetta.util.types.JavaParameterizedType -import jakarta.inject.Inject -import com.regnosys.rosetta.rosetta.RosettaReport -import com.fasterxml.jackson.core.type.TypeReference -import com.regnosys.rosetta.utils.ModelIdProvider -import org.eclipse.xtend2.lib.StringConcatenationClient -import com.rosetta.model.lib.annotations.RuneLabelProvider -import java.util.Map -import com.regnosys.rosetta.generator.java.types.RGeneratedJavaClass -import com.regnosys.rosetta.generator.java.RObjectJavaClassGenerator -import com.regnosys.rosetta.types.RFunction -import com.regnosys.rosetta.rosetta.RosettaModel -import com.rosetta.model.lib.functions.RosettaFunction -import com.regnosys.rosetta.generator.java.scoping.JavaClassScope - -class ReportGenerator extends RObjectJavaClassGenerator> { - @Inject extension RObjectFactory - @Inject FunctionGenerator functionGenerator - @Inject extension JavaTypeTranslator - @Inject extension ModelIdProvider - - override protected streamObjects(RosettaModel model) { - model.elements.stream.filter[it instanceof RosettaReport].map[it as RosettaReport].map[buildRFunction] - } - override protected createTypeRepresentation(RFunction rFunction) { - rFunction.toFunctionJavaClass - } - override protected generateClass(RFunction rFunction, RGeneratedJavaClass clazz, String version, JavaClassScope scope) { - val report = rFunction.EObject as RosettaReport - val baseInterface = JavaParameterizedType.from(new TypeReference>() {}, rFunction.inputs.head.toMetaJavaType, rFunction.output.toMetaJavaType) - - val Map, StringConcatenationClient> annotations = newLinkedHashMap - annotations.put(com.rosetta.model.lib.annotations.RosettaReport, '''namespace="«report.model.toDottedPath»", body="«report.regulatoryBody.body.name»", corpusList={«FOR corpus: report.regulatoryBody.corpusList SEPARATOR ", "»"«corpus.name»"«ENDFOR»}''') - val labelProviderClass = rFunction.toLabelProviderJavaClass - annotations.put(RuneLabelProvider, '''labelProvider=«labelProviderClass».class''') - - return functionGenerator.rBuildClass(rFunction, clazz, false, #[baseInterface], annotations, true, scope); - } -} diff --git a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/reports/RuleGenerator.java b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/reports/RuleGenerator.java new file mode 100644 index 0000000000..fd12a832a3 --- /dev/null +++ b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/reports/RuleGenerator.java @@ -0,0 +1,54 @@ +package com.regnosys.rosetta.generator.java.reports; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.regnosys.rosetta.codegen.api.CodeRenderer; +import com.regnosys.rosetta.generator.java.FluentRObjectJavaClassGenerator; +import com.regnosys.rosetta.generator.java.function.FunctionGenerator; +import com.regnosys.rosetta.generator.java.scoping.JavaClassScope; +import com.regnosys.rosetta.generator.java.types.JavaTypeTranslator; +import com.regnosys.rosetta.generator.java.types.RGeneratedJavaClass; +import com.regnosys.rosetta.rosetta.RosettaModel; +import com.regnosys.rosetta.rosetta.RosettaRule; +import com.regnosys.rosetta.types.RFunction; +import com.regnosys.rosetta.types.RObjectFactory; +import com.rosetta.model.lib.functions.RosettaFunction; +import com.rosetta.model.lib.reports.ReportFunction; +import com.rosetta.util.types.JavaParameterizedType; +import com.rosetta.util.types.JavaType; + +import jakarta.inject.Inject; + +public class RuleGenerator extends FluentRObjectJavaClassGenerator> { + @Inject + private JavaTypeTranslator typeTranslator; + @Inject + private RObjectFactory rObjectFactory; + @Inject + private FunctionGenerator functionGenerator; + + @Override + protected Stream streamObjects(RosettaModel model) { + return model.getElements().stream() + .filter(RosettaRule.class::isInstance) + .map(RosettaRule.class::cast) + .map(rObjectFactory::buildRFunction); + } + + @Override + protected RGeneratedJavaClass createTypeRepresentation(RFunction rFunction) { + return typeTranslator.toFunctionJavaClass(rFunction); + } + + @Override + protected CodeRenderer generateClass(RFunction rFunction, RGeneratedJavaClass clazz, String version, JavaClassScope scope) { + JavaType baseInterface = JavaParameterizedType.from( + new TypeReference>() {}, + typeTranslator.toMetaJavaType(rFunction.getInputs().get(0)), + typeTranslator.toMetaJavaType(rFunction.getOutput())); + return functionGenerator.rBuildClass(rFunction, clazz, false, List.of(baseInterface), Collections.emptyMap(), true, scope); + } +} diff --git a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/reports/RuleGenerator.xtend b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/reports/RuleGenerator.xtend deleted file mode 100644 index 0792a8253b..0000000000 --- a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/reports/RuleGenerator.xtend +++ /dev/null @@ -1,33 +0,0 @@ -package com.regnosys.rosetta.generator.java.reports - -import jakarta.inject.Inject -import com.regnosys.rosetta.generator.java.types.JavaTypeTranslator -import com.regnosys.rosetta.types.RObjectFactory -import com.rosetta.model.lib.reports.ReportFunction -import com.rosetta.util.types.JavaParameterizedType -import com.regnosys.rosetta.generator.java.function.FunctionGenerator -import com.regnosys.rosetta.rosetta.RosettaRule -import com.fasterxml.jackson.core.type.TypeReference -import com.regnosys.rosetta.generator.java.RObjectJavaClassGenerator -import com.regnosys.rosetta.types.RFunction -import com.regnosys.rosetta.generator.java.types.RGeneratedJavaClass -import com.rosetta.model.lib.functions.RosettaFunction -import com.regnosys.rosetta.rosetta.RosettaModel -import com.regnosys.rosetta.generator.java.scoping.JavaClassScope - -class RuleGenerator extends RObjectJavaClassGenerator> { - @Inject extension JavaTypeTranslator - @Inject extension RObjectFactory - @Inject FunctionGenerator functionGenerator - - override protected streamObjects(RosettaModel model) { - model.elements.stream.filter[it instanceof RosettaRule].map[it as RosettaRule].map[buildRFunction] - } - override protected createTypeRepresentation(RFunction rFunction) { - rFunction.toFunctionJavaClass - } - override protected generateClass(RFunction rFunction, RGeneratedJavaClass clazz, String version, JavaClassScope scope) { - val baseInterface = JavaParameterizedType.from(new TypeReference>() {}, rFunction.inputs.head.toMetaJavaType, rFunction.output.toMetaJavaType) - return functionGenerator.rBuildClass(rFunction, clazz, false, #[baseInterface], emptyMap, true, scope) - } -} \ No newline at end of file diff --git a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/statement/builder/JavaExpression.java b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/statement/builder/JavaExpression.java index a9403a4bd1..5709bbbc4f 100644 --- a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/statement/builder/JavaExpression.java +++ b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/statement/builder/JavaExpression.java @@ -27,6 +27,8 @@ import com.regnosys.rosetta.generator.DebuggingTargetLanguageStringConcatenation; import com.regnosys.rosetta.generator.GeneratedIdentifier; import com.regnosys.rosetta.generator.java.scoping.JavaStatementScope; +import com.regnosys.rosetta.generator.java.util.CodeWriterTargetStringConcatenation; +import com.regnosys.rosetta.generator.java.util.TargetStringConcatenationCodeWriter; import com.regnosys.rosetta.generator.java.statement.JavaAssignment; import com.regnosys.rosetta.generator.java.statement.JavaExpressionStatement; import com.regnosys.rosetta.generator.java.statement.JavaLambdaBody; @@ -149,155 +151,4 @@ public String toString() { return DebuggingTargetLanguageStringConcatenation.convertToDebugString(this); } - /** - * Migration bridge: renders legacy Xtend template code ({@link StringConcatenationClient}) - * into a fluent {@link CodeWriter}. To be removed once all generators use the fluent API. - */ - private static final class CodeWriterTargetStringConcatenation implements TargetStringConcatenation { - private final CodeWriter out; - private boolean lineHasContent = false; - - private CodeWriterTargetStringConcatenation(CodeWriter out) { - this.out = out; - } - - @Override - public int length() { - throw new UnsupportedOperationException(); - } - - @Override - public char charAt(int index) { - throw new UnsupportedOperationException(); - } - - @Override - public CharSequence subSequence(int start, int end) { - throw new UnsupportedOperationException(); - } - - @Override - public void newLineIfNotEmpty() { - if (lineHasContent) { - newLine(); - } - } - - @Override - public void newLine() { - out.newline(); - lineHasContent = false; - } - - @Override - public void appendImmediate(Object object, String indentation) { - append(object, indentation); - } - - @Override - public void append(Object object, String indentation) { - if (object instanceof String value) { - appendString(value, indentation); - } else { - append(object); - } - } - - @Override - public void append(Object object) { - if (object == null) { - return; - } - if (object instanceof StringConcatenationClient client) { - StringConcatenationClient.appendTo(client, this); - } else { - out.write(object); - markWritten(object); - } - } - - private void appendString(String value, String indentation) { - String[] lines = value.split("\n", -1); - for (int i = 0; i < lines.length; i++) { - if (i > 0) { - newLine(); - if (!lines[i].isEmpty() && !indentation.isEmpty()) { - out.write(indentation); - lineHasContent = true; - } - } - if (!lines[i].isEmpty()) { - out.write(lines[i]); - lineHasContent = true; - } - } - } - - // Best-effort heuristic for newLineIfNotEmpty: infers whether the written object - // left content on the current line from its toString(), which for identifiers and - // renderers may not equal the rendered text. Good enough for the migration bridge. - private void markWritten(Object object) { - String value = object.toString(); - int lastNewline = value.lastIndexOf('\n'); - if (lastNewline >= 0) { - lineHasContent = lastNewline < value.length() - 1; - } else if (!value.isEmpty()) { - lineHasContent = true; - } - } - } - - /** - * Migration bridge: lets a fluent {@link CodeRenderer} render into legacy Xtend - * template machinery. To be removed once all generators use the fluent API. - */ - private static final class TargetStringConcatenationCodeWriter implements CodeWriter { - private static final String INDENT = " "; - - private final TargetStringConcatenation target; - private int indent = 0; - private boolean atStartOfLine = true; - - private TargetStringConcatenationCodeWriter(TargetStringConcatenation target) { - this.target = target; - } - - @Override - public void write(Object object) { - if (object == null) { - return; - } - // Legacy representations (e.g. generated identifiers) must go through the - // target's own machinery, which defers identifier resolution until scopes - // are resolvable and substitutes desired names when debugging. - if (object instanceof CodeRenderer renderer && !(object instanceof com.regnosys.rosetta.generator.TargetLanguageRepresentation)) { - renderer.render(this); - return; - } - if (atStartOfLine) { - target.append(INDENT.repeat(indent)); - atStartOfLine = false; - } - target.append(object); - } - - @Override - public void newline() { - target.newLine(); - atStartOfLine = true; - } - - @Override - public void indent() { - indent++; - } - - @Override - public void dedent() { - if (indent == 0) { - throw new IllegalStateException("Cannot dedent below zero"); - } - indent--; - } - } } diff --git a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/types/RGeneratedJavaClass.java b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/types/RGeneratedJavaClass.java index b60519d367..96751c2dae 100644 --- a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/types/RGeneratedJavaClass.java +++ b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/types/RGeneratedJavaClass.java @@ -5,9 +5,13 @@ import java.util.List; import org.eclipse.xtend2.lib.StringConcatenationClient; +import org.eclipse.xtend2.lib.StringConcatenationClient.TargetStringConcatenation; import com.fasterxml.jackson.core.type.TypeReference; +import com.regnosys.rosetta.codegen.api.CodeWriter; +import com.regnosys.rosetta.generator.TargetLanguageRepresentation; import com.regnosys.rosetta.generator.java.scoping.JavaPackageName; +import com.regnosys.rosetta.generator.java.util.TargetStringConcatenationCodeWriter; import com.rosetta.util.DottedPath; import com.rosetta.util.types.JavaClass; import com.rosetta.util.types.JavaParameterizedType; @@ -46,27 +50,26 @@ public RGeneratedJavaClass createNestedClassImplementingInterfa return new SimpleGeneratedJavaClass<>(packageName, this.getNestedTypeName().child(simpleName), null, interf); } - public StringConcatenationClient asClassDeclaration() { - return new StringConcatenationClient() { + public TargetLanguageRepresentation asClassDeclaration() { + return new TargetLanguageRepresentation() { @Override - protected void appendTo(TargetStringConcatenation target) { - target.append("class "); - target.append(RGeneratedJavaClass.this.getSimpleName()); + public void render(CodeWriter out) { + out.write("class ", RGeneratedJavaClass.this.getSimpleName()); JavaClass superclass = RGeneratedJavaClass.this.getSuperclass(); if (!JavaClass.OBJECT.equals(superclass)) { - target.append(" extends "); - target.append(superclass); + out.write(" extends ", superclass); } List> interfaces = RGeneratedJavaClass.this.getInterfaces(); if (!interfaces.isEmpty()) { - target.append(" implements "); - target.append(interfaces.get(0)); - for (int i=1; iThis lets a generator that has moved to the fluent {@code CodeWriter} API + * keep embedding small fragments still produced as Xtend templates by + * not-yet-migrated code (e.g. method parameter lists or call arguments): wrap + * the fragment with {@link #asCodeRenderer}. Unlike resolving the template to a + * string up front, this keeps the surrounding scope open so the rest of the + * class can still claim identifiers while rendering. It is therefore suited to + * inline fragments rather than whole, multi-line class bodies. + */ +public final class CodeWriterTargetStringConcatenation implements TargetStringConcatenation { + private final CodeWriter out; + private boolean lineHasContent = false; + + public CodeWriterTargetStringConcatenation(CodeWriter out) { + this.out = out; + } + + /** + * Wraps a legacy Xtend template fragment as a fluent {@link CodeRenderer}. + */ + public static CodeRenderer asCodeRenderer(StringConcatenationClient template) { + return out -> StringConcatenationClient.appendTo(template, new CodeWriterTargetStringConcatenation(out)); + } + + @Override + public int length() { + throw new UnsupportedOperationException(); + } + + @Override + public char charAt(int index) { + throw new UnsupportedOperationException(); + } + + @Override + public CharSequence subSequence(int start, int end) { + throw new UnsupportedOperationException(); + } + + @Override + public void newLineIfNotEmpty() { + if (lineHasContent) { + newLine(); + } + } + + @Override + public void newLine() { + out.newline(); + lineHasContent = false; + } + + @Override + public void appendImmediate(Object object, String indentation) { + append(object, indentation); + } + + @Override + public void append(Object object, String indentation) { + if (object instanceof String value) { + appendString(value, indentation); + } else { + append(object); + } + } + + @Override + public void append(Object object) { + if (object == null) { + return; + } + if (object instanceof StringConcatenationClient client) { + StringConcatenationClient.appendTo(client, this); + } else { + out.write(object); + markWritten(object); + } + } + + private void appendString(String value, String indentation) { + String[] lines = value.split("\n", -1); + for (int i = 0; i < lines.length; i++) { + if (i > 0) { + newLine(); + if (!lines[i].isEmpty() && !indentation.isEmpty()) { + out.write(indentation); + lineHasContent = true; + } + } + if (!lines[i].isEmpty()) { + out.write(lines[i]); + lineHasContent = true; + } + } + } + + // Best-effort heuristic for newLineIfNotEmpty: infers whether the written object + // left content on the current line from its toString(), which for identifiers and + // renderers may not equal the rendered text. Good enough for the migration bridge. + private void markWritten(Object object) { + String value = object.toString(); + int lastNewline = value.lastIndexOf('\n'); + if (lastNewline >= 0) { + lineHasContent = lastNewline < value.length() - 1; + } else if (!value.isEmpty()) { + lineHasContent = true; + } + } +} diff --git a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/util/FluentImportManager.java b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/util/FluentImportManager.java new file mode 100644 index 0000000000..b70a0e61d4 --- /dev/null +++ b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/util/FluentImportManager.java @@ -0,0 +1,50 @@ +/* + * Copyright 2024 REGnosys + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.regnosys.rosetta.generator.java.util; + +import com.regnosys.rosetta.codegen.api.CodeRenderer; +import com.regnosys.rosetta.codegen.support.StringCodeWriter; +import com.regnosys.rosetta.generator.java.scoping.JavaFileScope; +import com.rosetta.util.DottedPath; + +/** + * Given the body of a Java class represented as a {@link CodeRenderer}, + * generates a full Java class file by adding imports and resolving identifiers. + * The fluent counterpart of {@link ImportManagerExtension}. + */ +public class FluentImportManager { + public String buildClass(DottedPath packageName, CodeRenderer classCode, JavaFileScope fileScope) { + if (fileScope.isClosed()) { + throw new IllegalStateException("The top scope may not be closed, as imports will be added to it."); + } + RecordingCodeWriter recording = new RecordingCodeWriter(fileScope); + classCode.render(recording); + + StringCodeWriter result = new StringCodeWriter(); + result.writeln("package ", packageName, ";"); + result.newline(); + recording.getImports().forEach(imp -> result.writeln("import ", imp, ";")); + result.newline(); + recording.getStaticImports().forEach(imp -> result.writeln("import static ", imp, ";")); + result.newline(); + recording.replay(result); + if (!result.toString().endsWith("\n")) { + result.newline(); + } + return result.toString(); + } +} diff --git a/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/util/TargetStringConcatenationCodeWriter.java b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/util/TargetStringConcatenationCodeWriter.java new file mode 100644 index 0000000000..1869f27dd6 --- /dev/null +++ b/rune-lang/src/main/java/com/regnosys/rosetta/generator/java/util/TargetStringConcatenationCodeWriter.java @@ -0,0 +1,82 @@ +/* + * Copyright 2024 REGnosys + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.regnosys.rosetta.generator.java.util; + +import org.eclipse.xtend2.lib.StringConcatenationClient.TargetStringConcatenation; + +import com.regnosys.rosetta.codegen.api.CodeRenderer; +import com.regnosys.rosetta.codegen.api.CodeWriter; +import com.regnosys.rosetta.generator.TargetLanguageRepresentation; + +/** + * Migration bridge: lets a fluent {@link CodeRenderer} render into the legacy Xtend + * template machinery by exposing a {@link CodeWriter} that appends to a + * {@link TargetStringConcatenation}. This is the counterpart of + * {@link CodeWriterTargetStringConcatenation}, and lets a value rendered with the + * fluent API still be embedded in a not-yet-migrated Xtend template (e.g. a + * {@link TargetLanguageRepresentation} whose {@code appendTo} delegates to its + * {@code render}). To be removed once all generators use the fluent API. + */ +public final class TargetStringConcatenationCodeWriter implements CodeWriter { + private static final String INDENT = " "; + + private final TargetStringConcatenation target; + private int indent = 0; + private boolean atStartOfLine = true; + + public TargetStringConcatenationCodeWriter(TargetStringConcatenation target) { + this.target = target; + } + + @Override + public void write(Object object) { + if (object == null) { + return; + } + // Legacy representations (e.g. generated identifiers) must go through the + // target's own machinery, which defers identifier resolution until scopes + // are resolvable and substitutes desired names when debugging. + if (object instanceof CodeRenderer renderer && !(object instanceof TargetLanguageRepresentation)) { + renderer.render(this); + return; + } + if (atStartOfLine) { + target.append(INDENT.repeat(indent)); + atStartOfLine = false; + } + target.append(object); + } + + @Override + public void newline() { + target.newLine(); + atStartOfLine = true; + } + + @Override + public void indent() { + indent++; + } + + @Override + public void dedent() { + if (indent == 0) { + throw new IllegalStateException("Cannot dedent below zero"); + } + indent--; + } +}