From ee18a88c36d4c793c7ab362e3a270e35d09dd66c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martti=20K=C3=A4=C3=A4rik?= <martti.kaarik@elvior.com>
Date: Thu, 1 May 2025 10:31:05 +0300
Subject: [PATCH] Added implementation of DataUse.java() + simplified scope for
 MemberReference (to avoid cyclic linking error)

---
 .../mts/tdl/scoping/TDLScopeProvider.java     | 308 ++++++++++--------
 .../org.etsi.mts.tdl.model/model/tdl.ecore    |   2 +-
 2 files changed, 165 insertions(+), 145 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 904cd360..424b0626 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
@@ -1,6 +1,5 @@
 package org.etsi.mts.tdl.scoping;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -459,155 +458,176 @@ 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;
-						}
-					}
-				} 
+				List<MemberReference> reduction = null;
+				DataType referenceType = null;
 				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) {
-							if (((MemberReference)targetContext).getMember().getDataType() instanceof StructuredDataType) {
-								IScope scope = Scopes.scopeFor(((StructuredDataType)((MemberReference)targetContext).getMember().getDataType()).allMembers());
-								return scope;
-							}
-						} else if (((MemberReference)targetContext).getCollectionIndex()!=null) {
-							if (targetContext.eContainer() instanceof DataInstanceUse) {
-								DataInstanceUse dataInstanceUse = (DataInstanceUse)targetContext.eContainer();
-								if (dataInstanceUse.getDataType()!=null) {
-									//TODO:?
-								} else if (dataInstanceUse.getDataInstance()!=null) {
-									//TODO: check type
-									DataType itemType = ((CollectionDataType)dataInstanceUse.getDataInstance().getDataType()).getItemType();
-									if (itemType instanceof StructuredDataType) {
-										IScope scope = Scopes.scopeFor(((StructuredDataType)itemType).allMembers());
-										return scope;
-									}
-								}
-							} else if (targetContext.eContainer() instanceof DataElementUse) {
-								DataElementUse dataElementUse = (DataElementUse)targetContext.eContainer();
-								DataType resolvedDataType = dataElementUse.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;
-									}
-									
-								}
-								
-							}
-							//TODO: handle other scenarios?
-							
-						}
-					} 
+					reduction = ((DataUse) context.eContainer()).getReduction();
+					referenceType = ((DataUse) context.eContainer()).resolveBaseDataType();
+				} else if (context.eContainer() instanceof ParameterBinding) {
+					reduction = ((ParameterBinding) context.eContainer()).getReduction();
+					referenceType = ((ParameterBinding) context.eContainer()).getParameter().getDataType();
 				}
