Commit | Line | Data |
---|---|---|
866e5b51 | 1 | /******************************************************************************* |
60ae41e1 | 2 | * Copyright (c) 2011, 2014 Ericsson, Ecole Polytechnique de Montreal and others |
866e5b51 FC |
3 | * |
4 | * All rights reserved. This program and the accompanying materials are made | |
5 | * available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: Matthew Khouzam - Initial Design and Grammar | |
10 | * Contributors: Simon Marchi - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | ||
ce2388e0 | 13 | package org.eclipse.linuxtools.internal.ctf.core.event.metadata; |
866e5b51 FC |
14 | |
15 | import java.util.HashMap; | |
0594c61c | 16 | import java.util.Map; |
108f70b8 | 17 | import java.util.Set; |
866e5b51 | 18 | |
866e5b51 FC |
19 | import org.eclipse.linuxtools.ctf.core.event.types.EnumDeclaration; |
20 | import org.eclipse.linuxtools.ctf.core.event.types.IDeclaration; | |
21 | import org.eclipse.linuxtools.ctf.core.event.types.StructDeclaration; | |
22 | import org.eclipse.linuxtools.ctf.core.event.types.VariantDeclaration; | |
ce2388e0 | 23 | import org.eclipse.linuxtools.internal.ctf.core.event.metadata.exceptions.ParseException; |
866e5b51 FC |
24 | |
25 | /** | |
26 | * <b><u>DeclarationScope</u></b> | |
27 | * <p> | |
28 | * A DeclarationScope keeps track of the various CTF declarations for a given | |
29 | * scope. | |
2c053b6e MK |
30 | * |
31 | * TODO: The notion of "symbols" and the notion of "scope" are misused in this | |
32 | * parser, which leads to inefficient tree management. It should be cleaned up. | |
33 | * | |
34 | * @author Matthew Khouzam | |
35 | * @author Simon Marchi | |
36 | * | |
866e5b51 | 37 | */ |
2c053b6e | 38 | class DeclarationScope { |
866e5b51 FC |
39 | |
40 | // ------------------------------------------------------------------------ | |
41 | // Attributes | |
42 | // ------------------------------------------------------------------------ | |
43 | ||
41b268ec | 44 | private DeclarationScope fParentScope = null; |
866e5b51 | 45 | |
41b268ec MK |
46 | private final Map<String, StructDeclaration> fStructs = new HashMap<>(); |
47 | private final Map<String, EnumDeclaration> fEnums = new HashMap<>(); | |
48 | private final Map<String, VariantDeclaration> fVariants = new HashMap<>(); | |
49 | private final Map<String, IDeclaration> fTypes = new HashMap<>(); | |
50 | private final Map<String, IDeclaration> fIdentifiers = new HashMap<>(); | |
866e5b51 FC |
51 | |
52 | // ------------------------------------------------------------------------ | |
53 | // Constructors | |
54 | // ------------------------------------------------------------------------ | |
55 | ||
56 | /** | |
57 | * Creates a declaration scope with no parent. | |
58 | */ | |
59 | public DeclarationScope() { | |
60 | } | |
61 | ||
62 | /** | |
63 | * Creates a declaration scope with the specified parent. | |
64 | * | |
65 | * @param parentScope | |
66 | * The parent of the newly created scope. | |
67 | */ | |
68 | public DeclarationScope(DeclarationScope parentScope) { | |
41b268ec | 69 | fParentScope = parentScope; |
866e5b51 FC |
70 | } |
71 | ||
72 | // ------------------------------------------------------------------------ | |
73 | // Getters/Setters/Predicates | |
74 | // ------------------------------------------------------------------------ | |
75 | ||
76 | /** | |
77 | * Returns the parent of the current scope. | |
78 | * | |
79 | * @return The parent scope. | |
80 | */ | |
81 | public DeclarationScope getParentScope() { | |
41b268ec | 82 | return fParentScope; |
866e5b51 FC |
83 | } |
84 | ||
85 | // ------------------------------------------------------------------------ | |
86 | // Registration operations | |
87 | // ------------------------------------------------------------------------ | |
88 | ||
89 | /** | |
90 | * Registers a type declaration. | |
91 | * | |
92 | * @param name | |
93 | * The name of the type. | |
94 | * @param declaration | |
95 | * The type declaration. | |
96 | * @throws ParseException | |
97 | * if a type with the same name has already been defined. | |
98 | */ | |
99 | public void registerType(String name, IDeclaration declaration) | |
100 | throws ParseException { | |
101 | /* Check if the type has been defined in the current scope */ | |
41b268ec | 102 | if (fTypes.containsKey(name)) { |
2c053b6e | 103 | throw new ParseException("Type has already been defined:" + name); //$NON-NLS-1$ |
866e5b51 FC |
104 | } |
105 | ||
106 | /* Add it to the register. */ | |
41b268ec | 107 | fTypes.put(name, declaration); |
866e5b51 FC |
108 | } |
109 | ||
2c053b6e MK |
110 | /** |
111 | * Registers an identifier declaration. | |
112 | * | |
113 | * @param name | |
114 | * name of the identifier | |
115 | * @param declaration | |
116 | * the identfier's declaration | |
117 | * @throws ParseException | |
118 | * if an identifier with the same name has already been defined. | |
119 | */ | |
120 | public void registerIdentifier(String name, IDeclaration declaration) throws ParseException { | |
121 | /* Check if the type has been defined in the current scope */ | |
41b268ec | 122 | if (fIdentifiers.containsKey(name)) { |
2c053b6e MK |
123 | throw new ParseException("Identifier has already been defined:" + name); //$NON-NLS-1$ |
124 | } | |
125 | ||
126 | /* Add it to the register. */ | |
41b268ec | 127 | fIdentifiers.put(name, declaration); |
2c053b6e MK |
128 | } |
129 | ||
866e5b51 FC |
130 | /** |
131 | * Registers a struct declaration. | |
132 | * | |
133 | * @param name | |
134 | * The name of the struct. | |
135 | * @param declaration | |
136 | * The declaration of the struct. | |
137 | * @throws ParseException | |
138 | * if a struct with the same name has already been registered. | |
139 | */ | |
140 | public void registerStruct(String name, StructDeclaration declaration) | |
141 | throws ParseException { | |
142 | /* Check if the struct has been defined in the current scope. */ | |
41b268ec | 143 | if (fStructs.containsKey(name)) { |
2c053b6e | 144 | throw new ParseException("Struct has already been defined:" + name); //$NON-NLS-1$ |
866e5b51 FC |
145 | } |
146 | ||
147 | /* Add it to the register. */ | |
41b268ec | 148 | fStructs.put(name, declaration); |
866e5b51 FC |
149 | |
150 | /* It also defined a new type, so add it to the type declarations. */ | |
0594c61c AM |
151 | String structPrefix = "struct "; //$NON-NLS-1$ |
152 | registerType(structPrefix + name, declaration); | |
866e5b51 FC |
153 | } |
154 | ||
155 | /** | |
156 | * Registers an enum declaration. | |
157 | * | |
158 | * @param name | |
159 | * The name of the enum. | |
160 | * @param declaration | |
161 | * The declaration of the enum. | |
162 | * @throws ParseException | |
163 | * if an enum with the same name has already been registered. | |
164 | */ | |
165 | public void registerEnum(String name, EnumDeclaration declaration) | |
166 | throws ParseException { | |
167 | /* Check if the enum has been defined in the current scope. */ | |
168 | if (lookupEnum(name) != null) { | |
2c053b6e | 169 | throw new ParseException("Enum has already been defined:" + name); //$NON-NLS-1$ |
866e5b51 FC |
170 | } |
171 | ||
172 | /* Add it to the register. */ | |
41b268ec | 173 | fEnums.put(name, declaration); |
866e5b51 FC |
174 | |
175 | /* It also defined a new type, so add it to the type declarations. */ | |
0594c61c AM |
176 | String enumPrefix = "enum "; //$NON-NLS-1$ |
177 | registerType(enumPrefix + name, declaration); | |
866e5b51 FC |
178 | } |
179 | ||
180 | /** | |
181 | * Registers a variant declaration. | |
182 | * | |
183 | * @param name | |
184 | * The name of the variant. | |
185 | * @param declaration | |
186 | * The declaration of the variant. | |
187 | * @throws ParseException | |
188 | * if a variant with the same name has already been registered. | |
189 | */ | |
190 | public void registerVariant(String name, VariantDeclaration declaration) | |
191 | throws ParseException { | |
192 | /* Check if the variant has been defined in the current scope. */ | |
193 | if (lookupVariant(name) != null) { | |
2c053b6e | 194 | throw new ParseException("Variant has already been defined:" + name); //$NON-NLS-1$ |
866e5b51 FC |
195 | } |
196 | ||
197 | /* Add it to the register. */ | |
41b268ec | 198 | fVariants.put(name, declaration); |
866e5b51 FC |
199 | |
200 | /* It also defined a new type, so add it to the type declarations. */ | |
0594c61c AM |
201 | String variantPrefix = "variant "; //$NON-NLS-1$ |
202 | registerType(variantPrefix + name, declaration); | |
866e5b51 FC |
203 | } |
204 | ||
205 | // ------------------------------------------------------------------------ | |
206 | // Lookup operations | |
207 | // ------------------------------------------------------------------------ | |
208 | ||
209 | /** | |
210 | * Looks up a type declaration in the current scope. | |
211 | * | |
212 | * @param name | |
213 | * The name of the type to search for. | |
214 | * @return The type declaration, or null if no type with that name has been | |
215 | * defined. | |
216 | */ | |
217 | public IDeclaration lookupType(String name) { | |
41b268ec | 218 | return fTypes.get(name); |
866e5b51 FC |
219 | } |
220 | ||
221 | /** | |
222 | * Looks up a type declaration in the current scope and recursively in the | |
223 | * parent scopes. | |
224 | * | |
225 | * @param name | |
226 | * The name of the type to search for. | |
227 | * @return The type declaration, or null if no type with that name has been | |
228 | * defined. | |
229 | */ | |
2c053b6e | 230 | public IDeclaration lookupTypeRecursive(String name) { |
866e5b51 FC |
231 | IDeclaration declaration = lookupType(name); |
232 | if (declaration != null) { | |
233 | return declaration; | |
41b268ec MK |
234 | } else if (fParentScope != null) { |
235 | return fParentScope.lookupTypeRecursive(name); | |
866e5b51 FC |
236 | } else { |
237 | return null; | |
238 | } | |
239 | } | |
240 | ||
241 | /** | |
242 | * Looks up a struct declaration. | |
243 | * | |
244 | * @param name | |
245 | * The name of the struct to search for. | |
246 | * @return The struct declaration, or null if no struct with that name has | |
247 | * been defined. | |
248 | */ | |
249 | public StructDeclaration lookupStruct(String name) { | |
41b268ec | 250 | return fStructs.get(name); |
866e5b51 FC |
251 | } |
252 | ||
253 | /** | |
254 | * Looks up a struct declaration in the current scope and recursively in the | |
255 | * parent scopes. | |
256 | * | |
257 | * @param name | |
258 | * The name of the struct to search for. | |
259 | * @return The struct declaration, or null if no struct with that name has | |
260 | * been defined. | |
261 | */ | |
2c053b6e | 262 | public StructDeclaration lookupStructRecursive(String name) { |
866e5b51 FC |
263 | StructDeclaration declaration = lookupStruct(name); |
264 | if (declaration != null) { | |
265 | return declaration; | |
41b268ec MK |
266 | } else if (fParentScope != null) { |
267 | return fParentScope.lookupStructRecursive(name); | |
866e5b51 FC |
268 | } else { |
269 | return null; | |
270 | } | |
271 | } | |
272 | ||
273 | /** | |
108f70b8 | 274 | * Looks up an enum declaration. |
866e5b51 FC |
275 | * |
276 | * @param name | |
277 | * The name of the enum to search for. | |
278 | * @return The enum declaration, or null if no enum with that name has been | |
279 | * defined. | |
280 | */ | |
281 | public EnumDeclaration lookupEnum(String name) { | |
41b268ec | 282 | return fEnums.get(name); |
866e5b51 FC |
283 | } |
284 | ||
285 | /** | |
286 | * Looks up an enum declaration in the current scope and recursively in the | |
287 | * parent scopes. | |
288 | * | |
289 | * @param name | |
290 | * The name of the enum to search for. | |
291 | * @return The enum declaration, or null if no enum with that name has been | |
292 | * defined. | |
293 | */ | |
2c053b6e | 294 | public EnumDeclaration lookupEnumRecursive(String name) { |
866e5b51 FC |
295 | EnumDeclaration declaration = lookupEnum(name); |
296 | if (declaration != null) { | |
297 | return declaration; | |
41b268ec MK |
298 | } else if (fParentScope != null) { |
299 | return fParentScope.lookupEnumRecursive(name); | |
866e5b51 FC |
300 | } else { |
301 | return null; | |
302 | } | |
303 | } | |
304 | ||
305 | /** | |
306 | * Looks up a variant declaration. | |
307 | * | |
308 | * @param name | |
309 | * The name of the variant to search for. | |
310 | * @return The variant declaration, or null if no variant with that name has | |
311 | * been defined. | |
312 | */ | |
313 | public VariantDeclaration lookupVariant(String name) { | |
41b268ec | 314 | return fVariants.get(name); |
866e5b51 FC |
315 | } |
316 | ||
317 | /** | |
318 | * Looks up a variant declaration in the current scope and recursively in | |
319 | * the parent scopes. | |
320 | * | |
321 | * @param name | |
322 | * The name of the variant to search for. | |
323 | * @return The variant declaration, or null if no variant with that name has | |
324 | * been defined. | |
325 | */ | |
2c053b6e | 326 | public VariantDeclaration lookupVariantRecursive(String name) { |
866e5b51 FC |
327 | VariantDeclaration declaration = lookupVariant(name); |
328 | if (declaration != null) { | |
329 | return declaration; | |
41b268ec MK |
330 | } else if (fParentScope != null) { |
331 | return fParentScope.lookupVariantRecursive(name); | |
866e5b51 FC |
332 | } else { |
333 | return null; | |
334 | } | |
335 | } | |
336 | ||
2c053b6e | 337 | /** |
108f70b8 | 338 | * Lookup query for an identifier in this scope. |
2c053b6e MK |
339 | * |
340 | * @param identifier | |
341 | * the name of the identifier to search for. In the case of int | |
342 | * x; it would be "x" | |
343 | * @return the declaration of the type associated to that identifier | |
344 | */ | |
345 | public IDeclaration lookupIdentifier(String identifier) { | |
41b268ec | 346 | return fIdentifiers.get(identifier); |
2c053b6e MK |
347 | } |
348 | ||
349 | /** | |
108f70b8 EB |
350 | * Lookup query for an identifier through this scope and its ancestors. |
351 | * An ancestor scope is a scope in which this scope is nested. | |
2c053b6e MK |
352 | * |
353 | * @param identifier | |
354 | * the name of the identifier to search for. In the case of int | |
355 | * x; it would be "x" | |
356 | * @return the declaration of the type associated to that identifier | |
357 | */ | |
358 | public IDeclaration lookupIdentifierRecursive(String identifier) { | |
359 | IDeclaration declaration = lookupIdentifier(identifier); | |
360 | if (declaration != null) { | |
361 | return declaration; | |
41b268ec MK |
362 | } else if (fParentScope != null) { |
363 | return fParentScope.lookupIdentifierRecursive(identifier); | |
2c053b6e MK |
364 | } |
365 | return null; | |
366 | } | |
72dbc4ac MK |
367 | |
368 | /** | |
369 | * Get all the type names of this scope. | |
370 | * | |
371 | * @return The type names | |
372 | */ | |
108f70b8 | 373 | public Set<String> getTypeNames() { |
41b268ec | 374 | return fTypes.keySet(); |
72dbc4ac MK |
375 | } |
376 | ||
377 | /** | |
378 | * Replace a type with a new one. | |
379 | * | |
380 | * @param name | |
381 | * The name of the type | |
382 | * @param newType | |
383 | * The type | |
384 | * @throws ParseException | |
385 | * If the type does not exist. | |
386 | */ | |
2c053b6e | 387 | public void replaceType(String name, IDeclaration newType) throws ParseException { |
41b268ec MK |
388 | if (fTypes.containsKey(name)) { |
389 | fTypes.put(name, newType); | |
72dbc4ac | 390 | } else { |
2c053b6e | 391 | throw new ParseException("Trace does not contain type:" + name); //$NON-NLS-1$ |
72dbc4ac MK |
392 | } |
393 | } | |
394 | ||
866e5b51 | 395 | } |