1 /*******************************************************************************
2 * Copyright (c) 2011-2012 Ericsson, Ecole Polytechnique de Montreal and others
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
9 * Contributors: Matthew Khouzam - Initial Design and Grammar
10 * Contributors: Simon Marchi - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.internal
.ctf
.core
.event
.metadata
;
15 import java
.util
.HashMap
;
18 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.EnumDeclaration
;
19 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.IDeclaration
;
20 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.StructDeclaration
;
21 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.VariantDeclaration
;
22 import org
.eclipse
.linuxtools
.internal
.ctf
.core
.event
.metadata
.exceptions
.ParseException
;
25 * <b><u>DeclarationScope</u></b>
27 * A DeclarationScope keeps track of the various CTF declarations for a given
30 * TODO: The notion of "symbols" and the notion of "scope" are misused in this
31 * parser, which leads to inefficient tree management. It should be cleaned up.
33 * @author Matthew Khouzam
34 * @author Simon Marchi
37 class DeclarationScope
{
39 // ------------------------------------------------------------------------
41 // ------------------------------------------------------------------------
43 private DeclarationScope parentScope
= null;
45 private final Map
<String
, StructDeclaration
> structs
= new HashMap
<String
, StructDeclaration
>();
46 private final Map
<String
, EnumDeclaration
> enums
= new HashMap
<String
, EnumDeclaration
>();
47 private final Map
<String
, VariantDeclaration
> variants
= new HashMap
<String
, VariantDeclaration
>();
48 private final Map
<String
, IDeclaration
> types
= new HashMap
<String
, IDeclaration
>();
49 private final Map
<String
, IDeclaration
> identifiers
= new HashMap
<String
, IDeclaration
>();
51 // ------------------------------------------------------------------------
53 // ------------------------------------------------------------------------
56 * Creates a declaration scope with no parent.
58 public DeclarationScope() {
62 * Creates a declaration scope with the specified parent.
65 * The parent of the newly created scope.
67 public DeclarationScope(DeclarationScope parentScope
) {
68 this.parentScope
= parentScope
;
71 // ------------------------------------------------------------------------
72 // Getters/Setters/Predicates
73 // ------------------------------------------------------------------------
76 * Returns the parent of the current scope.
78 * @return The parent scope.
80 public DeclarationScope
getParentScope() {
84 // ------------------------------------------------------------------------
85 // Registration operations
86 // ------------------------------------------------------------------------
89 * Registers a type declaration.
92 * The name of the type.
94 * The type declaration.
95 * @throws ParseException
96 * if a type with the same name has already been defined.
98 public void registerType(String name
, IDeclaration declaration
)
99 throws ParseException
{
100 /* Check if the type has been defined in the current scope */
101 if (types
.containsKey(name
)) {
102 throw new ParseException("Type has already been defined:" + name
); //$NON-NLS-1$
105 /* Add it to the register. */
106 types
.put(name
, declaration
);
110 * Registers an identifier declaration.
113 * name of the identifier
115 * the identfier's declaration
116 * @throws ParseException
117 * if an identifier with the same name has already been defined.
119 public void registerIdentifier(String name
, IDeclaration declaration
) throws ParseException
{
120 /* Check if the type has been defined in the current scope */
121 if (identifiers
.containsKey(name
)) {
122 throw new ParseException("Identifier has already been defined:" + name
); //$NON-NLS-1$
125 /* Add it to the register. */
126 identifiers
.put(name
, declaration
);
130 * Registers a struct declaration.
133 * The name of the struct.
135 * The declaration of the struct.
136 * @throws ParseException
137 * if a struct with the same name has already been registered.
139 public void registerStruct(String name
, StructDeclaration declaration
)
140 throws ParseException
{
141 /* Check if the struct has been defined in the current scope. */
142 if (structs
.containsKey(name
)) {
143 throw new ParseException("Struct has already been defined:" + name
); //$NON-NLS-1$
146 /* Add it to the register. */
147 structs
.put(name
, declaration
);
149 /* It also defined a new type, so add it to the type declarations. */
150 String structPrefix
= "struct "; //$NON-NLS-1$
151 registerType(structPrefix
+ name
, declaration
);
155 * Registers an enum declaration.
158 * The name of the enum.
160 * The declaration of the enum.
161 * @throws ParseException
162 * if an enum with the same name has already been registered.
164 public void registerEnum(String name
, EnumDeclaration declaration
)
165 throws ParseException
{
166 /* Check if the enum has been defined in the current scope. */
167 if (lookupEnum(name
) != null) {
168 throw new ParseException("Enum has already been defined:" + name
); //$NON-NLS-1$
171 /* Add it to the register. */
172 enums
.put(name
, declaration
);
174 /* It also defined a new type, so add it to the type declarations. */
175 String enumPrefix
= "enum "; //$NON-NLS-1$
176 registerType(enumPrefix
+ name
, declaration
);
180 * Registers a variant declaration.
183 * The name of the variant.
185 * The declaration of the variant.
186 * @throws ParseException
187 * if a variant with the same name has already been registered.
189 public void registerVariant(String name
, VariantDeclaration declaration
)
190 throws ParseException
{
191 /* Check if the variant has been defined in the current scope. */
192 if (lookupVariant(name
) != null) {
193 throw new ParseException("Variant has already been defined:" + name
); //$NON-NLS-1$
196 /* Add it to the register. */
197 variants
.put(name
, declaration
);
199 /* It also defined a new type, so add it to the type declarations. */
200 String variantPrefix
= "variant "; //$NON-NLS-1$
201 registerType(variantPrefix
+ name
, declaration
);
204 // ------------------------------------------------------------------------
206 // ------------------------------------------------------------------------
209 * Looks up a type declaration in the current scope.
212 * The name of the type to search for.
213 * @return The type declaration, or null if no type with that name has been
216 public IDeclaration
lookupType(String name
) {
217 return types
.get(name
);
221 * Looks up a type declaration in the current scope and recursively in the
225 * The name of the type to search for.
226 * @return The type declaration, or null if no type with that name has been
229 public IDeclaration
lookupTypeRecursive(String name
) {
230 IDeclaration declaration
= lookupType(name
);
231 if (declaration
!= null) {
233 } else if (parentScope
!= null) {
234 return parentScope
.lookupTypeRecursive(name
);
241 * Looks up a struct declaration.
244 * The name of the struct to search for.
245 * @return The struct declaration, or null if no struct with that name has
248 public StructDeclaration
lookupStruct(String name
) {
249 return structs
.get(name
);
253 * Looks up a struct declaration in the current scope and recursively in the
257 * The name of the struct to search for.
258 * @return The struct declaration, or null if no struct with that name has
261 public StructDeclaration
lookupStructRecursive(String name
) {
262 StructDeclaration declaration
= lookupStruct(name
);
263 if (declaration
!= null) {
265 } else if (parentScope
!= null) {
266 return parentScope
.lookupStructRecursive(name
);
273 * Looks up a enum declaration.
276 * The name of the enum to search for.
277 * @return The enum declaration, or null if no enum with that name has been
280 public EnumDeclaration
lookupEnum(String name
) {
281 return enums
.get(name
);
285 * Looks up an enum declaration in the current scope and recursively in the
289 * The name of the enum to search for.
290 * @return The enum declaration, or null if no enum with that name has been
293 public EnumDeclaration
lookupEnumRecursive(String name
) {
294 EnumDeclaration declaration
= lookupEnum(name
);
295 if (declaration
!= null) {
297 } else if (parentScope
!= null) {
298 return parentScope
.lookupEnumRecursive(name
);
305 * Looks up a variant declaration.
308 * The name of the variant to search for.
309 * @return The variant declaration, or null if no variant with that name has
312 public VariantDeclaration
lookupVariant(String name
) {
313 return variants
.get(name
);
317 * Looks up a variant declaration in the current scope and recursively in
321 * The name of the variant to search for.
322 * @return The variant declaration, or null if no variant with that name has
325 public VariantDeclaration
lookupVariantRecursive(String name
) {
326 VariantDeclaration declaration
= lookupVariant(name
);
327 if (declaration
!= null) {
329 } else if (parentScope
!= null) {
330 return parentScope
.lookupVariantRecursive(name
);
337 * Looks through the list of identifiers of a scope to find if it exists.
340 * the name of the identifier to search for. In the case of int
342 * @return the declaration of the type associated to that identifier
344 public IDeclaration
lookupIdentifier(String identifier
) {
345 return identifiers
.get(identifier
);
349 * Recursively looks through the list of identifiers of a scope to find if
353 * the name of the identifier to search for. In the case of int
355 * @return the declaration of the type associated to that identifier
357 public IDeclaration
lookupIdentifierRecursive(String identifier
) {
358 IDeclaration declaration
= lookupIdentifier(identifier
);
359 if (declaration
!= null) {
361 } else if (parentScope
!= null) {
362 return parentScope
.lookupIdentifierRecursive(identifier
);
368 * Get all the type names of this scope.
370 * @return The type names
372 public String
[] getTypeNames() {
373 String
[] keys
= new String
[types
.keySet().size()];
374 return types
.keySet().toArray(keys
);
378 * Replace a type with a new one.
381 * The name of the type
384 * @throws ParseException
385 * If the type does not exist.
387 public void replaceType(String name
, IDeclaration newType
) throws ParseException
{
388 if (types
.containsKey(name
)) {
389 types
.put(name
, newType
);
391 throw new ParseException("Trace does not contain type:" + name
); //$NON-NLS-1$