From 56bf203fd5efc3691e8c8c6885f896c26b6df6a7 Mon Sep 17 00:00:00 2001 From: Andreas Stiller Date: Wed, 11 Dec 2024 16:13:23 +0100 Subject: [PATCH 1/3] TacticDDD dsl formatting improvements * Traits and BasicTypes are included in formatting rules * Comments trigger a new-line * references and traits receive an leading "@" even if created by API --- .../ExtractIDValueObjectQuickFixTest.xtend | 2 +- ...erive-bc-from-subdomain-test-11-output.cml | 16 +- .../dsl/ContextMapDSLFormattingTest.xtend | 213 ++++++++++++++++++ ...ContextMapperCrossReferenceSerializer.java | 50 ++++ .../dsl/ContextMappingDSLRuntimeModule.xtend | 4 + .../ContextMappingDSLFormatter.xtend | 2 + .../tactic/dsl/TacticDDDLanguage.xtext | 1 + .../TacticDDDLanguageFormatter.xtend | 186 +++++++++------ 8 files changed, 396 insertions(+), 78 deletions(-) create mode 100644 org.contextmapper.dsl.tests/src/org/contextmapper/dsl/ContextMapDSLFormattingTest.xtend create mode 100644 org.contextmapper.dsl/src/org/contextmapper/dsl/ContextMapperCrossReferenceSerializer.java diff --git a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/ExtractIDValueObjectQuickFixTest.xtend b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/ExtractIDValueObjectQuickFixTest.xtend index c63cca2f..e92a0043 100644 --- a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/ExtractIDValueObjectQuickFixTest.xtend +++ b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/ExtractIDValueObjectQuickFixTest.xtend @@ -49,7 +49,7 @@ class ExtractIDValueObjectQuickFixTest extends AbstractCMLLanguageServerTest { Entity Customer { String firstname String lastname - - CustomerId customerId + - @CustomerId customerId } ValueObject CustomerId { String id diff --git a/org.contextmapper.dsl.tests/integ-test-files/refactorings/derive-bc-from-subdomain-test-11-output.cml b/org.contextmapper.dsl.tests/integ-test-files/refactorings/derive-bc-from-subdomain-test-11-output.cml index 9349738f..fbc7ea61 100644 --- a/org.contextmapper.dsl.tests/integ-test-files/refactorings/derive-bc-from-subdomain-test-11-output.cml +++ b/org.contextmapper.dsl.tests/integ-test-files/refactorings/derive-bc-from-subdomain-test-11-output.cml @@ -27,17 +27,17 @@ BoundedContext ClaimsManagement implements ClaimsManagement { Double amountClaimed String desc String claimId key - - Agent agent + - @Agent agent } Entity Policy { Date startDate Date endDate String policyId key - - List claims + - List<@Claim> claims } Entity Contract { String contractId key - - List policies + - List<@Policy> policies } Entity Agent { Long personalID @@ -49,7 +49,7 @@ BoundedContext ClaimsManagement implements ClaimsManagement { String firstName String lastName String claimantId key - - List claims + - List<@Claim> claims } } } @@ -60,15 +60,15 @@ Domain Insurance_Application { Date date Double amountClaimed String desc - - Agent agent + - @Agent agent } Entity Policy { Date startDate Date endDate - - List claims + - List<@Claim> claims } Entity Contract { - - List policies + - List<@Policy> policies } Entity Agent { Long personalID @@ -78,7 +78,7 @@ Domain Insurance_Application { Entity Claimant { String firstName String lastName - - List claims + - List<@Claim> claims } Service AccidentService { submitClaim; diff --git a/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/ContextMapDSLFormattingTest.xtend b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/ContextMapDSLFormattingTest.xtend new file mode 100644 index 00000000..050b6767 --- /dev/null +++ b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/ContextMapDSLFormattingTest.xtend @@ -0,0 +1,213 @@ +/* + * Copyright 2018 The Context Mapper Project Team + * + * 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 org.contextmapper.dsl + +import com.google.inject.Inject +import org.contextmapper.dsl.contextMappingDSL.ContextMappingModel +import org.eclipse.xtext.testing.InjectWith +import org.eclipse.xtext.testing.extensions.InjectionExtension +import org.eclipse.xtext.testing.util.ParseHelper +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.^extension.ExtendWith + +import static org.junit.jupiter.api.Assertions.* +import org.contextmapper.dsl.tests.ContextMappingDSLInjectorProvider +import org.eclipse.xtext.resource.SaveOptions +import org.eclipse.xtext.serializer.ISerializer +import org.contextmapper.dsl.standalone.ContextMapperStandaloneSetup +import org.contextmapper.dsl.contextMappingDSL.ContextMappingDSLFactory +import org.contextmapper.tactic.dsl.tacticdsl.TacticdslFactory + +@ExtendWith(InjectionExtension) +@InjectWith(ContextMappingDSLInjectorProvider) +class ContextMapDSLFormattingTest { + @Inject + ParseHelper parseHelper + @Inject extension ISerializer + + /** + * Aggregate with entities, traits, basic-types and enums with interspersed comments. + * The traits are used with the 'with' keyword + */ + @Test + def void formatsMapLoadedFromFile() { + val testInput = ''' + BoundedContext BC1 { Aggregate A1 { Entity E1 { String prop1 "prop1Comment" String prop2 } + enum State1 { A, B } Trait T1 {} + "State2Comment" enum State2 { "AA" A, B } "E2Comment" Entity E2 + with@T1 { package = abc validate = "validation" aggregateRoot "E2Comment" + String prop3 } Entity E3 { String prop1 } + Trait T2 { "prop3Comment" String prop3 "ref1Comment" - @E1 ref1 } + BasicType BT1 { "prop4Comment" int prop4 - List< @T2> prop5 } + "V1Comment" ValueObject V1 with@T1 with@T2 { int intProp }}} BoundedContext BC2 + { Aggregate A2 { Entity E3 extends @E2 { "prop5comment" String prop5 String prop6 "prop6comment" int prop6}}} + ContextMap TestContextMap { contains BC1 } + '''; + val expectedResult = ''' + ContextMap TestContextMap { + contains BC1 + } + + BoundedContext BC1 { + Aggregate A1 { + Entity E1 { + String prop1 + "prop1Comment" + String prop2 + } + enum State1 { + A, B + } + Trait T1 { + } + "State2Comment" + enum State2 { + "AA" A, B + } + "E2Comment" + Entity E2 with@T1 { + package = abc + validate = "validation" + aggregateRoot + "E2Comment" + String prop3 + } + Entity E3 { + String prop1 + } + Trait T2 { + "prop3Comment" + String prop3 + "ref1Comment" + - @E1 ref1 + } + BasicType BT1 { + "prop4Comment" + int prop4 + - List<@T2> prop5 + } + "V1Comment" + ValueObject V1 with@T1 with@T2 { + int intProp + } + } + } + + BoundedContext BC2 + { + Aggregate A2 { + Entity E3 extends @E2 { + "prop5comment" + String prop5 + String prop6 + "prop6comment" + int prop6 + } + } + } + + '''; + // given + val model = parseHelper.parse(testInput) + // when, then + assertEquals(expectedResult, + model.serialize(SaveOptions.newBuilder.format().getOptions())) + } + + @Test + def void formatsMapLoadedFromAPI() { + val contextMapper = ContextMapperStandaloneSetup.getStandaloneAPI(); + val factory = ContextMappingDSLFactory.eINSTANCE; + val tacticdslFactory = TacticdslFactory.eINSTANCE; + + val resource = contextMapper.createCML( "target/test-create-cm.cml" ); + + // given + val model = resource.getContextMappingModel(); + val contextMap = factory.createContextMap(); + contextMap.setName( "TestContextMap" ); + model.setMap( contextMap ); + + val boundedContext = factory.createBoundedContext(); + boundedContext.setName( "TestContext" ); + contextMap.getBoundedContexts().add( boundedContext ); + + val aggregate = factory.createAggregate(); + aggregate.setName( "A1" ); + model.getBoundedContexts().add( boundedContext ); + boundedContext.getAggregates().add( aggregate ); + + val trait1 = tacticdslFactory.createTrait(); + trait1.setName( "T1" ); + aggregate.getDomainObjects().add( trait1 ); + + val entity1 = tacticdslFactory.createEntity(); + aggregate.getDomainObjects().add( entity1 ); + entity1.setName( "E100" ); + entity1.setAggregateRoot( true ); + + val entity2 = tacticdslFactory.createEntity(); + entity2.setExtends( entity1 ); + entity2.setName( "E2" ); + entity2.getTraits().add( trait1 ); + aggregate.getDomainObjects().add( entity2 ); + + val attribute1 = tacticdslFactory.createAttribute(); + attribute1.setName( "prop1" ); + attribute1.setType( "String" ); + attribute1.doc = "prop1Comment" + entity2.getAttributes().add( attribute1 ); + + var reference1 = tacticdslFactory.createReference(); + reference1.setName( "ref1" ); + reference1.setDomainObjectType( entity2 ); + entity2.getReferences().add( reference1 ); + + val entity3 = tacticdslFactory.createEntity(); + entity3.setExtends( entity1 ); + entity3.setName( "E3" ); + aggregate.getDomainObjects().add( entity3 ); + + + val expectedResult = ''' + ContextMap TestContextMap { + contains TestContext + } + + BoundedContext TestContext { + Aggregate A1 { + Trait T1 + Entity E100 { + aggregateRoot + } + Entity E2 extends @E100 with@T1 { + "prop1Comment" + String prop1 + - @E2 ref1 + } + Entity E3 extends @E100 + } + } + + ''' + + // when, then + assertEquals(expectedResult, + model.serialize(SaveOptions.newBuilder.format().getOptions())) + } + + +} diff --git a/org.contextmapper.dsl/src/org/contextmapper/dsl/ContextMapperCrossReferenceSerializer.java b/org.contextmapper.dsl/src/org/contextmapper/dsl/ContextMapperCrossReferenceSerializer.java new file mode 100644 index 00000000..20c25f6a --- /dev/null +++ b/org.contextmapper.dsl/src/org/contextmapper/dsl/ContextMapperCrossReferenceSerializer.java @@ -0,0 +1,50 @@ +package org.contextmapper.dsl; + +import com.google.inject.Inject; +import org.contextmapper.tactic.dsl.tacticdsl.Reference; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.xtext.Assignment; +import org.eclipse.xtext.CrossReference; +import org.eclipse.xtext.nodemodel.INode; +import org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic; +import org.eclipse.xtext.serializer.tokens.CrossReferenceSerializer; +import org.eclipse.xtext.serializer.tokens.ICrossReferenceSerializer; + +public class ContextMapperCrossReferenceSerializer implements ICrossReferenceSerializer { + + private static final String REF_AT = "@"; + private final ICrossReferenceSerializer delegate; + + @Inject + public ContextMapperCrossReferenceSerializer(CrossReferenceSerializer delegate) { + this.delegate = delegate; + } + + @Override + public boolean isValid(EObject context, CrossReference crossref, EObject target, INode node, + ISerializationDiagnostic.Acceptor errorAcceptor) { + return delegate.isValid(context, crossref, target, node, errorAcceptor); + } + + @Override + public String serializeCrossRef(EObject context, CrossReference crossref, EObject target, INode node, + ISerializationDiagnostic.Acceptor errorAcceptor) { + var serialized = delegate.serializeCrossRef(context, crossref, target, node, errorAcceptor); + if (serialized != null && !serialized.startsWith(REF_AT)) { + if (node == null || !(node.hasPreviousSibling() && node.getPreviousSibling().getText().contains(REF_AT))) { + if (context instanceof Reference) { + serialized = REF_AT + serialized; + } else { + if (crossref.eContainer() instanceof Assignment) { + Assignment assignment = (Assignment) crossref.eContainer(); + var feature = assignment.getFeature(); + if (feature.equals("traits")) { + serialized = REF_AT + serialized; + } + } + } + } + } + return serialized; + } +} diff --git a/org.contextmapper.dsl/src/org/contextmapper/dsl/ContextMappingDSLRuntimeModule.xtend b/org.contextmapper.dsl/src/org/contextmapper/dsl/ContextMappingDSLRuntimeModule.xtend index 3a314976..098ab29e 100644 --- a/org.contextmapper.dsl/src/org/contextmapper/dsl/ContextMappingDSLRuntimeModule.xtend +++ b/org.contextmapper.dsl/src/org/contextmapper/dsl/ContextMappingDSLRuntimeModule.xtend @@ -31,4 +31,8 @@ class ContextMappingDSLRuntimeModule extends AbstractContextMappingDSLRuntimeMod return ImportUriGlobalScopeProvider } + override configure(com.google.inject.Binder binder) { + super.configure(binder) + binder.bind(org.eclipse.xtext.serializer.tokens.ICrossReferenceSerializer).to(org.contextmapper.dsl.ContextMapperCrossReferenceSerializer); + } } diff --git a/org.contextmapper.dsl/src/org/contextmapper/dsl/formatting2/ContextMappingDSLFormatter.xtend b/org.contextmapper.dsl/src/org/contextmapper/dsl/formatting2/ContextMappingDSLFormatter.xtend index b7265896..598f0395 100644 --- a/org.contextmapper.dsl/src/org/contextmapper/dsl/formatting2/ContextMappingDSLFormatter.xtend +++ b/org.contextmapper.dsl/src/org/contextmapper/dsl/formatting2/ContextMappingDSLFormatter.xtend @@ -325,10 +325,12 @@ class ContextMappingDSLFormatter extends TacticDDDLanguageFormatter { for (domainObject : aggregate.domainObjects) { domainObject.format + domainObject.prepend[newLine] } for (service : aggregate.services) { service.format + service.prepend[newLine] } } diff --git a/org.contextmapper.dsl/src/org/contextmapper/tactic/dsl/TacticDDDLanguage.xtext b/org.contextmapper.dsl/src/org/contextmapper/tactic/dsl/TacticDDDLanguage.xtext index 430db4ca..680c61e2 100644 --- a/org.contextmapper.dsl/src/org/contextmapper/tactic/dsl/TacticDDDLanguage.xtext +++ b/org.contextmapper.dsl/src/org/contextmapper/tactic/dsl/TacticDDDLanguage.xtext @@ -576,3 +576,4 @@ terminal REF : terminal ASC : ('--'|'association'); + diff --git a/org.contextmapper.dsl/src/org/contextmapper/tactic/dsl/formatting2/TacticDDDLanguageFormatter.xtend b/org.contextmapper.dsl/src/org/contextmapper/tactic/dsl/formatting2/TacticDDDLanguageFormatter.xtend index 22fe5a05..98ef61e4 100644 --- a/org.contextmapper.dsl/src/org/contextmapper/tactic/dsl/formatting2/TacticDDDLanguageFormatter.xtend +++ b/org.contextmapper.dsl/src/org/contextmapper/tactic/dsl/formatting2/TacticDDDLanguageFormatter.xtend @@ -16,144 +16,192 @@ package org.contextmapper.tactic.dsl.formatting2 import org.contextmapper.tactic.dsl.tacticdsl.Attribute -import org.contextmapper.tactic.dsl.tacticdsl.CommandEvent import org.contextmapper.tactic.dsl.tacticdsl.ComplexType -import org.contextmapper.tactic.dsl.tacticdsl.DomainEvent +import org.contextmapper.tactic.dsl.tacticdsl.DomainObject import org.contextmapper.tactic.dsl.tacticdsl.DomainObjectOperation +import org.contextmapper.tactic.dsl.tacticdsl.Trait +import org.contextmapper.tactic.dsl.tacticdsl.BasicType import org.contextmapper.tactic.dsl.tacticdsl.Entity import org.contextmapper.tactic.dsl.tacticdsl.Parameter import org.contextmapper.tactic.dsl.tacticdsl.Reference import org.contextmapper.tactic.dsl.tacticdsl.Service -import org.contextmapper.tactic.dsl.tacticdsl.ValueObject import org.contextmapper.tactic.dsl.tacticdsl.Enum import org.eclipse.xtext.formatting2.AbstractFormatter2 import org.eclipse.xtext.formatting2.IFormattableDocument import org.contextmapper.tactic.dsl.tacticdsl.ServiceOperation +import org.contextmapper.tactic.dsl.tacticdsl.TacticdslPackage +import org.eclipse.emf.ecore.EClass +import org.eclipse.emf.ecore.EStructuralFeature class TacticDDDLanguageFormatter extends AbstractFormatter2 { def dispatch void format(Entity entity, extension IFormattableDocument document) { + val EClass clazz = TacticdslPackage.eINSTANCE.getEntity() + val EStructuralFeature docFeature = clazz.getEStructuralFeature(TacticdslPackage.ENTITY__DOC) + entity.regionFor.feature(docFeature).append[newLine] + interior( - entity.regionFor.keyword('{').append[newLine], - entity.regionFor.keyword('}').prepend[newLine].append[newLine] + entity.regionFor.keyword('{').prepend[oneSpace].append[newLine], + entity.regionFor.keyword('}').prepend[newLine] )[indent] - entity.regionFor.keyword('aggregateRoot').append[newLine] - entity.prepend[newLines = 1] - entity.regionFor.keyword('Entity').prepend[newLine] + entity.regionFor.keyword('aggregateRoot').prepend[newLine] + entity.regionFor.keywords('hint', 'validate', 'belongsTo').forEach[ + prepend[newLine] + ] + entity.regionFor.keywords('with').forEach[ + append[noSpace].prepend[oneSpace] + ] + entity.regionFor.keywords('@').forEach[ + append[noSpace] + ] for (attribute : entity.attributes) { attribute.format - attribute.append[newLine] + attribute.prepend[newLine] } for (reference : entity.references) { reference.format - reference.append[newLine] + reference.prepend[newLine] } for (operation : entity.operations) { operation.format - operation.append[newLine] + operation.prepend[newLine] } } - - def dispatch void format(DomainEvent domainEvent, extension IFormattableDocument document) { - interior( - domainEvent.regionFor.keyword('{').append[newLine], - domainEvent.regionFor.keyword('}').prepend[newLine].append[newLine] - )[indent] - domainEvent.regionFor.keyword('aggregateRoot').append[newLine] - domainEvent.prepend[newLines = 1] - domainEvent.regionFor.keyword('DomainEvent').prepend[newLine] + def dispatch void format(DomainObject domainObject, extension IFormattableDocument document) { + val EClass clazz = TacticdslPackage.eINSTANCE.getDomainObject() + val EStructuralFeature docFeature = clazz.getEStructuralFeature(TacticdslPackage.DOMAIN_OBJECT__DOC) + domainObject.regionFor.feature(docFeature).append[newLine] - for (attribute : domainEvent.attributes) { - attribute.format - attribute.append[newLine] - } - for (reference : domainEvent.references) { - reference.format - reference.append[newLine] - } - for (operation : domainEvent.operations) { - operation.format - operation.append[newLine] - } - } - - def dispatch void format(CommandEvent commandEvent, extension IFormattableDocument document) { - interior( - commandEvent.regionFor.keyword('{').append[newLine], - commandEvent.regionFor.keyword('}').prepend[newLine].append[newLine] + interior( + domainObject.regionFor.keyword('{').prepend[oneSpace].append[newLine], + domainObject.regionFor.keyword('}').prepend[newLine] )[indent] - commandEvent.regionFor.keyword('aggregateRoot').append[newLine] - commandEvent.prepend[newLines = 1] - commandEvent.regionFor.keyword('CommandEvent').prepend[newLine] + domainObject.regionFor.keyword('aggregateRoot').append[newLine] + domainObject.regionFor.keyword('hint').prepend[newLine] + domainObject.regionFor.keywords('with').forEach[ + append[noSpace].prepend[oneSpace] + ] + domainObject.regionFor.keywords('@').forEach[ + append[noSpace] + ] - for (attribute : commandEvent.attributes) { + for (attribute : domainObject.attributes) { attribute.format - attribute.append[newLine] + attribute.prepend[newLine] } - for (reference : commandEvent.references) { + for (reference : domainObject.references) { reference.format - reference.append[newLine] + reference.prepend[newLine] } - for (operation : commandEvent.operations) { + for (operation : domainObject.operations) { operation.format - operation.append[newLine] + operation.prepend[newLine] } } - - def dispatch void format(ValueObject valueObject, extension IFormattableDocument document) { + + def dispatch void format(Trait trait, extension IFormattableDocument document) { + val EClass clazz = TacticdslPackage.eINSTANCE.getTrait() + val EStructuralFeature docFeature = clazz.getEStructuralFeature(TacticdslPackage.TRAIT__DOC) + trait.regionFor.feature(docFeature).append[newLine] + interior( - valueObject.regionFor.keyword('{').append[newLine], - valueObject.regionFor.keyword('}').prepend[newLine].append[newLine] + trait.regionFor.keyword('{').prepend[oneSpace].append[newLine], + trait.regionFor.keyword('}').prepend[newLine] )[indent] - valueObject.prepend[newLines = 1] - valueObject.regionFor.keyword('ValueObject').prepend[newLine] + trait.regionFor.keyword('hint').prepend[newLine] - for (attribute : valueObject.attributes) { + for (attribute : trait.attributes) { attribute.format - attribute.append[newLine] + attribute.prepend[newLine] } - for (reference : valueObject.references) { + for (reference : trait.references) { reference.format - reference.append[newLine] + reference.prepend[newLine] } - for (operation : valueObject.operations) { + for (operation : trait.operations) { operation.format - operation.append[newLine] + operation.prepend[newLine] } } - + + def dispatch void format(BasicType basicType, extension IFormattableDocument document) { + val EClass clazz = TacticdslPackage.eINSTANCE.getBasicType() + val EStructuralFeature docFeature = clazz.getEStructuralFeature(TacticdslPackage.BASIC_TYPE__DOC) + basicType.regionFor.feature(docFeature).append[newLine] + + interior( + basicType.regionFor.keyword('{').prepend[oneSpace].append[newLine], + basicType.regionFor.keyword('}').prepend[newLine] + )[indent] + + basicType.regionFor.keyword('hint').prepend[newLine] + basicType.regionFor.keywords('with').forEach[ + append[noSpace].prepend[oneSpace] + ] + basicType.regionFor.keywords('@').forEach[ + append[noSpace] + ] + + for (attribute : basicType.attributes) { + attribute.format + attribute.prepend[newLine] + } + for (reference : basicType.references) { + reference.format + reference.prepend[newLine] + } + for (operation : basicType.operations) { + operation.format + operation.prepend[newLine] + } + } + def dispatch void format(Enum enumm, extension IFormattableDocument document) { + val EClass clazz = TacticdslPackage.eINSTANCE.getEnum() + val EStructuralFeature docFeature = clazz.getEStructuralFeature(TacticdslPackage.ENUM__DOC) + enumm.regionFor.feature(docFeature).append[newLine] + interior( - enumm.regionFor.keyword('{').append[newLine], - enumm.regionFor.keyword('}').prepend[newLine].append[newLine] + enumm.regionFor.keyword('{').prepend[oneSpace].append[newLine], + enumm.regionFor.keyword('}').prepend[newLine] )[indent] - enumm.prepend[newLines = 1] - enumm.regionFor.keyword('enum').prepend[newLine] + enumm.regionFor.keywords(',').forEach [ + prepend[noSpace] + append[oneSpace] + ] for (attribute : enumm.attributes) { attribute.format - attribute.append[newLine] + attribute.prepend[newLine] } } def dispatch void format(Attribute attribute, extension IFormattableDocument document) { + val EClass attributeClass = TacticdslPackage.eINSTANCE.getAttribute() + val EStructuralFeature docFeature = attributeClass.getEStructuralFeature(TacticdslPackage.ATTRIBUTE__DOC) + + attribute.regionFor.feature(docFeature).append[newLine] attribute.regionFor.keyword('<').surround[noSpace] attribute.regionFor.keyword('>').prepend[noSpace] } def dispatch void format(Reference reference, extension IFormattableDocument document) { + val EClass referenceClass = TacticdslPackage.eINSTANCE.getReference() + val EStructuralFeature docFeature = referenceClass.getEStructuralFeature(TacticdslPackage.REFERENCE__DOC) + + reference.regionFor.feature(docFeature).append[newLine] reference.regionFor.keyword('<').surround[noSpace] reference.regionFor.keyword('>').prepend[noSpace] } def dispatch void format(DomainObjectOperation operation, extension IFormattableDocument document) { - operation.prepend[newLines = 1] + operation.prepend[newLine] operation.regionFor.keyword(';').prepend[noSpace] operation.regionFor.keyword('(').append[noSpace] @@ -187,11 +235,11 @@ class TacticDDDLanguageFormatter extends AbstractFormatter2 { def dispatch void format(Service service, extension IFormattableDocument document) { interior( - service.regionFor.keyword('{').append[newLine], + service.regionFor.keyword('{').prepend[oneSpace].append[newLine], service.regionFor.keyword('}').prepend[newLine].append[newLine] )[indent] - service.prepend[newLines = 1] + service.prepend[newLine] service.regionFor.keyword('Service').prepend[newLine] for (operation : service.operations) { @@ -200,7 +248,7 @@ class TacticDDDLanguageFormatter extends AbstractFormatter2 { } def dispatch void format(ServiceOperation operation, extension IFormattableDocument document) { - operation.prepend[newLines = 1] + operation.prepend[newLine] operation.regionFor.keyword(';').prepend[noSpace] operation.regionFor.keyword('(').append[noSpace] From 9e3dc1b2aaf14f19df78e8cc59bf952168fe3ea8 Mon Sep 17 00:00:00 2001 From: Andreas Stiller Date: Thu, 12 Dec 2024 06:23:14 +0100 Subject: [PATCH 2/3] no functional change, applied vanilla eclipse formatting for xtend and xtext files touched by former commit --- .../dsl/ContextMapDSLFormattingTest.xtend | 302 +++++++++--------- .../dsl/ContextMappingDSLRuntimeModule.xtend | 14 +- .../tactic/dsl/TacticDDDLanguage.xtext | 1 - .../TacticDDDLanguageFormatter.xtend | 154 ++++----- 4 files changed, 234 insertions(+), 237 deletions(-) diff --git a/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/ContextMapDSLFormattingTest.xtend b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/ContextMapDSLFormattingTest.xtend index 050b6767..5029adf7 100644 --- a/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/ContextMapDSLFormattingTest.xtend +++ b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/ContextMapDSLFormattingTest.xtend @@ -38,176 +38,172 @@ class ContextMapDSLFormattingTest { ParseHelper parseHelper @Inject extension ISerializer - /** - * Aggregate with entities, traits, basic-types and enums with interspersed comments. - * The traits are used with the 'with' keyword - */ + /** + * Aggregate with entities, traits, basic-types and enums with interspersed comments. + * The traits are used with the 'with' keyword + */ @Test def void formatsMapLoadedFromFile() { - val testInput = ''' - BoundedContext BC1 { Aggregate A1 { Entity E1 { String prop1 "prop1Comment" String prop2 } - enum State1 { A, B } Trait T1 {} - "State2Comment" enum State2 { "AA" A, B } "E2Comment" Entity E2 - with@T1 { package = abc validate = "validation" aggregateRoot "E2Comment" - String prop3 } Entity E3 { String prop1 } - Trait T2 { "prop3Comment" String prop3 "ref1Comment" - @E1 ref1 } - BasicType BT1 { "prop4Comment" int prop4 - List< @T2> prop5 } - "V1Comment" ValueObject V1 with@T1 with@T2 { int intProp }}} BoundedContext BC2 - { Aggregate A2 { Entity E3 extends @E2 { "prop5comment" String prop5 String prop6 "prop6comment" int prop6}}} - ContextMap TestContextMap { contains BC1 } - '''; - val expectedResult = ''' - ContextMap TestContextMap { - contains BC1 - } - - BoundedContext BC1 { - Aggregate A1 { - Entity E1 { - String prop1 - "prop1Comment" - String prop2 - } - enum State1 { - A, B - } - Trait T1 { - } - "State2Comment" - enum State2 { - "AA" A, B - } - "E2Comment" - Entity E2 with@T1 { - package = abc - validate = "validation" - aggregateRoot + val testInput = ''' + BoundedContext BC1 { Aggregate A1 { Entity E1 { String prop1 "prop1Comment" String prop2 } + enum State1 { A, B } Trait T1 {} + "State2Comment" enum State2 { "AA" A, B } "E2Comment" Entity E2 + with@T1 { package = abc validate = "validation" aggregateRoot "E2Comment" + String prop3 } Entity E3 { String prop1 } + Trait T2 { "prop3Comment" String prop3 "ref1Comment" - @E1 ref1 } + BasicType BT1 { "prop4Comment" int prop4 - List< @T2> prop5 } + "V1Comment" ValueObject V1 with@T1 with@T2 { int intProp }}} BoundedContext BC2 + { Aggregate A2 { Entity E3 extends @E2 { "prop5comment" String prop5 String prop6 "prop6comment" int prop6}}} + ContextMap TestContextMap { contains BC1 } + '''; + val expectedResult = ''' + ContextMap TestContextMap { + contains BC1 + } + + BoundedContext BC1 { + Aggregate A1 { + Entity E1 { + String prop1 + "prop1Comment" + String prop2 + } + enum State1 { + A, B + } + Trait T1 { + } + "State2Comment" + enum State2 { + "AA" A, B + } "E2Comment" - String prop3 - } - Entity E3 { - String prop1 - } - Trait T2 { - "prop3Comment" - String prop3 - "ref1Comment" - - @E1 ref1 - } - BasicType BT1 { - "prop4Comment" - int prop4 - - List<@T2> prop5 - } - "V1Comment" - ValueObject V1 with@T1 with@T2 { - int intProp + Entity E2 with@T1 { + package = abc + validate = "validation" + aggregateRoot + "E2Comment" + String prop3 + } + Entity E3 { + String prop1 + } + Trait T2 { + "prop3Comment" + String prop3 + "ref1Comment" + - @E1 ref1 + } + BasicType BT1 { + "prop4Comment" + int prop4 + - List<@T2> prop5 + } + "V1Comment" + ValueObject V1 with@T1 with@T2 { + int intProp + } } } - } - - BoundedContext BC2 - { - Aggregate A2 { - Entity E3 extends @E2 { - "prop5comment" - String prop5 - String prop6 - "prop6comment" - int prop6 + + BoundedContext BC2 + { + Aggregate A2 { + Entity E3 extends @E2 { + "prop5comment" + String prop5 + String prop6 + "prop6comment" + int prop6 + } } } - } - - '''; - // given - val model = parseHelper.parse(testInput) + + '''; + // given + val model = parseHelper.parse(testInput) // when, then - assertEquals(expectedResult, - model.serialize(SaveOptions.newBuilder.format().getOptions())) + assertEquals(expectedResult, model.serialize(SaveOptions.newBuilder.format().getOptions())) } @Test def void formatsMapLoadedFromAPI() { - val contextMapper = ContextMapperStandaloneSetup.getStandaloneAPI(); - val factory = ContextMappingDSLFactory.eINSTANCE; - val tacticdslFactory = TacticdslFactory.eINSTANCE; - - val resource = contextMapper.createCML( "target/test-create-cm.cml" ); - - // given - val model = resource.getContextMappingModel(); - val contextMap = factory.createContextMap(); - contextMap.setName( "TestContextMap" ); - model.setMap( contextMap ); - - val boundedContext = factory.createBoundedContext(); - boundedContext.setName( "TestContext" ); - contextMap.getBoundedContexts().add( boundedContext ); - - val aggregate = factory.createAggregate(); - aggregate.setName( "A1" ); - model.getBoundedContexts().add( boundedContext ); - boundedContext.getAggregates().add( aggregate ); - - val trait1 = tacticdslFactory.createTrait(); - trait1.setName( "T1" ); - aggregate.getDomainObjects().add( trait1 ); - - val entity1 = tacticdslFactory.createEntity(); - aggregate.getDomainObjects().add( entity1 ); - entity1.setName( "E100" ); - entity1.setAggregateRoot( true ); - - val entity2 = tacticdslFactory.createEntity(); - entity2.setExtends( entity1 ); - entity2.setName( "E2" ); - entity2.getTraits().add( trait1 ); - aggregate.getDomainObjects().add( entity2 ); - - val attribute1 = tacticdslFactory.createAttribute(); - attribute1.setName( "prop1" ); - attribute1.setType( "String" ); - attribute1.doc = "prop1Comment" - entity2.getAttributes().add( attribute1 ); - - var reference1 = tacticdslFactory.createReference(); - reference1.setName( "ref1" ); - reference1.setDomainObjectType( entity2 ); - entity2.getReferences().add( reference1 ); - - val entity3 = tacticdslFactory.createEntity(); - entity3.setExtends( entity1 ); - entity3.setName( "E3" ); - aggregate.getDomainObjects().add( entity3 ); - - + val contextMapper = ContextMapperStandaloneSetup.getStandaloneAPI(); + val factory = ContextMappingDSLFactory.eINSTANCE; + val tacticdslFactory = TacticdslFactory.eINSTANCE; + + val resource = contextMapper.createCML("target/test-create-cm.cml"); + + // given + val model = resource.getContextMappingModel(); + val contextMap = factory.createContextMap(); + contextMap.setName("TestContextMap"); + model.setMap(contextMap); + + val boundedContext = factory.createBoundedContext(); + boundedContext.setName("TestContext"); + contextMap.getBoundedContexts().add(boundedContext); + + val aggregate = factory.createAggregate(); + aggregate.setName("A1"); + model.getBoundedContexts().add(boundedContext); + boundedContext.getAggregates().add(aggregate); + + val trait1 = tacticdslFactory.createTrait(); + trait1.setName("T1"); + aggregate.getDomainObjects().add(trait1); + + val entity1 = tacticdslFactory.createEntity(); + aggregate.getDomainObjects().add(entity1); + entity1.setName("E100"); + entity1.setAggregateRoot(true); + + val entity2 = tacticdslFactory.createEntity(); + entity2.setExtends(entity1); + entity2.setName("E2"); + entity2.getTraits().add(trait1); + aggregate.getDomainObjects().add(entity2); + + val attribute1 = tacticdslFactory.createAttribute(); + attribute1.setName("prop1"); + attribute1.setType("String"); + attribute1.doc = "prop1Comment" + entity2.getAttributes().add(attribute1); + + var reference1 = tacticdslFactory.createReference(); + reference1.setName("ref1"); + reference1.setDomainObjectType(entity2); + entity2.getReferences().add(reference1); + + val entity3 = tacticdslFactory.createEntity(); + entity3.setExtends(entity1); + entity3.setName("E3"); + aggregate.getDomainObjects().add(entity3); + val expectedResult = ''' - ContextMap TestContextMap { - contains TestContext - } - - BoundedContext TestContext { - Aggregate A1 { - Trait T1 - Entity E100 { - aggregateRoot - } - Entity E2 extends @E100 with@T1 { - "prop1Comment" - String prop1 - - @E2 ref1 + ContextMap TestContextMap { + contains TestContext + } + + BoundedContext TestContext { + Aggregate A1 { + Trait T1 + Entity E100 { + aggregateRoot + } + Entity E2 extends @E100 with@T1 { + "prop1Comment" + String prop1 + - @E2 ref1 + } + Entity E3 extends @E100 } - Entity E3 extends @E100 } - } - + ''' - + // when, then - assertEquals(expectedResult, - model.serialize(SaveOptions.newBuilder.format().getOptions())) + assertEquals(expectedResult, model.serialize(SaveOptions.newBuilder.format().getOptions())) } - } diff --git a/org.contextmapper.dsl/src/org/contextmapper/dsl/ContextMappingDSLRuntimeModule.xtend b/org.contextmapper.dsl/src/org/contextmapper/dsl/ContextMappingDSLRuntimeModule.xtend index 098ab29e..39035585 100644 --- a/org.contextmapper.dsl/src/org/contextmapper/dsl/ContextMappingDSLRuntimeModule.xtend +++ b/org.contextmapper.dsl/src/org/contextmapper/dsl/ContextMappingDSLRuntimeModule.xtend @@ -17,22 +17,24 @@ package org.contextmapper.dsl import org.eclipse.xtext.util.formallang.PdaUtil import org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider +import org.contextmapper.dsl.ContextMapperCrossReferenceSerializer /** * Use this class to register components to be used at runtime / without the Equinox extension registry. */ class ContextMappingDSLRuntimeModule extends AbstractContextMappingDSLRuntimeModule { - + def Class bindPdaUtil() { return ContextMapperPDAUtil } - + override bindIGlobalScopeProvider() { return ImportUriGlobalScopeProvider } - + override configure(com.google.inject.Binder binder) { - super.configure(binder) - binder.bind(org.eclipse.xtext.serializer.tokens.ICrossReferenceSerializer).to(org.contextmapper.dsl.ContextMapperCrossReferenceSerializer); - } + super.configure(binder) + binder.bind(org.eclipse.xtext.serializer.tokens.ICrossReferenceSerializer).to( + ContextMapperCrossReferenceSerializer); + } } diff --git a/org.contextmapper.dsl/src/org/contextmapper/tactic/dsl/TacticDDDLanguage.xtext b/org.contextmapper.dsl/src/org/contextmapper/tactic/dsl/TacticDDDLanguage.xtext index 680c61e2..430db4ca 100644 --- a/org.contextmapper.dsl/src/org/contextmapper/tactic/dsl/TacticDDDLanguage.xtext +++ b/org.contextmapper.dsl/src/org/contextmapper/tactic/dsl/TacticDDDLanguage.xtext @@ -576,4 +576,3 @@ terminal REF : terminal ASC : ('--'|'association'); - diff --git a/org.contextmapper.dsl/src/org/contextmapper/tactic/dsl/formatting2/TacticDDDLanguageFormatter.xtend b/org.contextmapper.dsl/src/org/contextmapper/tactic/dsl/formatting2/TacticDDDLanguageFormatter.xtend index 98ef61e4..a20b55f1 100644 --- a/org.contextmapper.dsl/src/org/contextmapper/tactic/dsl/formatting2/TacticDDDLanguageFormatter.xtend +++ b/org.contextmapper.dsl/src/org/contextmapper/tactic/dsl/formatting2/TacticDDDLanguageFormatter.xtend @@ -37,7 +37,7 @@ class TacticDDDLanguageFormatter extends AbstractFormatter2 { def dispatch void format(Entity entity, extension IFormattableDocument document) { val EClass clazz = TacticdslPackage.eINSTANCE.getEntity() - val EStructuralFeature docFeature = clazz.getEStructuralFeature(TacticdslPackage.ENTITY__DOC) + val EStructuralFeature docFeature = clazz.getEStructuralFeature(TacticdslPackage.ENTITY__DOC) entity.regionFor.feature(docFeature).append[newLine] interior( @@ -46,23 +46,23 @@ class TacticDDDLanguageFormatter extends AbstractFormatter2 { )[indent] entity.regionFor.keyword('aggregateRoot').prepend[newLine] - entity.regionFor.keywords('hint', 'validate', 'belongsTo').forEach[ + entity.regionFor.keywords('hint', 'validate', 'belongsTo').forEach [ prepend[newLine] ] - entity.regionFor.keywords('with').forEach[ - append[noSpace].prepend[oneSpace] - ] - entity.regionFor.keywords('@').forEach[ - append[noSpace] - ] + entity.regionFor.keywords('with').forEach [ + append[noSpace].prepend[oneSpace] + ] + entity.regionFor.keywords('@').forEach [ + append[noSpace] + ] for (attribute : entity.attributes) { attribute.format - attribute.prepend[newLine] + attribute.prepend[newLine] } for (reference : entity.references) { reference.format - reference.prepend[newLine] + reference.prepend[newLine] } for (operation : entity.operations) { operation.format @@ -71,23 +71,23 @@ class TacticDDDLanguageFormatter extends AbstractFormatter2 { } def dispatch void format(DomainObject domainObject, extension IFormattableDocument document) { - val EClass clazz = TacticdslPackage.eINSTANCE.getDomainObject() - val EStructuralFeature docFeature = clazz.getEStructuralFeature(TacticdslPackage.DOMAIN_OBJECT__DOC) - domainObject.regionFor.feature(docFeature).append[newLine] + val EClass clazz = TacticdslPackage.eINSTANCE.getDomainObject() + val EStructuralFeature docFeature = clazz.getEStructuralFeature(TacticdslPackage.DOMAIN_OBJECT__DOC) + domainObject.regionFor.feature(docFeature).append[newLine] - interior( + interior( domainObject.regionFor.keyword('{').prepend[oneSpace].append[newLine], domainObject.regionFor.keyword('}').prepend[newLine] )[indent] domainObject.regionFor.keyword('aggregateRoot').append[newLine] domainObject.regionFor.keyword('hint').prepend[newLine] - domainObject.regionFor.keywords('with').forEach[ - append[noSpace].prepend[oneSpace] - ] - domainObject.regionFor.keywords('@').forEach[ - append[noSpace] - ] + domainObject.regionFor.keywords('with').forEach [ + append[noSpace].prepend[oneSpace] + ] + domainObject.regionFor.keywords('@').forEach [ + append[noSpace] + ] for (attribute : domainObject.attributes) { attribute.format @@ -105,7 +105,7 @@ class TacticDDDLanguageFormatter extends AbstractFormatter2 { def dispatch void format(Trait trait, extension IFormattableDocument document) { val EClass clazz = TacticdslPackage.eINSTANCE.getTrait() - val EStructuralFeature docFeature = clazz.getEStructuralFeature(TacticdslPackage.TRAIT__DOC) + val EStructuralFeature docFeature = clazz.getEStructuralFeature(TacticdslPackage.TRAIT__DOC) trait.regionFor.feature(docFeature).append[newLine] interior( @@ -129,41 +129,41 @@ class TacticDDDLanguageFormatter extends AbstractFormatter2 { } } - def dispatch void format(BasicType basicType, extension IFormattableDocument document) { - val EClass clazz = TacticdslPackage.eINSTANCE.getBasicType() - val EStructuralFeature docFeature = clazz.getEStructuralFeature(TacticdslPackage.BASIC_TYPE__DOC) - basicType.regionFor.feature(docFeature).append[newLine] - - interior( - basicType.regionFor.keyword('{').prepend[oneSpace].append[newLine], - basicType.regionFor.keyword('}').prepend[newLine] - )[indent] - - basicType.regionFor.keyword('hint').prepend[newLine] - basicType.regionFor.keywords('with').forEach[ - append[noSpace].prepend[oneSpace] - ] - basicType.regionFor.keywords('@').forEach[ - append[noSpace] - ] - - for (attribute : basicType.attributes) { - attribute.format - attribute.prepend[newLine] - } - for (reference : basicType.references) { - reference.format - reference.prepend[newLine] - } - for (operation : basicType.operations) { - operation.format - operation.prepend[newLine] - } - } + def dispatch void format(BasicType basicType, extension IFormattableDocument document) { + val EClass clazz = TacticdslPackage.eINSTANCE.getBasicType() + val EStructuralFeature docFeature = clazz.getEStructuralFeature(TacticdslPackage.BASIC_TYPE__DOC) + basicType.regionFor.feature(docFeature).append[newLine] + + interior( + basicType.regionFor.keyword('{').prepend[oneSpace].append[newLine], + basicType.regionFor.keyword('}').prepend[newLine] + )[indent] + + basicType.regionFor.keyword('hint').prepend[newLine] + basicType.regionFor.keywords('with').forEach [ + append[noSpace].prepend[oneSpace] + ] + basicType.regionFor.keywords('@').forEach [ + append[noSpace] + ] + + for (attribute : basicType.attributes) { + attribute.format + attribute.prepend[newLine] + } + for (reference : basicType.references) { + reference.format + reference.prepend[newLine] + } + for (operation : basicType.operations) { + operation.format + operation.prepend[newLine] + } + } def dispatch void format(Enum enumm, extension IFormattableDocument document) { val EClass clazz = TacticdslPackage.eINSTANCE.getEnum() - val EStructuralFeature docFeature = clazz.getEStructuralFeature(TacticdslPackage.ENUM__DOC) + val EStructuralFeature docFeature = clazz.getEStructuralFeature(TacticdslPackage.ENUM__DOC) enumm.regionFor.feature(docFeature).append[newLine] interior( @@ -171,10 +171,10 @@ class TacticDDDLanguageFormatter extends AbstractFormatter2 { enumm.regionFor.keyword('}').prepend[newLine] )[indent] - enumm.regionFor.keywords(',').forEach [ - prepend[noSpace] - append[oneSpace] - ] + enumm.regionFor.keywords(',').forEach [ + prepend[noSpace] + append[oneSpace] + ] for (attribute : enumm.attributes) { attribute.format @@ -184,16 +184,16 @@ class TacticDDDLanguageFormatter extends AbstractFormatter2 { def dispatch void format(Attribute attribute, extension IFormattableDocument document) { val EClass attributeClass = TacticdslPackage.eINSTANCE.getAttribute() - val EStructuralFeature docFeature = attributeClass.getEStructuralFeature(TacticdslPackage.ATTRIBUTE__DOC) + val EStructuralFeature docFeature = attributeClass.getEStructuralFeature(TacticdslPackage.ATTRIBUTE__DOC) attribute.regionFor.feature(docFeature).append[newLine] attribute.regionFor.keyword('<').surround[noSpace] attribute.regionFor.keyword('>').prepend[noSpace] } - + def dispatch void format(Reference reference, extension IFormattableDocument document) { val EClass referenceClass = TacticdslPackage.eINSTANCE.getReference() - val EStructuralFeature docFeature = referenceClass.getEStructuralFeature(TacticdslPackage.REFERENCE__DOC) + val EStructuralFeature docFeature = referenceClass.getEStructuralFeature(TacticdslPackage.REFERENCE__DOC) reference.regionFor.feature(docFeature).append[newLine] reference.regionFor.keyword('<').surround[noSpace] @@ -202,37 +202,37 @@ class TacticDDDLanguageFormatter extends AbstractFormatter2 { def dispatch void format(DomainObjectOperation operation, extension IFormattableDocument document) { operation.prepend[newLine] - + operation.regionFor.keyword(';').prepend[noSpace] operation.regionFor.keyword('(').append[noSpace] operation.regionFor.keyword(')').prepend[noSpace] - operation.regionFor.keywords(',').forEach[ + operation.regionFor.keywords(',').forEach [ prepend[noSpace] ] - + operation.returnType.format - - for(parameter : operation.parameters) { + + for (parameter : operation.parameters) { parameter.format } } - + def dispatch void format(ComplexType complexType, extension IFormattableDocument document) { - complexType.regionFor.keywords('<').forEach[ + complexType.regionFor.keywords('<').forEach [ surround[noSpace] ] - complexType.regionFor.keywords('>').forEach[ + complexType.regionFor.keywords('>').forEach [ prepend[noSpace] ] - complexType.regionFor.keywords('@').forEach[ + complexType.regionFor.keywords('@').forEach [ append[noSpace] ] } - + def dispatch void format(Parameter parameter, extension IFormattableDocument document) { parameter.parameterType.format } - + def dispatch void format(Service service, extension IFormattableDocument document) { interior( service.regionFor.keyword('{').prepend[oneSpace].append[newLine], @@ -246,20 +246,20 @@ class TacticDDDLanguageFormatter extends AbstractFormatter2 { operation.format } } - + def dispatch void format(ServiceOperation operation, extension IFormattableDocument document) { operation.prepend[newLine] - + operation.regionFor.keyword(';').prepend[noSpace] operation.regionFor.keyword('(').append[noSpace] operation.regionFor.keyword(')').prepend[noSpace] - operation.regionFor.keywords(',').forEach[ + operation.regionFor.keywords(',').forEach [ prepend[noSpace] ] - + operation.returnType.format - - for(parameter : operation.parameters) { + + for (parameter : operation.parameters) { parameter.format } } From f52c67fe75adb4cc562b68fd88a0c9f5a1b264ee Mon Sep 17 00:00:00 2001 From: Andreas Stiller Date: Wed, 15 Jan 2025 18:00:43 +0100 Subject: [PATCH 3/3] extend formatting to the domain-objects of a sculptor module not assigned to an aggregate --- .../dsl/formatting2/ContextMappingDSLFormatter.xtend | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/org.contextmapper.dsl/src/org/contextmapper/dsl/formatting2/ContextMappingDSLFormatter.xtend b/org.contextmapper.dsl/src/org/contextmapper/dsl/formatting2/ContextMappingDSLFormatter.xtend index 598f0395..8049a3a0 100644 --- a/org.contextmapper.dsl/src/org/contextmapper/dsl/formatting2/ContextMappingDSLFormatter.xtend +++ b/org.contextmapper.dsl/src/org/contextmapper/dsl/formatting2/ContextMappingDSLFormatter.xtend @@ -342,6 +342,11 @@ class ContextMappingDSLFormatter extends TacticDDDLanguageFormatter { for (aggregate : module.aggregates) { aggregate.format } + + for (domainObject : module.domainObjects) { + domainObject.format + domainObject.prepend[newLine] + } } def dispatch void format(Stakeholders stakeholderContainer, extension IFormattableDocument document) {