Commit 89006625 authored by Daniel Honsel's avatar Daniel Honsel
Browse files

improved scoping

parent 93d1e7a1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1151,6 +1151,7 @@ DefOrFieldRefList:
	refs+=DefOrFieldRef (COMMA refs+=DefOrFieldRef)*;

	// TODO: restrict references to some QID
	// TODO: check this rule
DefOrFieldRef:
	id=[TTCN3Reference|QualifiedIdentifier] | (field=FieldReference | {DefOrFieldRef} SQUAREOPEN MINUS SQUARECLOSE)
	extended=ExtendedFieldReference? | all=AllRef;
+8 −4
Original line number Diff line number Diff line
@@ -391,8 +391,9 @@ class TTCN3ScopeHelper {
		return list
	}

	def static void templateFieldScope(TemplateDef template, ArrayList<EObject> list) {
	def static IScope templateFieldScope(TemplateDef template) {
		val type = findOriginalType(getReferencedType((template.base.type.ref)))
		val list = newArrayList

		if (type != null && typeof(RecordDefNamed).isAssignableFrom(type.class)) {
			list.addAll((type as RecordDefNamed).body.defs)
@@ -406,10 +407,12 @@ class TTCN3ScopeHelper {
		if (type != null && typeof(SignatureDef).isAssignableFrom(type.class)) {
			list.addAll((type as SignatureDef).paramList.params)
		}
		scopeFor(list)
	}

	def static void templateFieldScope(InLineTemplate template, ArrayList<EObject> list) {
	def static IScope templateFieldScope(InLineTemplate template) {
		val type = findOriginalType(getReferencedType((template.type.ref)))
		val list = newArrayList

		if (type != null && typeof(RecordDefNamed).isAssignableFrom(type.class)) {
			list.addAll((type as RecordDefNamed).body.defs)
@@ -423,6 +426,7 @@ class TTCN3ScopeHelper {
		if (type != null && typeof(SignatureDef).isAssignableFrom(type.class)) {
			list.addAll((type as SignatureDef).paramList.params)
		}
		scopeFor(list)
	}

	// TODO: consider nested types
+71 −11
Original line number Diff line number Diff line
@@ -62,6 +62,8 @@ 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.ArrayExpression
import org.eclipse.xtext.resource.IEObjectDescription

class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {

@@ -99,6 +101,36 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
		}
	}

	private def void scopeFieldReferences(FieldReference fieldRef, ArrayList<EObject> list) {
		if (fieldRef instanceof StructFieldDef) {
			if (fieldRef.type != null && fieldRef.type.ref != null) {
				list.addAll(fieldRef.type.ref.scopeReferencedFields)
			} else if (fieldRef.nestedType != null) {
				if (fieldRef.nestedType != null) {
					val nType = fieldRef.nestedType.findUsedType
					if (nType != null) {
						list.addAll(nType.scopeReferencedFields)
					}
				}
			}
		} else if (fieldRef instanceof FormalValuePar) {
			if (fieldRef.type != null && fieldRef.type.ref != null) {
				list.addAll(fieldRef.type.ref.scopeReferencedFields)
			}
		} else if (fieldRef instanceof UnionFieldDef) {
			if (fieldRef.type != null && fieldRef.type.ref != null) {
				list.addAll(fieldRef.type.ref.scopeReferencedFields)
			} else if (fieldRef.nestedType != null) {
				if (fieldRef.nestedType != null) {
					val nType = fieldRef.nestedType.findUsedType
					if (nType != null) {
						list.addAll(nType.scopeReferencedFields)
					}
				}
			}
		}
	}

	private def IScope scopeFieldExpressionList(EObject field) {
		val inlineTemplate = field.findDesiredParent(InLineTemplate)
		val template = field.findDesiredParent(TemplateDef)
@@ -107,35 +139,63 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
		val cField = field.findDesiredParent(FieldConstExpressionSpec)
		val sField = field.findDesiredParent(FieldSpec)
		val constDef = field.findDesiredParent(ConstDef)
		val list = newArrayList
		val hasArrayAsParent = field.findDesiredParent(ArrayExpression) != null
		var IScope scope = null
		var nestedFields = newArrayList

		if (eField != null) {
			eField.fieldRef.scopeFieldReferences
			scope = eField.fieldRef.scopeFieldReferences
		} else if (cField != null) {
			cField.fieldRef.scopeFieldReferences
			scope = cField.fieldRef.scopeFieldReferences
		} else if (sField != null) {
			sField.ref.scopeFieldReferences
			scope = sField.ref.scopeFieldReferences
		} else if (constDef != null) {
			scopeFor(constDef.type.ref.scopeReferencedFields)
			scope = scopeFor(constDef.type.ref.scopeReferencedFields)
		} else if (inlineTemplate != null) {
			inlineTemplate.templateFieldScope(list)
			scopeFor(list)
			scope = inlineTemplate.templateFieldScope
		} else if (template != null) {
			template.templateFieldScope(list)
			scopeFor(list)
			scope = template.templateFieldScope
		} else if (variable != null) {
			if (variable.type != null && variable.type.ref != null) {
				scopeFor(variable.type.ref.scopeReferencedFields)
				scope = scopeFor(variable.type.ref.scopeReferencedFields)
			} else if (variable.listType != null && variable.listType.ref != null) {
				scopeFor(variable.listType.ref.scopeReferencedFields)
				scope = scopeFor(variable.listType.ref.scopeReferencedFields)
			}
		}

		//TODO: search for a more sophisticated condition	
		if (hasArrayAsParent) {
			nestedFields.addAll(scope.allElements.findNestedFields)
		}

		if (nestedFields.size > 0) {
			return scopeFor(nestedFields, scope)
		} else {
			return scope
		}
	}

	private def Iterable<EObject> findNestedFields(Iterable<IEObjectDescription> scope) {
		val list = newArrayList

		for (d : scope) {
			val o = d.EObjectOrProxy
			if (o instanceof FieldReference) {
				o.scopeFieldReferences(list)
			}
		}

		return list
	}

	def IScope scope_FieldExpressionSpec_fieldRef(FieldExpressionSpec field, EReference ref) {
		field.scopeFieldExpressionList
	}

	// TODO: this method is never called caused by a grammar issue. 
	// The ConstantExpression branches to a SingleExpression or a CompoundConstExpression. The SingleExpression
	// could branch to CompoundExpression. Therefore, FieldExpressionList is always parsed instead of
	// FieldConstExpressionList. 
	def IScope scope_FieldConstExpressionSpec_fieldRef(FieldConstExpressionSpec field, EReference ref) {
		field.scopeFieldExpressionList
	}