source: branches/t3e-tools/t3q/src/org/etsi/t3q/visitor/NamingConventionsChecker.java @ 28

Last change on this file since 28 was 28, checked in by phdmakk, 14 years ago
  • Property svn:mime-type set to text/plain
File size: 16.4 KB
Line 
1package org.etsi.t3q.visitor;
2
3import java.util.LinkedList;
4import java.util.List;
5import java.util.regex.Matcher;
6import java.util.regex.Pattern;
7
8import org.etsi.common.MiscTools;
9import org.etsi.common.exceptions.TerminationException;
10import org.etsi.common.logging.LoggingInterface.MessageClass;
11import org.etsi.t3q.T3Q;
12
13import antlr.collections.AST;
14
15import de.ugoe.cs.swe.trex.core.analyzer.rfparser.ASTUtil;
16import de.ugoe.cs.swe.trex.core.analyzer.rfparser.LocationAST;
17import de.ugoe.cs.swe.trex.core.analyzer.rfparser.TTCN3ParserTokenTypes;
18import de.ugoe.cs.swe.trex.core.analyzer.rfparser.symboltable.Symbol;
19
20public class NamingConventionsChecker {
21
22        private QualityChecker checker = null;
23
24        public NamingConventionsChecker(QualityChecker checker) {
25                this.checker = checker;
26        }
27
28        //TODO: remove coupling with quality checker and add custom logger, potentially the whole logging process shall be moved to a separate hierarchy
29       
30        private boolean regExpMatch(String regExp, String subject) {
31                boolean matches = false;
32                Pattern pattern = Pattern.compile(regExp);
33                Matcher matcher = pattern.matcher(subject);
34                // System.out.println(regExp + " : " + subject);
35                if (matcher.matches()) {
36                        matches = true;
37                }
38                return matches;
39        }
40
41        private void checkIdentifierForNamingConventionCompliance(LocationAST node,
42                        String regExp, String type) {
43                if (regExp == null){
44                        try {
45                                throw new TerminationException("ERROR: Naming conventions rule for \""+type+"\" is not set! Configuration profile may be outdated or corrupted!");
46                        } catch (TerminationException e) {
47                        }
48                }
49               
50                if (regExp.equals("")) {
51                        return;
52                }
53                LocationAST identifierNode = (LocationAST) ASTUtil.findChild(node,
54                                TTCN3ParserTokenTypes.Identifier);
55                if (identifierNode == null) {
56                        if (ASTUtil.findChild(node, TTCN3ParserTokenTypes.AddressKeyword) == null) {
57                                checker.getLoggingInterface().logFix(node.getLine(), node.getEndLine(), MessageClass.NAMING, "Could not determine identifier or address leaf node under: " + node + " while analyzing for type  \"" + type + "\"", "2.1, "+MiscTools.getMethodName());
58                        }
59                        return;
60                }
61                String identifier = identifierNode.getFirstChild().getText();
62
63                if (!regExpMatch(regExp, identifier)) {
64                        checker
65                                        .getLoggingInterface()
66                                        .logWarning(
67                                                        node.getLine(),
68                                                        node.getEndLine(),
69                                                        MessageClass.NAMING,
70                                                        "\""
71                                                                        + identifier
72                                                                        + "\" does not comply to the naming conventions for \""
73                                                                        + type + "\"!"
74                                                                        , "2.1, " + regExp);
75                       
76                }
77        }
78
79        public void checkFunction(LocationAST node) {
80                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
81                                .getFunctionRegExp();
82                checkIdentifierForNamingConventionCompliance(node, regExp, "Function");
83        }
84
85        public void checkExtFunction(LocationAST node) {
86                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
87                                .getExtFunctionRegExp();
88                checkIdentifierForNamingConventionCompliance(node, regExp,
89                                "ExtFunction");
90        }
91
92        public void checkConstant(LocationAST node) {
93                String regExp = "";
94                String message = "";
95                if (node.getNthParent(2).getType() == TTCN3ParserTokenTypes.ModuleDefinition){
96                        regExp = T3Q.activeProfile.getNamingConventionsConfig()
97                                        .getConstantRegExp();
98                        message = "Constant";
99                } else {
100                        regExp = T3Q.activeProfile.getNamingConventionsConfig()
101                        .getLocalConstantRegExp();
102                        message = "Local Constant";
103                }
104                checkIdentifierForNamingConventionCompliance(node, regExp, message);
105
106        }
107
108        public void checkExtConstant(LocationAST node) {
109                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
110                                .getExtConstantRegExp();
111
112                LocationAST identifierNode = node.getFirstChild().getNextSibling();
113                do {
114                        checkIdentifierForNamingConventionCompliance(identifierNode,
115                                        regExp, "External Constant");
116                } while ((identifierNode = identifierNode.getNextSibling()) != null);
117        }
118
119        public void checkAltstep(LocationAST node) {
120                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
121                                .getAltstepRegExp();
122                checkIdentifierForNamingConventionCompliance(node, regExp, "Altstep");
123        }
124
125        public void checkGroup(LocationAST node) {
126                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
127                                .getGroupRegExp();
128                checkIdentifierForNamingConventionCompliance(node, regExp, "Group");
129        }
130
131        public void checkModule(LocationAST node) {
132                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
133                                .getModuleRegExp();
134                checkIdentifierForNamingConventionCompliance(node, regExp, "Module");
135        }
136
137        public void checkModuleParameter(LocationAST node) {
138                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
139                                .getModuleParameterRegExp();
140                LocationAST identifierNode = node.getFirstChild();
141                do {
142                        if (identifierNode.getType() == TTCN3ParserTokenTypes.Identifier) {
143                                checkIdentifierForNamingConventionCompliance(identifierNode,
144                                                regExp, "ModuleParameter");
145                        }
146                } while ((identifierNode = identifierNode.getNextSibling()) != null);
147        }
148
149        public void checkPortInstance(LocationAST node) {
150                //TODO: quickly hacked together, revise, improve
151                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
152                                .getPortInstanceRegExp();
153                String typeRegExp = "";
154                String portType = "";
155               
156                LocationAST portElementNode = node.getFirstChild().getNextSibling();
157                LocationAST portTypeIdentifier = node.getParent().getFirstChild().getFirstChild().getFirstChild().getFirstChild();
158                Symbol portTypeSymbol = portTypeIdentifier.getSymbol();
159                if (portTypeSymbol!=null) {
160                        LocationAST portTypeDeclarationNode = portTypeSymbol.getDeclarationNode();
161                        LocationAST portAttribs = portTypeDeclarationNode.getParent().getNextSibling().getFirstChild();
162                        if (portAttribs.getType()==TTCN3ParserTokenTypes.MessageAttribs) {
163                                typeRegExp = T3Q.activeProfile.getNamingConventionsConfig()
164                                .getMessagePortInstanceRegExp();
165                                portType = "MessagePortInstance";
166                        } else {
167                                if (portAttribs.getType()==TTCN3ParserTokenTypes.StreamAttribs) {
168                                        typeRegExp = T3Q.activeProfile.getNamingConventionsConfig()
169                                        .getStreamPortInstanceRegExp();
170                                        portType = "StreamPortInstance";
171                                }
172                        }
173                } else {
174                        //handle
175                }
176                do {
177                        checkIdentifierForNamingConventionCompliance(portElementNode,
178                                        regExp, "PortInstance");
179                        if (portTypeSymbol==null) {
180                                checker
181                                .getLoggingInterface()
182                                .logInformation(
183                                                node.getLine(),
184                                                node.getEndLine(),
185                                                MessageClass.NAMING,
186                                                "The definition for port type \"" +
187                                                portTypeIdentifier.getText()+
188                                                "\" cannot be resolved. It cannot be determined which naming convention port instance \""
189                                                                + portElementNode.getFirstChild().getFirstChild().getText()
190                                                                + "\" shall comply to!"
191                                                                , "2.1");
192
193                        } else {
194                                checkIdentifierForNamingConventionCompliance(portElementNode,
195                                                typeRegExp, portType);
196                        }
197                } while ((portElementNode = portElementNode.getNextSibling()) != null);
198        }
199
200        //TODO: differentiate between stream and message ports
201       
202        public void checkTestcase(LocationAST node) {
203                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
204                                .getTestcaseRegExp();
205                checkIdentifierForNamingConventionCompliance(node, regExp, "Testcase");
206        }
207
208        public void checkSignatureTemplate(LocationAST node) {
209                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
210                                .getSignatureTemplateRegExp();
211                checkIdentifierForNamingConventionCompliance(node, regExp,
212                                "SignatureTemplate");
213        }
214
215        public void checkFormalParameter(LocationAST node) {
216                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
217                                .getFormalParameterRegExp();
218                LocationAST identifierNode = (LocationAST) ASTUtil.findSibling(node
219                                .getFirstChild(), TTCN3ParserTokenTypes.Identifier);
220                checkIdentifierForNamingConventionCompliance(identifierNode, regExp,
221                                "FormalParameter");
222        }
223
224        public void checkEnumeratedValue(LocationAST node) {
225                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
226                                .getEnumeratedValueRegExp();
227                checkIdentifierForNamingConventionCompliance(node, regExp,
228                                "EnumeratedValue");
229        }
230
231        public void checkDataType(LocationAST node) {
232                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
233                                .getDataTypeRegExp();
234                LocationAST targetNode = node;
235                // adjust for differences in tree structure
236                if ((node.getNthChild(2).getType() == TTCN3ParserTokenTypes.RecordOfDef)
237                                || (node.getNthChild(2).getType() == TTCN3ParserTokenTypes.SetOfDef)) {
238                        if (node.getNthChild(3).getType() == TTCN3ParserTokenTypes.StringLength){
239                                targetNode = node.getNthChild(3).getNextSibling().getFirstChild().getNextSibling();
240                        } else {
241                                targetNode = node.getNthChild(4).getNextSibling();
242                        }
243                } else if (node.getFirstChild().getType() == TTCN3ParserTokenTypes.SubTypeDef) {
244                        targetNode = node.getNthChild(2).getNextSibling();
245                }
246                checkIdentifierForNamingConventionCompliance(targetNode, regExp,
247                                "DataType");
248        }
249
250        public void checkSTF160Template(LocationAST node) {
251                String regExp = "";
252                String templateType = "";
253                boolean isSendTemplate = false;
254                boolean isAmbiguous = false;
255                LocationAST identifierNode = null;
256                boolean isDerived = false;
257                if (ASTUtil.findDerivedDef(node)!= null){
258                        isDerived = true;
259                }
260
261                //duplicates checkMessageTemplate
262                if (node.getFirstChild().getType() == TTCN3ParserTokenTypes.BaseTemplate) {
263                        identifierNode = node.getFirstChild().getFirstChild()
264                                        .getNextSibling();
265                } else {
266                        identifierNode = node.getFirstChild().getNextSibling()
267                                        .getFirstChild().getNextSibling();
268                }
269                //end of duplication
270               
271                LocationAST templateRestrictionNode = (LocationAST) ASTUtil.findChild(node,
272                                TTCN3ParserTokenTypes.TemplateRestriction);
273                if (templateRestrictionNode != null) {
274                        // check if it is not a present restriction
275                        if (templateRestrictionNode.getFirstChild().getType() != TTCN3ParserTokenTypes.PRESENT) {
276
277                                LinkedList<LocationAST> formalTemplateParameters = ASTUtil.findTypeNodes(node,
278                                                TTCN3ParserTokenTypes.FormalTemplatePar);
279                                for (LocationAST formalTemplateParameter : formalTemplateParameters) {
280                                        LinkedList<LocationAST> formalParameterTemplateRestrictionNodes = ASTUtil.findTypeNodes(formalTemplateParameter,
281                                                        TTCN3ParserTokenTypes.TemplateRestriction);
282                                        if (formalParameterTemplateRestrictionNodes == null
283                                                        || formalParameterTemplateRestrictionNodes.isEmpty()) {
284                                                // problem occurred, inconsistent definition
285                                                isAmbiguous=true;
286                                        } else {
287                                                LocationAST restrictionNode = formalParameterTemplateRestrictionNodes.get(0);
288                                                if (restrictionNode.getFirstChild().getType() == TTCN3ParserTokenTypes.PRESENT) {
289                                                        // problem occurred, inconsistent definition
290                                                        isAmbiguous     = true;
291                                                }
292                                        }
293                                        if (isAmbiguous) {
294                                                checker
295                                                .getLoggingInterface()
296                                                .logInformation(
297                                                                node.getLine(),
298                                                                node.getEndLine(),
299                                                                MessageClass.NAMING,
300                                                                "The template definition for \""
301                                                                                + identifierNode.getFirstChild().getText()
302                                                                                + "\" is ambiguous. It cannot be determined whether it is a send or a receive template according to STF160's conventions. It will not be analyzed further for naming conventions compliance.",
303                                                                "2.1, " + MiscTools.getMethodName());
304                                                return;
305                                        }
306                                }
307                                //if no problems occurred this far check name for send template
308                                isSendTemplate = true;
309                        }
310                        //(else) check name for receive template
311                }
312                //(else) check name for receive template
313                if (!isDerived) {
314                        if (isSendTemplate) {
315                                templateType = "STF160SendTemplate";
316                                regExp = T3Q.activeProfile      .getNamingConventionsConfig()
317                                                                                        .getStf160sendTemplateRegExp();
318                        } else {
319                                templateType = "STF160ReceiveTemplate";
320                                regExp = T3Q.activeProfile      .getNamingConventionsConfig()
321                                                                                        .getStf160receiveTemplateRegExp();
322                        }
323                } else {
324                        if (isSendTemplate) {
325                                templateType = "DerivedSTF160SendTemplate";
326                                regExp = T3Q.activeProfile      .getNamingConventionsConfig()
327                                                                                        .getDerivedStf160sendTemplateRegExp();
328                        } else {
329                                templateType = "DerivedSTF160ReceiveTemplate";
330                                regExp = T3Q.activeProfile      .getNamingConventionsConfig()
331                                                                                        .getDerivedStf160receiveTemplateRegExp();
332                        }
333
334                }
335                checkIdentifierForNamingConventionCompliance(identifierNode, regExp,
336                                templateType);
337        }
338       
339       
340       
341       
342        public void checkMessageTemplate(LocationAST node) {
343                // TODO: needs a deep analysis of contents (analyzing the referenced
344                // template types if any) and also modified templates (which may be
345                // difficult to impossible)
346                String regExp = "";
347                String templateType = "";
348                boolean isDerived = false;
349                if (ASTUtil.findDerivedDef(node)!= null){
350                        isDerived = true;
351                }
352               
353                // basic shallow search
354                LinkedList<LocationAST> matchingSymbolNodes = ASTUtil.findTypeNodes(
355                                node, TTCN3ParserTokenTypes.MatchingSymbol);
356                // TODO: implement an advanced deep search
357
358               
359                if (!isDerived){
360                        if (matchingSymbolNodes.isEmpty()) {
361                                regExp = T3Q.activeProfile      .getNamingConventionsConfig()
362                                                                                        .getMessageTemplateRegExp();
363                                templateType = "MessageTemplate";
364                        } else {
365                                regExp = T3Q.activeProfile      .getNamingConventionsConfig()
366                                                                                        .getMessageTemplateWithWildcardsRegExp();
367                                templateType = "MessageTemplateWithMatchingExpression";
368                        }
369                } else {
370                        if (matchingSymbolNodes.isEmpty()) {
371                                regExp = T3Q.activeProfile.getNamingConventionsConfig()
372                                                .getDerivedMessageTemplateRegExp();
373                                templateType = "DerivedMessageTemplate";
374                        } else {
375                                regExp = T3Q.activeProfile.getNamingConventionsConfig()
376                                                .getDerivedMessageTemplateWithWildcardsRegExp();
377                                templateType = "DerivedMessageTemplateWithMatchingExpression";
378                        }
379                       
380                }
381                LocationAST identifierNode = null;
382
383                //duplicated in checkSTF160Template
384                if (node.getFirstChild().getType() == TTCN3ParserTokenTypes.BaseTemplate) {
385                        identifierNode = node.getFirstChild().getFirstChild()
386                                        .getNextSibling();
387                } else {
388                        identifierNode = node.getFirstChild().getNextSibling()
389                                        .getFirstChild().getNextSibling();
390                }
391
392                checkIdentifierForNamingConventionCompliance(identifierNode, regExp,
393                                templateType);
394        }
395
396        public void checkTimer(LocationAST node) {
397                String regExp = "";
398                String timerType = "";
399
400                if (node.getParent().getType() == TTCN3ParserTokenTypes.ComponentElementDef) {
401                        regExp = T3Q.activeProfile.getNamingConventionsConfig()
402                                        .getComponentTimerRegExp();
403                        timerType = "ComponentTimer";
404                } else {
405                        regExp = T3Q.activeProfile.getNamingConventionsConfig()
406                                        .getTimerRegExp();
407                        timerType = "Timer";
408                }
409                LocationAST singleTimerInstanceNode = node.getFirstChild();
410                do {
411                        checkIdentifierForNamingConventionCompliance(
412                                        singleTimerInstanceNode, regExp, timerType);
413                } while ((singleTimerInstanceNode = singleTimerInstanceNode
414                                .getNextSibling()) != null);
415
416        }
417
418        public void checkVariable(LocationAST node) {
419                String regExp = "";
420                String variableType = "";
421
422                if (node.getParent().getType() == TTCN3ParserTokenTypes.ComponentElementDef) {
423                        regExp = T3Q.activeProfile.getNamingConventionsConfig()
424                                        .getComponentVariableRegExp();
425                        variableType = "ComponentVariable";
426                } else {
427                        regExp = T3Q.activeProfile.getNamingConventionsConfig()
428                                        .getVariableRegExp();
429                        variableType = "Variable";
430                }
431
432                LocationAST typeNode = node.getFirstChild();
433                if (node.getFirstChild().getType() != TTCN3ParserTokenTypes.Type) {
434                        typeNode = typeNode.getNextSibling();
435                }
436
437                if (typeNode.getFirstChild().getType() == TTCN3ParserTokenTypes.ReferencedType) {
438                        LocationAST typeReferenceNode = typeNode.getNthChild(2);
439                        if (typeReferenceNode.getType() != TTCN3ParserTokenTypes.TypeReference) {
440                                typeReferenceNode = typeReferenceNode.getNextSibling();
441                        }
442                        LocationAST typeNodeIdentifier = typeReferenceNode.getNthChild(2);
443                        Symbol typeSymbol = typeNodeIdentifier.getSymbol();
444                        if (typeSymbol == null) {
445                                checker
446                                                .getLoggingInterface()
447                                                .logInformation(
448                                                                node.getLine(),
449                                                                node.getEndLine(),
450                                                                MessageClass.NAMING,
451                                                                "The type declaration for \""
452                                                                                + typeNodeIdentifier.getText()
453                                                                                + "\" could not be resolved. It cannot be determined whether the variable instances of this type are component instances. They will be treated as variable instances.",
454                                                                "2.1, " + MiscTools.getMethodName());
455                               
456                        } else {
457                                LocationAST declarationNode = typeSymbol.getDeclarationNode();
458                                if (declarationNode.getNthParent(2).getType() == TTCN3ParserTokenTypes.ComponentDef) {
459                                        regExp = T3Q.activeProfile
460                                                        .getNamingConventionsConfig()
461                                                        .getComponentInstanceRegExp();
462                                        variableType = "ComponentInstance";
463
464                                }
465                        }
466                }
467
468                LocationAST singleVarInstanceNode = typeNode.getNextSibling()
469                                .getFirstChild();
470                do {
471                        checkIdentifierForNamingConventionCompliance(singleVarInstanceNode,
472                                        regExp, variableType);
473                } while ((singleVarInstanceNode = singleVarInstanceNode
474                                .getNextSibling()) != null);
475        }
476
477}
Note: See TracBrowser for help on using the repository browser.