1 | package org.etsi.t3d.visitor; |
---|
2 | |
---|
3 | import java.util.ArrayList; |
---|
4 | import java.util.Iterator; |
---|
5 | import java.util.LinkedList; |
---|
6 | import java.util.List; |
---|
7 | import java.util.Map; |
---|
8 | |
---|
9 | import org.apache.commons.lang.StringEscapeUtils; |
---|
10 | |
---|
11 | import antlr.RecognitionException; |
---|
12 | |
---|
13 | import de.ugoe.cs.swe.trex.core.analyzer.astutil.ReferenceFinder; |
---|
14 | import de.ugoe.cs.swe.trex.core.analyzer.astutil.ReferenceWithContext; |
---|
15 | import de.ugoe.cs.swe.trex.core.analyzer.rfparser.ASTUtil; |
---|
16 | import de.ugoe.cs.swe.trex.core.analyzer.rfparser.KeywordExtractor; |
---|
17 | import de.ugoe.cs.swe.trex.core.analyzer.rfparser.LocationAST; |
---|
18 | import de.ugoe.cs.swe.trex.core.analyzer.rfparser.TTCN3FormatterTreeParser; |
---|
19 | import de.ugoe.cs.swe.trex.core.analyzer.rfparser.TTCN3Lexer; |
---|
20 | import de.ugoe.cs.swe.trex.core.analyzer.rfparser.TTCN3ParserTokenTypes; |
---|
21 | import de.ugoe.cs.swe.trex.core.analyzer.rfparser.symboltable.Scope; |
---|
22 | import de.ugoe.cs.swe.trex.core.analyzer.rfparser.symboltable.Symbol; |
---|
23 | import de.ugoe.cs.swe.trex.core.formatter.TTCN3FormatterParameters; |
---|
24 | |
---|
25 | public class VisitorCommonFunctions { |
---|
26 | |
---|
27 | |
---|
28 | public static String addSyntaxHighlighting(String element){ |
---|
29 | String[] TTCN3_KEYWORDS = KeywordExtractor.getInstance().getLiterals().toArray(new String[0]); |
---|
30 | element = " " + element; |
---|
31 | for(String keyword : TTCN3_KEYWORDS) |
---|
32 | element = element.replaceAll(" " + keyword + " ", " <keyword>" + keyword + "</keyword> ").replaceAll("\\n" + keyword + " ", "\n<keyword>" + keyword + "</keyword> ").replaceAll(">" + keyword + " ", "><keyword>" + keyword + "</keyword> "); |
---|
33 | return element.substring(1); |
---|
34 | } |
---|
35 | |
---|
36 | static class TTCN3Reference{ |
---|
37 | public TTCN3Reference(String name, String location) { |
---|
38 | this.name = name; |
---|
39 | this.location = location; |
---|
40 | } |
---|
41 | public String name; |
---|
42 | public String location; |
---|
43 | } |
---|
44 | //returns a list of all references of a node in the TTCN3 project |
---|
45 | public static LinkedList<TTCN3Reference> getReferences(LocationAST node){ |
---|
46 | LinkedList<TTCN3Reference> refvector = new LinkedList<TTCN3Reference>(); |
---|
47 | LinkedList<LocationAST> refNodeList = ASTUtil.findTypeNodes(node, TTCN3ParserTokenTypes.IDENTIFIER); |
---|
48 | for(LocationAST IdNode : refNodeList){ |
---|
49 | String name = IdNode.getText(); |
---|
50 | String location = getDecLocationFromIdentifier(IdNode); |
---|
51 | if(!location.equals("#") && !location.startsWith("trexPredefined") |
---|
52 | && isValidCrossReference(IdNode)){ |
---|
53 | refvector.add(new TTCN3Reference(name, location)); |
---|
54 | } |
---|
55 | } |
---|
56 | return refvector; |
---|
57 | } |
---|
58 | //returns true if refNode is a valid cross-reference |
---|
59 | //TODO: REVIEW, seems rather pointless |
---|
60 | public static boolean isValidCrossReference(LocationAST identifierNode){ |
---|
61 | LocationAST declarationNode = getDeclarationNodeFromIdentifier(identifierNode); |
---|
62 | LocationAST declarationModuleDefinitionNode = LocationAST.resolveParentsUntilType(declarationNode, TTCN3ParserTokenTypes.ModuleDefinition); |
---|
63 | |
---|
64 | if(declarationModuleDefinitionNode == null) { |
---|
65 | return true; |
---|
66 | } |
---|
67 | |
---|
68 | LinkedList<String> identifierNames = new LinkedList<String>(); |
---|
69 | for(LocationAST node : LocationAST.getModuleDefinitionIdentifiersList(declarationModuleDefinitionNode)) { |
---|
70 | identifierNames.add(node.getFirstChild().getText()); |
---|
71 | } |
---|
72 | // if(modDefNode.getFirstChild().getType() == TTCN3ParserTokenTypes.ExtFunctionDef || modDefNode.getFirstChild().getType() == TTCN3ParserTokenTypes.ExtConstDef) |
---|
73 | // return false; |
---|
74 | // else { |
---|
75 | return (identifierNames.contains(identifierNode.getText())); |
---|
76 | // } |
---|
77 | } |
---|
78 | |
---|
79 | public static String replaceReferences(String b, LinkedList<TTCN3Reference> reflist){ |
---|
80 | for(TTCN3Reference r : reflist){ |
---|
81 | b = b.replaceAll("( |\\t)" + r.name + " ", " <link loc=\"" + r.location + "\">" + r.name + "</link> "); |
---|
82 | b = b.replaceAll("( |\\t)" + r.name + ";", " <link loc=\"" + r.location + "\">" + r.name + "</link>;"); |
---|
83 | b = b.replaceAll("( |\\t)" + r.name + ",", " <link loc=\"" + r.location + "\">" + r.name + "</link>,"); |
---|
84 | b = b.replaceAll("( |\\t)" + r.name + "\n", " <link loc=\"" + r.location + "\">" + r.name + "</link>\n"); |
---|
85 | } |
---|
86 | return b; |
---|
87 | } |
---|
88 | |
---|
89 | //returns the XML representation(<behaviour>) of a ModuleDefinition node |
---|
90 | public static String getBehaviour(LocationAST node, int tabs, boolean syntaxHighlighting, boolean showContructBody){ |
---|
91 | String tabString = ""; |
---|
92 | for(int i=0; i < tabs; i++) |
---|
93 | tabString += "<tab/>"; |
---|
94 | LinkedList<TTCN3Reference> reflist = getReferences(node); |
---|
95 | String b = getWholeElement(node, showContructBody).replaceAll("\\r", ""); |
---|
96 | b = StringEscapeUtils.escapeXml(b); |
---|
97 | b = replaceReferences(b, reflist); |
---|
98 | String constrEndString = ""; |
---|
99 | if(b.contains("{")){ |
---|
100 | b = b.replaceFirst("\\{", "<constructbody id=\"id" + node.getOffset() + "\">{"); |
---|
101 | constrEndString = "</constructbody>"; |
---|
102 | } |
---|
103 | if(syntaxHighlighting) |
---|
104 | b = addSyntaxHighlighting(b); |
---|
105 | |
---|
106 | if(b.charAt(b.length()-2) == '}' && b.charAt(b.length()-3) != ';'){ |
---|
107 | return tabString + b.substring(0, b.length()-3).replaceAll("\n", "\n" + tabString + "<tab/>") + "\n" + tabString + "}" + constrEndString + "\n"; |
---|
108 | }else{ |
---|
109 | |
---|
110 | String beh = tabString + b.replaceAll("\n", "\n" + tabString + "<tab/>") + ";" + constrEndString + "\n"; |
---|
111 | return beh.replaceAll("(\\s|\\n|<tab/>)*;", ";").replaceFirst("<tab/>\\};</constructbody>", "};</constructbody>"); |
---|
112 | } |
---|
113 | } |
---|
114 | |
---|
115 | //returns String representation of a ModuleDefinition node |
---|
116 | public static String getWholeElement(LocationAST node, boolean showContructBody){ |
---|
117 | TTCN3FormatterTreeParser prettyPrinter = new TTCN3FormatterTreeParser(); |
---|
118 | prettyPrinter.setFormatterParameters(new TTCN3FormatterParameters()); |
---|
119 | try { |
---|
120 | String element; |
---|
121 | if(node.getType() == TTCN3ParserTokenTypes.ModuleControlPart) |
---|
122 | element = prettyPrinter.pr_ModuleControlPart(node).toString() + " "; |
---|
123 | else if(node.getType() == TTCN3ParserTokenTypes.ModulePar) |
---|
124 | element = "modulepar " + prettyPrinter.pr_ModulePar(node).toString() + " "; |
---|
125 | else |
---|
126 | element = prettyPrinter.pr_ModuleDefinition(node.getParent()).toString() + " "; |
---|
127 | if(!showContructBody && element.contains("{")){ |
---|
128 | if(node.getType() == TTCN3ParserTokenTypes.TemplateDef && element.contains(":=")) |
---|
129 | element= element.substring(0, element.indexOf(":=")); |
---|
130 | else |
---|
131 | element= element.substring(0, element.indexOf('{')); |
---|
132 | } |
---|
133 | |
---|
134 | return element.replaceAll("\\r",""); |
---|
135 | } catch (RecognitionException e) { |
---|
136 | e.printStackTrace(); |
---|
137 | } |
---|
138 | return "*** Parser error ***"; |
---|
139 | } |
---|
140 | |
---|
141 | // returns a list of every node that references the given node |
---|
142 | public static LinkedList<LocationAST> getReferenceList(LocationAST node){ |
---|
143 | LinkedList<LocationAST> linkedRefList = new LinkedList<LocationAST>(); |
---|
144 | ReferenceFinder referenceFinder = new ReferenceFinder(); |
---|
145 | Scope scope = node.getScope(); |
---|
146 | if (scope == null) |
---|
147 | return null; |
---|
148 | Symbol symb = scope.resolve(node); |
---|
149 | Map<String, List<ReferenceWithContext>> result = referenceFinder.findReferences(symb); |
---|
150 | |
---|
151 | Iterator<List<ReferenceWithContext>> refIt = result.values().iterator(); |
---|
152 | if(refIt != null) |
---|
153 | while(refIt.hasNext()){ |
---|
154 | |
---|
155 | ArrayList<ReferenceWithContext> refList = (ArrayList<ReferenceWithContext>)refIt.next(); |
---|
156 | for(ReferenceWithContext ref : refList){ |
---|
157 | linkedRefList.add(ref.getReferenceNode()); |
---|
158 | } |
---|
159 | } |
---|
160 | if(linkedRefList.isEmpty()) |
---|
161 | return null; |
---|
162 | return linkedRefList; |
---|
163 | } |
---|
164 | |
---|
165 | |
---|
166 | //returns the location of an html file that would represent node |
---|
167 | public static String getLocationFromIdentifier(LocationAST node){ |
---|
168 | return getModuleName(node) + "-" + node.getText() + "-" + node.getOffset() + ".html"; |
---|
169 | } |
---|
170 | |
---|
171 | public static String getIdFromIdentifier(LocationAST node){ |
---|
172 | return getModuleName(node) + "-" + VisitorCommonFunctions.getName(node); |
---|
173 | } |
---|
174 | //returns the name of the TTCN3 module node belongs to |
---|
175 | public static String getModuleName(LocationAST node){ |
---|
176 | LocationAST module = getModule(node); |
---|
177 | while(module.getFirstChild() != null) |
---|
178 | module = module.getFirstChild(); |
---|
179 | return module.getText(); |
---|
180 | } |
---|
181 | |
---|
182 | public static LocationAST getModule(LocationAST node){ |
---|
183 | LocationAST module = node; |
---|
184 | while(module.getParent() != null){ |
---|
185 | module = module.getParent(); |
---|
186 | } |
---|
187 | return module; |
---|
188 | } |
---|
189 | |
---|
190 | //returns the name of a TTCN3 element |
---|
191 | public static String getName(LocationAST node){ |
---|
192 | return getIdentifier(node).getText(); |
---|
193 | } |
---|
194 | //returns the identifier of a TTCN3 element |
---|
195 | public static LocationAST getIdentifier(LocationAST node){ |
---|
196 | if(node.getType() == TTCN3ParserTokenTypes.Identifier) |
---|
197 | return node.getFirstChild(); |
---|
198 | LocationAST identifier = null; |
---|
199 | for(int i = 1; identifier == null && i < 1000; i++) |
---|
200 | identifier = searchIdentifier(node, i); |
---|
201 | |
---|
202 | if(identifier.getFirstChild() != null) |
---|
203 | identifier = identifier.getFirstChild(); |
---|
204 | return identifier; |
---|
205 | } |
---|
206 | //returns the first identifier node found in a certain depth or null if none is found |
---|
207 | public static LocationAST searchIdentifier(LocationAST node, int depth){ |
---|
208 | if(node.getType() == TTCN3ParserTokenTypes.Identifier) |
---|
209 | return node; |
---|
210 | if(node.getParent().getType() == TTCN3ParserTokenTypes.Identifier) |
---|
211 | return node; |
---|
212 | if(depth <= 0) |
---|
213 | return null; |
---|
214 | LocationAST currNode = node.getFirstChild(); |
---|
215 | LocationAST identifier = null; |
---|
216 | while(currNode != null && identifier == null){ |
---|
217 | identifier = searchIdentifier(currNode, depth-1); |
---|
218 | currNode = currNode.getNextSibling(); |
---|
219 | } |
---|
220 | return identifier; |
---|
221 | } |
---|
222 | |
---|
223 | //returns getLocationFromIdentifier() of the declaration node of node |
---|
224 | public static String getDecLocationFromIdentifier(LocationAST node){ |
---|
225 | LocationAST decNode = getDeclarationNodeFromIdentifier(node); |
---|
226 | if(decNode != null) |
---|
227 | if(VisitorCommonFunctions.getModuleName(decNode).equals(node.getText())) |
---|
228 | return node.getText() + ".html"; |
---|
229 | else |
---|
230 | return VisitorCommonFunctions.getLocationFromIdentifier(decNode); |
---|
231 | else |
---|
232 | return "#"; |
---|
233 | } |
---|
234 | |
---|
235 | public static LocationAST getDeclarationNodeFromIdentifier(LocationAST node){ |
---|
236 | Scope identifierScope = node.getScope(); |
---|
237 | Symbol decSymbol = null; |
---|
238 | if(identifierScope != null) |
---|
239 | decSymbol = identifierScope.resolve(node); |
---|
240 | else |
---|
241 | return null; |
---|
242 | //Symbol decSymbol = node.getSymbol(); |
---|
243 | if(decSymbol != null){ |
---|
244 | LocationAST decNode = decSymbol.getDeclarationNode(); |
---|
245 | return decNode; |
---|
246 | } |
---|
247 | else |
---|
248 | return null; |
---|
249 | } |
---|
250 | |
---|
251 | } |
---|