From 2f290b127f0d680d7d2735e7b160c842e6027650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Dinis=20Ferreira?= Date: Thu, 24 Sep 2026 22:55:05 +0200 Subject: [PATCH] perf(export): ignore Java type deltas when checking export models Since the Xbase migration (#1405) the Export language uses the default XbaseResourceDescriptionManager. Its descriptions record, as imported names and outgoing references, the JVM types of the inferred model - including the EMF interfaces of the exported EClasses (parameter types from GenModelUtilX.instanceClassName) and all their super interfaces. JDT deltas for those types (JavaChangeQueueFiller -> JdtQueuedBuildData -> pending deltas of the builder) therefore mark every export model referencing them as affected, so a branch switch that only changes Java files re-processes and recompiles export models; before #1405 it never did. Bind an ExportResourceDescriptionManager that drops java:/ deltas before the affectedness check. The generated code depends only on the EMF model (ecore and genmodel), whose deltas still affect export models, as they did before #1405. PROTOTYPE: not for review; to be measured with the branch-switch benchmark. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../META-INF/MANIFEST.MF | 3 +- .../ddk/xtext/export/ExportRuntimeModule.java | 12 ++++ .../ExportResourceDescriptionManager.java | 58 +++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 com.avaloq.tools.ddk.xtext.export/src/com/avaloq/tools/ddk/xtext/export/resource/ExportResourceDescriptionManager.java diff --git a/com.avaloq.tools.ddk.xtext.export/META-INF/MANIFEST.MF b/com.avaloq.tools.ddk.xtext.export/META-INF/MANIFEST.MF index 2f1495a0a..f60522c69 100644 --- a/com.avaloq.tools.ddk.xtext.export/META-INF/MANIFEST.MF +++ b/com.avaloq.tools.ddk.xtext.export/META-INF/MANIFEST.MF @@ -38,6 +38,7 @@ Export-Package: com.avaloq.tools.ddk.xtext.export, com.avaloq.tools.ddk.xtext.export.formatting, com.avaloq.tools.ddk.xtext.export.serializer, com.avaloq.tools.ddk.xtext.export.generator, - com.avaloq.tools.ddk.xtext.export.jvmmodel + com.avaloq.tools.ddk.xtext.export.jvmmodel, + com.avaloq.tools.ddk.xtext.export.resource Automatic-Module-Name: com.avaloq.tools.ddk.xtext.export Import-Package: org.apache.log4j diff --git a/com.avaloq.tools.ddk.xtext.export/src/com/avaloq/tools/ddk/xtext/export/ExportRuntimeModule.java b/com.avaloq.tools.ddk.xtext.export/src/com/avaloq/tools/ddk/xtext/export/ExportRuntimeModule.java index 3cb93e319..1bfef7134 100644 --- a/com.avaloq.tools.ddk.xtext.export/src/com/avaloq/tools/ddk/xtext/export/ExportRuntimeModule.java +++ b/com.avaloq.tools.ddk.xtext.export/src/com/avaloq/tools/ddk/xtext/export/ExportRuntimeModule.java @@ -13,12 +13,14 @@ import org.eclipse.xtext.formatting.ILineSeparatorInformation; import org.eclipse.xtext.generator.IOutputConfigurationProvider; import org.eclipse.xtext.naming.IQualifiedNameConverter; +import org.eclipse.xtext.resource.IResourceDescription; import org.eclipse.xtext.xbase.compiler.JvmModelGenerator; import com.avaloq.tools.ddk.xtext.export.conversion.ExportValueConverterService; import com.avaloq.tools.ddk.xtext.export.generator.ExportJvmModelGenerator; import com.avaloq.tools.ddk.xtext.export.generator.ExportOutputConfigurationProvider; import com.avaloq.tools.ddk.xtext.export.naming.ExportQualifiedNameConverter; +import com.avaloq.tools.ddk.xtext.export.resource.ExportResourceDescriptionManager; import com.avaloq.tools.ddk.xtext.formatting.LfLineSeparatorInformation; @@ -70,6 +72,16 @@ public Class bindJvmModelGenerator() { return ExportJvmModelGenerator.class; } + /** + * Binds the description manager which keeps Java type changes from re-queuing export models. + * + * @return the export specific resource description manager + */ + @Override + public Class bindIResourceDescription$Manager() { // NOPMD + return ExportResourceDescriptionManager.class; + } + @Override public Class bindIFormatter() { return com.avaloq.tools.ddk.xtext.export.formatting.ExportFormatter.class; diff --git a/com.avaloq.tools.ddk.xtext.export/src/com/avaloq/tools/ddk/xtext/export/resource/ExportResourceDescriptionManager.java b/com.avaloq.tools.ddk.xtext.export/src/com/avaloq/tools/ddk/xtext/export/resource/ExportResourceDescriptionManager.java new file mode 100644 index 000000000..c890eb507 --- /dev/null +++ b/com.avaloq.tools.ddk.xtext.export/src/com/avaloq/tools/ddk/xtext/export/resource/ExportResourceDescriptionManager.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2026 Avaloq Group AG and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Avaloq Group AG - initial API and implementation + *******************************************************************************/ +package com.avaloq.tools.ddk.xtext.export.resource; + +import java.util.Collection; +import java.util.List; + +import org.eclipse.xtext.common.types.access.impl.URIHelperConstants; +import org.eclipse.xtext.resource.IResourceDescription; +import org.eclipse.xtext.resource.IResourceDescription.Delta; +import org.eclipse.xtext.resource.IResourceDescriptions; +import org.eclipse.xtext.xbase.resource.XbaseResourceDescriptionManager; + +import com.google.inject.Singleton; + + +/** + * Resource description manager for export models which ignores deltas of Java types. + *

+ * The inferred JVM model of an export model references the Java interfaces of the exported EClasses, so the Xbase + * description manager records them as imported names and outgoing references. The builder then re-processes every export + * model whenever JDT reports a structural change to one of those interfaces, although the generated code only depends + * on the EMF model (the ecore and genmodel), whose own changes still affect export models. + *

+ */ +@Singleton +public class ExportResourceDescriptionManager extends XbaseResourceDescriptionManager { + + @Override + public boolean isAffected(final Delta delta, final IResourceDescription candidate) { + return !isJavaTypeDelta(delta) && super.isAffected(delta, candidate); + } + + @Override + public boolean isAffected(final Collection deltas, final IResourceDescription candidate, final IResourceDescriptions context) { + final List nonJavaDeltas = deltas.stream().filter(delta -> !isJavaTypeDelta(delta)).toList(); + return !nonJavaDeltas.isEmpty() && super.isAffected(nonJavaDeltas, candidate, context); + } + + /** + * Returns whether the given delta describes a Java type, as reported by JDT through the {@code java:/} URI scheme. + * + * @param delta + * the delta, must not be {@code null} + * @return {@code true} if the delta is about a Java type + */ + private static boolean isJavaTypeDelta(final Delta delta) { + return URIHelperConstants.PROTOCOL.equals(delta.getUri().scheme()); + } +}