Commit ab7a3ec8 authored by Daniel Honsel's avatar Daniel Honsel
Browse files

completed data structure validation

parent e40e0681
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -695,7 +695,7 @@ MixedList:
	Direction list=ProcOrTypeList;

ProcOrTypeList:
	{ProcOrTypeList} ALLKEYWORD | type+=ProcOrType (COMMA type+=ProcOrType)*;
	all=ALLKEYWORD | type+=ProcOrType (COMMA type+=ProcOrType)*;

	// changed Signature -> Type
ProcOrType:
@@ -738,10 +738,10 @@ ComponentElementDef:
	port=PortInstance | variable=VarInstance | timer=TimerInstance | const=ConstDef;

ProcedureList:
	Direction AllOrSignatureList;
	Direction allOrSigList=AllOrSignatureList;

AllOrSignatureList:
	{AllOrSignatureList} ALLKEYWORD | SignatureList;
	all=ALLKEYWORD | signatureList=SignatureList;

SignatureList:
	sigs+=Signature (COMMA sigs+=Signature)*;
@@ -774,10 +774,10 @@ NestedEnumDef:
	ENUMKEYWORD LBRACKET EnumerationList RBRACKET;

MessageList:
	Direction AllOrTypeList;
	Direction allOrTypeList=AllOrTypeList;

AllOrTypeList:
	{AllOrTypeList} ALLKEYWORD | TypeList;
	all=ALLKEYWORD | typeList=TypeList;

TypeList:
	types+=Type (COMMA types+=Type)*;
+161 −17
Original line number Diff line number Diff line
@@ -78,6 +78,12 @@ import de.ugoe.cs.swe.common.MiscTools
import de.ugoe.cs.swe.tTCN3.MatchingSymbol
import de.ugoe.cs.swe.tTCN3.StructuredTypeDef
import de.ugoe.cs.swe.tTCN3.SubTypeDef
import java.util.List
import de.ugoe.cs.swe.tTCN3.Type
import de.ugoe.cs.swe.tTCN3.Signature
import de.ugoe.cs.swe.tTCN3.ProcOrTypeList
import de.ugoe.cs.swe.tTCN3.AllOrSignatureList
import de.ugoe.cs.swe.tTCN3.AllOrTypeList

