Commit cac47e2b authored by Philip Makedonski's avatar Philip Makedonski
Browse files

+ store template modifier property in return type

+ improved ExtendedFieldReference resolution with function references, #21
parent be0b6f5c
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -239,6 +239,7 @@ SUTStatements:
ActionText:
	{ActionText} FREE_TEXT | expr=Expression;

//TODO: this is massively ambiguous
BehaviourStatements:
	testcase=TestcaseInstance | function=FunctionInstance | return=ReturnStatement | alt=AltConstruct |
	interleaved=InterleavedConstruct | label=LabelStatement | goto=GotoStatement | {BehaviourStatements} REPEATSTATEMENT
@@ -1314,7 +1315,7 @@ RunsOnSpec:
	RUNSKEYWORD ONKEYWORD component=[ComponentDef|QualifiedIdentifier];

ReturnType:
	RETURNKEYWORD (TEMPLATEKEYWORD | RestrictedTemplate)? type=Type;
	RETURNKEYWORD (template=TEMPLATEKEYWORD | restricted=RestrictedTemplate)? type=Type;

	//TODO: try to remove extra=ExtraMatchingAttributes? from this rule 
Assignment:
+46 −2
Original line number Diff line number Diff line
@@ -79,6 +79,8 @@ import org.eclipse.emf.ecore.EClass
import de.ugoe.cs.swe.tTCN3.ExtendedFieldReference
import de.ugoe.cs.swe.tTCN3.ReferencedValue
import java.util.HashMap
import de.ugoe.cs.swe.tTCN3.OpCall
import de.ugoe.cs.swe.tTCN3.FunctionRef

//TODO: switch to TTCN3LocalScopeProvider as base class?
class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
@@ -680,12 +682,47 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
	def IScope scope_ExtendedFieldReference_field(ExtendedFieldReference it, EReference ref) {
		val list = newArrayList();
		//TODO: also tail?
		val target = ((eContainer as ReferencedValue).head.target as RefValue)
		//root
		if (eContainer instanceof OpCall) {
			var target = ((eContainer as OpCall).function.ref as RefValue)
			val fields = (eContainer as OpCall).extendedFunction
			//TODO: identical as below, reuse
			val index =	fields.indexOf(it)
			target = getParentFieldTarget(target, fields, index)
			list.addAll(target.directValueElements)
						
		} else {
			//TODO: check for type?
			var target = ((eContainer as ReferencedValue).head.target as RefValue)
			
			//handle deeper nesting through indices
			//TODO: may need optimisation / caching
			val fields = (eContainer as ReferencedValue).fields
			val index =	fields.indexOf(it)
			target = getParentFieldTarget(target, fields, index)
			list.addAll(target.directValueElements)
		}
		val s = scopeFor(list)
		return s
	}
	
	private def RefValue getParentFieldTarget(RefValue target, List<ExtendedFieldReference> fields, int index) {
		if (index > 0) {
			var parentIndex = index-1
			var parentField = fields.get(parentIndex)
			if (parentField.field !== null) {
				//use as target
				return parentField.field
			} else {
				//handle array
				//recursion	
				return getParentFieldTarget(target, fields, parentIndex)	
			}
		} else {
			return target
		}
	}

	private def IScope scope_ReferencedValueHead(EObject value, EReference ref) {
		val list = newArrayList();

@@ -701,6 +738,8 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
				}
			}
			scopeFor(list, delegate.getScope(value, ref))
			//TODO: use when switching to TTCN3LocalScopeProvider as base class
//			scopeFor(list, getScope(value, ref))
		} else if (value instanceof StatementBlock) {
			value.scopeStatementBlock(list)
			scopeFor(list, value.eContainer.scope_ReferencedValueHead(ref))
@@ -822,6 +861,11 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
			if (variable.type.ref !== null) {
				variable.type.ref.scopeReferencedFields
			}
        } else if (value instanceof FunctionDef) {
        	if (value.returnType.type.ref !== null) {
	        	value.returnType.type.ref.scopeReferencedFields
        	}
        	
        } else if (value instanceof NamedObject) {
            val variable = value.findDesiredParent(ExtConstDef)
            if (variable.type.ref !== null) {