Commit 0dcaecc4 authored by Daniel Honsel's avatar Daniel Honsel
Browse files

improved scoping of referenced fields and groups

parent 5360f3d9
Loading
Loading
Loading
Loading
+21 −6
Original line number Diff line number Diff line
@@ -1051,11 +1051,30 @@ Value:
	predef=PredefinedValue | ref=ReferencedValue;

ReferencedValue:
	ref=[RefValue|QualifiedIdentifier] fieldRefs+=ExtendedFieldReference*;
	Head fields+=ExtendedFieldReference*;

RefValueHead:
	RefValue | GroupDef;
	
RefValueElement:
	RefValue | GroupDef | FieldReference;
	
Head:
	target=[RefValueHead|IDENTIFIER] tail=RefValueTail?;
		
RefValueTail:
	DOT value=[RefValueElement|IDENTIFIER] tail=RefValueTail?;

SpecElement:
	Head | RefValueTail;

ExtendedFieldReference:
	DOT (field=[FieldReference|IDENTIFIER] | type=PredefinedType) | array=ArrayOrBitRef | {ExtendedFieldReference}
	SQUAREOPEN MINUS SQUARECLOSE;

RefValue:
	SingleConstDef | ModuleParameter | FieldReference | FormalTemplatePar | SingleTempVarInstance | Enumeration |
	FunctionRef | TimerVarInstance | FormalPortPar;
	FunctionRef | TimerVarInstance | FormalPortPar | BaseTemplate;

	// IDENTIFIER omitted
PredefinedValue:
@@ -1165,10 +1184,6 @@ ReadTimerOp:
PermutationMatch:
	PERMUTATIONKEYWORD list=ListOfTemplates;

ExtendedFieldReference:
	DOT (field=[FieldReference|IDENTIFIER] | type=PredefinedType) | array=ArrayOrBitRef | {ExtendedFieldReference}
	SQUAREOPEN MINUS SQUARECLOSE;

LoopConstruct:
	forStm=ForStatement | whileStm=WhileStatement | doStm=DoWhileStatement;

+6 −2
Original line number Diff line number Diff line
@@ -55,6 +55,8 @@ import de.ugoe.cs.swe.tTCN3.FunctionDef
import static org.eclipse.xtext.scoping.Scopes.*
import de.ugoe.cs.swe.tTCN3.TestcaseDef
import de.ugoe.cs.swe.tTCN3.InLineTemplate
import de.ugoe.cs.swe.tTCN3.RefValueElement
import java.util.List

