From 00a0d16ee2c79aa6f45c2f27d888ea28acd32287 Mon Sep 17 00:00:00 2001 From: Philip Makedonski <makedonski@cs.uni-goettingen.de> Date: Thu, 11 Jan 2024 20:40:35 +0100 Subject: [PATCH] + location expressions for parameter bindings (meta-model, constraints) + (partial?) scoping support --- .../mts/tdl/scoping/TDLScopeProvider.java | 84 +++++++++++++++++++ .../model/tdl-constraints.ocl | 6 +- .../org.etsi.mts.tdl.model/model/tdl.ecore | 11 ++- .../org.etsi.mts.tdl.model/model/tdl.genmodel | 2 + 4 files changed, 99 insertions(+), 4 deletions(-) diff --git a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/scoping/TDLScopeProvider.java b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/scoping/TDLScopeProvider.java index dff9d411..5d444f4d 100644 --- a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/scoping/TDLScopeProvider.java +++ b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/scoping/TDLScopeProvider.java @@ -383,10 +383,50 @@ public class TDLScopeProvider extends AbstractDeclarativeScopeProvider { return scope; } else if (dataElement == null) { //TODO: use more widely! Will save a lot of the code in here... + //if reduction? + if (context.eContainer().eContainer() instanceof ParameterBinding) { + //TODO: use newly introduced resolveParameterType? + EList<MemberReference> reduction = ((ParameterBinding)context.eContainer().eContainer()).getReduction(); + if (reduction.size() > 0) { + if (reduction.get(reduction.size()-1).getMember() == null) { + DataType dataType = ((ParameterBinding)reduction.get(reduction.size()-1).eContainer()).getParameter().getDataType(); + if (dataType instanceof StructuredDataType) { + IScope scope = Scopes.scopeFor(((StructuredDataType)dataType).allMembers()); + return scope; + } else if (dataType instanceof CollectionDataType) { + DataType itemType = ((CollectionDataType)dataType).getItemType(); + if (itemType instanceof StructuredDataType) { + IScope scope = Scopes.scopeFor(((StructuredDataType) itemType).allMembers()); + return scope; + } + } + } else { + DataType dataType = reduction.get(reduction.size()-1).getMember().getDataType(); + if (dataType instanceof StructuredDataType) { + IScope scope = Scopes.scopeFor(((StructuredDataType)dataType).allMembers()); + return scope; + } else if (dataType instanceof CollectionDataType) { + DataType itemType = ((CollectionDataType)dataType).getItemType(); + if (itemType instanceof StructuredDataType) { + IScope scope = Scopes.scopeFor(((StructuredDataType) itemType).allMembers()); + return scope; + } + } + IScope scope = Scopes.scopeFor(((StructuredDataType) dataType).allMembers()); + return scope; + } + } + } DataType resolvedDataType = ((DataElementUse)context.eContainer()).resolveDataType(); if (resolvedDataType instanceof StructuredDataType) { IScope scope = Scopes.scopeFor(((StructuredDataType)resolvedDataType).allMembers()); return scope; + } else if (resolvedDataType instanceof CollectionDataType) { + DataType itemType = ((CollectionDataType)resolvedDataType).getItemType(); + if (itemType instanceof StructuredDataType) { + IScope scope = Scopes.scopeFor(((StructuredDataType) itemType).allMembers()); + return scope; + } } else if (resolvedDataType == null) { // DataType resolvedContextDataType = null; // if (context.eContainer().eContainer() instanceof DataElementUse) { @@ -404,6 +444,12 @@ public class TDLScopeProvider extends AbstractDeclarativeScopeProvider { // IScope scope = Scopes.scopeFor(dataElement.eContents()); // return scope; + } else if (context.eContainer() instanceof ParameterBinding) { + DataType pdt = ((ParameterBinding)context.eContainer()).getParameter().getDataType(); + if (pdt instanceof StructuredDataType) { + IScope scope = Scopes.scopeFor(((StructuredDataType) pdt).allMembers()); + return scope; + } } else if (context.eContainer() instanceof LiteralValueUse) { DataType resolvedDataType = ((LiteralValueUse)context.eContainer()).resolveDataType(); if (resolvedDataType instanceof StructuredDataType) { @@ -412,6 +458,43 @@ public class TDLScopeProvider extends AbstractDeclarativeScopeProvider { } } } else if (context instanceof MemberReference) { + if (context.eContainer() instanceof ParameterBinding) { + //TODO: use newly introduced resolveParameterType? + if (((ParameterBinding)context.eContainer()).getReduction().indexOf(context)>0) { + EObject targetContext = ((ParameterBinding)context.eContainer()).getReduction().get(((ParameterBinding)context.eContainer()).getReduction().indexOf(context)-1); + if (((MemberReference)targetContext).getMember()!=null) { + if (((MemberReference)targetContext).getMember().getDataType() instanceof StructuredDataType) { + IScope scope = Scopes.scopeFor(((StructuredDataType)((MemberReference)targetContext).getMember().getDataType()).allMembers()); + return scope; + } else if (((MemberReference)targetContext).getMember().getDataType() instanceof CollectionDataType) { + DataType itemType = ((CollectionDataType)((MemberReference)targetContext).getMember().getDataType()).getItemType(); + if (itemType instanceof StructuredDataType) { + IScope scope = Scopes.scopeFor(((StructuredDataType) itemType).allMembers()); + return scope; + } + } + } else if (((MemberReference)targetContext).getCollectionIndex() != null) { + DataType dataType = ((ParameterBinding)targetContext.eContainer()).getParameter().getDataType(); + if (dataType instanceof StructuredDataType) { + IScope scope = Scopes.scopeFor(((StructuredDataType) dataType).allMembers()); + return scope; + } else if (dataType instanceof CollectionDataType) { + DataType itemType = ((CollectionDataType)dataType).getItemType(); + if (itemType instanceof StructuredDataType) { + IScope scope = Scopes.scopeFor(((StructuredDataType) itemType).allMembers()); + return scope; + } + } + } + } else { + DataType pdt = ((ParameterBinding)context.eContainer()).getParameter().getDataType(); + if (pdt instanceof StructuredDataType) { + IScope scope = Scopes.scopeFor(((StructuredDataType) pdt).allMembers()); + return scope; + } + } + } + if (context.eContainer() instanceof DataUse) { if (((DataUse)context.eContainer()).getReduction().indexOf(context)>0) { EObject targetContext = ((DataUse)context.eContainer()).getReduction().get(((DataUse)context.eContainer()).getReduction().indexOf(context)-1); if (((MemberReference)targetContext).getMember()!=null) { @@ -452,6 +535,7 @@ public class TDLScopeProvider extends AbstractDeclarativeScopeProvider { } } + } if (context.eContainer() instanceof DataInstanceUse) { if (((DataInstanceUse)context.eContainer()).getDataInstance() instanceof StructuredDataInstance) { DataInstance dataInstance = ((DataInstanceUse)context.eContainer()).getDataInstance(); diff --git a/plugins/org.etsi.mts.tdl.model/model/tdl-constraints.ocl b/plugins/org.etsi.mts.tdl.model/model/tdl-constraints.ocl index 440da939..79a60574 100644 --- a/plugins/org.etsi.mts.tdl.model/model/tdl-constraints.ocl +++ b/plugins/org.etsi.mts.tdl.model/model/tdl-constraints.ocl @@ -288,7 +288,8 @@ context DataUse context ParameterBinding -- Matching data type inv ParameterBindingTypes ('The provided \'DataUse\' shall conform to the \'DataType\' of the referenced \'Parameter\'.' + self.toString()): - self.dataUse.resolveDataType().conformsTo(self.parameter.dataType) + self.dataUse.resolveDataType().conformsTo(self.resolveParameterType()) + or self.dataUse.oclIsKindOf(SpecialValueUse) -- Use of a 'StructuredDataInstance' with non-optional 'Member's @@ -303,6 +304,7 @@ context MemberReference -- Collection index expressions for collections only inv CollectionIndex ('If the type of the related \'DataUse\' is not \'CollectionDataType\' then the collectionIndex shall be undefined. ' + self.toString()): self.collectionIndex.oclIsUndefined() + or self.container().oclIsTypeOf(ParameterBinding) --and self.container().oclAsType(ParameterBinding).resolveDataType().oclIsKindOf(CollectionDataType) or self.container().oclAsType(DataUse).resolveDataType().oclIsKindOf(CollectionDataType) @@ -1088,7 +1090,7 @@ context TestDescriptionReference self.componentInstanceBinding->one(c | c.formalComponent = b.formalComponent or c.actualComponent = b.actualComponent)) - + -- Compatible test configurations inv CompatibleConfiguration ('The \'TestConfiguration\' of the referenced (invoked) \'TestDescription\' shall be compatible with the \'TestConfiguration\' of the referencing (invoking) \'TestDescription\' under the provided \'ComponentInstanceBinding\'s between the \'ComponentInstance\'s of the \'TestConfiguration\'s of referenced and referencing \'TestDescription\'s. ' + self.toString()): self.componentInstanceBinding->isEmpty() diff --git a/plugins/org.etsi.mts.tdl.model/model/tdl.ecore b/plugins/org.etsi.mts.tdl.model/model/tdl.ecore index 9ddbac7d..bcb804f9 100644 --- a/plugins/org.etsi.mts.tdl.model/model/tdl.ecore +++ b/plugins/org.etsi.mts.tdl.model/model/tdl.ecore @@ -208,10 +208,17 @@ eType="#//MemberReference" containment="true"/> </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="ParameterBinding" eSuperTypes="#//Element"> + <eOperations name="resolveParameterType" eType="#//DataType"> + <eAnnotations source="http://www.eclipse.org/emf/2002/Ecore/OCL/Pivot"> + <details key="body" value="			
	 	if (self.reduction->isEmpty()) then
	 	self.parameter.dataType
	 	else 
	 		if (self.reduction->last().member.oclIsUndefined()) then
	 			if (self.reduction->last().collectionIndex.oclIsUndefined()) then
	 			self.parameter.dataType
	 			else
	 				self.parameter.dataType.oclAsType(CollectionDataType).itemType
	 			endif 
	 		else 
	 		self.reduction->last().member.dataType
	 		endif
	 endif
	 "/> + </eAnnotations> + </eOperations> <eStructuralFeatures xsi:type="ecore:EReference" name="dataUse" lowerBound="1" eType="#//DataUse" containment="true"/> <eStructuralFeatures xsi:type="ecore:EReference" name="parameter" lowerBound="1" eType="#//Parameter"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="reduction" upperBound="-1" + eType="#//MemberReference" containment="true"/> </eClassifiers> <eClassifiers xsi:type="ecore:EEnum" name="UnassignedMemberTreatment"> <eLiterals name="undefined"/> @@ -691,7 +698,7 @@ <eClassifiers xsi:type="ecore:EClass" name="PredefinedFunctionCall" eSuperTypes="#//DynamicDataUse"> <eOperations name="resolveDataType" eType="#//DataType"> <eAnnotations source="http://www.eclipse.org/emf/2002/Ecore/OCL/Pivot"> - <details key="body" value="self.function.returnType"/> + <details key="body" value="
	 if not self.function.returnType.oclIsUndefined() then
						self.function.returnType
					else 
						self.actualParameters.resolveDataType()->asOrderedSet()->first()
					endif
					"/> </eAnnotations> </eOperations> <eStructuralFeatures xsi:type="ecore:EReference" name="function" lowerBound="1" @@ -804,7 +811,7 @@ <eClassifiers xsi:type="ecore:EClass" name="DataElementUse" eSuperTypes="#//DataUse"> <eOperations name="resolveDataType" eType="#//DataType"> <eAnnotations source="http://www.eclipse.org/emf/2002/Ecore/OCL/Pivot"> - <details key="body" value="
 if (not self.dataElement.oclIsUndefined()) then
 if (self.dataElement.oclIsKindOf(DataType)) then
 self.dataElement.oclAsType(DataType)
 else
 if (self.dataElement.oclIsKindOf(DataInstance)) then
 self.dataElement.oclAsType(DataInstance).dataType
 else 
 if (self.dataElement.oclIsTypeOf(FormalParameter)) then
 self.dataElement.oclAsType(FormalParameter).dataType
 else 
 if (self.dataElement.oclIsTypeOf(Function)) then
 self.dataElement.oclAsType(Function).returnType
 else
 null
 endif
 endif 
 endif
 endif
 else 
 if (self.container().oclIsTypeOf(MemberAssignment)) then
 self.container().oclAsType(MemberAssignment).member.dataType
 else 
 if (self.container().oclIsTypeOf(ParameterBinding)) then
 self.container().oclAsType(ParameterBinding).parameter.dataType
 else
 if (self.container().oclIsTypeOf(CollectionDataInstance)) then
 self.container().oclAsType(CollectionDataInstance).dataType.oclAsType(CollectionDataType).itemType
 else
 if (self.container().oclIsTypeOf(DataElementUse)) then
 self.container().oclAsType(DataElementUse).resolveDataType().oclAsType(CollectionDataType).itemType
 else
 if (self.container().oclIsTypeOf(DataInstanceUse)) then
 self.container().oclAsType(DataInstanceUse).resolveDataType().oclAsType(CollectionDataType).itemType
 else
 null
 endif
 endif
 endif
 endif
 endif
 endif
 "/> + <details key="body" value="
 if (not self.dataElement.oclIsUndefined()) then
 if (self.dataElement.oclIsKindOf(DataType)) then
 self.dataElement.oclAsType(DataType)
 else
 if (self.dataElement.oclIsKindOf(DataInstance)) then
 self.dataElement.oclAsType(DataInstance).dataType
 else 
 if (self.dataElement.oclIsTypeOf(FormalParameter)) then
 self.dataElement.oclAsType(FormalParameter).dataType
 else 
 if (self.dataElement.oclIsTypeOf(Function)) then
 self.dataElement.oclAsType(Function).returnType
 else
 null
 endif
 endif 
 endif
 endif
 else 
 if (self.container().oclIsTypeOf(MemberAssignment)) then
 self.container().oclAsType(MemberAssignment).member.dataType
 else 
 if (self.container().oclIsTypeOf(ParameterBinding)) then
 	self.container().oclAsType(ParameterBinding).resolveParameterType()
 else
 if (self.container().oclIsTypeOf(CollectionDataInstance)) then
 self.container().oclAsType(CollectionDataInstance).dataType.oclAsType(CollectionDataType).itemType
 else
 if (self.container().oclIsTypeOf(DataElementUse)) then
 self.container().oclAsType(DataElementUse).resolveDataType().oclAsType(CollectionDataType).itemType
 else
 if (self.container().oclIsTypeOf(DataInstanceUse)) then
 self.container().oclAsType(DataInstanceUse).resolveDataType().oclAsType(CollectionDataType).itemType
 else
 null
 endif
 endif
 endif
 endif
 endif
 endif
 "/> </eAnnotations> </eOperations> <eStructuralFeatures xsi:type="ecore:EAttribute" name="unassignedMember" eType="#//UnassignedMemberTreatment"/> diff --git a/plugins/org.etsi.mts.tdl.model/model/tdl.genmodel b/plugins/org.etsi.mts.tdl.model/model/tdl.genmodel index 0893cc65..b086084b 100644 --- a/plugins/org.etsi.mts.tdl.model/model/tdl.genmodel +++ b/plugins/org.etsi.mts.tdl.model/model/tdl.genmodel @@ -135,6 +135,8 @@ <genClasses ecoreClass="tdl.ecore#//ParameterBinding"> <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference tdl.ecore#//ParameterBinding/dataUse"/> <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference tdl.ecore#//ParameterBinding/parameter"/> + <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference tdl.ecore#//ParameterBinding/reduction"/> + <genOperations ecoreOperation="tdl.ecore#//ParameterBinding/resolveParameterType"/> </genClasses> <genClasses ecoreClass="tdl.ecore#//Action"> <genFeatures createChild="false" ecoreFeature="ecore:EAttribute tdl.ecore#//Action/body"/> -- GitLab