Commit 3d6f61cd authored by René Schöne's avatar René Schöne
Browse files

Add tests to this repo again.

parent c2531c48
build
src/gen-res/
src/gen/
out/
*.class
buildscript {
repositories.mavenCentral()
dependencies {
classpath 'org.jastadd:jastaddgradle:1.13.3'
classpath fileTree(include: ['buildSrc.jar'], dir: '../libs')
}
}
import org.jastadd.relast.plugin.RelastPlugin
import org.jastadd.relast.plugin.RelastTest
plugins {
id 'java'
id 'java-library'
id 'idea'
id 'com.github.ben-manes.versions' version '0.36.0'
id 'com.google.protobuf' version "0.8.14"
}
apply plugin: 'jastadd'
apply plugin: RelastPlugin
group = 'de.tudresden.inf.st'
repositories {
mavenCentral()
jcenter()
}
dependencies {
implementation project(':ragconnect.base')
runtime group: 'org.jastadd', name: 'jastadd', version: '2.3.4'
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.4.0'
testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.4.0'
testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.12.1'
// mqtt
testImplementation group: 'org.fusesource.mqtt-client', name: 'mqtt-client', version: '1.15'
// rest and client
testImplementation group: 'com.sparkjava', name: 'spark-core', version: '2.9.2'
testImplementation group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.11.2'
testImplementation group: 'org.glassfish.jersey.core', name: 'jersey-client', version: '2.31'
testImplementation group: 'org.glassfish.jersey.inject', name: 'jersey-hk2', version: '2.31'
testImplementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
api group: 'com.google.protobuf', name: 'protobuf-java', version: '3.0.0'
}
test {
useJUnitPlatform {
excludeTags 'mqtt'
}
maxHeapSize = '1G'
}
protobuf {
protoc {
// The artifact spec for the Protobuf Compiler
artifact = 'com.google.protobuf:protoc:3.0.0'
}
}
task allTests(type: Test, dependsOn: testClasses) {
description = 'Run every test'
group = 'verification'
useJUnitPlatform {
includeTags 'mqtt'
}
}
relastTest {
//noinspection GroovyAssignabilityCheck
compilerLocation = '../libs/relast.jar'
}
File genSrc = file("src/test/java-gen")
sourceSets.test.java.srcDir genSrc
idea.module.generatedSourceDirs += genSrc
clean {
delete 'src/test/02-after-ragconnect/*/', 'src/test/03-after-relast/*/', 'src/test/java-gen/*/'
}
// --- Test: Example ---
task preprocessExampleTest(type: JavaExec, group: 'verification') {
doFirst {
delete 'src/test/02-after-ragconnect/example/Test.relast',
'src/test/02-after-ragconnect/example/MqttHandler.jadd',
'src/test/02-after-ragconnect/example/RagConnect.jadd'
}
classpath = sourceSets.main.runtimeClasspath
main = 'org.jastadd.ragconnect.compiler.Compiler'
args '--o=src/test/02-after-ragconnect/example',
'src/test/01-input/example/Test.relast',
'src/test/01-input/example/Test.connect',
'--rootNode=Model',
'--logReads', '--logWrites'
}
task compileExampleTest(type: RelastTest) {
useJastAddNames = true
jastAddList = 'JastAddList'
relastFiles 'src/test/02-after-ragconnect/example/Test.relast',
'src/test/02-after-ragconnect/example/RagConnect.relast'
grammarName = 'src/test/03-after-relast/example/example'
packageName = 'example.ast'
moreInputFiles 'src/test/01-input/example/Test.jadd',
'src/test/02-after-ragconnect/example/MqttHandler.jadd',
'src/test/02-after-ragconnect/example/RagConnect.jadd'
}
compileTestJava.dependsOn compileExampleTest
compileExampleTest.dependsOn preprocessExampleTest
// --- Test: default-only-read ---
task preprocessDefaultOnlyReadTest(type: JavaExec, group: 'verification') {
doFirst {
delete 'src/test/02-after-ragconnect/defaultOnlyRead/Test.relast',
'src/test/02-after-ragconnect/defaultOnlyRead/MqttHandler.jadd',
'src/test/02-after-ragconnect/defaultOnlyRead/RagConnect.jadd'
}
classpath = sourceSets.main.runtimeClasspath
main = 'org.jastadd.ragconnect.compiler.Compiler'
args '--o=src/test/02-after-ragconnect/defaultOnlyRead',
'src/test/01-input/defaultOnlyRead/Test.relast',
'src/test/01-input/defaultOnlyRead/Test.connect',
'--rootNode=A'
}
task compileDefaultOnlyReadTest(type: RelastTest) {
useJastAddNames = true
jastAddList = 'JastAddList'
relastFiles 'src/test/02-after-ragconnect/defaultOnlyRead/Test.relast',
'src/test/02-after-ragconnect/defaultOnlyRead/RagConnect.relast'
grammarName = 'src/test/03-after-relast/defaultOnlyRead/defaultOnlyRead'
packageName = 'defaultOnlyRead.ast'
moreInputFiles 'src/test/02-after-ragconnect/defaultOnlyRead/MqttHandler.jadd',
'src/test/02-after-ragconnect/defaultOnlyRead/RagConnect.jadd'
}
compileTestJava.dependsOn compileDefaultOnlyReadTest
compileDefaultOnlyReadTest.dependsOn preprocessDefaultOnlyReadTest
// --- Test: default-only-write ---
task preprocessDefaultOnlyWriteTest(type: JavaExec, group: 'verification') {
doFirst {
delete 'src/test/02-after-ragconnect/defaultOnlyWrite/Test.relast',
'src/test/02-after-ragconnect/defaultOnlyWrite/MqttHandler.jadd',
'src/test/02-after-ragconnect/defaultOnlyWrite/RagConnect.jadd'
}
classpath = sourceSets.main.runtimeClasspath
main = 'org.jastadd.ragconnect.compiler.Compiler'
args '--o=src/test/02-after-ragconnect/defaultOnlyWrite',
'src/test/01-input/defaultOnlyWrite/Test.relast',
'src/test/01-input/defaultOnlyWrite/Test.connect',
'--rootNode=A'
}
task compileDefaultOnlyWriteTest(type: RelastTest) {
useJastAddNames = true
jastAddList = 'JastAddList'
relastFiles 'src/test/02-after-ragconnect/defaultOnlyWrite/Test.relast',
'src/test/02-after-ragconnect/defaultOnlyWrite/RagConnect.relast'
grammarName = 'src/test/03-after-relast/defaultOnlyWrite/defaultOnlyWrite'
packageName = 'defaultOnlyWrite.ast'
moreInputFiles 'src/test/01-input/defaultOnlyWrite/Test.jadd',
'src/test/02-after-ragconnect/defaultOnlyWrite/MqttHandler.jadd',
'src/test/02-after-ragconnect/defaultOnlyWrite/RagConnect.jadd'
}
compileTestJava.dependsOn compileDefaultOnlyWriteTest
compileDefaultOnlyWriteTest.dependsOn preprocessDefaultOnlyWriteTest
// --- Test: read1write2 ---
task preprocessRead1Write2Test(type: JavaExec, group: 'verification') {
doFirst {
delete 'src/test/02-after-ragconnect/read1write2/Test.relast',
'src/test/02-after-ragconnect/read1write2/MqttHandler.jadd',
'src/test/02-after-ragconnect/read1write2/RagConnect.jadd'
}
classpath = sourceSets.main.runtimeClasspath
main = 'org.jastadd.ragconnect.compiler.Compiler'
args '--o=src/test/02-after-ragconnect/read1write2',
'src/test/01-input/read1write2/Test.relast',
'src/test/01-input/read1write2/Test.connect',
'--rootNode=A'
}
task compileRead1Write2Test(type: RelastTest) {
useJastAddNames = true
jastAddList = 'JastAddList'
relastFiles 'src/test/02-after-ragconnect/read1write2/Test.relast',
'src/test/02-after-ragconnect/read1write2/RagConnect.relast'
grammarName = 'src/test/03-after-relast/read1write2/read1write2'
packageName = 'read1write2.ast'
moreInputFiles 'src/test/01-input/read1write2/Test.jadd',
'src/test/02-after-ragconnect/read1write2/MqttHandler.jadd',
'src/test/02-after-ragconnect/read1write2/RagConnect.jadd'
}
compileTestJava.dependsOn compileRead1Write2Test
compileRead1Write2Test.dependsOn preprocessRead1Write2Test
// --- Test: read2write1 ---
task preprocessRead2Write1Test(type: JavaExec, group: 'verification') {
doFirst {
delete 'src/test/02-after-ragconnect/read2write1/Test.relast',
'src/test/02-after-ragconnect/read2write1/MqttHandler.jadd',
'src/test/02-after-ragconnect/read2write1/RagConnect.jadd'
}
classpath = sourceSets.main.runtimeClasspath
main = 'org.jastadd.ragconnect.compiler.Compiler'
args '--o=src/test/02-after-ragconnect/read2write1',
'src/test/01-input/read2write1/Test.relast',
'src/test/01-input/read2write1/Test.connect',
'--rootNode=A'
}
task compileRead2Write1Test(type: RelastTest) {
useJastAddNames = true
jastAddList = 'JastAddList'
relastFiles 'src/test/02-after-ragconnect/read2write1/Test.relast',
'src/test/02-after-ragconnect/read2write1/RagConnect.relast'
grammarName = 'src/test/03-after-relast/read2write1/read2write1'
packageName = 'read2write1.ast'
moreInputFiles 'src/test/01-input/read2write1/Test.jadd',
'src/test/02-after-ragconnect/read2write1/MqttHandler.jadd',
'src/test/02-after-ragconnect/read2write1/RagConnect.jadd'
}
compileTestJava.dependsOn compileRead2Write1Test
compileRead2Write1Test.dependsOn preprocessRead2Write1Test
// --- Test: via ---
task preprocessViaTest(type: JavaExec, group: 'verification') {
doFirst {
delete 'src/test/02-after-ragconnect/via/Test.relast',
'src/test/02-after-ragconnect/via/MqttHandler.jadd',
'src/test/02-after-ragconnect/via/RestHandler.jadd',
'src/test/02-after-ragconnect/via/RagConnect.jadd'
}
classpath = sourceSets.main.runtimeClasspath
main = 'org.jastadd.ragconnect.compiler.Compiler'
args '--o=src/test/02-after-ragconnect/via',
'src/test/01-input/via/Test.relast',
'src/test/01-input/via/Test.connect',
'--rootNode=A',
'--protocols=mqtt,rest'
}
task compileViaTest(type: RelastTest) {
useJastAddNames = true
jastAddList = 'JastAddList'
relastFiles 'src/test/02-after-ragconnect/via/Test.relast',
'src/test/02-after-ragconnect/via/RagConnect.relast'
grammarName = 'src/test/03-after-relast/via/via'
packageName = 'via.ast'
moreInputFiles 'src/test/01-input/via/Test.jadd',
'src/test/02-after-ragconnect/via/MqttHandler.jadd',
'src/test/02-after-ragconnect/via/RestHandler.jadd',
'src/test/02-after-ragconnect/via/RagConnect.jadd'
}
compileTestJava.dependsOn compileViaTest
compileViaTest.dependsOn preprocessViaTest
// --- Test: token-value-send ---
task preprocessTokenValueSendTest(type: JavaExec, group: 'verification') {
doFirst {
delete 'src/test/02-after-ragconnect/tokenValueSend/Test.relast',
'src/test/02-after-ragconnect/tokenValueSend/MqttHandler.jadd',
'src/test/02-after-ragconnect/tokenValueSend/RestHandler.jadd',
'src/test/02-after-ragconnect/tokenValueSend/RagConnect.jadd'
}
classpath = sourceSets.main.runtimeClasspath
main = 'org.jastadd.ragconnect.compiler.Compiler'
args '--o=src/test/02-after-ragconnect/tokenValueSend',
'src/test/01-input/tokenValueSend/Test.relast',
'src/test/01-input/tokenValueSend/Test.connect',
'--rootNode=A'
}
task compileTokenValueSendTest(type: RelastTest) {
useJastAddNames = true
jastAddList = 'JastAddList'
relastFiles 'src/test/02-after-ragconnect/tokenValueSend/Test.relast',
'src/test/02-after-ragconnect/tokenValueSend/RagConnect.relast'
grammarName = 'src/test/03-after-relast/tokenValueSend/tokenValueSend'
packageName = 'tokenValueSend.ast'
moreInputFiles 'src/test/01-input/tokenValueSend/Test.jadd',
'src/test/02-after-ragconnect/tokenValueSend/MqttHandler.jadd',
'src/test/02-after-ragconnect/tokenValueSend/RagConnect.jadd'
}
compileTestJava.dependsOn compileTokenValueSendTest
compileTokenValueSendTest.dependsOn preprocessTokenValueSendTest
// --- Test: tutorial ---
task preprocessTutorialTest(type: JavaExec, group: 'verification') {
doFirst {
delete 'src/test/02-after-ragconnect/tutorial/Test.relast',
'src/test/02-after-ragconnect/tutorial/MqttHandler.jadd',
'src/test/02-after-ragconnect/tutorial/RagConnect.jadd'
}
classpath = sourceSets.main.runtimeClasspath
main = 'org.jastadd.ragconnect.compiler.Compiler'
args '--o=src/test/02-after-ragconnect/tutorial',
'src/test/01-input/tutorial/Test.relast',
'src/test/01-input/tutorial/Test.connect',
'--rootNode=A'
}
task compileTutorialTest(type: RelastTest) {
useJastAddNames = true
jastAddList = 'JastAddList'
relastFiles 'src/test/02-after-ragconnect/tutorial/Test.relast',
'src/test/02-after-ragconnect/tutorial/RagConnect.relast'
grammarName = 'src/test/03-after-relast/tutorial/tutorial'
packageName = 'tutorial.ast'
moreInputFiles 'src/test/01-input/tutorial/Test.jadd',
'src/test/02-after-ragconnect/tutorial/MqttHandler.jadd',
'src/test/02-after-ragconnect/tutorial/RagConnect.jadd'
}
compileTestJava.dependsOn compileTutorialTest
compileTutorialTest.dependsOn preprocessTutorialTest
# Default Only Read
Idea: Use only `ReadFromMqttDefinition`, test all default mapping definitions from `byte[]` to primitive (and boxed) types
// --- update definitions ---
receive NativeTypes.IntValue;
receive NativeTypes.ShortValue;
receive NativeTypes.LongValue;
receive NativeTypes.FloatValue;
receive NativeTypes.DoubleValue;
receive NativeTypes.CharValue;
receive NativeTypes.StringValue;
receive BoxedTypes.IntValue;
receive BoxedTypes.ShortValue;
receive BoxedTypes.LongValue;
receive BoxedTypes.FloatValue;
receive BoxedTypes.DoubleValue;
receive BoxedTypes.CharValue;
A ::= NativeTypes* BoxedTypes* ;
NativeTypes ::= <IntValue:int> <ShortValue:short> <LongValue:long> <FloatValue:float> <DoubleValue:double> <CharValue:char> <StringValue:String> ;
BoxedTypes ::= <IntValue:Integer> <ShortValue:Short> <LongValue:Long> <FloatValue:Float> <DoubleValue:Double> <CharValue:Character> ;
# Default Only Write
Idea: Use only `WriteToMqttDefintion`, test all default mapping definitions from primitive (and boxed) types to `byte[]`.
// --- update definitions ---
// native types, synthesized
send NativeTypesSyn.IntValue;
send NativeTypesSyn.ShortValue;
send NativeTypesSyn.LongValue;
send NativeTypesSyn.FloatValue;
send NativeTypesSyn.DoubleValue;
send NativeTypesSyn.CharValue;
send NativeTypesSyn.StringValue;
// boxed types, synthesized
send BoxedTypesSyn.IntValue;
send BoxedTypesSyn.ShortValue;
send BoxedTypesSyn.LongValue;
send BoxedTypesSyn.FloatValue;
send BoxedTypesSyn.DoubleValue;
send BoxedTypesSyn.CharValue;
// --- dependency definitions ---
NativeTypesSyn.IntValue canDependOn NativeTypesSyn.DriverSyn as nativeIntDependency;
NativeTypesSyn.ShortValue canDependOn NativeTypesSyn.DriverSyn as nativeShortDependency;
NativeTypesSyn.LongValue canDependOn NativeTypesSyn.DriverSyn as nativeLongDependency;
NativeTypesSyn.FloatValue canDependOn NativeTypesSyn.DriverSyn as nativeFloatDependency;
NativeTypesSyn.DoubleValue canDependOn NativeTypesSyn.DriverSyn as nativeDoubleDependency;
NativeTypesSyn.CharValue canDependOn NativeTypesSyn.DriverSyn as nativeCharDependency;
NativeTypesSyn.StringValue canDependOn NativeTypesSyn.DriverSyn as nativeStringDependency;
BoxedTypesSyn.IntValue canDependOn BoxedTypesSyn.DriverSyn as boxedIntDependency;
BoxedTypesSyn.ShortValue canDependOn BoxedTypesSyn.DriverSyn as boxedShortDependency;
BoxedTypesSyn.LongValue canDependOn BoxedTypesSyn.DriverSyn as boxedLongDependency;
BoxedTypesSyn.FloatValue canDependOn BoxedTypesSyn.DriverSyn as boxedFloatDependency;
BoxedTypesSyn.DoubleValue canDependOn BoxedTypesSyn.DriverSyn as boxedDoubleDependency;
BoxedTypesSyn.CharValue canDependOn BoxedTypesSyn.DriverSyn as boxedCharDependency;
// --- inherited attributes not supported ---
//// native types, inherited
//send NativeTypesInh.IntValue;
//send NativeTypesInh.ShortValue;
//send NativeTypesInh.LongValue;
//send NativeTypesInh.FloatValue;
//send NativeTypesInh.DoubleValue;
//send NativeTypesInh.CharValue;
//send NativeTypesInh.StringValue;
//
//// boxed types, inherited
//send BoxedTypesInh.IntValue;
//send BoxedTypesInh.ShortValue;
//send BoxedTypesInh.LongValue;
//send BoxedTypesInh.FloatValue;
//send BoxedTypesInh.DoubleValue;
//send BoxedTypesInh.CharValue;
aspect Computation {
// native types, synthesized
syn int NativeTypesSyn.getIntValue() = Integer.parseInt(getDriverSyn());
syn short NativeTypesSyn.getShortValue() = Short.parseShort(getDriverSyn());
syn long NativeTypesSyn.getLongValue() = Long.parseLong(getDriverSyn());
syn float NativeTypesSyn.getFloatValue() = Float.parseFloat(getDriverSyn());
syn double NativeTypesSyn.getDoubleValue() = Double.parseDouble(getDriverSyn());
syn char NativeTypesSyn.getCharValue() = getDriverSyn().charAt(0);
syn String NativeTypesSyn.getStringValue() = new String(getDriverSyn());
// boxed types, synthesized
syn Integer BoxedTypesSyn.getIntValue() = Integer.valueOf(getDriverSyn());
syn Short BoxedTypesSyn.getShortValue() = Short.valueOf(getDriverSyn());
syn Long BoxedTypesSyn.getLongValue() = Long.valueOf(getDriverSyn());
syn Float BoxedTypesSyn.getFloatValue() = Float.valueOf(getDriverSyn());
syn Double BoxedTypesSyn.getDoubleValue() = Double.valueOf(getDriverSyn());
syn Character BoxedTypesSyn.getCharValue() = getDriverSyn().charAt(0);
// --- inherited attributes not supported ---
// // native types, inherited
// inh int NativeTypesInh.getIntValue();
// eq A.getNativeTypesInh().getIntValue() = Integer.parseInt(getDriverInh());
// inh short NativeTypesInh.getShortValue();
// eq A.getNativeTypesInh().getShortValue() = Short.parseShort(getDriverInh());
// inh long NativeTypesInh.getLongValue();
// eq A.getNativeTypesInh().getLongValue() = Long.parseLong(getDriverInh());
// inh float NativeTypesInh.getFloatValue();
// eq A.getNativeTypesInh().getFloatValue() = Float.parseFloat(getDriverInh());
// inh double NativeTypesInh.getDoubleValue();
// eq A.getNativeTypesInh().getDoubleValue() = Double.parseDouble(getDriverInh());
// inh char NativeTypesInh.getCharValue();
// eq A.getNativeTypesInh().getCharValue() = getDriverInh().charAt(0);
// inh String NativeTypesInh.getStringValue();
// eq A.getNativeTypesInh().getStringValue() = new String(getDriverInh());
//
// // boxed types, inherited
// inh Integer BoxedTypesInh.getIntValue();
// eq A.getBoxedTypesInh().getIntValue() = Integer.valueOf(getDriverInh());
// inh Short BoxedTypesInh.getShortValue();
// eq A.getBoxedTypesInh().getShortValue() = Short.valueOf(getDriverInh());
// inh Long BoxedTypesInh.getLongValue();
// eq A.getBoxedTypesInh().getLongValue() = Long.valueOf(getDriverInh());
// inh Float BoxedTypesInh.getFloatValue();
// eq A.getBoxedTypesInh().getFloatValue() = Float.valueOf(getDriverInh());
// inh Double BoxedTypesInh.getDoubleValue();
// eq A.getBoxedTypesInh().getDoubleValue() = Double.valueOf(getDriverInh());
// inh Character BoxedTypesInh.getCharValue();
// eq A.getBoxedTypesInh().getCharValue() = getDriverInh().charAt(0);
}
A ::= NativeTypesSyn* BoxedTypesSyn* <DriverInh:String>;
// native types, synthesized
NativeTypesSyn ::= <DriverSyn:String> /<IntValue:int>/ /<ShortValue:short>/ /<LongValue:long>/ /<FloatValue:float>/ /<DoubleValue:double>/ /<CharValue:char>/ /<StringValue:String>/ ;
// boxed types, synthesized
BoxedTypesSyn ::= <DriverSyn:String> /<IntValue:Integer>/ /<ShortValue:Short>/ /<LongValue:Long>/ /<FloatValue:Float>/ /<DoubleValue:Double>/ /<CharValue:Character>/ ;
// --- inherited attributes not supported ---
//// native types, inherited
//NativeTypesInh ::= /<IntValue:int>/ /<ShortValue:short>/ /<LongValue:long>/ /<FloatValue:float>/ /<DoubleValue:double>/ /<CharValue:char>/ /<StringValue:String>/ ;
//// boxed types, inherited
//BoxedTypesInh ::= /<IntValue:Integer>/ /<ShortValue:Short>/ /<LongValue:Long>/ /<FloatValue:Float>/ /<DoubleValue:Double>/ /<CharValue:Character>/ ;
// --- update receive definitions ---
// Error: there must not be two receive definitions for the same token
receive B.DoubledValue ;
receive B.DoubledValue using IntToInt ;
// NOT HANDLED \\ Error: the token must be resolvable within the parent type
// NOT HANDLED \\ receive B.NonExisting ;
// Error: the Token must not be a TokenNTA (i.e., check for !Token.getNTA())
receive B.ErrorNTA ;
// Error: from-type of first mapping must be byte[] or a supported primitive type
receive B.ErrorTypeOfFirstMapping using ListToList ;
// Error: to-type of last mapping must be type of the Token
receive B.ErrorTypeOfLastMapping using StringToList ;
// Error: types of mappings must match (modulo inheritance)
receive B.ErrorTypeMismatch using StringToList, IntToInt ;
// --- update send definitions ---
// NOT HANDLED \\ Error: the token must be resolvable within the parent type
// NOT HANDLED \\ receive C.NonExisting ;
// Error: Token must be a TokenNTA (i.e., check for Token.getNTA())
send C.ErrorNotNTA ;
// Error: from-type of first mapping must be type of Token
send C.ErrorTypeOfFirstMapping using IntToInt ;
// Error: to-type of last mapping must be byte[] or a supported primitive type
send C.ErrorTypeOfLastMapping1 using StringToList ;
send C.ErrorTypeOfLastMapping2 ;
// Error: types of mappings must match (modulo inheritance)
send C.ErrorTypeMismatch using StringToList, IntToInt ;
// Error: no more than one send mapping for each TokenComponent
send C.DoubledValue ;
send C.DoubledValue using IntToInt ;
// --- dependency definitions ---
// NOT HANDLED \\ Error: Both, source and target must be resolvable within the parent type
// NOT HANDLED \\ D.SourceNonExistingTarget canDependOn D.NonExisting as NonExistingTarget ;
// NOT HANDLED \\ D.NonExisting canDependOn D.TargetNonExistingSource as NonExistingSource ;
// Error: There must be a send update definition for the target token
D.SourceNoWriteDef canDependOn D.TargetNoWriteDef as NoWriteDef ;
// Error: The name of a dependency definition must not be equal to a list-node on the source
D.SourceSameAsListNode canDependOn D.TargetSameAsListNode as MyList ;
send D.TargetSameAsListNode;
// Error: There must not be two dependency definitions with the same name
D.SourceDoubledValue canDependOn D.TargetDoubledValue as DoubledValue ;
D.SourceDoubledValue canDependOn D.TargetDoubledValue as DoubledValue ;
send D.TargetDoubledValue;
// --- mapping definitions ---
ListToList maps java.util.List<String> list to java.util.List<String> {:
return list;
:}
StringToList maps String s to List<String> {:
java.util.List<String> result = new java.util.ArrayList<>();
result.add(s);
return result;
:}
IntToInt maps int number to int {:
return number + 1;
:}
A ::= B C D ;
// read definitions
B ::= /<ErrorNTA:String>/ <ErrorTypeOfFirstMapping:String> <ErrorTypeOfLastMapping:String> <DoubledValue:int> <ErrorTypeMismatch:String> ;
// write definitions
C ::= <ErrorNotNTA:String> /<ErrorTypeOfFirstMapping:String>/ /<ErrorTypeOfLastMapping1:String>/ /<ErrorTypeOfLastMapping2:List<String>>/ /<ErrorTypeMismatch:String>/ /<DoubledValue:int>/ ;
// dependency definitions
D ::= <SourceNonExistingTarget>
/<TargetNonExistingSource>/
<SourceNoWriteDef> /<TargetNoWriteDef>/
<SourceSameAsListNode> /<TargetSameAsListNode>/
<SourceDoubledValue> /<TargetDoubledValue>/
MyList:D* ;
Ideas for errors:
- Read-Update
- the token must be resolvable within the parent type
- the Token must not be a TokenNTA (i.e., check for `!Token.getNTA()`)
- type of first mapping must be `byte[]`
- type of last mapping must be type of the Token
- types of mappings must match (modulo inheritance)
- Write-Update
- the token must be resolvable within the parent type
- Token must be a TokenNTA (i.e., check for `Token.getNTA()`)
- type of first mapping must be type of Token
- type of last mapping must be `byte[]`
- types of mappings must match (modulo inheritance)
- no more than one write mapping for each TokenComponent
- for all type checks, there are three cases regarding the two types to check against:
1) both are nonterminal types, check with grammar
2) both are known classes, check with `Class.forName()` and subclass-checking-methods
3) otherwise issue warning, that types could not be matched
- dependency-definition
- There **must be** a write update definition for the target token
- Otherwise there are missing update and write methods used in the virtual setter
- Both, source and target must be resolvable within the parent type
- The name of a dependency definition must not be equal to a list-node on the source
- There must not be two dependency definitions with the same name
# Example
Idea: Use the motivating example from our paper as a test case, including one read, one write update definition