package org.etsi.t3q.visitor; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.etsi.common.MiscTools; import org.etsi.common.logging.LoggingInterface.MessageClass; import org.etsi.t3q.T3Q; import de.ugoe.cs.swe.trex.core.analyzer.astutil.ReferenceFinder; import de.ugoe.cs.swe.trex.core.analyzer.astutil.ReferenceWithContext; import de.ugoe.cs.swe.trex.core.analyzer.rfparser.LocationAST; import de.ugoe.cs.swe.trex.core.analyzer.rfparser.TTCN3ParserTokenTypes; import de.ugoe.cs.swe.trex.core.analyzer.rfparser.symboltable.Symbol; public class QualityCheckerExtras extends QualityChecker { public QualityCheckerExtras(T3QVisitor visitor) { super(visitor); // TODO Auto-generated constructor stub } public void checkZeroReferencedTestCases(LocationAST node) { if (node.getFirstChild().getType() != TTCN3ParserTokenTypes.TestcaseDef){ return; } ArrayList identifiersList = LocationAST.getModuleDefinitionIdentifiersList(node); LocationAST identifierNode = null; String identifierText = null; for (int i = 0; i < identifiersList.size(); i++){ identifierNode = identifiersList.get(i); identifierText = identifierNode.getFirstChild().getText(); Symbol s = identifierNode.getFirstChild().getSymbol(); //TODO: add safety check here if (getReferenceFinder().countReferences(s) == 0){ //TODO: add stats counters //TODO: add type information //TODO: groups shall probably be excluded this.getLoggingInterface().logWarning(identifierNode.getLine(), identifierNode.getEndLine(), MessageClass.LOGGING, "Testcase definition for \""+identifierText+"\" is never used!", MiscTools.getMethodName()); } } } public void checkSetVerdictPrecededByLog(LocationAST node) { //TODO: duplicated and combined constraints (presence and content according to context) // Fixed: currently based on SetLocalVerdict node, // consider starting at the fail or inconc node instead, checking // whether it is // within a set verdict context and proceed from there // fix: it is specific to the set verdict and not to inconc or fail // alone boolean problemOccured = false; String warning = ""; if (node.getFirstChild().getType() == TTCN3ParserTokenTypes.Fail){ LocationAST functionStatementOrDefNode = LocationAST.resolveParentsUntilType(node, TTCN3ParserTokenTypes.FunctionStatement); LocationAST parentNode = functionStatementOrDefNode.getParent(); LocationAST siblingNode = parentNode.getFirstChild(); LocationAST prevSiblingNode = null; do { if (siblingNode.getType()!=TTCN3ParserTokenTypes.SemiColon){ prevSiblingNode = siblingNode; } siblingNode = siblingNode.getNextSibling(); } while ((siblingNode != functionStatementOrDefNode) && (siblingNode !=null)); if (prevSiblingNode!=null && prevSiblingNode.getType()==TTCN3ParserTokenTypes.FunctionStatement){ if (prevSiblingNode.getNthChild(3).getType()!=TTCN3ParserTokenTypes.LogStatement){ problemOccured = true; warning = "Failing verdict not preceded by a log statement"; } else { //check log statement format according to context LocationAST moduleDefinitionNode = LocationAST.resolveParentsUntilType(node, TTCN3ParserTokenTypes.ModuleDefinition); if (moduleDefinitionNode.getFirstChild().getType()==TTCN3ParserTokenTypes.AltstepDef){ LocationAST altstepDefIdentifierNode = moduleDefinitionNode.getNthChild(3); //CHECK REFERENCING CONTEXTS int activatedAsDefault = 0; boolean mixedContext = false; Symbol altstepDefSymbol = altstepDefIdentifierNode.getSymbol(); Map> referenceMap = getReferenceFinder() .findReferences(altstepDefSymbol); if (referenceMap.isEmpty()) { activatedAsDefault = -1; } else { Iterator>> referenceMapIterator = referenceMap .entrySet().iterator(); while (referenceMapIterator.hasNext()) { Entry> referenceEntry = referenceMapIterator .next(); Iterator referenceIterator = referenceEntry .getValue().iterator(); while (referenceIterator.hasNext()) { ReferenceWithContext referenceWithContext = referenceIterator .next(); LocationAST referenceNode = referenceWithContext .getReferenceNode(); //HERE if (referenceNode.getNthParent(3).getType() != TTCN3ParserTokenTypes.ActivateOp) { if (activatedAsDefault==1){ mixedContext = true; } activatedAsDefault = -1; } else { if (activatedAsDefault==-1){ mixedContext = true; } activatedAsDefault = 1; } } } } if (mixedContext){ this.getLoggingInterface().logInformation(node.getLine(), node.getEndLine(), MessageClass.LOGGING, "Alstep \""+altstepDefIdentifierNode.getText()+"\" is used in mixed contexts (both activated as default and not), therefore the results for the correct log statement format may be unreliable!", MiscTools.getMethodName()); } if (activatedAsDefault > 0){ this.checkLogStatementFormat(prevSiblingNode.getNthChild(3),false); } else { this.checkLogStatementFormat(prevSiblingNode.getNthChild(3),true); } } } } else { problemOccured = true; warning = "Failing verdict not preceded by a log statement!"; } } if (node.getFirstChild().getType() == TTCN3ParserTokenTypes.None){ //TODO: DUPLICATE BLOCK LocationAST functionStatementOrDefNode = LocationAST.resolveParentsUntilType(node, TTCN3ParserTokenTypes.FunctionStatement); LocationAST parentNode = functionStatementOrDefNode.getParent(); LocationAST siblingNode = parentNode.getFirstChild(); LocationAST prevSiblingNode = null; do { if (siblingNode.getType()!=TTCN3ParserTokenTypes.SemiColon){ prevSiblingNode = siblingNode; } siblingNode = siblingNode.getNextSibling(); } while ((siblingNode != functionStatementOrDefNode) && (siblingNode !=null)); if (prevSiblingNode!=null && prevSiblingNode.getType()==TTCN3ParserTokenTypes.FunctionStatement){ if (prevSiblingNode.getNthChild(3).getType()!=TTCN3ParserTokenTypes.LogStatement){ problemOccured = true; warning = "Verdict \"none\" not preceded by a log statement!"; } else { this.checkLogStatementFormat(prevSiblingNode.getNthChild(3),false); } } } if (problemOccured) { this.getLoggingInterface().logWarning(node.getLine(), node.getEndLine(), MessageClass.LOGGING, warning, MiscTools.getMethodName()); } // boolean problemOccured = false; // // if (ASTUtil.findChild(node, TTCN3ParserTokenTypes.Fail) != null // || ASTUtil.findChild(node, TTCN3ParserTokenTypes.Inconc) != null) { // // LocationAST parentNode = LocationAST.resolveParentsUntilType(node, // TTCN3ParserTokenTypes.FunctionStatementOrDef); // // int functionStatementOrDefsVisited = visitor // .getFunctionStatementOrDefNodes().size(); // if (parentNode == visitor.getFunctionStatementOrDefNodes().get( // functionStatementOrDefsVisited - 1)) { // int i = functionStatementOrDefsVisited - 2; // if (i > 0) { // LocationAST next = null; // // skip semicolons // next = visitor.getFunctionStatementOrDefNodes().get(i) // .getNextSibling(); // while ((next != null) // && (next.getType() == TTCN3ParserTokenTypes.SemiColon)) { // next = next.getNextSibling(); // } // // if (next == parentNode) { // LocationAST resultNode = (LocationAST) ASTUtil // .findChild(visitor // .getFunctionStatementOrDefNodes() // .get(i), // TTCN3ParserTokenTypes.LogStatement); // if (resultNode == null) { // problemOccured = true; // } // } else { // problemOccured = true; // } // } else { // problemOccured = true; // } // } // } } public void checkLogStatementFormat(LocationAST node, boolean withVerificationPoint) { boolean problemOccured = false; String warning = ""; String logItemText = ""; LocationAST logItem = node.getFirstChild(); do { if (logItem.getFirstChild().getType()!=TTCN3ParserTokenTypes.TemplateInstance){ logItemText += logItem.getFirstChild().getText(); } else { //TODO: attempt to perform resolution logItemText += "<>"; } logItem = logItem.getNextSibling(); } while (logItem!=null && logItem.getType()==TTCN3ParserTokenTypes.LogItem); Pattern logPattern = Pattern.compile(T3Q.activeProfile .getLogFormatRegExp()); Matcher logMatcher = logPattern.matcher(logItemText); if (!logMatcher.matches()) { problemOccured = true; warning = "Invalid log format (\"" + logItemText + "\")!"; } else if (logMatcher.group(1).equals("") && withVerificationPoint) { problemOccured = true; warning = "Invalid log format (\"" + logItemText + "\") - missing verification point!"; } if (problemOccured) { this.getLoggingInterface().logWarning(node.getLine(), node.getEndLine(), MessageClass.LOGGING, warning, MiscTools.getMethodName()); } } }