diff --git a/rosetta-ide/rosetta.tmLanguage.yaml b/rosetta-ide/rosetta.tmLanguage.yaml index 84d6f0483..16d1fb67c 100644 --- a/rosetta-ide/rosetta.tmLanguage.yaml +++ b/rosetta-ide/rosetta.tmLanguage.yaml @@ -55,6 +55,7 @@ patterns: repository: model: patterns: + - include: '#override' - include: '#namespace' - include: '#version' - include: '#import' @@ -62,6 +63,16 @@ repository: - include: '#rootElement' repository: + override: + name: meta.override.rosetta + begin: '{{wordStart}}override{{wordEnd}}' + beginCaptures: + 0: { name: keyword.other.override.rosetta } + end: '{{rootEnd}}' + patterns: + - include: '#comment' + - include: '#string' + namespace: name: meta.namespace.rosetta begin: '{{wordStart}}namespace{{wordEnd}}' diff --git a/rosetta-lang/model/Rosetta.xcore b/rosetta-lang/model/Rosetta.xcore index fca67db2f..e668255b3 100644 --- a/rosetta-lang/model/Rosetta.xcore +++ b/rosetta-lang/model/Rosetta.xcore @@ -15,6 +15,7 @@ import com.regnosys.rosetta.rosetta.expression.RosettaExpression class RosettaModel extends RosettaDefinable { String name String version = "0.0.0" + boolean overridden contains Import[] imports contains RosettaQualifiableConfiguration[] configurations opposite model contains RosettaRootElement[] elements opposite model diff --git a/rosetta-lang/src/main/java/com/regnosys/rosetta/Rosetta.xtext b/rosetta-lang/src/main/java/com/regnosys/rosetta/Rosetta.xtext index a62506a8b..ceaefaf3e 100644 --- a/rosetta-lang/src/main/java/com/regnosys/rosetta/Rosetta.xtext +++ b/rosetta-lang/src/main/java/com/regnosys/rosetta/Rosetta.xtext @@ -10,7 +10,7 @@ import "http://www.eclipse.org/emf/2002/Ecore" as ecore // - [RosettaSynonymSource|QualifiedName] RosettaModel: - 'namespace' name=(QualifiedName | STRING) (':' RosettaDefinable)? // TODO do we need STRING here? It is not supported for highlighting. + (overridden?='override')? 'namespace' name=(QualifiedName | STRING) (':' RosettaDefinable)? // TODO do we need STRING here? It is not supported for highlighting. // TODO colon is inconsistent with other documentation ('version' version=STRING)? // TODO: could do better than STRING diff --git a/rosetta-lang/src/main/java/com/regnosys/rosetta/config/file/FileBasedRosettaConfigurationProvider.java b/rosetta-lang/src/main/java/com/regnosys/rosetta/config/file/FileBasedRosettaConfigurationProvider.java index e41402a1a..8b12fbfba 100644 --- a/rosetta-lang/src/main/java/com/regnosys/rosetta/config/file/FileBasedRosettaConfigurationProvider.java +++ b/rosetta-lang/src/main/java/com/regnosys/rosetta/config/file/FileBasedRosettaConfigurationProvider.java @@ -54,7 +54,7 @@ protected RosettaConfiguration readConfigFromFile() { if (file != null) { return mapper.readValue(file, RosettaConfiguration.class); } - LOGGER.info("No configuration file was found. Falling back to the default configuration."); + LOGGER.debug("No configuration file was found. Falling back to the default configuration."); return null; } catch (IOException e) { LOGGER.error("Could not read Rosetta configuration.", e); diff --git a/rosetta-lang/src/main/java/com/regnosys/rosetta/formatting2/RosettaFormatter.xtend b/rosetta-lang/src/main/java/com/regnosys/rosetta/formatting2/RosettaFormatter.xtend index 44b182125..eb5f60b5a 100644 --- a/rosetta-lang/src/main/java/com/regnosys/rosetta/formatting2/RosettaFormatter.xtend +++ b/rosetta-lang/src/main/java/com/regnosys/rosetta/formatting2/RosettaFormatter.xtend @@ -73,11 +73,19 @@ class RosettaFormatter extends AbstractRosettaFormatter2 { def dispatch void format(RosettaModel rosettaModel, extension IFormattableDocument document) { val extension modelGrammarAccess = rosettaModelAccess - - rosettaModel.regionFor.keyword(namespaceKeyword_0) - .prepend[noSpace] + if (rosettaModel.regionFor.keyword(overriddenOverrideKeyword_0_0) !== null) { + rosettaModel.regionFor.keyword(overriddenOverrideKeyword_0_0) + .prepend[noSpace] + .append[oneSpace] + + } else { + rosettaModel.regionFor.keyword(namespaceKeyword_1) + .prepend[noSpace] + } + rosettaModel.regionFor.keyword(namespaceKeyword_1) .append[oneSpace] - rosettaModel.regionFor.keyword(versionKeyword_3_0) + + rosettaModel.regionFor.keyword(versionKeyword_4_0) .prepend[newLine] .append[oneSpace] diff --git a/rosetta-lang/src/main/java/com/regnosys/rosetta/generator/RosettaGenerator.xtend b/rosetta-lang/src/main/java/com/regnosys/rosetta/generator/RosettaGenerator.xtend index 5209d7961..17a85f342 100644 --- a/rosetta-lang/src/main/java/com/regnosys/rosetta/generator/RosettaGenerator.xtend +++ b/rosetta-lang/src/main/java/com/regnosys/rosetta/generator/RosettaGenerator.xtend @@ -66,7 +66,7 @@ class RosettaGenerator implements IGenerator2 { @Inject ResourceAwareFSAFactory fsaFactory; - + @Inject RosettaGeneratorsConfiguration config; @@ -74,19 +74,16 @@ class RosettaGenerator implements IGenerator2 { val ignoredFiles = #{'model-no-code-gen.rosetta', 'basictypes.rosetta', 'annotations.rosetta'} val Map locks = newHashMap - + def void beforeAllGenerate(ResourceSet resourceSet, IFileSystemAccess2 fsa2, IGeneratorContext context) { LOGGER.trace("Starting the before all generate method") val lock = locks.computeIfAbsent(resourceSet, [new DemandableLock]); try { lock.getWriteLock(true); - val models = resourceSet.resources - .filter[!ignoredFiles.contains(URI.segments.last)] - .map[contents.head as RosettaModel] - .filter[config.namespaceFilter.test(it.name)] - .toList + val models = resourceSet.resources.filter[!ignoredFiles.contains(URI.segments.last)].map [ + contents.head as RosettaModel + ].filter[it.shouldGenerate].toList val version = models.head?.version // TODO: find a way to access the version of a project directly - externalGenerators.forEach [ generator | generator.beforeAllGenerate(resourceSet, models, version, [ map | map.entrySet.forEach[fsa2.generateFile(key, generator.outputConfiguration.getName, value)] @@ -95,13 +92,14 @@ class RosettaGenerator implements IGenerator2 { } catch (CancellationException e) { LOGGER.trace("Code generation cancelled, this is expected") } catch (Exception e) { - LOGGER.warn("Unexpected calling before all generate for rosetta -" + e.message + " - see debug logging for more") + LOGGER.warn("Unexpected calling before all generate for rosetta -" + e.message + + " - see debug logging for more") LOGGER.debug("Unexpected calling before all generate for rosetta", e); } finally { lock.releaseWriteLock } } - + override void beforeGenerate(Resource resource, IFileSystemAccess2 fsa2, IGeneratorContext context) { if (!ignoredFiles.contains(resource.URI.segments.last)) { LOGGER.trace("Starting the before generate method for " + resource.URI.toString) @@ -109,24 +107,25 @@ class RosettaGenerator implements IGenerator2 { val fsa = fsaFactory.resourceAwareFSA(resource, fsa2, true) try { lock.getWriteLock(true); - + fsaFactory.beforeGenerate(resource) - + val model = resource.contents.head as RosettaModel - if (!config.namespaceFilter.test(model.name)) { + if (!model.shouldGenerate) { return } val version = model.version - + externalGenerators.forEach [ generator | - generator.beforeGenerate(resource, model, version, [ map | - map.entrySet.forEach[fsa.generateFile(key, generator.outputConfiguration.getName, value)] - ], lock) - ] + generator.beforeGenerate(resource, model, version, [ map | + map.entrySet.forEach[fsa.generateFile(key, generator.outputConfiguration.getName, value)] + ], lock) + ] } catch (CancellationException e) { LOGGER.trace("Code generation cancelled, this is expected") } catch (Exception e) { - LOGGER.warn("Unexpected calling before generate for rosetta -" + e.message + " - see debug logging for more") + LOGGER.warn("Unexpected calling before generate for rosetta -" + e.message + + " - see debug logging for more") LOGGER.debug("Unexpected calling before generate for rosetta", e); } finally { lock.releaseWriteLock @@ -141,13 +140,13 @@ class RosettaGenerator implements IGenerator2 { val lock = locks.computeIfAbsent(resource.resourceSet, [new DemandableLock]); try { lock.getWriteLock(true); - + val model = resource.contents.head as RosettaModel - if (!config.namespaceFilter.test(model.name)) { + if (!model.shouldGenerate) { return } val version = model.version - + // generate val packages = new RootPackage(model) @@ -159,13 +158,13 @@ class RosettaGenerator implements IGenerator2 { Data: { dataGenerator.generate(packages, fsa, it, version) metaGenerator.generate(packages, fsa, it, version) - //Legacy + // Legacy validatorsGenerator.generate(packages, fsa, it, version) it.conditions.forEach [ cond | conditionGenerator.generate(packages, fsa, it, cond, version) ] - //new - //validatorGenerator.generate(packages, fsa, it, version) + // new + // validatorGenerator.generate(packages, fsa, it, version) tabulatorGenerator.generate(fsa, it, Optional.empty) } Function: { @@ -218,51 +217,47 @@ class RosettaGenerator implements IGenerator2 { val fsa = fsaFactory.resourceAwareFSA(resource, fsa2, true) try { lock.getWriteLock(true) - + val model = resource.contents.head as RosettaModel - if (!config.namespaceFilter.test(model.name)) { + if (!model.shouldGenerate) { return } val version = model.version - + externalGenerators.forEach [ generator | generator.afterGenerate(resource, model, version, [ map | map.entrySet.forEach[fsa.generateFile(key, generator.outputConfiguration.getName, value)] ], lock) ] fsaFactory.afterGenerate(resource) - + // TODO: move this over to `afterAllGenerate` once the language supports that method as well. - val models = resource.resourceSet.resources - .filter[!ignoredFiles.contains(URI.segments.last)] - .map[contents.head as RosettaModel] - .filter[config.namespaceFilter.test(it.name)] - .toList - javaPackageInfoGenerator.generatePackageInfoClasses(fsa2, models) + val models = resource.resourceSet.resources.filter[!ignoredFiles.contains(URI.segments.last)].map [ + contents.head as RosettaModel + ].filter[shouldGenerate].toList + javaPackageInfoGenerator.generatePackageInfoClasses(fsa2, models) } catch (CancellationException e) { LOGGER.trace("Code generation cancelled, this is expected") } catch (Exception e) { - LOGGER.warn("Unexpected calling after generate for rosetta -" + e.message + " - see debug logging for more") + LOGGER.warn("Unexpected calling after generate for rosetta -" + e.message + + " - see debug logging for more") LOGGER.debug("Unexpected calling after generate for rosetta", e); } finally { lock.releaseWriteLock } } } - - def void afterAllGenerate(ResourceSet resourceSet, IFileSystemAccess2 fsa2, IGeneratorContext context) { + + def void afterAllGenerate(ResourceSet resourceSet, IFileSystemAccess2 fsa2, IGeneratorContext context) { LOGGER.trace("Starting the after all generate method") val lock = locks.computeIfAbsent(resourceSet, [new DemandableLock]); try { lock.getWriteLock(true) - - val models = resourceSet.resources - .filter[!ignoredFiles.contains(URI.segments.last)] - .map[contents.head as RosettaModel] - .filter[config.namespaceFilter.test(it.name)] - .toList + + val models = resourceSet.resources.filter[!ignoredFiles.contains(URI.segments.last)].map [ + contents.head as RosettaModel + ].filter[shouldGenerate].toList val version = models.head?.version // TODO: find a way to access the version of a project directly - externalGenerators.forEach [ generator | generator.afterAllGenerate(resourceSet, models, version, [ map | map.entrySet.forEach[fsa2.generateFile(key, generator.outputConfiguration.getName, value)] @@ -271,10 +266,16 @@ class RosettaGenerator implements IGenerator2 { } catch (CancellationException e) { LOGGER.trace("Code generation cancelled, this is expected") } catch (Exception e) { - LOGGER.warn("Unexpected calling after all generate for rosetta -" + e.message + " - see debug logging for more") + LOGGER.warn("Unexpected calling after all generate for rosetta -" + e.message + + " - see debug logging for more") LOGGER.debug("Unexpected calling after all generate for rosetta", e); } finally { lock.releaseWriteLock } } + + private def boolean shouldGenerate(RosettaModel model) { + config.namespaceFilter.test(model.name) || model.overridden + } + } diff --git a/rosetta-lang/src/main/java/com/regnosys/rosetta/generator/java/object/MetaFieldGenerator.xtend b/rosetta-lang/src/main/java/com/regnosys/rosetta/generator/java/object/MetaFieldGenerator.xtend index 2bdfc2b86..7574c9365 100644 --- a/rosetta-lang/src/main/java/com/regnosys/rosetta/generator/java/object/MetaFieldGenerator.xtend +++ b/rosetta-lang/src/main/java/com/regnosys/rosetta/generator/java/object/MetaFieldGenerator.xtend @@ -92,7 +92,7 @@ class MetaFieldGenerator { for (ref:refs) { val targetModel = ref.type.model - if (config.namespaceFilter.test(targetModel.name)) { + if (targetModel.shouldGenerate) { val targetPackage = new RootPackage(targetModel) val metaJt = ref.toMetaJavaType @@ -106,7 +106,7 @@ class MetaFieldGenerator { val metas = nsc.value.filter(Data).flatMap[expandedAttributes].filter[hasMetas && !metas.exists[name=="reference" || name=="address"]].toSet for (meta:metas) { val targetModel = meta.type.model - if (config.namespaceFilter.test(targetModel.name)) { + if (targetModel.shouldGenerate) { val targetPackage = new RootPackage(targetModel) val metaJt = meta.toMetaJavaType @@ -306,6 +306,10 @@ class MetaFieldGenerator { return rc.model.name } + private def boolean shouldGenerate(RosettaModel model) { + config.namespaceFilter.test(model.name) || model.overridden + } + /** generate once per resource marker */ static class MarkerAdapterFactory extends AdapterFactoryImpl {