class TTCN3Validator extends AbstractTTCN3Validator {
	val ConfigTools configTools = ConfigTools.getInstance;
@@ -380,9 +386,9 @@ class TTCN3Validator extends AbstractTTCN3Validator {
			return;

		for (d : group.list.definitions) {
			if (d instanceof TypeDef) {
				struct = d.body.structured
				sub = d.body.sub
			if (d.def instanceof TypeDef) {
				struct = (d.def as TypeDef).body.structured
				sub = (d.def as TypeDef).body.sub
				if (struct != null) {
					if (struct.record != null && struct.record instanceof RecordDefNamed) {
						current = (struct.record as RecordDefNamed).name
@@ -407,14 +413,18 @@ class TTCN3Validator extends AbstractTTCN3Validator {
					}
				}
			}

			if (!Strings.isNullOrEmpty(current)) {
				compareAlphabeticOrder(group, previous, current)
				previous = current
				current = ""
			}
		}
	}

	// TODO: more information are available (concrete types). use them?
	private def compareAlphabeticOrder(GroupDef group, String previous, String current) {
		if (Strings.isNullOrEmpty(previous) || Strings.isNullOrEmpty(current))
		if (Strings.isNullOrEmpty(current))
			return;

		val INode node = NodeModelUtils.getNode(group)
@@ -428,7 +438,7 @@ class TTCN3Validator extends AbstractTTCN3Validator {
				MessageClass.STRUCTURE.toString,
				node.startLine.toString,
				node.endLine.toString,
				"4.1, " + MiscTools.getMethodName()
				"4.1, " + "checkTypeDefOrderInGroup"
			);
		}
	}
@@ -443,17 +453,151 @@ class TTCN3Validator extends AbstractTTCN3Validator {
		var message = "";

		if (parentGroup == null) {
			message = "Port type definition for \"" + port.name + "\" is found outside a group definition! Related messages can therefore never be in the same group as the port definition!"
			message = "Port type definition for \"" + port.name +
				"\" is found outside a group definition! Related messages can therefore never be in the same group as the port definition!"
			warning(
				message,
				TTCN3Package.eINSTANCE.TTCN3Reference_Name,
				MessageClass.STRUCTURE.toString,
				node.startLine.toString,
				node.endLine.toString,
				"4.1, " + MiscTools.getMethodName()
				"4.2, " + MiscTools.getMethodName()
			);
		} else {
			val types = port.body.attribs.getAllContentsOfType(Type)
			val signatures = port.body.attribs.getAllContentsOfType(Signature)
			for (t : types) {
				val ref = t.ref
				if (ref != null) {
					switch ref {
						SignatureDef: portReferencedTypeCHeck(port, ref, "Signature")
						RecordDefNamed: portReferencedTypeCHeck(port, ref, "Message type")
						SetDefNamed: portReferencedTypeCHeck(port, ref, "Message type")
						SubTypeDefNamed: portReferencedTypeCHeck(port, ref, "Message type")
					}
				}
			}
			for (s : signatures) {
				portReferencedTypeCHeck(port, s.ref, "Signature")
			}
		}
	}

	private def portReferencedTypeCHeck(PortDef port, ReferencedType type, String typeName) {
		val INode nodePort = NodeModelUtils.getNode(port)
		val INode nodeType = NodeModelUtils.getNode(type)
		val TTCN3Module parentModulePort = port.findDesiredParent(TTCN3Module)
		val TTCN3Module parentModuleType = type.findDesiredParent(TTCN3Module)
		val GroupDef parentGroupPort = port.findDesiredParent(GroupDef)
		val GroupDef parentGroupType = type.findDesiredParent(GroupDef)

		if (parentGroupType == null) {
			val message = "" + typeName + " definition for \"" + type.name + "\" <" + nodeType.startLine + "," +
				parentModuleType.name + ",- " + "> " + "related to port type definition for \"" + port.name + "\" <" +
				nodePort.startLine + "," + parentModulePort.name + "," + parentGroupPort.name + "> " +
				"is found outside a group definition! It can therefore never be in the same group as the port type definition!"

			warning(
				message,
				TTCN3Package.eINSTANCE.TTCN3Reference_Name,
				MessageClass.STRUCTURE.toString,
				nodeType.startLine.toString,
				nodeType.endLine.toString,
				"4.2, " + MiscTools.getMethodName()
			);
			return;
		}

		if (parentModulePort != parentModuleType) {
			val message = "" + typeName + " definition for \"" + type.name + "\" <" + nodeType.startLine + "," +
				parentModuleType.name + "," + parentGroupType.name + "> " + "related to port type definition for \"" +
				port.name + "\" <" + nodePort.startLine + "," + parentModulePort.name + "," + parentGroupPort.name +
				"> " +
				"is not within the same module as the port type definition! It can therefore never be in the same group as the port definition!"
			warning(
				message,
				TTCN3Package.eINSTANCE.TTCN3Reference_Name,
				MessageClass.STRUCTURE.toString,
				nodeType.startLine.toString,
				nodeType.endLine.toString,
				"4.2, " + MiscTools.getMethodName()
			);
			return;
		}

		if (parentGroupPort != parentGroupType) {

			// check nested subgroups
			if (parentGroupPort.getAllContentsOfType(GroupDef).contains(parentGroupType)) {
				val message = "" + typeName + " definition for \"" + type.name + "\" <" + nodeType.startLine + "," +
					parentModuleType.name + "," + parentGroupType.name + "> " + "related to port type definition for \"" +
					port.name + "\" <" + nodePort.startLine + "," + parentModulePort.name + "," + parentGroupPort.name +
					"> " + "is within a nested subgroup within the same group as the port type definition!"
				info(
					message,
					TTCN3Package.eINSTANCE.TTCN3Reference_Name,
					MessageClass.STRUCTURE.toString,
					nodeType.startLine.toString,
					nodeType.endLine.toString,
					"4.2, " + MiscTools.getMethodName(),
					LogLevel.INFORMATION.toString
				);
				return;
			} else {
			// TODO: implement!
				val message = "" + typeName + " definition for \"" + type.name + "\" <" + nodeType.startLine + "," +
					parentModuleType.name + "," + parentGroupType.name + "> " + "related to port type definition for \"" +
					port.name + "\" <" + nodePort.startLine + "," + parentModulePort.name + "," + parentGroupPort.name +
					"> " + "is not within the same group as the port type definition!"
				warning(
					message,
					TTCN3Package.eINSTANCE.TTCN3Reference_Name,
					MessageClass.STRUCTURE.toString,
					nodeType.startLine.toString,
					nodeType.endLine.toString,
					"4.2, " + MiscTools.getMethodName()
				);
				return;
			}
		}
	}

	@Check
	def checkNoAllKeywordInPortDefinitions(PortDef port) {
		val INode node = NodeModelUtils.getNode(port)
		var allIsUsed = false;
		val procOrTypeList = port.body.attribs.getAllContentsOfType(ProcOrTypeList)
		val allOrSignatureList = port.body.attribs.getAllContentsOfType(AllOrSignatureList)
		val allOrTypeList = port.body.attribs.getAllContentsOfType(AllOrTypeList)
		for (a : procOrTypeList) {
			if (a.all != null) {
				allIsUsed = true
			}
		}
		if (!allIsUsed) {
			for (a : allOrSignatureList) {
				if (a.all != null) {
					allIsUsed = true
				}
			}
		}
		if (!allIsUsed) {
			for (a : allOrTypeList) {
				if (a.all != null) {
					allIsUsed = true
				}
			}
		}

		if (allIsUsed) {
			val message = "\"all\" keyword is used in the definition of port \"" + port.name + "\"!"
			warning(
				message,
				TTCN3Package.eINSTANCE.TTCN3Reference_Name,
				MessageClass.STRUCTURE.toString,
				node.startLine.toString,
				node.endLine.toString,
				"4.2.1, " + MiscTools.getMethodName()
			);
		}
	}