Commit 030f3582 authored by Daniel Honsel's avatar Daniel Honsel
Browse files

basic scoping for variables, needs some improvements

parent 1b2ba833
Loading
Loading
Loading
Loading
+120 −59
Original line number Diff line number Diff line
package de.ugoe.cs.swe.common

import de.ugoe.cs.swe.tTCN3.AltstepLocalDef
import de.ugoe.cs.swe.tTCN3.AltstepLocalDefList
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.ConstList
import de.ugoe.cs.swe.tTCN3.ControlStatementOrDefList
import de.ugoe.cs.swe.tTCN3.FunctionDefList
import de.ugoe.cs.swe.tTCN3.FunctionFormalPar
import de.ugoe.cs.swe.tTCN3.FunctionFormalParList
import de.ugoe.cs.swe.tTCN3.Initial
import de.ugoe.cs.swe.tTCN3.ModuleControlPart
import de.ugoe.cs.swe.tTCN3.ModuleDefinition
import de.ugoe.cs.swe.tTCN3.ModuleDefinitionsList
import de.ugoe.cs.swe.tTCN3.RefValue
import de.ugoe.cs.swe.tTCN3.SingleConstDef
import de.ugoe.cs.swe.tTCN3.SingleVarInstance
import de.ugoe.cs.swe.tTCN3.StatementBlock
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.TemplateOrValueFormalPar
import de.ugoe.cs.swe.tTCN3.TemplateOrValueFormalParList
import de.ugoe.cs.swe.tTCN3.VarList
import java.util.ArrayList
import de.ugoe.cs.swe.tTCN3.FunctionDef
import de.ugoe.cs.swe.tTCN3.FunctionFormalPar
import de.ugoe.cs.swe.tTCN3.LoopConstruct
import de.ugoe.cs.swe.tTCN3.SingleVarInstance
import org.eclipse.emf.ecore.EObject

class TTCN3ScopeHelper {

@@ -28,85 +35,139 @@ class TTCN3ScopeHelper {
			o.eContainer.findDesiredParent(t)
	}

