Commit 7a9f53e0 authored by Daniel Honsel's avatar Daniel Honsel
Browse files

recognize type name clashes

parent a55017fc
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1143,9 +1143,9 @@ ReadTimerOp:
PermutationMatch:
	PERMUTATIONKEYWORD ListOfTemplates;

	// TODO: complete this rule parRef!
	// TODO: complete this rule parRef! TypeReference
StructFieldRef:
	StructFieldDef | {StructFieldRef} PredefinedType | ReferencedType;
	ref=[StructFieldDef|IDENTIFIER] | {StructFieldRef} PredefinedType;

ExtendedFieldReference:
	DOT (field+=ReferencedValue | type+=PredefinedType) | array+=ArrayOrBitRef | {ExtendedFieldReference} SQUAREOPEN
+83 −53
Original line number Diff line number Diff line
@@ -51,6 +51,18 @@ import de.ugoe.cs.swe.tTCN3.EnumDefNamed
import de.ugoe.cs.swe.tTCN3.SubTypeDefNamed
import de.ugoe.cs.swe.tTCN3.TemplateDef
import de.ugoe.cs.swe.tTCN3.SignatureDef
import de.ugoe.cs.swe.tTCN3.TypeDefBody
import de.ugoe.cs.swe.tTCN3.ReferencedType

class TypeAttribs {
	String name
	EStructuralFeature feature

	new(String name, EStructuralFeature feature) {
		this.name = name
		this.feature = feature
	}
}

class TTCN3Validator extends AbstractTTCN3Validator {

@@ -70,7 +82,7 @@ class TTCN3Validator extends AbstractTTCN3Validator {
			for (SingleConstDef d : constDefList.list) {
				if (field.name.equals(d.name)) {
					error('Name clash with another variable definition in this scope!',
						TTCN3Package.eINSTANCE.structFieldRef_Name);
						TTCN3Package.eINSTANCE.structFieldDef_Name);
					return;
				}
			}
@@ -81,7 +93,7 @@ class TTCN3Validator extends AbstractTTCN3Validator {
		for (StructFieldDef f : body.defs) {
			if (f != field && f.name.equals(field.name)) {
				error('Name clash with another variable definition in this scope!',
					TTCN3Package.eINSTANCE.structFieldRef_Name);
					TTCN3Package.eINSTANCE.structFieldDef_Name);
				return;
			}
		}
@@ -105,13 +117,25 @@ class TTCN3Validator extends AbstractTTCN3Validator {
		for (ComponentDef d : component.extends.sortBy[it.name]) {
			current = d;
			if (current == last) {
				error('The extension list contains the type ' + current.name + ' twice!', null, -1);
				error('The extension list contains the type ' + current.name + ' twice!',
					TTCN3Package.eINSTANCE.referencedType_Name);
				return;
			}
			last = current
		}
	}

	@Check
	def checkTypeNames(ReferencedType type) {
		val module = type.findDesiredParent(typeof(TTCN3Module)) as TTCN3Module

		if (module.defs.checkNameClashModuleDefinitionsList(type, type.name)) {
			error('Name clash with another variable definition in this scope!',
				TTCN3Package.eINSTANCE.referencedType_Name);
			return;
		}
	}

