source: trunk/t3q/src/org/etsi/t3q/visitor/NamingConventionsChecker.java @ 7

Last change on this file since 7 was 7, checked in by phdmakk, 14 years ago
  • Property svn:mime-type set to text/plain
File size: 14.9 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                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
151                                .getPortInstanceRegExp();
152                LocationAST portElementNode = node.getFirstChild().getNextSibling();
153                do {
154                        checkIdentifierForNamingConventionCompliance(portElementNode,
155                                        regExp, "PortInstance");
156                } while ((portElementNode = portElementNode.getNextSibling()) != null);
157        }
158
159        public void checkTestcase(LocationAST node) {
160                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
161                                .getTestcaseRegExp();
162                checkIdentifierForNamingConventionCompliance(node, regExp, "Testcase");
163        }
164
165        public void checkSignatureTemplate(LocationAST node) {
166                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
167                                .getSignatureTemplateRegExp();
168                checkIdentifierForNamingConventionCompliance(node, regExp,
169                                "SignatureTemplate");
170        }
171
172        public void checkFormalParameter(LocationAST node) {
173                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
174                                .getFormalParameterRegExp();
175                LocationAST identifierNode = (LocationAST) ASTUtil.findSibling(node
176                                .getFirstChild(), TTCN3ParserTokenTypes.Identifier);
177                checkIdentifierForNamingConventionCompliance(identifierNode, regExp,
178                                "FormalParameter");
179        }
180
181        public void checkEnumeratedValue(LocationAST node) {
182                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
183                                .getEnumeratedValueRegExp();
184                checkIdentifierForNamingConventionCompliance(node, regExp,
185                                "EnumeratedValue");
186        }
187
188        public void checkDataType(LocationAST node) {
189                String regExp = T3Q.activeProfile.getNamingConventionsConfig()
190                                .getDataTypeRegExp();
191                LocationAST targetNode = node;
192                // adjust for differences in tree structure
193                if ((node.getNthChild(2).getType() == TTCN3ParserTokenTypes.RecordOfDef)
194                                || (node.getNthChild(2).getType() == TTCN3ParserTokenTypes.SetOfDef)) {
195                        if (node.getNthChild(3).getType() == TTCN3ParserTokenTypes.StringLength){
196                                targetNode = node.getNthChild(3).getNextSibling().getFirstChild().getNextSibling();
197                        } else {
198                                targetNode = node.getNthChild(4).getNextSibling();
199                        }
200                } else if (node.getFirstChild().getType() == TTCN3ParserTokenTypes.SubTypeDef) {
201                        targetNode = node.getNthChild(2).getNextSibling();
202                }
203                checkIdentifierForNamingConventionCompliance(targetNode, regExp,
204                                "DataType");
205        }
206
207        public void checkSTF160Template(LocationAST node) {
208                String regExp = "";
209                String templateType = "";
210                boolean isSendTemplate = false;
211                boolean isAmbiguous = false;
212                LocationAST identifierNode = null;
213                boolean isDerived = false;
214                if (ASTUtil.findDerivedDef(node)!= null){
215                        isDerived = true;
216                }
217
218                //duplicates checkMessageTemplate
219                if (node.getFirstChild().getType() == TTCN3ParserTokenTypes.BaseTemplate) {
220                        identifierNode = node.getFirstChild().getFirstChild()
221                                        .getNextSibling();
222                } else {
223                        identifierNode = node.getFirstChild().getNextSibling()
224                                        .getFirstChild().getNextSibling();
225                }
226                //end of duplication
227               
228                LocationAST templateRestrictionNode = (LocationAST) ASTUtil.findChild(node,
229                                TTCN3ParserTokenTypes.TemplateRestriction);
230                if (templateRestrictionNode != null) {
231                        // check if it is not a present restriction
232                        if (templateRestrictionNode.getFirstChild().getType() != TTCN3ParserTokenTypes.PRESENT) {
233
234                                LinkedList<LocationAST> formalTemplateParameters = ASTUtil.findTypeNodes(node,
235                                                TTCN3ParserTokenTypes.FormalTemplatePar);
236                                for (LocationAST formalTemplateParameter : formalTemplateParameters) {
237                                        LinkedList<LocationAST> formalParameterTemplateRestrictionNodes = ASTUtil.findTypeNodes(formalTemplateParameter,
238                                                        TTCN3ParserTokenTypes.TemplateRestriction);
239                                        if (formalParameterTemplateRestrictionNodes == null
240                                                        || formalParameterTemplateRestrictionNodes.isEmpty()) {
241                                                // problem occurred, inconsistent definition
242                                                isAmbiguous=true;
243                                        } else {
244                                                LocationAST restrictionNode = formalParameterTemplateRestrictionNodes.get(0);
245                                                if (restrictionNode.getFirstChild().getType() == TTCN3ParserTokenTypes.PRESENT) {
246                                                        // problem occurred, inconsistent definition
247                                                        isAmbiguous     = true;
248                                                }
249                                        }
250                                        if (isAmbiguous) {
251                                                checker
252                                                .getLoggingInterface()
253                                                .logInformation(
254                                                                node.getLine(),
255                                                                node.getEndLine(),
256                                                                MessageClass.NAMING,
257                                                                "The template definition for \""
258                                                                                + identifierNode.getFirstChild().getText()
259                                                                                + "\" 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.",
260                                                                "2.1, " + MiscTools.getMethodName());
261                                                return;
262                                        }
263                                }
264                                //if no problems occurred this far check name for send template
265                                isSendTemplate = true;
266                        }
267                        //(else) check name for receive template
268                }
269                //(else) check name for receive template
270                if (!isDerived) {
271                        if (isSendTemplate) {
272                                templateType = "STF160SendTemplate";
273                                regExp = T3Q.activeProfile      .getNamingConventionsConfig()
274                                                                                        .getStf160sendTemplateRegExp();
275                        } else {
276                                templateType = "STF160ReceiveTemplate";
277                                regExp = T3Q.activeProfile      .getNamingConventionsConfig()
278                                                                                        .getStf160receiveTemplateRegExp();
279                        }
280                } else {
281                        if (isSendTemplate) {
282                                templateType = "DerivedSTF160SendTemplate";
283                                regExp = T3Q.activeProfile      .getNamingConventionsConfig()
284                                                                                        .getDerivedStf160sendTemplateRegExp();
285                        } else {
286                                templateType = "DerivedSTF160ReceiveTemplate";
287                                regExp = T3Q.activeProfile      .getNamingConventionsConfig()
288                                                                                        .getDerivedStf160receiveTemplateRegExp();
289                        }
290
291                }
292                checkIdentifierForNamingConventionCompliance(identifierNode, regExp,
293                                templateType);
294        }
295       
296       
297       
298       
299        public void checkMessageTemplate(LocationAST node) {
300                // TODO: needs a deep analysis of contents (analyzing the referenced
301                // template types if any) and also modified templates (which may be
302                // difficult to impossible)
303                String regExp = "";
304                String templateType = "";
305                boolean isDerived = false;
306                if (ASTUtil.findDerivedDef(node)!= null){
307                        isDerived = true;
308                }
309               
310                // basic shallow search
311                LinkedList<LocationAST> matchingSymbolNodes = ASTUtil.findTypeNodes(
312                                node, TTCN3ParserTokenTypes.MatchingSymbol);
313                // TODO: implement an advanced deep search
314
315               
316                if (!isDerived){
317                        if (matchingSymbolNodes.isEmpty()) {
318                                regExp = T3Q.activeProfile      .getNamingConventionsConfig()
319                                                                                        .getMessageTemplateRegExp();
320                                templateType = "MessageTemplate";
321                        } else {
322                                regExp = T3Q.activeProfile      .getNamingConventionsConfig()
323                                                                                        .getMessageTemplateWithWildcardsRegExp();
324                                templateType = "MessageTemplateWithMatchingExpression";
325                        }
326                } else {
327                        if (matchingSymbolNodes.isEmpty()) {
328                                regExp = T3Q.activeProfile.getNamingConventionsConfig()
329                                                .getDerivedMessageTemplateRegExp();
330                                templateType = "DerivedMessageTemplate";
331                        } else {
332                                regExp = T3Q.activeProfile.getNamingConventionsConfig()
333                                                .getDerivedMessageTemplateWithWildcardsRegExp();
334                                templateType = "DerivedMessageTemplateWithMatchingExpression";
335                        }
336                       
337                }
338                LocationAST identifierNode = null;
339
340                //duplicated in checkSTF160Template
341                if (node.getFirstChild().getType() == TTCN3ParserTokenTypes.BaseTemplate) {
342                        identifierNode = node.getFirstChild().getFirstChild()
343                                        .getNextSibling();
344                } else {
345                        identifierNode = node.getFirstChild().getNextSibling()
346                                        .getFirstChild().getNextSibling();
347                }
348
349                checkIdentifierForNamingConventionCompliance(identifierNode, regExp,
350                                templateType);
351        }
352
353        public void checkTimer(LocationAST node) {
354                String regExp = "";
355                String timerType = "";
356
357                if (node.getParent().getType() == TTCN3ParserTokenTypes.ComponentElementDef) {
358                        regExp = T3Q.activeProfile.getNamingConventionsConfig()
359                                        .getComponentTimerRegExp();
360                        timerType = "ComponentTimer";
361                } else {
362                        regExp = T3Q.activeProfile.getNamingConventionsConfig()
363                                        .getTimerRegExp();
364                        timerType = "Timer";
365                }
366                LocationAST singleTimerInstanceNode = node.getFirstChild();
367                do {
368                        checkIdentifierForNamingConventionCompliance(
369                                        singleTimerInstanceNode, regExp, timerType);
370                } while ((singleTimerInstanceNode = singleTimerInstanceNode
371                                .getNextSibling()) != null);
372
373        }
374
375        public void checkVariable(LocationAST node) {
376                String regExp = "";
377                String variableType = "";
378
379                if (node.getParent().getType() == TTCN3ParserTokenTypes.ComponentElementDef) {
380                        regExp = T3Q.activeProfile.getNamingConventionsConfig()
381                                        .getComponentVariableRegExp();
382                        variableType = "ComponentVariable";
383                } else {
384                        regExp = T3Q.activeProfile.getNamingConventionsConfig()
385                                        .getVariableRegExp();
386                        variableType = "Variable";
387                }
388
389                LocationAST typeNode = node.getFirstChild();
390                if (node.getFirstChild().getType() != TTCN3ParserTokenTypes.Type) {
391                        typeNode = typeNode.getNextSibling();
392                }
393
394                if (typeNode.getFirstChild().getType() == TTCN3ParserTokenTypes.ReferencedType) {
395                        LocationAST typeReferenceNode = typeNode.getNthChild(2);
396                        if (typeReferenceNode.getType() != TTCN3ParserTokenTypes.TypeReference) {
397                                typeReferenceNode = typeReferenceNode.getNextSibling();
398                        }
399                        LocationAST typeNodeIdentifier = typeReferenceNode.getNthChild(2);
400                        Symbol typeSymbol = typeNodeIdentifier.getSymbol();
401                        if (typeSymbol == null) {
402                                checker
403                                                .getLoggingInterface()
404                                                .logInformation(
405                                                                node.getLine(),
406                                                                node.getEndLine(),
407                                                                MessageClass.NAMING,
408                                                                "The type declaration for \""
409                                                                                + typeNodeIdentifier.getText()
410                                                                                + "\" 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.",
411                                                                "2.1, " + MiscTools.getMethodName());
412                               
413                        } else {
414                                LocationAST declarationNode = typeSymbol.getDeclarationNode();
415                                if (declarationNode.getNthParent(2).getType() == TTCN3ParserTokenTypes.ComponentDef) {
416                                        regExp = T3Q.activeProfile
417                                                        .getNamingConventionsConfig()
418                                                        .getComponentInstanceRegExp();
419                                        variableType = "ComponentInstance";
420
421                                }
422                        }
423                }
424
425                LocationAST singleVarInstanceNode = typeNode.getNextSibling()
426                                .getFirstChild();
427                do {
428                        checkIdentifierForNamingConventionCompliance(singleVarInstanceNode,
429                                        regExp, variableType);
430                } while ((singleVarInstanceNode = singleVarInstanceNode
431                                .getNextSibling()) != null);
432        }
433
434}
Note: See TracBrowser for help on using the repository browser.