Commit 6eab94f3 authored by Daniel Honsel's avatar Daniel Honsel
Browse files

improved type resolution

parent 997ca666
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -14,9 +14,17 @@ ConstDef:
Type:
	pre=PredefinedType | ref=TypeReference extensions+=ExtendedFieldReference*;

TypeReferenceTailType:
	ReferencedType | FieldReference;
	
TypeReferenceTail:
	DOT type=[TypeReferenceTailType|IDENTIFIER] array=ArrayOrBitRef? tail=TypeReferenceTail?;

TypeReference:
	head=[ReferencedType|IDENTIFIER] (DOT field=[FieldReference|IDENTIFIER])? array=ArrayOrBitRef? (DOT
	tail=TypeReference)?;
	head=[ReferencedType|IDENTIFIER] tail=TypeReferenceTail?;

SpecTypeElement:
	TypeReference | TypeReferenceTail;

ArrayDef:
	(SQUAREOPEN expr+=SingleExpression (RANGEOP range+=SingleExpression)? SQUARECLOSE)+;
@@ -130,6 +138,7 @@ IdentifierListOrAllWithExcept:
AllWithExcept:
	{AllWithExcept} ALLKEYWORD (EXCEPTKEYWORD idList=IdentifierList)?;
				

ImportTypeDefSpec:
	TYPEDEFKEYWORD idOrAll=IdentifierListOrAllWithExcept;

+14 −8
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ import org.eclipse.emf.ecore.EObject
import org.eclipse.xtext.scoping.IScope

import static org.eclipse.xtext.scoping.Scopes.*
import de.ugoe.cs.swe.tTCN3.TypeReferenceTail

