Просмотр исходного кода

Added Validation rules for generics to expression language, added type arguments to stext

Andreas Mülder 12 лет назад
Родитель
Сommit
66ae926f76

+ 35 - 49
plugins/org.yakindu.sct.model.stext/src/org/yakindu/sct/model/stext/SText.xtext

@@ -30,7 +30,7 @@ ScopedElement returns sgraph::ScopedElement:
 	StatechartSpecification;
 
 StatechartSpecification:
-	{StatechartSpecification} ('namespace' namespace=FQN)? 
+	{StatechartSpecification} ('namespace' namespace=FQN)?
 	(imports+=Import)*
 	(scopes+=StatechartScope)*;
 
@@ -39,15 +39,14 @@ StateSpecification:
 
 TransitionSpecification:
 	reaction=TransitionReaction;
-/* ---- scope rules ----
-Defines different kinds of scopes that contain element definitions. Scopes are used for element definitions in statechart, regions, and state 
-*/
+
 Scope returns sgraph::Scope:
-	(StateScope | StatechartScope); // a SimpleScope is used for states and regions
- StateScope returns sgraph::Scope:
-	{SimpleScope} (declarations+=(LocalReaction /* | Entrypoint | Exitpoint */))*;
-// defines the poosible scopes for statecharts
- StatechartScope:
+	(StateScope | StatechartScope);
+
+StateScope returns sgraph::Scope:
+	{SimpleScope} (declarations+=(LocalReaction))*;
+
+StatechartScope:
 	InterfaceScope | InternalScope;
 
 NamedInterfaceScope returns base::NamedElement:
@@ -55,45 +54,37 @@ NamedInterfaceScope returns base::NamedElement:
 
 InterfaceScope:
 	{InterfaceScope} 'interface' (name=XID)? ':' (declarations+=(EventDeclarartion | VariableDeclaration |
-	OperationDeclaration //		| Entrypoint 
- //		| Exitpoint
-))*;
+	OperationDeclaration))*;
 
 InternalScope:
 	{InternalScope} 'internal' ':' (declarations+=(EventDeclarartion | VariableDeclaration | OperationDeclaration |
-	LocalReaction))*; /* ---- declarations ----
-a definition is a top level element of a definition scope. */ 
+	LocalReaction))*;
 
 Import returns sgraph::Import:
-	'import' importedNamespace=QIDWithWildcards';'
-;
+	'import' importedNamespace=QIDWithWildcards ';';
 
 QIDWithWildcards:
 	QID ('.*')?;
-	
+
 QID:
 	ID ('.' ID)*;
 
-
 Declaration returns sgraph::Declaration:
-	EventDeclarartion | VariableDeclaration | OperationDeclaration | LocalReaction //		| Entrypoint 
- //		| Exitpoint
-;
+	EventDeclarartion | VariableDeclaration | OperationDeclaration | LocalReaction;
 
-/* ---- event definition ---- */ EventDeclarartion returns sgraph::Event:
+EventDeclarartion returns sgraph::Event:
 	EventDefinition;
 
 EventFeature returns types::Event:
 	EventDefinition;
 
 EventDefinition:
-	(direction=Direction)? 'event' name=XID (':' type=[types::Type|FQN])?; // (derivation=EventDerivation)?;
+	(direction=Direction)? 'event' name=XID (':' type=[types::Type|FQN])?;
+
+enum Direction:
+	LOCAL='local' | IN='in' | OUT='out';
 
-//EventDerivation:
- //	 (':' value=Expression)?;
- enum Direction:
-	LOCAL='local' | IN='in' | OUT='out'; /* ---- variable definition ---- */ VariableDeclaration returns
-sgraph::Variable:
+VariableDeclaration returns sgraph::Variable:
 	VariableDefinition;
 
 VariableFeature returns types::Property:
@@ -101,6 +92,7 @@ VariableFeature returns types::Property:
 
 VariableDefinition:
 	{VariableDefinition} 'var' ((readonly?='readonly')? & (external?='external')?) name=XID ':' type=[types::Type|FQN]
+	(('<' (typeArguments+=[types::Type|QID]) (',' typeArguments+=[types::Type|QID])* '>'))?
 	('=' initialValue=Expression)?; /* ---- operation definition ---- */ OperationDeclaration returns
 sgraph::Declaration:
 	OperationDefinition;