-				if (context.eContainer() instanceof DataInstanceUse) {
-					if (((DataInstanceUse)context.eContainer()).getDataInstance() instanceof StructuredDataInstance) {
-						DataInstance dataInstance = ((DataInstanceUse)context.eContainer()).getDataInstance();
-						if (dataInstance instanceof StructuredDataInstance && dataInstance.getDataType() instanceof StructuredDataType) {
-							IScope scope = Scopes.scopeFor(((StructuredDataType)((StructuredDataInstance)dataInstance).getDataType()).allMembers());
-							return scope;
-						}
-					}
-				} else if (context.eContainer() instanceof FunctionCall) {
-					if (((FunctionCall)context.eContainer()).getFunction().getReturnType() instanceof StructuredDataType) {
-						IScope scope = Scopes.scopeFor(((StructuredDataType)((FunctionCall)context.eContainer()).getFunction().getReturnType()).allMembers());
-						return scope;
-					}
-				} else if (context.eContainer() instanceof FormalParameterUse) {
-					if (((FormalParameterUse)context.eContainer()).getParameter().getDataType() instanceof StructuredDataType) {
-						IScope scope = Scopes.scopeFor(((StructuredDataType)((FormalParameterUse)context.eContainer()).getParameter().getDataType()).allMembers());
-						return scope;
-					}
-				} else if (context.eContainer() instanceof VariableUse) {
-					if (((VariableUse)context.eContainer()).getVariable().getDataType() instanceof StructuredDataType) {
-						IScope scope = Scopes.scopeFor(((StructuredDataType)((VariableUse)context.eContainer()).getVariable().getDataType()).allMembers());
-						return scope;
-					}
-				} else if (context.eContainer() instanceof DataElementUse) {
-					NamedElement dataElement = ((DataElementUse) context.eContainer()).getDataElement();
-					//TODO: duplicated from above ->extract
-					if (dataElement instanceof org.etsi.mts.tdl.Function) {
-						DataType returnType = ((org.etsi.mts.tdl.Function)dataElement).getReturnType();
-						if (returnType instanceof StructuredDataType) {
-							IScope scope = Scopes.scopeFor(((StructuredDataType)returnType).allMembers());
-							return scope;
-						}
-					} else if (dataElement instanceof FormalParameter) {
-						IScope scope = Scopes.scopeFor(((StructuredDataType)((FormalParameter) dataElement).getDataType()).allMembers());
-						return scope;
-					} else if (dataElement instanceof StructuredDataInstance) {
-						if (((StructuredDataInstance) dataElement).getDataType() instanceof StructuredDataType) {
-							IScope scope = Scopes.scopeFor(((StructuredDataType)((StructuredDataInstance) dataElement).getDataType()).allMembers());
-							return scope;
-						}
-					} else if (dataElement instanceof StructuredDataType) {
-						IScope scope = Scopes.scopeFor(((StructuredDataType)dataElement).allMembers());
-						return scope;
-					} else if (dataElement == null) {
-						//TODO: use more widely! Will save a lot of the code in here...
-						DataType resolvedDataType = ((DataElementUse)context.eContainer()).resolveDataType();
-						if (resolvedDataType instanceof StructuredDataType) {
-							IScope scope = Scopes.scopeFor(((StructuredDataType)resolvedDataType).allMembers());
-							return scope;
-						}
-					}
-				} else if (context.eContainer() instanceof LiteralValueUse) {
-					DataType resolvedDataType = ((LiteralValueUse)context.eContainer()).resolveDataType();
-					if (resolvedDataType instanceof StructuredDataType) {
-						IScope scope = Scopes.scopeFor(((StructuredDataType)resolvedDataType).allMembers());
-						return scope;
-					}
-				} else if (context.eContainer() instanceof CastDataUse) {
-					DataType resolvedDataType = ((CastDataUse)context.eContainer()).resolveDataType();
-					if (resolvedDataType instanceof StructuredDataType) {
-						IScope scope = Scopes.scopeFor(((StructuredDataType)resolvedDataType).allMembers());
-						return scope;
-					}
-				} else if (context.eContainer() instanceof PredefinedFunctionCall) {
-//					DataType resolvedDataType = ((PredefinedFunctionCall)context.eContainer()).resolveDataType();
+				if (reduction != null && !reduction.isEmpty()) {
+					int rIndex = reduction.indexOf(context);
+					if (rIndex > 0)
+						referenceType = reduction.get(rIndex - 1).getMember().getDataType();
+				}
+				if (referenceType instanceof CollectionDataType) {
+					referenceType = ((CollectionDataType) referenceType).getItemType();
+				}
+				if (referenceType instanceof StructuredDataType) {
+					IScope scope = Scopes.scopeFor(((StructuredDataType) referenceType).allMembers());
+					return scope;
+				}
+//				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) {
+//							if (((MemberReference)targetContext).getMember().getDataType() instanceof StructuredDataType) {
+//								IScope scope = Scopes.scopeFor(((StructuredDataType)((MemberReference)targetContext).getMember().getDataType()).allMembers());
+//								return scope;
+//							}
+//						} else if (((MemberReference)targetContext).getCollectionIndex()!=null) {
+//							if (targetContext.eContainer() instanceof DataInstanceUse) {
+//								DataInstanceUse dataInstanceUse = (DataInstanceUse)targetContext.eContainer();
+//								if (dataInstanceUse.getDataType()!=null) {
+//									//TODO:?
+//								} else if (dataInstanceUse.getDataInstance()!=null) {
+//									//TODO: check type
+//									DataType itemType = ((CollectionDataType)dataInstanceUse.getDataInstance().getDataType()).getItemType();
+//									if (itemType instanceof StructuredDataType) {
+//										IScope scope = Scopes.scopeFor(((StructuredDataType)itemType).allMembers());
+//										return scope;
+//									}
+//								}
+//							} else if (targetContext.eContainer() instanceof DataElementUse) {
+//								DataElementUse dataElementUse = (DataElementUse)targetContext.eContainer();
+//								DataType resolvedDataType = dataElementUse.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;
+//									}
+//									
+//								}
+//								
+//							}
+//							//TODO: handle other scenarios?
+//							
+//						}
+//					} 
+//				}
+//				if (context.eContainer() instanceof DataInstanceUse) {
+//					if (((DataInstanceUse)context.eContainer()).getDataInstance() instanceof StructuredDataInstance) {
+//						DataInstance dataInstance = ((DataInstanceUse)context.eContainer()).getDataInstance();
+//						if (dataInstance instanceof StructuredDataInstance && dataInstance.getDataType() instanceof StructuredDataType) {
+//							IScope scope = Scopes.scopeFor(((StructuredDataType)((StructuredDataInstance)dataInstance).getDataType()).allMembers());
+//							return scope;
+//						}
+//					}
+//				} else if (context.eContainer() instanceof FunctionCall) {
+//					if (((FunctionCall)context.eContainer()).getFunction().getReturnType() instanceof StructuredDataType) {
+//						IScope scope = Scopes.scopeFor(((StructuredDataType)((FunctionCall)context.eContainer()).getFunction().getReturnType()).allMembers());
+//						return scope;
+//					}
+//				} else if (context.eContainer() instanceof FormalParameterUse) {
+//					if (((FormalParameterUse)context.eContainer()).getParameter().getDataType() instanceof StructuredDataType) {
+//						IScope scope = Scopes.scopeFor(((StructuredDataType)((FormalParameterUse)context.eContainer()).getParameter().getDataType()).allMembers());
+//						return scope;
+//					}
+//				} else if (context.eContainer() instanceof VariableUse) {
+//					if (((VariableUse)context.eContainer()).getVariable().getDataType() instanceof StructuredDataType) {
+//						IScope scope = Scopes.scopeFor(((StructuredDataType)((VariableUse)context.eContainer()).getVariable().getDataType()).allMembers());
+//						return scope;
+//					}
+//				} else if (context.eContainer() instanceof DataElementUse) {
+//					NamedElement dataElement = ((DataElementUse) context.eContainer()).getDataElement();
+//					//TODO: duplicated from above ->extract
+//					if (dataElement instanceof org.etsi.mts.tdl.Function) {
+//						DataType returnType = ((org.etsi.mts.tdl.Function)dataElement).getReturnType();
+//						if (returnType instanceof StructuredDataType) {
+//							IScope scope = Scopes.scopeFor(((StructuredDataType)returnType).allMembers());
+//							return scope;
+//						}
+//					} else if (dataElement instanceof FormalParameter) {
+//						IScope scope = Scopes.scopeFor(((StructuredDataType)((FormalParameter) dataElement).getDataType()).allMembers());
+//						return scope;
+//					} else if (dataElement instanceof StructuredDataInstance) {
+//						if (((StructuredDataInstance) dataElement).getDataType() instanceof StructuredDataType) {
+//							IScope scope = Scopes.scopeFor(((StructuredDataType)((StructuredDataInstance) dataElement).getDataType()).allMembers());
+//							return scope;
+//						}
+//					} else if (dataElement instanceof StructuredDataType) {
+//						IScope scope = Scopes.scopeFor(((StructuredDataType)dataElement).allMembers());
+//						return scope;
+//					} else if (dataElement == null) {
+//						//TODO: use more widely! Will save a lot of the code in here...
+//						DataType resolvedDataType = ((DataElementUse)context.eContainer()).resolveDataType();
+//						if (resolvedDataType instanceof StructuredDataType) {
+//							IScope scope = Scopes.scopeFor(((StructuredDataType)resolvedDataType).allMembers());
+//							return scope;
+//						}
+//					}
+//				} else if (context.eContainer() instanceof LiteralValueUse) {
+//					DataType resolvedDataType = ((LiteralValueUse)context.eContainer()).resolveDataType();
 //					if (resolvedDataType instanceof StructuredDataType) {
 //						IScope scope = Scopes.scopeFor(((StructuredDataType)resolvedDataType).allMembers());
 //						return scope;
 //					}
-				} else {
-				}
+//				} else if (context.eContainer() instanceof CastDataUse) {
+//					DataType resolvedDataType = ((CastDataUse)context.eContainer()).resolveDataType();
+//					if (resolvedDataType instanceof StructuredDataType) {
+//						IScope scope = Scopes.scopeFor(((StructuredDataType)resolvedDataType).allMembers());
+//						return scope;
+//					}
+//				} else if (context.eContainer() instanceof PredefinedFunctionCall) {
+////					DataType resolvedDataType = ((PredefinedFunctionCall)context.eContainer()).resolveDataType();
+////					if (resolvedDataType instanceof StructuredDataType) {
+////						IScope scope = Scopes.scopeFor(((StructuredDataType)resolvedDataType).allMembers());
+////						return scope;
+////					}
+//				} else {
+//				}
 			} else if (context instanceof ValueAssignment) {
 				IScope scope = Scopes.scopeFor(((ProcedureCall)context.eContainer().eContainer()).getSignature().getParameter());
 				return scope;
diff --git a/plugins/org.etsi.mts.tdl.model/model/tdl.ecore b/plugins/org.etsi.mts.tdl.model/model/tdl.ecore
index ccb0a635..57758551 100644
--- a/plugins/org.etsi.mts.tdl.model/model/tdl.ecore
+++ b/plugins/org.etsi.mts.tdl.model/model/tdl.ecore
@@ -194,7 +194,7 @@
   <eClassifiers xsi:type="ecore:EClass" name="DataUse" abstract="true" eSuperTypes="#//Element">
     <eOperations name="resolveDataType" eType="#//DataType">
       <eAnnotations source="http://www.eclipse.org/emf/2002/Ecore/OCL/Pivot">
-        <details key="body" value="&#xA;                    self.resolveBaseDataType()&#xA;                "/>
+        <details key="body" value="&#xA;            &#x9;if (self.reduction->isEmpty()) then&#xA;                    self.resolveBaseDataType()&#xA;            &#x9;else&#xA;            &#x9;&#x9;self.reduction->last().member.dataType&#xA;                endif"/>
       </eAnnotations>
     </eOperations>
     <eOperations name="resolveBaseDataType" eType="#//DataType">
-- 
GitLab