refactor: migrate Xtend to Java - com.avaloq.tools.ddk.xtext.scope - #1519
Merged
Merged
Conversation
rubenporras
previously approved these changes
Sep 7, 2026
joaodinissf
marked this pull request as ready for review
September 7, 2026 10:37
joaodinissf
force-pushed
the
migrate/xtend-to-java/scope-step-3
branch
from
September 7, 2026 21:28
83a9b91 to
92eb335
Compare
rubenporras
previously approved these changes
Sep 8, 2026
joaodinissf
force-pushed
the
migrate/xtend-to-java/scope-step-3
branch
from
September 8, 2026 07:36
92eb335 to
c607928
Compare
rubenporras
previously approved these changes
Sep 8, 2026
Base automatically changed from
migrate/xtend-to-java/export-step-2
to
master
September 8, 2026 07:52
…/2: rename sources) Pure `git mv` of the three generator sources from .xtend to .java with their content unchanged, so Git's rename detection traverses the edge at 100% similarity and `git log --follow` / `git blame` keep connecting the .java history to its Xtend past. This commit intentionally does not compile: the renamed files still hold Xtend syntax. The following commit rewrites them in place to Java 21. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…/2: translate to Java 21) In-place translation of the three renamed generator sources, faithful to the Xtend compiler's own xtend-gen output (freshly rebuilt off the base commit and byte-verified against it before any edit). All 15 templates keep the reference's exact StringConcatenation call sequence (tier 4, chain retained rather than rebuilt on StringBuilder). Eleven of them are unconvertible under rules/04-templates.md 4.8 - two-arg append(value, indent) of provably multi-line values (scopeRuleBlock, scopeExpression, nameFunctions, javaExpression), appendImmediate separator loops (nameFunctions, query, scopeExpressionPart) and whitespace-retracting newLineIfNotEmpty after an indent-only line (doGlobalCache*, scopeExpression(ScopeDelegation)). The remaining four are kept on the same idiom so that sibling templates which append each other's output stay delimiter- and indent-consistent. The full append sequence of both emitters was diffed against the reference mechanically: 407 builder operations, identical in order, per method, with identical literal arguments. Per-file notes: - ScopeProviderX: every public dispatcher keeps the reference's branch order and terminal behaviour, including the (Void) null routing of isEqual/allScopeRules/allScopes/allInjections/allExtensions and the IllegalArgumentException scopeType falls through to. Collection semantics preserved: toSet is a LinkedHashSet (filterUniqueRules, the name sets the case labels are emitted from), the result lists that removeIf/addAll run on stay mutable ArrayLists, and sortedRules keeps delegating to ScopingGeneratorUtil. - ScopeNameProviderGenerator / ScopeProviderGenerator: the non-@Inject extension fields become plain private fields assigned in configure; the configure signatures are unchanged. org.eclipse.xtext.xbase.lib.Pair is kept where ScopeExpressionTranslator.newCompilationContext demands it in its parameter type. - Guard expression, scope method and global-cache bodies emit the same Java as before; ordering-sensitive iteration (allScopes, allScopeRules, sortBy, filterUniqueRules) is unchanged, so the emitted case labels and method bodies keep their order. Gate-driven deviations from the reference, all output-neutral: - error(...) and the "only one global rule allowed" guard still throw RuntimeException; the raw type is marked // NOPMD, matching the four existing prod sites in this repo. - scopeMethodBody gains an @throws tag for that RuntimeException (checkstyle JavadocMethod requires it on a documented method). - configure's parameters are renamed (nameGenerator, genModelUtilX) to clear checkstyle HiddenField; the Javadoc text is otherwise verbatim. - _isEqual(EClass)/_isEqual(EReference) share a haveSameName helper and _isThisCall uses a guard clause, to satisfy BooleanExpressionComplexity without changing short-circuit order. Further deviations from the reference, all output-neutral: - collectAllScopeRules: the reference's `if (d == null)` branch on the filter(...) result was dropped as unreachable (IterableExtensions.filter never returns null); same list, same order. - Nine private helpers factor out repeated model filtering the compiler inlined (haveSameName, newContext, scopesWithReference, scopeNames, namedScopes, globalRules, ruleContextType, dataOfType, reversed); pure functions evaluated at the same points, no public/protected surface added. - Guava/xbase.lib calls replaced by stdlib (Lists.newArrayList + ListExtensions.reverse -> reversed, Iterables.filter(..., T.class) -> dataOfType, Iterables.concat/addAll -> loops); order and element identity preserved. - eContainer uses type.cast(it) instead of the unchecked (T) it, guarded by the preceding isInstance check. - new StringBuilder(512) where the reference had the default capacity. - Parameters named `it` in the reference are kept as `it` (their preserved Javadoc documents @PARAM it); every call on them is qualified. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
cpd-check finds four intra-file duplications in ScopeProviderGenerator and ScopeNameProviderGenerator: the by-reference/by-type scope bodies, the global-cache bodies and the FeatureCall/OperationCall name functions are parallel templates in the Xtend source, and the faithful Java keeps that structure. Baselined with file-scoped CPD-OFF markers, as for the migrated ANTLR generators (a68a240) and FormatJvmModelInferrer. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
joaodinissf
force-pushed
the
migrate/xtend-to-java/scope-step-3
branch
from
September 8, 2026 07:52
c607928 to
28b340e
Compare
rubenporras
approved these changes
Sep 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Migrates the three remaining legacy Xtend sources of
com.avaloq.tools.ddk.xtext.scopeto Java 21:generator/ScopeProviderX— scope/rule/injection/extension collection helpers and theisEqualdispatch familygenerator/ScopeNameProviderGenerator— name-function bodiesgenerator/ScopeProviderGenerator— scope-provider method bodies, global caches, rule blocksWith this, the last 2017-era Xtend in the repository is gone; the remaining
.xtendfiles are the Xbase inferrer layer injvmmodel/, so the Xtend build infrastructure (xtend-gen,.classpath,build.properties) is untouched.Stacked on the
xtext.exportmigration.Public API is unchanged. The consumers are
ScopeJvmModelInferrer.xtend(configure(...), thedoGet*Body/doGlobalCache*Body/scopeMethodBody/internalGetNameFunctionsBodytemplate methods,scopeMethodName) andScopeExpressionTranslator.xtend(allExtensions). They compile unchanged against the Java.Faithfulness notes
StringConcatenationcall sequence. Eleven cannot be rebuilt onStringBuilder/text blocks under the migration skill's §4.8 (two-argappend(value, indent)of multi-line values,appendImmediateseparator loops, whitespace-retractingnewLineIfNotEmptyafter indent-only lines); the other four are kept on the same idiom because sibling templates two-arg-append their output. The full append sequence was diffed mechanically against the compiler output: 407 operations, identical order and literals.StringConcatenationlives inorg.eclipse.xtext.xbase.liband needs no Xtend compiler.isEqual(EObject, EObject)including itsVoid-typed null routing;scopeType,nameFunction,scopeExpression,factoryArgument,scopeExpressionPart,scopeExpressionNaming,isEmptyListwith theirIllegalArgumentException("Unhandled parameter types: …")terminals.toSet→LinkedHashSet, stablesortBy, insertion-orderedfilterUniqueRules): these sets drive the emittedcaselabels and method bodies.@Injectextension GenModelUtilXfields become plain private fields assigned inconfigure(...); signatures unchanged.org.eclipse.xtext.xbase.lib.Pairis kept whereScopeExpressionTranslator.newCompilationContextdemands it.error(...)and the single-global-rule guard still throw rawRuntimeException(PMD-suppressed with// NOPMD, as at the existing production sites) rather than a narrower type, to keep the thrown type identical.FeatureCall/OperationCallname functions); they mirror the Xtend structure and are baselined with file-scopedCPD-OFFmarkers, as for the migrated ANTLR generators.if (d == null)branch on afilterresult dropped; nine private helpers factor out model filtering the compiler inlined; Guava/xbase.lib helper calls replaced by stdlib equivalents with the same order;type.castinstead of an unchecked cast; explicitStringBuildercapacity;configureparameters renamed for CheckstyleHiddenField; parameters documented as@param itkeep that name.Known deltas
@XbaseGeneratedon the generated dispatchers; the migrated Java does not. The annotation is runtime-retained on public methods in an exported package, so it is a reflectively observable delta — but nothing in the target platform reads it (onlyJvmModelGeneratoremits it), and re-applying a "machine-generated" marker to hand-written code would be false.Verification
xtend-genfrom a clean build of the base commit.RuntimeExceptionthrows toIllegalStateException, which the bytecode comparison caught. All other differences were style.StringConcatenationappend/newLine sequences identical; dispatcher branch order identical.-amdcompile ✅;pmd:check checkstyle:check spotbugs:check✅; full reactorclean verifywith the CI static-analysis goals ✅ (354 tests, 0 failures, 2 skipped). No version bump needed: the bundle is already at 17.3.3, ahead of the baseline.🤖 Generated with Claude Code