@@ -110,24 +102,12 @@ OperationFeature returns types::Operation:
 
 OperationDefinition:
 	{OperationDefinition} 'operation' name=XID '(' (parameters+=Parameter (',' parameters+=Parameter)*)? ')' (':'
-	type=[types::Type|FQN])?;
+	type=[types::Type|FQN] (('<' (typeArguments+=[types::Type|QID]) (',' typeArguments+=[types::Type|QID])* '>'))?)?;
 
 Parameter returns types::Parameter:
-	name=XID ':' type=[types::Type|FQN]; /* ---- entrypoint definition ---- */ //Entrypoint returns sgraph::Declaration:
-
-//	{Entrypoint} 'entrypoint' name=XID;
- /* ---- exitpoint definition ---- */ //Exitpoint returns sgraph::Declaration:
+	name=XID ':' type=[types::Type|FQN] (('<' (typeArguments+=[types::Type|QID]) (',' typeArguments+=[types::Type|QID])*
+	'>'))?;
 
-//	{Exitpoint} 'exitpoint' name=XID;
- /* ---- Datatype rules ---- */ XID:
-	ID | 'namespace' | 'interface' | 'internal' | 'event' | 'local' | 'in' | 'out' | 'var' | 'readonly' | 'external' |
-	'operation' | 'default' | 'else' | 'entry' | 'exit' | 'always' | 'oncycle' | 'raise' | 'valueof' | 'active';
-
-FQN:
-	XID ('.' XID)*;
-/* ---- reaction rules ----
-Define the structure of reactions that are central for describing the statecharts behavior. 
-*/
 Reaction returns sgraph::Reaction:
 	LocalReaction | TransitionReaction;
 
@@ -167,8 +147,9 @@ EventSpec:
 	RegularEventSpec | TimeEventSpec | BuiltinEventSpec;
 
 RegularEventSpec:
-	event=FeatureCall; // TODO: redefine after trigger - we need to use it with clocks
- TimeEventSpec:
+	event=FeatureCall;
+
+TimeEventSpec:
 	type=TimeEventType value=ConditionalExpression unit=TimeUnit;
 
 enum TimeEventType:
@@ -184,9 +165,7 @@ ExitEvent:
 	{ExitEvent} 'exit';
 
 AlwaysEvent:
-	{AlwaysEvent} ('always' | 'oncycle'); //****************
- // Statechart specific expressions
- //****************
+	{AlwaysEvent} ('always' | 'oncycle');
 
 EventRaisingExpression returns exp::Expression:
 	{EventRaisingExpression} 'raise' event=FeatureCall (':' value=Expression)?;
@@ -202,4 +181,11 @@ PrimaryExpression returns exp::Expression:
 	ParenthesizedExpression;
 
 enum TimeUnit:
-	second='s' | millisecond='ms' | microsecond='us' | nanosecond='ns';
+	second='s' | millisecond='ms' | microsecond='us' | nanosecond='ns';
+
+XID:
+	ID | 'namespace' | 'interface' | 'internal' | 'event' | 'local' | 'in' | 'out' | 'var' | 'readonly' | 'external' |
+	'operation' | 'default' | 'else' | 'entry' | 'exit' | 'always' | 'oncycle' | 'raise' | 'valueof' | 'active';
+
+FQN:
+	XID ('.' XID)*;

+ 2 - 1
plugins/org.yakindu.sct.model.stext/src/org/yakindu/sct/model/stext/validation/STextJavaValidator.java

@@ -38,6 +38,7 @@ import org.yakindu.base.expressions.expressions.ElementReferenceExpression;
 import org.yakindu.base.expressions.expressions.Expression;
 import org.yakindu.base.expressions.expressions.ExpressionsPackage;
 import org.yakindu.base.expressions.expressions.FeatureCall;
+import org.yakindu.base.expressions.validation.ExpressionsJavaValidator;
 import org.yakindu.base.types.Event;
 import org.yakindu.base.types.Feature;
 import org.yakindu.base.types.ITypeSystem;
@@ -94,7 +95,7 @@ import com.google.inject.name.Named;
  * @auhor muelder
  * 
  */