class TTCN3ScopeHelper {

@@ -384,8 +385,8 @@ class TTCN3ScopeHelper {
		}
	}
	
	def static Iterable<RefValueElement> scopeReferencedFields(ReferencedType type) {
		val List<RefValueElement> list = newArrayList
	def static Iterable<EObject> scopeReferencedFields(ReferencedType type) {
		val List<EObject> list = newArrayList
		val ReferencedType originalType = findOriginalType(type)

		if (originalType == null)
@@ -409,7 +410,7 @@ class TTCN3ScopeHelper {
		return list		
	}	
	
	def static Iterable<RefValueElement> scopeReferencedFields(TypeReference type) {
	def static Iterable<EObject> scopeReferencedFields(TypeReference type) {
		scopeReferencedFields(getReferencedType(type))
	}

@@ -503,16 +504,21 @@ class TTCN3ScopeHelper {
		if (reference == null)
			return null;

		var TypeReference ref = reference
		var ReferencedType type = ref.head
		var TypeReferenceTail tail = reference.tail
		var ReferencedType type = reference.head

		if (type == null) {
			return type;
		}

		while (ref.tail != null) {
			ref = ref.tail
			type = ref.head
		while (tail != null) {
			val t = tail.type
			if (t instanceof ReferencedType) {
				type = t
				tail = tail.tail
			} else {
				tail = null
			}
		}

		return type;
+100 −22
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import de.ugoe.cs.swe.tTCN3.SingleConstDef
import de.ugoe.cs.swe.tTCN3.SingleTempVarInstance
import de.ugoe.cs.swe.tTCN3.SingleVarInstance
import de.ugoe.cs.swe.tTCN3.SpecElement
import de.ugoe.cs.swe.tTCN3.SpecTypeElement
import de.ugoe.cs.swe.tTCN3.StartTimerStatement
import de.ugoe.cs.swe.tTCN3.StatementBlock
import de.ugoe.cs.swe.tTCN3.StructFieldDef
@@ -53,6 +54,8 @@ 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.TypeReference
import de.ugoe.cs.swe.tTCN3.TypeReferenceTail
import de.ugoe.cs.swe.tTCN3.TypeReferenceTailType
import de.ugoe.cs.swe.tTCN3.UnionFieldDef
import de.ugoe.cs.swe.tTCN3.VarInstance
import java.util.ArrayList
@@ -67,8 +70,6 @@ import static org.eclipse.xtext.scoping.Scopes.*

import static extension de.ugoe.cs.swe.common.TTCN3ScopeHelper.*
import static extension org.eclipse.xtext.EcoreUtil2.*
import org.eclipse.xtend.typesystem.emf.EcoreUtil2
import de.ugoe.cs.swe.tTCN3.SubTypeDefNamed

class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
	private final static Logger LOG = Logger.getLogger(TTCN3LocalScopeProvider);
@@ -77,7 +78,7 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
		spec.scopeFieldExpressionList
	}

	private def Iterable<RefValueElement> scopeFieldReferences(FieldReference fieldRef) {
	private def Iterable<EObject> scopeFieldReferences(FieldReference fieldRef) {
		if (fieldRef instanceof StructFieldDef) {
			if (fieldRef.type != null && fieldRef.type.ref != null) {
				fieldRef.type.ref.scopeReferencedFields
@@ -181,7 +182,7 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
		scopeFor(list)
	}

	private def Iterable<RefValueElement> scopeListFieldExpressionList(EObject field) {
	private def Iterable<EObject> scopeListFieldExpressionList(EObject field) {
		val inlineTemplate = field.findDesiredParent(InLineTemplate)
		val template = field.findDesiredParent(TemplateDef)
		val variable = field.findDesiredParent(VarInstance)
@@ -190,7 +191,7 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
		val sField = field.findDesiredParent(FieldSpec)
		val constDef = field.findDesiredParent(ConstDef)
		val hasArrayAsParent = field.findDesiredParent(ArrayExpression) != null
		var ArrayList<RefValueElement> list = newArrayList
		var ArrayList<EObject> list = newArrayList
		var nestedFields = newArrayList

		if (eField != null) {
@@ -226,7 +227,7 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
		return list
	}

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

		for (d : scope) {
@@ -453,16 +454,93 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
		scopeFor(list, pRef.scope_communicationPort)
	}
	
	def IScope scope_TypeReference_field(TypeReference tr, EReference ref) {
		//TODO: test other nested possibilities
		if (!(tr.head instanceof TTCN3Module))
			scopeFor(tr.head.scopeReferencedFields)
	def IScope scope_TypeReferenceTail_type(
		TypeReferenceTail it,
		EReference ref
	) {
		scopeFor((eContainer as SpecTypeElement).directTypeElements)
	}	
	
	// TODO: consider all possible cases! Types, Modules(?), Fields, etc.
	// TODO: consider special treatment for SubTypeDefNamed
	private def dispatch Iterable<EObject> directTypeElements(ReferencedType it) {
		switch it {
			TTCN3Module: directModuleTypes
			GroupDef: directGroupTypes
			ReferencedType: scopeReferencedFields
		}
	}	
		
	// TODO: consider special treatment for SubTypeDefNamed
	private def dispatch Iterable<EObject> directTypeElements(TypeReferenceTailType it) {
		switch it {
			GroupDef: directGroupTypes
			FieldReference: directFieldTypeElements
		}
	}	
	
	private def dispatch Iterable<EObject> directTypeElements(SpecTypeElement it) {
		switch it {
			TypeReference: head.directTypeElements
			TypeReferenceTail: type.directTypeElements
		}
	}	
	
	def IScope scope_TypeReference_head(TypeReference tr, EReference ref) {
		// TODO: fix me!
	private def Iterable<EObject> directModuleTypes(TTCN3Module it) {
		val List<EObject> list = newArrayList
		list.addAll(eAllOfType(ReferencedType))
		list.addAll(eAllOfType(GroupDef))
		list
	}
	
	private def Iterable<EObject> directGroupTypes(GroupDef it) {
		val List<EObject> res = newArrayList
		if (list == null)
			return res

		for (ModuleDefinition g : list.definitions) {
			val elt = g.def
			if (elt instanceof GroupDef) {
				res.add(elt)
			} else if (elt instanceof ReferencedType) {
				res.add(elt)
			}
 		}
		return res
	}	
	
	
	
	private def Iterable<EObject> directFieldTypeElements(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
			}
		} else if (field instanceof FormalTemplatePar) {
			if (field.type != null) {
				field.type.ref.scopeReferencedFields
			}
		} else if (field instanceof UnionFieldDef) {
			if (field.type != null) {
				field.type.ref.scopeReferencedFields
			}
		}
	}	
	
//	def IScope scope_TypeReference_field(TypeReference tr, EReference ref) {
//		//TODO: test other nested possibilities
//		if (!(tr.head instanceof TTCN3Module && tr.tail == null))
//			scopeFor(tr.head.scopeReferencedFields)
//	}
//
//	def IScope scope_TypeReference_head(TypeReference tr, EReference ref) {
//		// TODO: fix me!
//	}

	def IScope scope_Head_target(Head value, EReference ref) {
		value.scope_ReferencedValueHead(ref)
	}
@@ -539,7 +617,7 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
		scopeFor((eContainer as SpecElement).directElements)
	}

	private def dispatch Iterable<RefValueElement> directElements(RefValueElement it) {
	private def dispatch Iterable<EObject> directElements(RefValueElement it) {
		switch it {
			FieldReference: directFieldElements
			RefValue: directValueElements
@@ -547,21 +625,21 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
		}
	}

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

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

	private def Iterable<RefValueElement> directValueElements(RefValue value) {
	private def Iterable<EObject> directValueElements(RefValue value) {
		if (value instanceof SingleTempVarInstance) {
			val variable = value.findDesiredParent(VarInstance)
			if (variable != null && variable.type.ref != null) {
@@ -603,7 +681,7 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
		}
	}

	private def Iterable<RefValueElement> directFieldElements(FieldReference field) {
	private def Iterable<EObject> directFieldElements(FieldReference field) {
		if (field instanceof StructFieldDef) {
			if (field.type != null) {
				field.type.ref.scopeReferencedFields
@@ -623,8 +701,8 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
		}
	}

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