Commit 5935e224 authored by Philip Makedonski's avatar Philip Makedonski
Browse files

+ addressed reference resolution issues, #18

parent 431c9f77
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ public class TTCN3RuntimeModule extends AbstractTTCN3RuntimeModule {
	}
	
	//This overrides the scope provide implementation and mixes up references
	//on the other hand it seems to be required for handling groups properly..
	//so it is needed but needs to be fixed.. 
//	@Override
//	public Class<? extends IScopeProvider> bindIScopeProvider() {
//		// TODO Auto-generated method stub
+8 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import org.eclipse.xtext.scoping.IScope
import static org.eclipse.xtext.scoping.Scopes.*
import de.ugoe.cs.swe.tTCN3.ExtConstDef
import de.ugoe.cs.swe.tTCN3.IdentifierObjectList
import de.ugoe.cs.swe.tTCN3.BaseTemplate

class TTCN3ScopeHelper {

@@ -150,6 +151,13 @@ class TTCN3ScopeHelper {
			}
		}

		//handle templates
		defs = moduleDef.definitions.filter[it.def instanceof TemplateDef]
		for (ModuleDefinition v : defs) {
			list.add((v.def as TemplateDef).base as BaseTemplate)
		}


        defs = moduleDef.definitions.filter[it.def instanceof ExtConstDef]
        for (ModuleDefinition v : defs) {
            val constDefList = (v.def as ExtConstDef).id as IdentifierObjectList
+5 −2
Original line number Diff line number Diff line
@@ -95,9 +95,12 @@ public class TTCN3GlobalScopeProvider extends AbstractGlobalScopeProvider {
			IScope scope = IScope.NULLSCOPE;
			List<IEObjectDescription> objects = Lists.newArrayList();
			
			//TODO: check performance implications, seems to be needed for GUI usage within eclipse
			synchronized (IMPORTS) {
				for (ImportData importData : IMPORTS.get(resource)) {
					objects.addAll(importData.getExportedObjects());
				}
			}
			
			if (reference == null)
				return scope;
+106 −28
Original line number Diff line number Diff line
@@ -73,9 +73,18 @@ import static extension de.ugoe.cs.swe.common.TTCN3ScopeHelper.*
import static extension org.eclipse.xtext.EcoreUtil2.*
import de.ugoe.cs.swe.tTCN3.ExtConstDef
import de.ugoe.cs.swe.tTCN3.NamedObject

import org.eclipse.xtext.TypeRef
import de.ugoe.cs.swe.tTCN3.Type
import org.eclipse.emf.ecore.EClass
import de.ugoe.cs.swe.tTCN3.ExtendedFieldReference
import de.ugoe.cs.swe.tTCN3.ReferencedValue
import java.util.HashMap

//TODO: switch to TTCN3LocalScopeProvider as base class?
class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
	final static Logger LOG = Logger.getLogger(TTCN3LocalScopeProvider);
	static HashMap<EObject, HashMap<EObject, List<EObject>>> cache = newHashMap
	static HashMap<EObject, HashMap<EObject, List<EObject>>> importedCache = newHashMap

	def IScope scope_FieldSpec_ref(FieldSpec spec, EReference ref) {
		spec.scopeFieldExpressionList
@@ -235,19 +244,9 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
		//TODO:why is this here and is it ever filtered afterwards? 
		//list.addAll(module.eAllOfType(FieldReference))

		synchronized (IMPORTS) {
			if (IMPORTS.containsKey(module.eResource)) {
				val imported = IMPORTS.get(module.eResource)
				for (i : 0 .. imported.size - 1) {
					val d = imported.get(i)
					for (o : d.exportedObjects) {
						if (TTCN3Package.eINSTANCE.fieldReference.isAssignableFrom(o.EClass)) {
							list.add(o.EObjectOrProxy)
						}
					}
				}
			}
		}
		//switched to cached version
		list.addAll(field.importedElementsOfType(TTCN3Package.eINSTANCE.fieldReference))
		
		return list
	}

@@ -499,32 +498,102 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
		    //TODO: filter for types actually used as system? 
		    val module = pRef.findDesiredParent(TTCN3Module)

			//TODO: switch to cached version
            for (ComponentDef ct : module.eAllOfType(ComponentDef)) {
                list.addAll(ct.scopeReferencedFields)
            }
            
		    //switched to cached version, fixed incorrect selection criteria
    		list.addAll(pRef.importedElementsOfType(TTCN3Package.eINSTANCE.componentDef))
		}
		scopeFor(list, pRef.scope_communicationPort)
	}

	def IScope scope_TypeReferenceTail_type(
		TypeReferenceTail it,
		EReference ref
	) {
		scopeFor((eContainer as SpecTypeElement).directTypeElements)
	}

	//partial workaround, helps with type resolution from groups and import
	//needs to be solved on a global level probably as it does not work e.g. for templates
	//need to revise scope resolution anyway.. 
	def IScope scope_TypeReference_head(
		TypeReference it,
		EReference ref
	) {
		var list = newArrayList
		list.addAll(containedElementsOfType(TTCN3Package.eINSTANCE.referencedType))
		list.addAll(importedElementsOfType(TTCN3Package.eINSTANCE.referencedType))
		var s = scopeFor(list)
		return s
	}

	//workaround for FunctionInstance->ref
	//TODO: separate issue with template references resolved as function references (likely grammar ambiguity) 
	def IScope scope_FunctionInstance_ref(FunctionInstance it, EReference ref) {
		var list = <EObject>newArrayList
		list.addAll(containedElementsOfType(TTCN3Package.eINSTANCE.functionDef))
		list.addAll(importedElementsOfType(TTCN3Package.eINSTANCE.functionDef))
		list.addAll(containedElementsOfType(TTCN3Package.eINSTANCE.extFunctionDef))
		list.addAll(importedElementsOfType(TTCN3Package.eINSTANCE.extFunctionDef))
		list.addAll(containedElementsOfType(TTCN3Package.eINSTANCE.altstepDef))
		list.addAll(importedElementsOfType(TTCN3Package.eINSTANCE.altstepDef))
		//TODO: others?
		//TODO: hack for templates, need to be parsed differently in the first place, but not sure how..
		var containedTemplates = containedElementsOfType(TTCN3Package.eINSTANCE.moduleDefinition)
			.filter[(it as ModuleDefinition).def instanceof TemplateDef]
			.map[((it as ModuleDefinition).def as TemplateDef).base]
		list.addAll(containedTemplates)
		var importedTemplates = importedElementsOfType(TTCN3Package.eINSTANCE.baseTemplate)
		list.addAll(importedTemplates)
		var s = scopeFor(list)
		return s
	}
	

	//TODO: reuse and cache
	//TODO: check in IDE.. may need to be deactivated
	//TODO: switch to this everywhere
	//TODO: reset caches?
	private def Iterable<EObject> containedElementsOfType(EObject it, EClass t) {
		var module = findDesiredParent(TTCN3Module)
		if (!LIVE && cache.get(module) !== null && cache.get(module).get(t) !== null) {
			return cache.get(module).get(t)
		}
		var list = <EObject>newArrayList
		list.addAll(module.eAllOfType(t.instanceClass as Class<? extends EObject>))
		cache.putIfAbsent(module, newHashMap)
		cache.get(module).putIfAbsent(t, list);
		return list
	}
	//TODO: reuse and cache
	//TODO: check in IDE.. may need to be deactivated
	//TODO: switch to this everywhere
	//TODO: reset caches?
	private def Iterable<EObject> importedElementsOfType(EObject it, EClass t) {
		var module = findDesiredParent(TTCN3Module)
		if (!LIVE && importedCache.get(module) !== null && importedCache.get(module).get(t) !== null) {
			return importedCache.get(module).get(t)
		}
		var list = <EObject>newArrayList
		synchronized (IMPORTS) {
			if (IMPORTS.containsKey(module.eResource)) {
				val imported = IMPORTS.get(module.eResource)
				for (i : 0 .. imported.size - 1) {
					val d = imported.get(i)
					for (o : d.exportedObjects) {
                            if (TTCN3Package.eINSTANCE.fieldReference.isAssignableFrom(ComponentDef.newInstance.eClass)) {
						if (t.isAssignableFrom(o.EClass)) {
							list.add(o.EObjectOrProxy)
						}
					}
				}
			}
		}
		}
		scopeFor(list, pRef.scope_communicationPort)
	}

	def IScope scope_TypeReferenceTail_type(
		TypeReferenceTail it,
		EReference ref
	) {
		scopeFor((eContainer as SpecTypeElement).directTypeElements)
		importedCache.putIfAbsent(module, newHashMap)
		importedCache.get(module).putIfAbsent(t, list);
		return list
	}	

	// TODO: consider all possible cases! Types, Modules(?), Fields, etc.
@@ -608,6 +677,15 @@ class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {
		return value.scope_ReferencedValueHead(ref)
	}

	def IScope scope_ExtendedFieldReference_field(ExtendedFieldReference it, EReference ref) {
		val list = newArrayList();
		//TODO: also tail?
		val target = ((eContainer as ReferencedValue).head.target as RefValue)
		list.addAll(target.directValueElements)
		val s = scopeFor(list)
		return s
	}

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