-@ComposedChecks(validators = { SGraphJavaValidator.class, SCTResourceValidator.class })
+@ComposedChecks(validators = { SGraphJavaValidator.class, SCTResourceValidator.class, ExpressionsJavaValidator.class })
 public class STextJavaValidator extends AbstractSTextJavaValidator {
 
 	public static final String CHOICE_ONE_OUTGOING_DEFAULT_TRANSITION = "A choice should have one outgoing default transition";

+ 20 - 4
plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/container/DefaultExecutionContextInitializer.xtend

@@ -11,9 +11,12 @@
 package org.yakindu.sct.simulation.core.sexec.container
 
 import com.google.inject.Inject
+import org.eclipse.emf.workspace.util.WorkspaceSynchronizer
 import org.eclipse.xtext.naming.IQualifiedNameProvider
+import org.yakindu.base.types.ComplexType
 import org.yakindu.base.types.ITypeSystem
 import org.yakindu.base.types.InferredType
+import org.yakindu.sct.commons.WorkspaceClassLoaderFactory
 import org.yakindu.sct.model.sexec.ExecutionFlow
 import org.yakindu.sct.model.sexec.TimeEvent
 import org.yakindu.sct.model.sgraph.Scope
@@ -63,14 +66,14 @@ class DefaultExecutionContextInitializer implements IExecutionContextInitializer
 		it.name = variable.fullyQualifiedName.lastSegment
 		it.fqName = variable.fullyQualifiedName.toString
 		it.type = variable.inferType.type
-		it.value = it.type.defaultValue
+		it.value = it.type.initialValue
 	}
 
 	def dispatch create new ExecutionEventImpl() transform(EventDefinition event) {
 		it.name = event.fullyQualifiedName.lastSegment
 		it.fqName = event.fullyQualifiedName.toString
 		it.type = event.inferType.type
-		it.value = it.type.defaultValue
+		it.value = it.type.initialValue
 		it.direction = EventDirection.get(event.direction.value)
 	}
 
@@ -78,13 +81,26 @@ class DefaultExecutionContextInitializer implements IExecutionContextInitializer
 		it.name = op.fullyQualifiedName.lastSegment
 		it.fqName = op.fullyQualifiedName.toString
 		it.type = new InferredType(if(op.type != null) op.type else voidType)
-		it.value = it.type.defaultValue
+		it.value = it.type.initialValue
 	}
 
 	def dispatch create new ExecutionEventImpl() transform(TimeEvent event) {
 		it.name = event.fullyQualifiedName.lastSegment
 		it.fqName = event.fullyQualifiedName.toString
 		it.type = new InferredType(integerType)
-		it.value = defaultValue(it.type)
+		it.value = initialValue(it.type)
+	}
+
+	def Object initialValue(InferredType inferredType) {
+		var type = inferredType.type
+		if (type instanceof ComplexType) {
+			var factory = new WorkspaceClassLoaderFactory();
+			var classLoader = factory.createClassLoader(WorkspaceSynchronizer.getFile(type.eResource()).getProject(),
+				null);
+			var clazz = classLoader.loadClass(type.fullyQualifiedName.toString());
+			return clazz.newInstance();
+		} else {
+			return type.defaultValue
+		}
 	}
 }

+ 8 - 4
plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/interpreter/StextStatementInterpreter.xtend

@@ -124,8 +124,7 @@ class StextStatementInterpreter extends AbstractStatementInterpreter {
 		var parameter = expression.args.map(it|execute)
 		if (expression.operationCall) {
 			if (operationDelegate.canExecute(expression.reference as Operation, parameter.toArray)) {
-				return operationDelegate.execute((expression.reference as Operation),
-					parameter.toArray)
+				return operationDelegate.execute((expression.reference as Operation), parameter.toArray)
 			}
 		}
 
@@ -157,7 +156,7 @@ class StextStatementInterpreter extends AbstractStatementInterpreter {
 		e.reference.getFullyQualifiedName.toString
 	}
 
-	def dispatch Object execute(ActiveStateReferenceExpression expression) {
+	def dispatch Object execute(ActiveStateReferenceExpression expression) {
 		var state = expression.value
 		return context.allActiveStates.contains(state)
 	}
@@ -239,7 +238,12 @@ class StextStatementInterpreter extends AbstractStatementInterpreter {
 			if (variableRef != null) {
 				return variableRef.getValue
 			}
-			return context.getEvent(fqn).raised
+			var event = context.getEvent(fqn)
+			if (event != null)
+				return event.raised
+			println("No feature found for " + fqn + " -> returning null")
+			return null;
+
 		}
 	}