	def private isNameClashInHierarchy(RefValue variable) {
		var parent = variable.eContainer
		val EStructuralFeature feature = TTCN3Package.eINSTANCE.refValue_Name;
@@ -119,7 +143,7 @@ class TTCN3Validator extends AbstractTTCN3Validator {
		while (parent != null) {

			if (parent instanceof TTCN3Module) {
				if (parent.defs != null && parent.defs.checkNameClashModuleDefinitionsList(variable)) {
				if (parent.defs != null && parent.defs.checkNameClashModuleDefinitionsList(variable, variable.name)) {
					error('Name clash with another variable definition in this scope!', feature);
					return;
				}
@@ -179,7 +203,7 @@ class TTCN3Validator extends AbstractTTCN3Validator {
					return;
				}
			} else if (parent instanceof GroupDef) {
				if (parent.list.checkNameClashModuleDefinitionsList(variable)) {
				if (parent.list.checkNameClashModuleDefinitionsList(variable, variable.name)) {
					error('Name clash with another variable definition in this scope!', feature);
					return;
				}
@@ -189,13 +213,14 @@ class TTCN3Validator extends AbstractTTCN3Validator {
		}
	}

	def private boolean checkNameClashModuleDefinitionsList(ModuleDefinitionsList list, RefValue variable) {
	def private boolean checkNameClashModuleDefinitionsList(ModuleDefinitionsList list, EObject variable,
		String variableName) {
		for (ModuleDefinition v : list.definitions) {

			if (v.def instanceof ConstDef) {
				val constDefList = (v.def as ConstDef).defs as ConstList
				for (SingleConstDef d : constDefList.list) {
					if (d != variable && d.name == variable.name) {
					if (d != variable && d.name == variableName) {
						return true
					}
				}
@@ -203,56 +228,20 @@ class TTCN3Validator extends AbstractTTCN3Validator {

			if (v.def instanceof TypeDef) {
				val body = (v.def as TypeDef).body
				if (body.structured != null) {
					if (body.structured.recordOf != null && body.structured.recordOf != variable &&
						body.structured.recordOf instanceof RecordOfDefNamed &&
						(body.structured.recordOf as RecordOfDefNamed).name == variable.name)
						return true
					if (body.structured.setOf != null && body.structured.setOf != variable &&
						body.structured.setOf instanceof SetOfDefNamed &&
						(body.structured.setOf as SetOfDefNamed).name == variable.name)
						return true
					if (body.structured.record != null && body.structured.record != variable &&
						body.structured.record instanceof RecordDefNamed &&
						(body.structured.record as RecordDefNamed).name == variable.name)
						return true
					if (body.structured.union != null && body.structured.union != variable &&
						body.structured.union instanceof UnionDefNamed &&
						(body.structured.union as UnionDefNamed).name == variable.name)
						return true
					if (body.structured.set != null && body.structured.set != variable &&
						body.structured.set instanceof SetDefNamed &&
						(body.structured.set as SetDefNamed).name == variable.name)
						return true
					if (body.structured.enumDef != null && body.structured.enumDef != variable &&
						body.structured.enumDef instanceof EnumDefNamed &&
						(body.structured.enumDef as EnumDefNamed).name == variable.name)
						return true
					if (body.structured.port != null && body.structured.port != variable &&
						body.structured.port instanceof PortDef &&
						(body.structured.port as PortDef).name == variable.name)
						return true
					if (body.structured.component != null && body.structured.component != variable &&
						body.structured.component instanceof ComponentDef &&
						(body.structured.component as ComponentDef).name == variable.name)
						return true
				} else if (body.sub != null) {
					if (body.sub != variable && body.sub instanceof SubTypeDefNamed &&
						(body.sub as SubTypeDefNamed).name == variable.name)
						return true
				}
				if (body.checkTypeNameClash(variable, variableName))
					return true;
			}

			if (v.def instanceof ModuleParDef) {
				if ((v.def as ModuleParDef).param != null) {
					for (ModuleParameter p : (v.def as ModuleParDef).param.list.params) {
						if (p != variable && p.name == variable.name)
						if (p != variable && p.name == variableName)
							return true
					}
				} else if ((v.def as ModuleParDef).multitypeParam != null) {
					for (ModulePar p : (v.def as ModuleParDef).multitypeParam.params) {
						for (ModuleParameter pa : p.list.params) {
							if (pa != variable && pa.name == variable.name)
							if (pa != variable && pa.name == variableName)
								return true
						}
					}
@@ -260,32 +249,32 @@ class TTCN3Validator extends AbstractTTCN3Validator {
			}

			if (v.def instanceof FunctionDef) {
				if (v.def != variable && (v.def as FunctionDef).name == variable.name)
				if (v.def != variable && (v.def as FunctionDef).name == variableName)
					return true
			}

			if (v.def instanceof TemplateDef) {
				if ((v.def as TemplateDef).base != variable && (v.def as TemplateDef).base.name == variable.name)
				if ((v.def as TemplateDef).base != variable && (v.def as TemplateDef).base.name == variableName)
					return true
			}

			if (v.def instanceof SignatureDef) {
				if (v.def != variable && (v.def as SignatureDef).name == variable.name)
				if (v.def != variable && (v.def as SignatureDef).name == variableName)
					return true
			}

			if (v.def instanceof TestcaseDef) {
				if (v.def != variable && (v.def as TestcaseDef).name == variable.name)
				if (v.def != variable && (v.def as TestcaseDef).name == variableName)
					return true
			}

			if (v.def instanceof AltstepDef) {
				if (v.def != variable && (v.def as AltstepDef).name == variable.name)
				if (v.def != variable && (v.def as AltstepDef).name == variableName)
					return true
			}

			if (v.def instanceof GroupDef) {
				if (v.def != variable && (v.def as GroupDef).name == variable.name)
				if (v.def != variable && (v.def as GroupDef).name == variableName)
					return true
			}

@@ -293,6 +282,47 @@ class TTCN3Validator extends AbstractTTCN3Validator {
		return false;
	}

	def private boolean checkTypeNameClash(TypeDefBody body, EObject variable, String variableName) {
		if (body.structured != null) {
			if (body.structured.recordOf != null && body.structured.recordOf != variable &&
				body.structured.recordOf instanceof RecordOfDefNamed &&
				(body.structured.recordOf as RecordOfDefNamed).name == variableName)
				return true
			if (body.structured.setOf != null && body.structured.setOf != variable &&
				body.structured.setOf instanceof SetOfDefNamed &&
				(body.structured.setOf as SetOfDefNamed).name == variableName)
				return true
			if (body.structured.record != null && body.structured.record != variable &&
				body.structured.record instanceof RecordDefNamed &&
				(body.structured.record as RecordDefNamed).name == variableName)
				return true
			if (body.structured.union != null && body.structured.union != variable &&
				body.structured.union instanceof UnionDefNamed &&
				(body.structured.union as UnionDefNamed).name == variableName)
				return true
			if (body.structured.set != null && body.structured.set != variable &&
				body.structured.set instanceof SetDefNamed &&
				(body.structured.set as SetDefNamed).name == variableName)
				return true
			if (body.structured.enumDef != null && body.structured.enumDef != variable &&
				body.structured.enumDef instanceof EnumDefNamed &&
				(body.structured.enumDef as EnumDefNamed).name == variableName)
				return true
			if (body.structured.port != null && body.structured.port != variable &&
				body.structured.port instanceof PortDef && (body.structured.port as PortDef).name == variableName)
				return true
			if (body.structured.component != null && body.structured.component != variable &&
				body.structured.component instanceof ComponentDef &&
				(body.structured.component as ComponentDef).name == variableName)
				return true
		} else if (body.sub != null) {
			if (body.sub != variable && body.sub instanceof SubTypeDefNamed &&
				(body.sub as SubTypeDefNamed).name == variableName)
				return true
		}
		return false
	}

	def private boolean checkNameClasStatementBlock(StatementBlock block, RefValue variable) {
		for (FunctionDefList l : block.def.filter[it != null]) {