Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion com.avaloq.tools.ddk.xtext.export/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: com.avaloq.tools.ddk.xtext.export
Bundle-SymbolicName: com.avaloq.tools.ddk.xtext.export;singleton:=true
Bundle-Version: 17.3.2.qualifier
Bundle-Version: 17.3.3.qualifier
Bundle-Vendor: Avaloq Group AG
Bundle-RequiredExecutionEnvironment: JavaSE-21
Bundle-ActivationPolicy: lazy
Expand Down
4 changes: 2 additions & 2 deletions com.avaloq.tools.ddk.xtext.export/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<version>18.0.1-SNAPSHOT</version>
<relativePath>../ddk-parent</relativePath>
</parent>
<version>17.3.2-SNAPSHOT</version>
<version>17.3.3-SNAPSHOT</version>
<groupId>com.avaloq.tools.ddk</groupId>
<artifactId>com.avaloq.tools.ddk.xtext.export</artifactId>
<packaging>eclipse-plugin</packaging>
</project>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,10 @@ class ExportExpressionCompiler {
}

def private boolean isNumber(Expression it, ExportTranslationContext ctx) {
if (isArithmeticOperatorCall(ctx)) {
// Arithmetic calls have no resolvable JVM method but still produce numeric values.
return true
}
val type = translator.resolveType(it, ctx)
type !== null && type.isNumeric
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ import org.eclipse.xtext.common.types.util.TypeReferences
import org.eclipse.xtext.xbase.XExpression
import org.eclipse.xtext.xbase.XbaseFactory
import org.eclipse.xtext.xbase.lib.BooleanExtensions
import org.eclipse.xtext.xbase.lib.ObjectExtensions

/**
* Translates the custom {@link Expression} AST of the export expression DSL into equivalent Xbase
Expand Down Expand Up @@ -436,8 +435,9 @@ class ExportExpressionTranslator {
switch operator {
case '||': toBinaryOperation(xLeft, xRight, BooleanExtensions, 'operator_or', sourceElement)
case '&&': toBinaryOperation(xLeft, xRight, BooleanExtensions, 'operator_and', sourceElement)
case '==': toBinaryOperation(xLeft, xRight, ObjectExtensions, 'operator_equals', sourceElement)
case '!=': toBinaryOperation(xLeft, xRight, ObjectExtensions, 'operator_notEquals', sourceElement)
// Xbase equality is value-based, unlike the identity equality emitted by the legacy Java generator.
case '==': null
case '!=': null
default: null
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ Bundle-RequiredExecutionEnvironment: JavaSE-21
Bundle-ActivationPolicy: lazy
Fragment-Host: com.avaloq.tools.ddk.xtext.generator
Require-Bundle: com.avaloq.tools.ddk.test.core,
com.avaloq.tools.ddk.xtext.export,
com.avaloq.tools.ddk.xtext.expression,
com.avaloq.tools.ddk.xtext.scope,
com.avaloq.tools.ddk.xtext.test.core,
org.eclipse.xtext,
org.mockito.mockito-core,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*******************************************************************************
* 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.generator.expression;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

import java.io.IOException;

import org.eclipse.xtext.xbase.XExpression;
import org.junit.jupiter.api.Test;

import com.avaloq.tools.ddk.xtext.expression.expression.Expression;
import com.avaloq.tools.ddk.xtext.generator.test.util.GeneratorTestUtil;
import com.avaloq.tools.ddk.xtext.test.jupiter.AbstractXtextTest;


/**
* Shared expression code-generation contract for DSL-specific compiler implementations.
*/
@SuppressWarnings("nls")
abstract class AbstractExpressionCodeGenerationTest extends AbstractXtextTest {

@Override
protected GeneratorTestUtil getXtextTestUtil() {
return GeneratorTestUtil.getInstance();
}

/**
* This test class does not have a test source file. {@inheritDoc}
*/
@Override
protected String getTestSourceFileName() {
return null;
}

@Test
@SuppressWarnings("PMD.SignatureDeclareThrowsException")
void testNestedArithmetic() throws IOException {
assertCompilesUnchanged("(4 + 2) * 3");
assertCompilesUnchanged("(4 + 2) * 3 * 4");
}

@Test
@SuppressWarnings("PMD.SignatureDeclareThrowsException")
void testArithmeticControls() throws IOException {
assertCompilesUnchanged("4 + 2");
assertEquals("\"x\" + 2 + 3 + 4", compile("('x' + 2) + 3 + 4"));
}

@Test
@SuppressWarnings("PMD.SignatureDeclareThrowsException")
void testEqualityIsNotTranslated() throws IOException {
assertNull(translate("1 == 2"));
assertNull(translate("1 != 2"));
}

protected abstract String compile(Expression expression);

protected abstract XExpression translate(Expression expression);

private String compile(final String source) throws IOException {
return compile(parse(source));
}

private void assertCompilesUnchanged(final String source) throws IOException {
assertEquals(source, compile(source));
}

private XExpression translate(final String source) throws IOException {
return translate(parse(source));
}

private Expression parse(final String source) throws IOException {
return (Expression) getXtextTestUtil().getModel("test.expression", source);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*******************************************************************************
* 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.generator.expression;

import org.eclipse.xtext.xbase.XExpression;

import com.avaloq.tools.ddk.xtext.export.ExportStandaloneSetup;
import com.avaloq.tools.ddk.xtext.export.jvmmodel.ExportExpressionCompiler;
import com.avaloq.tools.ddk.xtext.export.jvmmodel.ExportExpressionTranslator;
import com.avaloq.tools.ddk.xtext.export.jvmmodel.ExportTranslationContext;
import com.avaloq.tools.ddk.xtext.expression.expression.Expression;
import com.google.inject.Injector;


/**
* Tests Java source generation for expressions used by the Export DSL.
*/
public class ExportExpressionCodeGenerationTest extends AbstractExpressionCodeGenerationTest {

@Override
protected void beforeAllTests() {
super.beforeAllTests();
final Injector injector = new ExportStandaloneSetup().createInjector();
getTestInformation().putTestObject(ExportExpressionCompiler.class, injector.getInstance(ExportExpressionCompiler.class));
getTestInformation().putTestObject(ExportExpressionTranslator.class, injector.getInstance(ExportExpressionTranslator.class));
}

@Override
protected String compile(final Expression expression) {
final ExportTranslationContext context = new ExportTranslationContext();
context.setSourceElement(expression);
final ExportExpressionCompiler compiler = (ExportExpressionCompiler) getTestInformation().getTestObject(ExportExpressionCompiler.class);
return compiler.javaExpression(expression, context);
}

@Override
protected XExpression translate(final Expression expression) {
final ExportTranslationContext context = new ExportTranslationContext();
context.setSourceElement(expression);
final ExportExpressionTranslator translator = (ExportExpressionTranslator) getTestInformation().getTestObject(ExportExpressionTranslator.class);
return translator.translate(expression, context);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*******************************************************************************
* 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.generator.expression;

import org.eclipse.xtext.xbase.XExpression;

import com.avaloq.tools.ddk.xtext.expression.expression.Expression;
import com.avaloq.tools.ddk.xtext.scope.ScopeStandaloneSetup;
import com.avaloq.tools.ddk.xtext.scope.jvmmodel.ScopeExpressionCompiler;
import com.avaloq.tools.ddk.xtext.scope.jvmmodel.ScopeExpressionTranslator;
import com.avaloq.tools.ddk.xtext.scope.jvmmodel.ScopeTranslationContext;
import com.google.inject.Injector;


/**
* Tests Java source generation for expressions used by the Scope DSL.
*/
public class ScopeExpressionCodeGenerationTest extends AbstractExpressionCodeGenerationTest {

@Override
protected void beforeAllTests() {
super.beforeAllTests();
final Injector injector = new ScopeStandaloneSetup().createInjector();
getTestInformation().putTestObject(ScopeExpressionCompiler.class, injector.getInstance(ScopeExpressionCompiler.class));
getTestInformation().putTestObject(ScopeExpressionTranslator.class, injector.getInstance(ScopeExpressionTranslator.class));
}

@Override
protected String compile(final Expression expression) {
final ScopeTranslationContext context = new ScopeTranslationContext();
context.setSourceElement(expression);
final ScopeExpressionCompiler compiler = (ScopeExpressionCompiler) getTestInformation().getTestObject(ScopeExpressionCompiler.class);
return compiler.javaExpression(expression, context);
}

@Override
protected XExpression translate(final Expression expression) {
final ScopeTranslationContext context = new ScopeTranslationContext();
context.setSourceElement(expression);
final ScopeExpressionTranslator translator = (ScopeExpressionTranslator) getTestInformation().getTestObject(ScopeExpressionTranslator.class);
return translator.translate(expression, context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;

import com.avaloq.tools.ddk.xtext.generator.expression.ExportExpressionCodeGenerationTest;
import com.avaloq.tools.ddk.xtext.generator.expression.ExpressionsExtentionsTest;
import com.avaloq.tools.ddk.xtext.generator.expression.ScopeExpressionCodeGenerationTest;
import com.avaloq.tools.ddk.xtext.generator.test.util.EClassComparatorTest;
import com.avaloq.tools.ddk.xtext.generator.test.util.GraphTest;
import com.avaloq.tools.ddk.xtext.generator.xbase.test.XbaseGeneratorFragmentTest;
Expand All @@ -25,7 +27,9 @@
@Suite
@SelectClasses({
// @Format-Off
ExportExpressionCodeGenerationTest.class,
ExpressionsExtentionsTest.class,
ScopeExpressionCodeGenerationTest.class,
EClassComparatorTest.class,
GraphTest.class,
XbaseGeneratorFragmentTest.class
Expand Down
2 changes: 1 addition & 1 deletion com.avaloq.tools.ddk.xtext.scope/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: com.avaloq.tools.ddk.xtext.scope
Bundle-SymbolicName: com.avaloq.tools.ddk.xtext.scope;singleton:=true
Bundle-Version: 17.3.2.qualifier
Bundle-Version: 17.3.3.qualifier
Bundle-Vendor: Avaloq Group AG
Bundle-RequiredExecutionEnvironment: JavaSE-21
Require-Bundle: org.eclipse.xtext,
Expand Down
4 changes: 2 additions & 2 deletions com.avaloq.tools.ddk.xtext.scope/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<version>18.0.1-SNAPSHOT</version>
<relativePath>../ddk-parent</relativePath>
</parent>
<version>17.3.2-SNAPSHOT</version>
<version>17.3.3-SNAPSHOT</version>
<groupId>com.avaloq.tools.ddk</groupId>
<artifactId>com.avaloq.tools.ddk.xtext.scope</artifactId>
<packaging>eclipse-plugin</packaging>
</project>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,10 @@ class ScopeExpressionCompiler {
}

def private boolean isNumber(Expression it, ScopeTranslationContext ctx) {
if (isArithmeticOperatorCall(ctx)) {
// Arithmetic calls have no resolvable JVM method but still produce numeric values.
return true
}
val type = translator.resolveType(it, ctx)
type !== null && type.isNumeric
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ import org.eclipse.xtext.common.types.util.TypeReferences
import org.eclipse.xtext.xbase.XExpression
import org.eclipse.xtext.xbase.XbaseFactory
import org.eclipse.xtext.xbase.lib.BooleanExtensions
import org.eclipse.xtext.xbase.lib.ObjectExtensions

/**
* Translates the custom {@link Expression} AST of the scope/export expression DSL into equivalent Xbase
Expand Down Expand Up @@ -531,8 +530,9 @@ class ScopeExpressionTranslator {
switch operator {
case '||': toBinaryOperation(xLeft, xRight, BooleanExtensions, 'operator_or', sourceElement)
case '&&': toBinaryOperation(xLeft, xRight, BooleanExtensions, 'operator_and', sourceElement)
case '==': toBinaryOperation(xLeft, xRight, ObjectExtensions, 'operator_equals', sourceElement)
case '!=': toBinaryOperation(xLeft, xRight, ObjectExtensions, 'operator_notEquals', sourceElement)
// Xbase equality is value-based, unlike the identity equality emitted by the legacy Java generator.
case '==': null
case '!=': null
default: null
}
}
Expand Down