Loading de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/GenerateTTCN3.mwe2 +1 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ Workflow { // composedCheck = "de.ugoe.cs.swe.validation.CodeStyleValidator" // composedCheck = "de.ugoe.cs.swe.validation.ModularizationValidator" // composedCheck = "de.ugoe.cs.swe.validation.MiscFeatureValidator" // composedCheck = "de.ugoe.cs.swe.validation.LogValidator" // name clash validator // can currently only be used with the eclipse editor, does not work Loading de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/validation/LogValidator.xtend 0 → 100644 +280 −0 Original line number Diff line number Diff line package de.ugoe.cs.swe.validation import com.google.common.base.Strings import de.ugoe.cs.swe.TTCN3Configuration.QualityCheckProfile import de.ugoe.cs.swe.common.ConfigTools import de.ugoe.cs.swe.common.MiscTools import de.ugoe.cs.swe.common.logging.LoggingInterface.LogLevel import de.ugoe.cs.swe.common.logging.LoggingInterface.MessageClass import de.ugoe.cs.swe.tTCN3.AltstepDef import de.ugoe.cs.swe.tTCN3.ControlStatementOrDefList import de.ugoe.cs.swe.tTCN3.ExtFunctionDef import de.ugoe.cs.swe.tTCN3.FunctionDef import de.ugoe.cs.swe.tTCN3.FunctionInstance import de.ugoe.cs.swe.tTCN3.FunctionStatement import de.ugoe.cs.swe.tTCN3.FunctionStatementList import de.ugoe.cs.swe.tTCN3.LogStatement import de.ugoe.cs.swe.tTCN3.ModuleControlBody import de.ugoe.cs.swe.tTCN3.PredefinedValue import de.ugoe.cs.swe.tTCN3.SetLocalVerdict import de.ugoe.cs.swe.tTCN3.TTCN3Reference import de.ugoe.cs.swe.tTCN3.TestcaseDef import de.ugoe.cs.swe.tTCN3.Value import de.ugoe.cs.swe.tTCN3.VerdictTypeValue import java.util.regex.Matcher import java.util.regex.Pattern import org.eclipse.xtext.nodemodel.INode import org.eclipse.xtext.nodemodel.util.NodeModelUtils import org.eclipse.xtext.validation.AbstractDeclarativeValidator import org.eclipse.xtext.validation.Check import org.eclipse.xtext.validation.EValidatorRegistrar import static extension de.ugoe.cs.swe.common.TTCN3ScopeHelper.* import static extension org.eclipse.xtext.EcoreUtil2.* class LogValidator extends AbstractDeclarativeValidator { val ConfigTools configTools = ConfigTools.getInstance; var QualityCheckProfile activeProfile = configTools.selectedProfile as QualityCheckProfile @Check def checkLogStatementFormat(FunctionStatementList functionStmList) { val parentTC = functionStmList.findDesiredParent(TestcaseDef) val parentFunc = functionStmList.findDesiredParent(FunctionDef) val parentAlt = functionStmList.findDesiredParent(AltstepDef) var TTCN3Reference parent = null; if (parentTC != null) { parent = parentTC; } else if (parentFunc != null) { parent = parentFunc; } else if (parentAlt != null) { parent = parentAlt; } var INode node = null var statementToCheck = "" var other = false for (s : functionStmList.eContents) { if (s instanceof FunctionStatement) { val log = s.findLogStatement if (log != null) { node = NodeModelUtils.getNode(log) if (other) { if (!Strings.isNullOrEmpty(statementToCheck)) { statementToCheck.checkLogStatementFormat(node, parent) } other = false statementToCheck = "" } statementToCheck += log.concatLogItems if (!activeProfile.processSubsequentLogStatementsAsOne) { statementToCheck.checkLogStatementFormat(node, parent) statementToCheck = "" } } else { other = true } } } if (!Strings.isNullOrEmpty(statementToCheck)) { statementToCheck.checkLogStatementFormat(node, parent) } } @Check def checkLogStatementFormat(ModuleControlBody ctrl) { var INode node = null var statementToCheck = "" var other = false for (s : ctrl.eContents) { if (s instanceof ControlStatementOrDefList) { val log = s.findLogStatement if (log != null) { node = NodeModelUtils.getNode(log) if (other) { if (!Strings.isNullOrEmpty(statementToCheck)) { statementToCheck.checkLogStatementFormat(node, null) } other = false statementToCheck = "" } statementToCheck += log.concatLogItems if (!activeProfile.processSubsequentLogStatementsAsOne) { statementToCheck.checkLogStatementFormat(node, null) statementToCheck = "" } } else { other = true } } } if (!Strings.isNullOrEmpty(statementToCheck)) { statementToCheck.checkLogStatementFormat(node, null) } } private def LogStatement findLogStatement(ControlStatementOrDefList stm) { if (stm.def.control != null && stm.def.control.basic != null && stm.def.control.basic.log != null) { return stm.def.control.basic.log } else { return null } } private def LogStatement findLogStatement(FunctionStatement stm) { if (stm.basic != null && stm.basic.log != null) { return stm.basic.log } else { return null } } private def String concatLogItems(LogStatement log) { var logString = "" val items = log.getAllContentsOfType(PredefinedValue) for (i : items) { if (i.charString != null) { var String subString = i.charString.toString.subSequence(1, i.charString.toString.length - 1) as String logString += subString.replaceAll("\"\"", "\"") } } return logString; } private def checkLogStatementFormat(String log, INode node, TTCN3Reference parent) { var problemOccured = false var warning = "" val Pattern logPattern = Pattern.compile(activeProfile.getLogFormatRegExp(), Pattern.DOTALL) val Matcher logMatcher = logPattern.matcher(log) if (!logMatcher.matches()) { problemOccured = true; warning = "Invalid log format (\"" + log + "\")!"; } else if (!logMatcher.group(1).equals("") && parent != null) { val logItemContainerIdentifier = logMatcher.group(1) if (!parent.name.equals(logItemContainerIdentifier)) { problemOccured = true; warning = "Log statement contains invalid container identifier (\"" + logItemContainerIdentifier + "\", should be \"" + parent.name + "\")!"; } } if (problemOccured) { TTCN3StatisticsProvider.getInstance.incrementCountLog warning( warning, null, MessageClass.LOGGING.toString, node.startLine.toString, node.endLine.toString, "5.1, " + MiscTools.getMethodName() ); } } @Check def checkExternalFunctionInvocationPrecededByLogStatement(FunctionInstance function) { if (!activeProfile.checkExternalFunctionInvocationPrecededByLogStatement) return; val INode node = NodeModelUtils.getNode(function) var problemsOccured = false if (function.ref instanceof ExtFunctionDef) { val parent = function.findDesiredParent(FunctionStatement) val parentList = function.findDesiredParent(FunctionStatementList) if (parent == null) { val message = "Call to external function \"" + function.ref.name + "\" within a definition on the module level. It cannot be preceded by a log statement!" info( message, null, MessageClass.LOGGING.toString, node.startLine.toString, node.endLine.toString, "5.3, " + MiscTools.getMethodName(), LogLevel.INFORMATION.toString ); } else { val items = parentList.eContents val idx = items.indexOf(parent) if (idx > 0 && idx < items.size) { val log = (items.get(idx - 1) as FunctionStatement).findLogStatement if (log == null) { problemsOccured = true } } else { problemsOccured = true } } } if (problemsOccured) { TTCN3StatisticsProvider.getInstance.incrementCountLog val message = "Call to external function \"" + function.ref.name + "\" not preceded by a log statement!" warning( message, null, MessageClass.LOGGING.toString, node.startLine.toString, node.endLine.toString, "5.3, " + MiscTools.getMethodName() ); } } @Check def checkInconcOrFailSetverdictPrecededByLog(SetLocalVerdict verdict) { if (!activeProfile.checkInconcOrFailSetVerdictPrecededByLog) return; val parent = verdict.findDesiredParent(FunctionStatement) val parentList = verdict.findDesiredParent(FunctionStatementList) val INode node = NodeModelUtils.getNode(verdict) var problemsOccured = false val exp = verdict.expression var isInconcOrFail = false if (exp instanceof Value) { if (exp.predef != null && exp.predef.verdictType != null) { if (exp.predef.verdictType == VerdictTypeValue.INCONC || exp.predef.verdictType == VerdictTypeValue.FAIL) { isInconcOrFail = true } } } if (!isInconcOrFail) return; val items = parentList.eContents val idx = items.indexOf(parent) if (idx > 0 && idx < items.size) { val log = (items.get(idx - 1) as FunctionStatement).findLogStatement if (log == null) { problemsOccured = true } } else { problemsOccured = true } if (problemsOccured) { TTCN3StatisticsProvider.getInstance.incrementCountLog val message = "No log statement precedes a fail or inconc setverdict statement!!" warning( message, null, MessageClass.LOGGING.toString, node.startLine.toString, node.endLine.toString, "5.4, " + MiscTools.getMethodName() ); } } override register(EValidatorRegistrar registrar) { //not needed for classes used as ComposedCheck } } Loading
de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/GenerateTTCN3.mwe2 +1 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ Workflow { // composedCheck = "de.ugoe.cs.swe.validation.CodeStyleValidator" // composedCheck = "de.ugoe.cs.swe.validation.ModularizationValidator" // composedCheck = "de.ugoe.cs.swe.validation.MiscFeatureValidator" // composedCheck = "de.ugoe.cs.swe.validation.LogValidator" // name clash validator // can currently only be used with the eclipse editor, does not work Loading
de.ugoe.cs.swe.TTCN3/src/de/ugoe/cs/swe/validation/LogValidator.xtend 0 → 100644 +280 −0 Original line number Diff line number Diff line package de.ugoe.cs.swe.validation import com.google.common.base.Strings import de.ugoe.cs.swe.TTCN3Configuration.QualityCheckProfile import de.ugoe.cs.swe.common.ConfigTools import de.ugoe.cs.swe.common.MiscTools import de.ugoe.cs.swe.common.logging.LoggingInterface.LogLevel import de.ugoe.cs.swe.common.logging.LoggingInterface.MessageClass import de.ugoe.cs.swe.tTCN3.AltstepDef import de.ugoe.cs.swe.tTCN3.ControlStatementOrDefList import de.ugoe.cs.swe.tTCN3.ExtFunctionDef import de.ugoe.cs.swe.tTCN3.FunctionDef import de.ugoe.cs.swe.tTCN3.FunctionInstance import de.ugoe.cs.swe.tTCN3.FunctionStatement import de.ugoe.cs.swe.tTCN3.FunctionStatementList import de.ugoe.cs.swe.tTCN3.LogStatement import de.ugoe.cs.swe.tTCN3.ModuleControlBody import de.ugoe.cs.swe.tTCN3.PredefinedValue import de.ugoe.cs.swe.tTCN3.SetLocalVerdict import de.ugoe.cs.swe.tTCN3.TTCN3Reference import de.ugoe.cs.swe.tTCN3.TestcaseDef import de.ugoe.cs.swe.tTCN3.Value import de.ugoe.cs.swe.tTCN3.VerdictTypeValue import java.util.regex.Matcher import java.util.regex.Pattern import org.eclipse.xtext.nodemodel.INode import org.eclipse.xtext.nodemodel.util.NodeModelUtils import org.eclipse.xtext.validation.AbstractDeclarativeValidator import org.eclipse.xtext.validation.Check import org.eclipse.xtext.validation.EValidatorRegistrar import static extension de.ugoe.cs.swe.common.TTCN3ScopeHelper.* import static extension org.eclipse.xtext.EcoreUtil2.* class LogValidator extends AbstractDeclarativeValidator { val ConfigTools configTools = ConfigTools.getInstance; var QualityCheckProfile activeProfile = configTools.selectedProfile as QualityCheckProfile @Check def checkLogStatementFormat(FunctionStatementList functionStmList) { val parentTC = functionStmList.findDesiredParent(TestcaseDef) val parentFunc = functionStmList.findDesiredParent(FunctionDef) val parentAlt = functionStmList.findDesiredParent(AltstepDef) var TTCN3Reference parent = null; if (parentTC != null) { parent = parentTC; } else if (parentFunc != null) { parent = parentFunc; } else if (parentAlt != null) { parent = parentAlt; } var INode node = null var statementToCheck = "" var other = false for (s : functionStmList.eContents) { if (s instanceof FunctionStatement) { val log = s.findLogStatement if (log != null) { node = NodeModelUtils.getNode(log) if (other) { if (!Strings.isNullOrEmpty(statementToCheck)) { statementToCheck.checkLogStatementFormat(node, parent) } other = false statementToCheck = "" } statementToCheck += log.concatLogItems if (!activeProfile.processSubsequentLogStatementsAsOne) { statementToCheck.checkLogStatementFormat(node, parent) statementToCheck = "" } } else { other = true } } } if (!Strings.isNullOrEmpty(statementToCheck)) { statementToCheck.checkLogStatementFormat(node, parent) } } @Check def checkLogStatementFormat(ModuleControlBody ctrl) { var INode node = null var statementToCheck = "" var other = false for (s : ctrl.eContents) { if (s instanceof ControlStatementOrDefList) { val log = s.findLogStatement if (log != null) { node = NodeModelUtils.getNode(log) if (other) { if (!Strings.isNullOrEmpty(statementToCheck)) { statementToCheck.checkLogStatementFormat(node, null) } other = false statementToCheck = "" } statementToCheck += log.concatLogItems if (!activeProfile.processSubsequentLogStatementsAsOne) { statementToCheck.checkLogStatementFormat(node, null) statementToCheck = "" } } else { other = true } } } if (!Strings.isNullOrEmpty(statementToCheck)) { statementToCheck.checkLogStatementFormat(node, null) } } private def LogStatement findLogStatement(ControlStatementOrDefList stm) { if (stm.def.control != null && stm.def.control.basic != null && stm.def.control.basic.log != null) { return stm.def.control.basic.log } else { return null } } private def LogStatement findLogStatement(FunctionStatement stm) { if (stm.basic != null && stm.basic.log != null) { return stm.basic.log } else { return null } } private def String concatLogItems(LogStatement log) { var logString = "" val items = log.getAllContentsOfType(PredefinedValue) for (i : items) { if (i.charString != null) { var String subString = i.charString.toString.subSequence(1, i.charString.toString.length - 1) as String logString += subString.replaceAll("\"\"", "\"") } } return logString; } private def checkLogStatementFormat(String log, INode node, TTCN3Reference parent) { var problemOccured = false var warning = "" val Pattern logPattern = Pattern.compile(activeProfile.getLogFormatRegExp(), Pattern.DOTALL) val Matcher logMatcher = logPattern.matcher(log) if (!logMatcher.matches()) { problemOccured = true; warning = "Invalid log format (\"" + log + "\")!"; } else if (!logMatcher.group(1).equals("") && parent != null) { val logItemContainerIdentifier = logMatcher.group(1) if (!parent.name.equals(logItemContainerIdentifier)) { problemOccured = true; warning = "Log statement contains invalid container identifier (\"" + logItemContainerIdentifier + "\", should be \"" + parent.name + "\")!"; } } if (problemOccured) { TTCN3StatisticsProvider.getInstance.incrementCountLog warning( warning, null, MessageClass.LOGGING.toString, node.startLine.toString, node.endLine.toString, "5.1, " + MiscTools.getMethodName() ); } } @Check def checkExternalFunctionInvocationPrecededByLogStatement(FunctionInstance function) { if (!activeProfile.checkExternalFunctionInvocationPrecededByLogStatement) return; val INode node = NodeModelUtils.getNode(function) var problemsOccured = false if (function.ref instanceof ExtFunctionDef) { val parent = function.findDesiredParent(FunctionStatement) val parentList = function.findDesiredParent(FunctionStatementList) if (parent == null) { val message = "Call to external function \"" + function.ref.name + "\" within a definition on the module level. It cannot be preceded by a log statement!" info( message, null, MessageClass.LOGGING.toString, node.startLine.toString, node.endLine.toString, "5.3, " + MiscTools.getMethodName(), LogLevel.INFORMATION.toString ); } else { val items = parentList.eContents val idx = items.indexOf(parent) if (idx > 0 && idx < items.size) { val log = (items.get(idx - 1) as FunctionStatement).findLogStatement if (log == null) { problemsOccured = true } } else { problemsOccured = true } } } if (problemsOccured) { TTCN3StatisticsProvider.getInstance.incrementCountLog val message = "Call to external function \"" + function.ref.name + "\" not preceded by a log statement!" warning( message, null, MessageClass.LOGGING.toString, node.startLine.toString, node.endLine.toString, "5.3, " + MiscTools.getMethodName() ); } } @Check def checkInconcOrFailSetverdictPrecededByLog(SetLocalVerdict verdict) { if (!activeProfile.checkInconcOrFailSetVerdictPrecededByLog) return; val parent = verdict.findDesiredParent(FunctionStatement) val parentList = verdict.findDesiredParent(FunctionStatementList) val INode node = NodeModelUtils.getNode(verdict) var problemsOccured = false val exp = verdict.expression var isInconcOrFail = false if (exp instanceof Value) { if (exp.predef != null && exp.predef.verdictType != null) { if (exp.predef.verdictType == VerdictTypeValue.INCONC || exp.predef.verdictType == VerdictTypeValue.FAIL) { isInconcOrFail = true } } } if (!isInconcOrFail) return; val items = parentList.eContents val idx = items.indexOf(parent) if (idx > 0 && idx < items.size) { val log = (items.get(idx - 1) as FunctionStatement).findLogStatement if (log == null) { problemsOccured = true } } else { problemsOccured = true } if (problemsOccured) { TTCN3StatisticsProvider.getInstance.incrementCountLog val message = "No log statement precedes a fail or inconc setverdict statement!!" warning( message, null, MessageClass.LOGGING.toString, node.startLine.toString, node.endLine.toString, "5.4, " + MiscTools.getMethodName() ); } } override register(EValidatorRegistrar registrar) { //not needed for classes used as ComposedCheck } }