class TTCN3ScopeHelper {

@@ -339,7 +341,8 @@ class TTCN3ScopeHelper {
		}
	}

	def static void scopeReferencedFields(ReferencedType type, ArrayList<EObject> list) {
	def static Iterable<RefValueElement> scopeReferencedFields(ReferencedType type) {
		val List<RefValueElement> list = newArrayList
		if (type instanceof RecordDefNamed) {
			type.body.scopeFieldsStructDefBody(list)
		} else if (type instanceof SetDefNamed) {
@@ -349,9 +352,10 @@ class TTCN3ScopeHelper {
		} else if (type instanceof SetOfDefNamed) {
			//TODO: implement!
		}
		return list
	}

	def static void scopeFieldsStructDefBody(StructDefBody body, ArrayList<EObject> list) {
	def static void scopeFieldsStructDefBody(StructDefBody body, List<RefValueElement> list) {
		for (StructFieldDef f : body.defs) {
			list.add(f)
		}
+115 −282
Original line number Diff line number Diff line
@@ -4,23 +4,37 @@ import de.ugoe.cs.swe.tTCN3.AltstepDef
import de.ugoe.cs.swe.tTCN3.AltstepLocalDef
import de.ugoe.cs.swe.tTCN3.ComponentDef
import de.ugoe.cs.swe.tTCN3.ComponentDefList
import de.ugoe.cs.swe.tTCN3.ConstDef
import de.ugoe.cs.swe.tTCN3.ControlStatementOrDefList
import de.ugoe.cs.swe.tTCN3.FieldExpressionSpec
import de.ugoe.cs.swe.tTCN3.FieldSpec
import de.ugoe.cs.swe.tTCN3.FormalTimerPar
import de.ugoe.cs.swe.tTCN3.FormalValuePar
import de.ugoe.cs.swe.tTCN3.FunctionDef
import de.ugoe.cs.swe.tTCN3.GroupDef
import de.ugoe.cs.swe.tTCN3.Head
import de.ugoe.cs.swe.tTCN3.InLineTemplate
import de.ugoe.cs.swe.tTCN3.ModuleControlBody
import de.ugoe.cs.swe.tTCN3.ModuleDefinition
import de.ugoe.cs.swe.tTCN3.ModulePar
import de.ugoe.cs.swe.tTCN3.ModuleParDef
import de.ugoe.cs.swe.tTCN3.ModuleParameter
import de.ugoe.cs.swe.tTCN3.PortOrAny
import de.ugoe.cs.swe.tTCN3.PortRef
import de.ugoe.cs.swe.tTCN3.RefValue
import de.ugoe.cs.swe.tTCN3.RefValueHead
import de.ugoe.cs.swe.tTCN3.RefValueTail
import de.ugoe.cs.swe.tTCN3.SendStatement
import de.ugoe.cs.swe.tTCN3.SingleVarInstance
import de.ugoe.cs.swe.tTCN3.SpecElement
import de.ugoe.cs.swe.tTCN3.StructFieldDef
import de.ugoe.cs.swe.tTCN3.TemplateDef
import de.ugoe.cs.swe.tTCN3.TestcaseDef
import de.ugoe.cs.swe.tTCN3.TimerRefOrAny
import de.ugoe.cs.swe.tTCN3.VarInstance
import java.util.List
import org.eclipse.emf.ecore.EReference
import org.eclipse.xtend.typesystem.Feature
import org.eclipse.xtext.scoping.IScope
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider

@@ -28,7 +42,10 @@ import static org.eclipse.xtext.scoping.Scopes.*

import static extension de.ugoe.cs.swe.common.TTCN3ScopeHelper.*
import static extension org.eclipse.xtext.EcoreUtil2.*
import de.ugoe.cs.swe.tTCN3.InLineTemplate
import de.ugoe.cs.swe.tTCN3.RefValueElement
import de.ugoe.cs.swe.tTCN3.FieldReference
import de.ugoe.cs.swe.tTCN3.SingleTempVarInstance
import de.ugoe.cs.swe.tTCN3.BaseTemplate

class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {

@@ -55,21 +72,22 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
			val fieldRef = field.ref
			if (fieldRef instanceof StructFieldDef) {
				if (fieldRef.type != null && fieldRef.type.ref != null) {
					fieldRef.type.ref.scopeReferencedFields(list)
					scopeFor(fieldRef.type.ref.scopeReferencedFields)
				}
			} else if (field.ref instanceof FormalValuePar) {
				if (fieldRef.type != null && fieldRef.type.ref != null) {
					fieldRef.type.ref.scopeReferencedFields(list)
					scopeFor(fieldRef.type.ref.scopeReferencedFields)
				}
			}
		} else if (inlineTemplate != null) {
			inlineTemplate.templateFieldScope(list)
			scopeFor(list)
		} else if (template != null) {
			template.templateFieldScope(list)
			scopeFor(list)
		} else if (variable != null && variable.type.ref != null) {
			variable.type.ref.scopeReferencedFields(list)
			scopeFor(variable.type.ref.scopeReferencedFields)
		}
		scopeFor(list)
	}

	def IScope scope_FieldExpressionSpec_fieldRef(FieldExpressionSpec field, EReference ref) {
@@ -83,21 +101,22 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
			val fieldRef = cField.fieldRef
			if (fieldRef instanceof StructFieldDef) {
				if (fieldRef.type != null && fieldRef.type.ref != null) {
					fieldRef.type.ref.scopeReferencedFields(list)
					scopeFor(fieldRef.type.ref.scopeReferencedFields)
				}
			} else if (cField.fieldRef instanceof FormalValuePar) {
				if (fieldRef.type != null && fieldRef.type.ref != null) {
					fieldRef.type.ref.scopeReferencedFields(list)
					scopeFor(fieldRef.type.ref.scopeReferencedFields)
				}
			}
		} else if (inlineTemplate != null) {
			inlineTemplate.templateFieldScope(list)
			scopeFor(list)
		} else if (template != null) {
			template.templateFieldScope(list)
			scopeFor(list)
		} else if (variable != null && variable.type.ref != null) {
			variable.type.ref.scopeReferencedFields(list)
			scopeFor(variable.type.ref.scopeReferencedFields)
		}
		scopeFor(list)
	}

	def IScope scope_TimerRefOrAny_ref(TimerRefOrAny variable, EReference ref) {
@@ -234,277 +253,91 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
		scopeFor(list)
	}

	def IScope scope_RefValueTail_value(RefValueTail it, EReference ref) {
		scopeFor((eContainer as SpecElement).directElements)
	}

	private def Iterable<RefValueElement> directElements(RefValueElement it) {
		switch it {
			FieldReference: directFieldElements
			RefValue: directValueElements
			GroupDef: directGroupElements
		}
	}

	private def Iterable<RefValueElement> directElements(RefValueHead it) {
		switch it {
			GroupDef: directGroupElements
			RefValue: directValueElements
		}
	}

	private def Iterable<RefValueElement> directElements(SpecElement it) {
		switch it {
			Head: target.directElements
			RefValueTail: value.directElements
		}
	}

	private def Iterable<RefValueElement> directValueElements(RefValue template) {
		if (template instanceof SingleTempVarInstance) {
			val variable = template.findDesiredParent(VarInstance)
			if (variable != null && variable.type.ref != null) {
				variable.type.ref.scopeReferencedFields
			}
		} else if (template instanceof BaseTemplate) {
			template.type.ref.scopeReferencedFields
		}
	}

	private def Iterable<RefValueElement> directFieldElements(FieldReference field) {
		if (field instanceof StructFieldDef) {
			if (field.type != null) {
				field.type.ref.scopeReferencedFields
			}
		} else if (field instanceof FormalValuePar) {
			if (field.type != null) {
				field.type.ref.scopeReferencedFields
			}
		}
	}

	private def Iterable<RefValueElement> directGroupElements(GroupDef it) {
		val List<RefValueElement> res = newArrayList
		if (it.list == null)
			return res

		for (ModuleDefinition g : it.list.definitions) {
			val elt = g.def
			if (elt instanceof GroupDef) {
				res.add(elt)
			} else if (elt instanceof ConstDef) {
				res.addAll(elt.defs.list)
			} else if (elt instanceof ModuleParDef) {
				res.addAll(elt.directModulePrams)
			} else if (elt instanceof FunctionDef) {
				res.add(elt)
			} else if (elt instanceof TemplateDef) {
				res.add(elt.base)
			}
		}
		return res
	}

	private def Iterable<RefValue> directModulePrams(ModuleParDef it) {
		val list = newArrayList
		if (it.param != null) {
			for (ModuleParameter p : it.param.list.params) {
				list.add(p)
			}
		} else if (it.multitypeParam != null) {
			for (ModulePar p : it.multitypeParam.params) {
				for (ModuleParameter pa : p.list.params) {
					list.add(pa)
				}
			}
		}
		return list
	}

}
/**
 * old stuff...
 */
//	def IScope scope_ReferencedValue_ref(ReferencedValue value, EReference ref) {
//		val list = newArrayList();
//		var parent = value.eContainer
//
//		while (parent != null) {
//			if (parent instanceof TTCN3Module) {
//				parent.defs.scopeModuleVariable(list)
//				for (ModuleDefinition g : parent.defs.definitions.filter[it.def instanceof GroupDef]) {
//					val GroupDef group = g.def as GroupDef
//					if (group.list != null) {
//						group.list.scopeModuleVariable(list)
//					}
//				}
//			} else if (parent instanceof StatementBlock) {
//				parent.scopeStatementBlock(list)
//			} else if (parent instanceof Initial) {
//				parent.scopeInitial(list)
//			} else if (parent instanceof ForStatement) {
//				parent.init.scopeInitial(list)
//			} else if (parent instanceof FunctionDef) {
//				if(parent.parameterList != null) parent.parameterList.scopeFunctionParameterValue(list)
//				if (parent.runsOn != null) {
//					parent.runsOn.component.componentScopeValueRefs(list, false, true)
//				}
//			} else if (parent instanceof ModuleControlPart) {
//				parent.scopeModuleControlPart(list)
//			} else if (parent instanceof ComponentDef) {
//				parent.componentScopeValueRefs(list, false, true)
//			} else if (parent instanceof TestcaseDef) {
//				val ComponentDef comp = parent.spec.runsOn.component
//				parent.parList.scopeTemplateOrValueFormalParList(list)
//				comp.componentScopeValueRefs(list, false, true)
//			} else if (parent instanceof AltstepDef) {
//				if (parent.params != null) {
//					parent.params.scopeFunctionParameterValue(list)
//				}
//				parent.scopeAltstepExtendedDefList(list)
//				parent.local.scopeAltstepLocalDefList(list)
//			} else if (parent instanceof GroupDef) {
//				parent.list.scopeModuleVariable(list)
//			} else if (parent instanceof ModuleParDef) {
//				parent.scopeModuleParDef(list)
//			} else if (parent instanceof TemplateDef) {
//				parent.scopeTemplateParameter(list)
//			}
//			parent = parent.eContainer
//
//		}
//		scopeFor(list, value.polymorphicFindScopeForClassName(ref))
//	}
//
//	def IScope scope_ReferencedType(ReferencedType type, EReference ref) {
//		val module = type.findDesiredParent(typeof(TTCN3Module)) as TTCN3Module
//		val list = newArrayList
//
//		if (module.defs != null) {
//			module.defs.scopeModuleTypes(list, false)
//
//			for (ModuleDefinition g : module.defs.definitions.filter[it.def instanceof GroupDef]) {
//				val GroupDef group = g.def as GroupDef
//				if (group.list != null) {
//					group.list.scopeModuleTypes(list, false)
//				}
//			}
//		}
//		scopeFor(list, type.polymorphicFindScopeForClassName(ref))
//	}
//
//	def IScope scope_ComponentDef_extends(ComponentDef component, EReference ref) {
//		val container = component.findDesiredParent(typeof(ModuleDefinitionsList)) as ModuleDefinitionsList
//		val inner = newArrayList
//
//		for (ModuleDefinition d : container.definitions.filter[
//			it.def != null && it.def instanceof TypeDef && (it.def as TypeDef).body.structured.component != null]) {
//
//			val comp = (d.def as TypeDef).body.structured.component as ComponentDef
//
//			if (component != comp) {
//				inner.add(comp)
//			}
//		}
//		scopeFor(inner)
//	}
//
//	def IScope scope_FieldSpec_ref(FieldSpec spec, EReference ref) {
//		val template = spec.findDesiredParent(typeof(TemplateDef)) as TemplateDef
//		val variable = spec.findDesiredParent(typeof(VarInstance)) as VarInstance
//		val field = spec.findDesiredParent(typeof(FieldSpec)) as FieldSpec
//		val list = newArrayList
//		if (field != null) {
//			val fieldRef = field.ref
//			if (fieldRef instanceof StructFieldDef) {
//				if (fieldRef.type != null && fieldRef.type.ref != null) {
//					fieldRef.type.ref.scopeReferencedFields(list)
//				}
//			} else if (field.ref instanceof FormalValuePar) {
//				if (fieldRef.type != null && fieldRef.type.ref != null) {
//					fieldRef.type.ref.scopeReferencedFields(list)
//				}
//			}
//		} else if (template != null) {
//			template.templateFieldScope(list)
//		} else if (variable != null && variable.type.ref != null) {
//			variable.type.ref.scopeReferencedFields(list)
//		}
//		scopeFor(list)
//	}
//
//	def IScope scope_FieldExpressionSpec_fieldRef(FieldExpressionSpec field, EReference ref) {
//		val template = field.findDesiredParent(typeof(TemplateDef)) as TemplateDef
//		val variable = field.findDesiredParent(typeof(VarInstance)) as VarInstance
//		val cField = field.findDesiredParent(typeof(FieldExpressionSpec)) as FieldExpressionSpec
//		val list = newArrayList
//
//		if (cField != null) {
//			val fieldRef = cField.fieldRef
//			if (fieldRef instanceof StructFieldDef) {
//				if (fieldRef.type != null && fieldRef.type.ref != null) {
//					fieldRef.type.ref.scopeReferencedFields(list)
//				}
//			} else if (cField.fieldRef instanceof FormalValuePar) {
//				if (fieldRef.type != null && fieldRef.type.ref != null) {
//					fieldRef.type.ref.scopeReferencedFields(list)
//				}
//			}
//		} else if (template != null) {
//			template.templateFieldScope(list)
//		} else if (variable != null && variable.type.ref != null) {
//			variable.type.ref.scopeReferencedFields(list)
//		}
//		scopeFor(list)
//	}
//
//	def IScope scope_TimerRefOrAny_ref(TimerRefOrAny variable, EReference ref) {
//		val list = newArrayList
//		var parent = variable.eContainer
//
//		while (parent != null) {
//			if (parent instanceof AltstepDef) {
//				if (parent.spec != null) {
//					componentScopeValueRefs(parent.spec.component, list, true, false)
//				}
//				for (AltstepLocalDef d : parent.local.defs) {
//					if (d.timer != null) {
//						for (SingleVarInstance v : d.timer.list.variables) {
//							list.add(v)
//						}
//					}
//				}
//			} else if (parent instanceof ComponentDef) {
//				for (ComponentDefList l : parent.defs) {
//					if (l.element.timer != null) {
//						for (SingleVarInstance v : l.element.timer.list.variables) {
//							list.add(v)
//						}
//					}
//				}
//			} else if (parent instanceof ModuleControlBody) {
//				for (ControlStatementOrDefList l : parent.list) {
//					if (l.def.localInst != null && l.def.localInst.timer != null) {
//						for (SingleVarInstance v : l.def.localInst.timer.list.variables) {
//							list.add(v)
//						}
//					}
//				}
//			}
//			parent = parent.eContainer
//		}
//		scopeFor(list)
//	}
//
//	def IScope scope_PortOrAny_ref(PortOrAny spec, EReference ref) {
//		val altstep = spec.findDesiredParent(typeof(AltstepDef)) as AltstepDef
//		val inner = newArrayList
//
//		if (altstep.spec != null) {
//			componentScopePorts(altstep.spec.component, inner)
//		}
//		scopeFor(inner)
//	}
//
//	def IScope scope_SendStatement_port(SendStatement stm, EReference ref) {
//		val list = newArrayList
//
//		// ports from parent function
//		val function = stm.findDesiredParent(typeof(FunctionDef)) as FunctionDef
//		if (function.runsOn != null) {
//			function.runsOn.component.componentScopePorts(list)
//		}
//		scopeFor(list)
//	}
//
//	def IScope scope_PortRef_port(PortRef pRef, EReference ref) {
//		val testcase = pRef.findDesiredParent(typeof(TestcaseDef)) as TestcaseDef
//		val list = newArrayList
//
//		if (pRef.component.mtc != null) {
//			testcase.spec.runsOn.component.componentScopePorts(list)
//		} else if (pRef.component.system != null) {
//			if (testcase.spec.systemSpec != null) {
//				testcase.spec.systemSpec.component.componentScopePorts(list)
//			}
//		}
//		scopeFor(list)
//	}
//
//	def IScope scope_ExtendedFieldReference_field(ExtendedFieldReference ext, EReference ref) {
//		val value = ext.findDesiredParent(typeof(ReferencedValue)) as ReferencedValue
//		val list = newArrayList
//		val idx = value.fieldRefs.indexOf(ext)
//		val template = value.ref
//
//		if (idx == 0) {
//			if (template instanceof SingleTempVarInstance) {
//				val variable = template.findDesiredParent(typeof(VarInstance)) as VarInstance
//				if (variable != null && variable.type.ref != null) {
//					variable.type.ref.scopeReferencedFields(list)
//				}
//			} else if (template instanceof BaseTemplate) {
//				template.type.ref.scopeReferencedFields(list)
//			}
//		} else {
//			val parent = value.fieldRefs.get(idx - 1)
//			if (parent.field instanceof StructFieldDef) {
//				if (parent.field.type != null) {
//					parent.field.type.ref.scopeReferencedFields(list)
//				}
//			} else if (parent.field instanceof FormalValuePar) {
//				if (parent.field.type != null) {
//					parent.field.type.ref.scopeReferencedFields(list)
//				}
//			}
//		}
//		scopeFor(list)
//	}
//
//	def IScope scope_PortInstance_ref(PortInstance port, EReference ref) {
//		val module = port.findDesiredParent(typeof(TTCN3Module)) as TTCN3Module
//		val list = newArrayList
//
//		if (module.defs != null) {
//			module.defs.scopeModuleTypes(list, true)
//
//			for (ModuleDefinition g : module.defs.definitions.filter[it.def instanceof GroupDef]) {
//				val GroupDef group = g.def as GroupDef
//				if (group.list != null) {
//					group.list.scopeModuleTypes(list, true)
//				}
//			}
//		}
//		scopeFor(list)
//	}
//
//	def IScope scope_Type_ref(Type type, EReference ref) {
//		val module = type.findDesiredParent(typeof(TTCN3Module)) as TTCN3Module
//		val list = newArrayList
//
//		if (module.defs != null) {
//			module.defs.scopeModuleTypes(list, false)
//
//			for (ModuleDefinition g : module.defs.definitions.filter[it.def instanceof GroupDef]) {
//				val GroupDef group = g.def as GroupDef
//				if (group.list != null) {
//					group.list.scopeModuleTypes(list, false)
//				}
//			}
//		}
//		scopeFor(list, type.polymorphicFindScopeForClassName(ref))
//	}
//}