	def static IScope moduleVariableScope(RefValue value) {
		val container = value.findDesiredParent(typeof(ModuleDefinitionsList)) as ModuleDefinitionsList
	def static void scopeModuleVariable(RefValue variable, ArrayList<EObject> list) {
		val container = variable.findDesiredParent(typeof(ModuleDefinitionsList)) as ModuleDefinitionsList

		// TODO:  || it.def instanceof ModuleParDef
		val defs = container.definitions.filter[it.def instanceof ConstDef]
		val inner = newArrayList;

		for (EObject v : defs) {
			val constDefList = ((v as ModuleDefinition).def as ConstDef).defs as ConstList
			for (EObject d : constDefList.list) {
				if(d != value) inner.add(d)
				if(d != variable) list.add(d)
			}
		}
		scopeFor(inner)
	}

	def static IScope functionVariableScope(RefValue value) {
		val container = value.findDesiredParent(typeof(FunctionDef)) as FunctionDef

		if (container == null) {
			value.moduleVariableScope
		} else {
			val inner = newArrayList
			inner.addAll(value.functionParameter)
			if(container.statement != null) inner.addAll(container.statement.statementBlockVaraibles(value))
			scopeFor(inner, value.moduleVariableScope)
	def static void scopeStatementBlock(RefValue variable, StatementBlock block, ArrayList<EObject> list) {
		for (FunctionDefList l : block.def.filter[it != null]) {
			if (l.locDef != null && l.locDef.constDef != null) {
				val constDefList = l.locDef.constDef.defs as ConstList
				for (SingleConstDef d : constDefList.list) {
					if (d != variable) {
						list.add(d);
					}
				}
			}
			if (l.locInst != null && l.locInst.variable != null) {
				val varList = l.locInst.variable.list as VarList
				for (SingleVarInstance d : varList.variables) {
					if (d != variable) {
						list.add(d);
					}
				}
			}
		}
	}

	def static IScope loopVariableScope(RefValue value) {
		val loop = value.findDesiredParent(typeof(LoopConstruct)) as LoopConstruct
		val inner = newArrayList;

		if (loop != null && loop.forStm != null) {
			val list = loop.forStm.init.variable.list

			if (list != null) {
				for (SingleVarInstance v : list.variables) {
					inner.add(v)
	def static void scopeInitial(RefValue variable, Initial init, ArrayList<EObject> list) {
		if (init.variable != null) {
			val varList = init.variable.list as VarList
			for (SingleVarInstance d : varList.variables) {
				if (d != variable) {
					list.add(d);
				}
			}
			if(loop.forStm.statement != null) inner.addAll(loop.forStm.statement.statementBlockVaraibles(value))
			scopeFor(inner, value.functionVariableScope)
		} else if (loop != null && loop.doStm != null) {
			if(loop.doStm.statement != null) inner.addAll(loop.doStm.statement.statementBlockVaraibles(value))
			scopeFor(inner, value.functionVariableScope)
		} else if (loop != null && loop.whileStm != null) {
			if(loop.whileStm.statement != null) inner.addAll(loop.whileStm.statement.statementBlockVaraibles(value))
			scopeFor(inner, value.functionVariableScope)
		} else {
			value.functionVariableScope
		}
	}

	def static private ArrayList<EObject> statementBlockVaraibles(StatementBlock sb, RefValue value) {
		val res = newArrayList
	def static void scopeFunctionParameterValue(RefValue variable, FunctionFormalParList parList,
		ArrayList<EObject> list) {
		for (FunctionFormalPar p : parList.params.filter[it.value != null]) {
			if (p.value != variable) {
				list.add(p);
			}
		}
	}

		for (FunctionDefList l : sb.def.filter[it != null]) {
			if (l.locDef.constDef != null) {
				val constDefList = l.locDef.constDef.defs as ConstList
				for (EObject d : constDefList.list) {
					if(d != value) res.add(d)
	def static void scopeModuleControlPart(RefValue variable, ModuleControlPart control, ArrayList<EObject> list) {
		for (ControlStatementOrDefList o : control.body.list) {
			if (o.def.localDef != null && o.def.localDef.constDef != null) {
				val constDefList = o.def.localDef.constDef.defs as ConstList
				for (SingleConstDef d : constDefList.list) {
					if (d != variable) {
						list.add(d);
					}
				}
			}
			if (o.def.localInst != null && o.def.localInst.variable != null) {
				val varList = o.def.localInst.variable.list as VarList
				for (SingleVarInstance d : varList.variables) {
					if (d != variable) {
						list.add(d);
					}
				}
			}
		}
	}

		res
	def static void scopeComponentDef(RefValue variable, ComponentDef component, ArrayList<EObject> list) {
		for (ComponentDefList l : component.defs) {
			if (l.element.const != null) {
				val constDefList = l.element.const.defs as ConstList
				for (SingleConstDef d : constDefList.list) {
					if (d != variable) {
						list.add(d);
					}
				}
			}
			if (l.element.variable != null) {
				val varList = l.element.variable.list as VarList
				for (SingleVarInstance d : varList.variables) {
					if (d != variable) {
						list.add(d);
					}
				}
			}
		}
		for (ComponentDef e : component.extends) {
			scopeComponentDef(variable, e, list)
		}
	}

	def static private ArrayList<EObject> functionParameter(RefValue value) {
		val function = value.findDesiredParent(typeof(FunctionDef)) as FunctionDef
		val list = newArrayList;
	def static void scopeTemplateOrValueFormalParList(RefValue variable, TemplateOrValueFormalParList paramsList,
		ArrayList<EObject> list) {
		var RefValue value;

		if (function.parameterList != null) {
			for (FunctionFormalPar v : function.parameterList.params.filter[it.value != null]) {
				list.add(v.value)
			}
		for (TemplateOrValueFormalPar p : paramsList.params) {
			if (p.value != null)
				value = p.value as RefValue
			else if (p.template != null)
				value = p.template as RefValue;

			if (value != null && value != variable)
				list.add(value);
		}
		list
	}

	def static void scopeAltstepLocalDefList(RefValue variable, AltstepLocalDefList localList, ArrayList<EObject> list) {
		for (AltstepLocalDef a : localList.local.filter[it != null]) {
			if (a.const != null) {
				val constDefList = a.const.defs as ConstList
				for (SingleConstDef d : constDefList.list) {
					if (d != variable) {
						list.add(d);
					}
				}
			}
			if (a.variable != null) {
				val varList = a.variable.list as VarList
				for (SingleVarInstance d : varList.variables) {
					if (d != variable) {
						list.add(d);
					}
				}
			}
		}
	}
}
+63 −16
Original line number Diff line number Diff line
package de.ugoe.cs.swe.scoping

import de.ugoe.cs.swe.tTCN3.AltstepDef
import de.ugoe.cs.swe.tTCN3.AltstepLocalDefList
import de.ugoe.cs.swe.tTCN3.ComponentDef
import de.ugoe.cs.swe.tTCN3.ComponentDefList
import de.ugoe.cs.swe.tTCN3.FieldSpec
import de.ugoe.cs.swe.tTCN3.ForStatement
import de.ugoe.cs.swe.tTCN3.FunctionDef
import de.ugoe.cs.swe.tTCN3.FunctionFormalParList
import de.ugoe.cs.swe.tTCN3.GroupDef
import de.ugoe.cs.swe.tTCN3.Initial
import de.ugoe.cs.swe.tTCN3.ModuleControlPart
import de.ugoe.cs.swe.tTCN3.ModuleDefinition
import de.ugoe.cs.swe.tTCN3.ModuleDefinitionsList
import de.ugoe.cs.swe.tTCN3.PortElement
import de.ugoe.cs.swe.tTCN3.PortOrAny
import de.ugoe.cs.swe.tTCN3.RecordDefNamed
import de.ugoe.cs.swe.tTCN3.RefValue
import de.ugoe.cs.swe.tTCN3.StatementBlock
import de.ugoe.cs.swe.tTCN3.TTCN3Module
import de.ugoe.cs.swe.tTCN3.TemplateDef
import de.ugoe.cs.swe.tTCN3.TemplateOrValueFormalParList
import de.ugoe.cs.swe.tTCN3.TestcaseDef
import de.ugoe.cs.swe.tTCN3.TypeDef
import java.util.ArrayList
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EReference
import org.eclipse.xtext.scoping.IScope
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider

import static extension de.ugoe.cs.swe.common.TTCN3ScopeHelper.*
import static org.eclipse.xtext.scoping.Scopes.*
import de.ugoe.cs.swe.tTCN3.ComponentDef
import de.ugoe.cs.swe.tTCN3.ModuleDefinitionsList
import de.ugoe.cs.swe.tTCN3.TypeDef
import de.ugoe.cs.swe.tTCN3.ModuleDefinition
import de.ugoe.cs.swe.tTCN3.FieldSpec
import de.ugoe.cs.swe.tTCN3.TemplateDef
import de.ugoe.cs.swe.tTCN3.RecordDefNamed
import de.ugoe.cs.swe.tTCN3.PortOrAny
import de.ugoe.cs.swe.tTCN3.AltstepDef
import java.util.ArrayList
import org.eclipse.emf.ecore.EObject
import de.ugoe.cs.swe.tTCN3.ComponentDefList
import de.ugoe.cs.swe.tTCN3.PortElement

import static extension de.ugoe.cs.swe.common.TTCN3ScopeHelper.*

class TTCN3ScopeProvider extends AbstractDeclarativeScopeProvider {

	def IScope scope_RefValue(RefValue value, EReference ref) {
		value.loopVariableScope
	def IScope scope_RefValue(RefValue variable, EReference ref) {
		val list = newArrayList();
		var parent = variable.eContainer

		while (parent != null) {
			if (parent instanceof TTCN3Module) {
				variable.scopeModuleVariable(list)
			} else if (parent instanceof StatementBlock) {
				variable.scopeStatementBlock(parent, list)
			} else if (parent instanceof Initial) {
				variable.scopeInitial(parent, list)
			} else if (parent instanceof ForStatement) {
				variable.scopeInitial(parent.init, list)
			} else if (parent instanceof FunctionDef) {
				if(parent.parameterList != null) variable.scopeFunctionParameterValue(parent.parameterList, list)
			} else if (parent instanceof FunctionFormalParList) {
				variable.scopeFunctionParameterValue(parent, list)
			} else if (parent instanceof ModuleControlPart) {
				variable.scopeModuleControlPart(parent, list)
			} else if (parent instanceof ComponentDef) {
				variable.scopeComponentDef(parent, list)
			} else if (parent instanceof TestcaseDef) {
				variable.scopeTemplateOrValueFormalParList(parent.parList, list)
			} else if (parent instanceof TemplateOrValueFormalParList) {
				variable.scopeTemplateOrValueFormalParList(parent, list)
			} else if (parent instanceof AltstepDef) {
				if(parent.params != null) variable.scopeFunctionParameterValue(parent.params, list)
			} else if (parent instanceof AltstepLocalDefList) {
				variable.scopeAltstepLocalDefList(parent, list)
			} else if (parent instanceof GroupDef) {
				variable.scopeModuleVariable(list)
			}

			parent = parent.eContainer
		}

		scopeFor(list)
	}

	def IScope scope_ComponentDef_extends(ComponentDef component, EReference ref) {
+3 −3
Original line number Diff line number Diff line
@@ -174,7 +174,7 @@ class TTCN3Validator extends AbstractTTCN3Validator {
					return;
				}
			} else if (parent instanceof AltstepLocalDefList) {
				if (parent.checkNameClasAltstepLocalDefList(variable)) {
				if (parent.checkNameClashAltstepLocalDefList(variable)) {
					error('Name clash with another variable definition in this scope!', feature);
					return;
				}
@@ -318,7 +318,7 @@ class TTCN3Validator extends AbstractTTCN3Validator {
		return false;
	}

	def private boolean checkNameClasAltstepLocalDefList(AltstepLocalDefList list, RefValue variable) {
	def private boolean checkNameClashAltstepLocalDefList(AltstepLocalDefList list, RefValue variable) {
		for (AltstepLocalDef a : list.local.filter[it != null]) {

			if (a.const != null) {