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

started data structure validation

parent cde1583a
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -688,16 +688,16 @@ PortDefAttribs:
	message=MessageAttribs | procedure=ProcedureAttribs | mixed=MixedAttribs;

MixedAttribs:
	{MixedAttribs} MIXEDKEYWORD LBRACKET ((decl+=AddressDecl | list+=MixedList | def+=ConfigParamDef) SEMICOLON?)+
	{MixedAttribs} MIXEDKEYWORD LBRACKET ((addressDecls+=AddressDecl | mixedLists+=MixedList | configDefs+=ConfigParamDef) SEMICOLON?)+
	RBRACKET;

MixedList:
	Direction ProcOrTypeList;
	Direction list=ProcOrTypeList;

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

	/// changed Signature -> Type
	// changed Signature -> Type
ProcOrType:
	type=Type;

@@ -706,7 +706,7 @@ MessageAttribs:
	RBRACKET;

ConfigParamDef:
	MapParamDef | UnmapParamDef;
	map=MapParamDef | unmap=UnmapParamDef;

MapParamDef:
	MAPKEYWORD PARAMKEYWORD LPAREN values+=FormalValuePar (COMMA values+=FormalValuePar)* RPAREN;
@@ -715,7 +715,7 @@ UnmapParamDef:
	UNMAPKEYWORD PARAMKEYWORD LPAREN values+=FormalValuePar (COMMA values+=FormalValuePar)* RPAREN;

AddressDecl:
	ADDRESSKEYWORD Type;
	ADDRESSKEYWORD type=Type;

ProcedureAttribs:
	PROCEDUREKEYWORD LBRACKET ((addresses+=AddressDecl | procs+=ProcedureList | configs+=ConfigParamDef) SEMICOLON?)+
+100 −6
Original line number Diff line number Diff line
@@ -76,6 +76,8 @@ import de.ugoe.cs.swe.common.logging.LoggingInterface.MessageClass
import de.ugoe.cs.swe.tTCN3.BaseTemplate
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

class TTCN3Validator extends AbstractTTCN3Validator {
	val ConfigTools configTools = ConfigTools.getInstance;
@@ -283,12 +285,10 @@ class TTCN3Validator extends AbstractTTCN3Validator {
				if (p instanceof FormalTemplatePar) {
					if (p.restriction == null || p.restriction.restriction == null ||
						p.restriction.restriction.present != null) {
						// problem occurred, inconsistent definition
						isAmbiguous = true
						isAmbiguous = true // problem occurred, inconsistent definition
					}
				} else {
					// problem occurred, inconsistent definition
					isAmbiguous = true
					isAmbiguous = true // problem occurred, inconsistent definition
				}
				if (isAmbiguous) {
					val INode node = NodeModelUtils.getNode(template)
@@ -366,6 +366,100 @@ class TTCN3Validator extends AbstractTTCN3Validator {
	/**
	 * END: NAMING CONVENTIONS -----------------------------------------------------------------------
	 */
	/**
	  * BEGIN: Structure of Data ---------------------------------------------------------------------
	  */
	@Check
	def checkTypeDefOrderInGroup(GroupDef group) {
		var StructuredTypeDef struct = null;
		var SubTypeDef sub = null;
		var previous = ""
		var current = ""

		if (!activeProfile.checkTypeDefOrderInGroup || group.list == null)
			return;

		for (d : group.list.definitions) {
			if (d instanceof TypeDef) {
				struct = d.body.structured
				sub = d.body.sub
				if (struct != null) {
					if (struct.record != null && struct.record instanceof RecordDefNamed) {
						current = (struct.record as RecordDefNamed).name
					} else if (struct.union != null && struct.union instanceof UnionDefNamed) {
						current = (struct.union as UnionDefNamed).name
					} else if (struct.set != null && struct.set instanceof SetDefNamed) {
						current = (struct.set as SetDefNamed).name
					} else if (struct.recordOf != null && struct.recordOf instanceof RecordOfDefNamed) {
						current = (struct.recordOf as RecordOfDefNamed).name
					} else if (struct.setOf != null && struct.setOf instanceof SetOfDefNamed) {
						current = (struct.setOf as SetOfDefNamed).name
					} else if (struct.enumDef != null && struct.enumDef instanceof EnumDefNamed) {
						current = (struct.enumDef as EnumDefNamed).name
					} else if (struct.port != null) {
						current = (struct.port as PortDef).name
					} else if (struct.component != null) {
						current = (struct.component as ComponentDef).name
					}
				} else if (sub != null) {
					if (sub instanceof SubTypeDefNamed) {
						current = sub.name
					}
				}
			}
			compareAlphabeticOrder(group, previous, current)
			previous = 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))
			return;

		val INode node = NodeModelUtils.getNode(group)
		if (current.compareToIgnoreCase(previous) <= 0) {
			val message = "Type definitions <\"" + previous + "\",\"" + current + "\"> within group \"" + group.name +
				"\" are not alphabetically ordered!"

			warning(
				message,
				TTCN3Package.eINSTANCE.TTCN3Reference_Name,
				MessageClass.STRUCTURE.toString,
				node.startLine.toString,
				node.endLine.toString,
				"4.1, " + MiscTools.getMethodName()
			);
		}
	}
	
	@Check
	def checkPortMessageGrouping(PortDef port) {	
		if (!activeProfile.checkPortMessageGrouping)
			return;
		
		val INode node = NodeModelUtils.getNode(port)
		val parentGroup = port.findDesiredParent(GroupDef)
		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!"
			warning(
				message,
				TTCN3Package.eINSTANCE.TTCN3Reference_Name,
				MessageClass.STRUCTURE.toString,
				node.startLine.toString,
				node.endLine.toString,
				"4.1, " + MiscTools.getMethodName()
			);			
		} else {
			// TODO: implement!
		}
	}
	
	/**
	  * END: Structure of Data   ---------------------------------------------------------------------
	  */
	@Check
	def checkUniqueNameNestedVariable(RefValue variable) {
		variable.isNameClashInHierarchy