1 /*******************************************************************************
2 * Copyright (c) 2011, 2014 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
.tracecompass
.internal
.ctf
.core
.event
.metadata
;
15 import java
.util
.HashMap
;
19 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.EnumDeclaration
;
20 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.IDeclaration
;
21 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.StructDeclaration
;
22 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.VariantDeclaration
;
23 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.exceptions
.ParseException
;
26 * <b><u>DeclarationScope</u></b>
28 * A DeclarationScope keeps track of the various CTF declarations for a given
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.
34 * @author Matthew Khouzam
35 * @author Simon Marchi
38 class DeclarationScope
{
40 // ------------------------------------------------------------------------
42 // ------------------------------------------------------------------------
44 private DeclarationScope fParentScope
= null;
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
<>();
52 // ------------------------------------------------------------------------
54 // ------------------------------------------------------------------------
57 * Creates a declaration scope with no parent.
59 public DeclarationScope() {
63 * Creates a declaration scope with the specified parent.
66 * The parent of the newly created scope.
68 public DeclarationScope(DeclarationScope parentScope
) {
69 fParentScope
= parentScope
;
72 // ------------------------------------------------------------------------
73 // Getters/Setters/Predicates
74 // ------------------------------------------------------------------------
77 * Returns the parent of the current scope.
79 * @return The parent scope.
81 public DeclarationScope
getParentScope() {
85 // ------------------------------------------------------------------------
86 // Registration operations
87 // ------------------------------------------------------------------------
90 * Registers a type declaration.
93 * The name of the type.
95 * The type declaration.
96 * @throws ParseException
97 * if a type with the same name has already been defined.
99 public void registerType(String name
, IDeclaration declaration
)
100 throws ParseException
{
101 /* Check if the type has been defined in the current scope */
102 if (fTypes
.containsKey(name
)) {
103 throw new ParseException("Type has already been defined:" + name
); //$NON-NLS-1$
106 /* Add it to the register. */
107 fTypes
.put(name
, declaration
);
111 * Registers an identifier declaration.
114 * name of the identifier
116 * the identfier's declaration
117 * @throws ParseException
118 * if an identifier with the same name has already been defined.
120 public void registerIdentifier(String name
, IDeclaration declaration
) throws ParseException
{
121 /* Check if the type has been defined in the current scope */
122 if (fIdentifiers
.containsKey(name
)) {
123 throw new ParseException("Identifier has already been defined:" + name
); //$NON-NLS-1$
126 /* Add it to the register. */
127 fIdentifiers
.put(name
, declaration
);
131 * Registers a struct declaration.
134 * The name of the struct.
136 * The declaration of the struct.
137 * @throws ParseException
138 * if a struct with the same name has already been registered.
140 public void registerStruct(String name
, StructDeclaration declaration
)
141 throws ParseException
{
142 /* Check if the struct has been defined in the current scope. */
143 if (fStructs
.containsKey(name
)) {
144 throw new ParseException("Struct has already been defined:" + name
); //$NON-NLS-1$
147 /* Add it to the register. */
148 fStructs
.put(name
, declaration
);
150 /* It also defined a new type, so add it to the type declarations. */
151 String structPrefix
= "struct "; //$NON-NLS-1$
152 registerType(structPrefix
+ name
, declaration
);
156 * Registers an enum declaration.
159 * The name of the enum.
161 * The declaration of the enum.
162 * @throws ParseException
163 * if an enum with the same name has already been registered.
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) {
169 throw new ParseException("Enum has already been defined:" + name
); //$NON-NLS-1$
172 /* Add it to the register. */
173 fEnums
.put(name
, declaration
);
175 /* It also defined a new type, so add it to the type declarations. */
176 String enumPrefix
= "enum "; //$NON-NLS-1$
177 registerType(enumPrefix
+ name
, declaration
);
181 * Registers a variant declaration.
184 * The name of the variant.
186 * The declaration of the variant.
187 * @throws ParseException
188 * if a variant with the same name has already been registered.
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) {
194 throw new ParseException("Variant has already been defined:" + name
); //$NON-NLS-1$
197 /* Add it to the register. */
198 fVariants
.put(name
, declaration
);
200 /* It also defined a new type, so add it to the type declarations. */
201 String variantPrefix
= "variant "; //$NON-NLS-1$
202 registerType(variantPrefix
+ name
, declaration
);
205 // ------------------------------------------------------------------------
207 // ------------------------------------------------------------------------
210 * Looks up a type declaration in the current scope.
213 * The name of the type to search for.
214 * @return The type declaration, or null if no type with that name has been
217 public IDeclaration
lookupType(String name
) {
218 return fTypes
.get(name
);
222 * Looks up a type declaration in the current scope and recursively in the
226 * The name of the type to search for.
227 * @return The type declaration, or null if no type with that name has been
230 public IDeclaration
lookupTypeRecursive(String name
) {
231 IDeclaration declaration
= lookupType(name
);
232 if (declaration
!= null) {
234 } else if (fParentScope
!= null) {
235 return fParentScope
.lookupTypeRecursive(name
);
242 * Looks up a struct declaration.
245 * The name of the struct to search for.
246 * @return The struct declaration, or null if no struct with that name has
249 public StructDeclaration
lookupStruct(String name
) {
250 return fStructs
.get(name
);
254 * Looks up a struct declaration in the current scope and recursively in the
258 * The name of the struct to search for.
259 * @return The struct declaration, or null if no struct with that name has
262 public StructDeclaration
lookupStructRecursive(String name
) {
263 StructDeclaration declaration
= lookupStruct(name
);
264 if (declaration
!= null) {
266 } else if (fParentScope
!= null) {
267 return fParentScope
.lookupStructRecursive(name
);
274 * Looks up an enum declaration.
277 * The name of the enum to search for.
278 * @return The enum declaration, or null if no enum with that name has been
281 public EnumDeclaration
lookupEnum(String name
) {
282 return fEnums
.get(name
);
286 * Looks up an enum declaration in the current scope and recursively in the
290 * The name of the enum to search for.
291 * @return The enum declaration, or null if no enum with that name has been
294 public EnumDeclaration
lookupEnumRecursive(String name
) {
295 EnumDeclaration declaration
= lookupEnum(name
);
296 if (declaration
!= null) {
298 } else if (fParentScope
!= null) {
299 return fParentScope
.lookupEnumRecursive(name
);
306 * Looks up a variant declaration.
309 * The name of the variant to search for.
310 * @return The variant declaration, or null if no variant with that name has
313 public VariantDeclaration
lookupVariant(String name
) {
314 return fVariants
.get(name
);
318 * Looks up a variant declaration in the current scope and recursively in
322 * The name of the variant to search for.
323 * @return The variant declaration, or null if no variant with that name has
326 public VariantDeclaration
lookupVariantRecursive(String name
) {
327 VariantDeclaration declaration
= lookupVariant(name
);
328 if (declaration
!= null) {
330 } else if (fParentScope
!= null) {
331 return fParentScope
.lookupVariantRecursive(name
);
338 * Lookup query for an identifier in this scope.
341 * the name of the identifier to search for. In the case of int
343 * @return the declaration of the type associated to that identifier
345 public IDeclaration
lookupIdentifier(String identifier
) {
346 return fIdentifiers
.get(identifier
);
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.
354 * the name of the identifier to search for. In the case of int
356 * @return the declaration of the type associated to that identifier
358 public IDeclaration
lookupIdentifierRecursive(String identifier
) {
359 IDeclaration declaration
= lookupIdentifier(identifier
);
360 if (declaration
!= null) {
362 } else if (fParentScope
!= null) {
363 return fParentScope
.lookupIdentifierRecursive(identifier
);
369 * Get all the type names of this scope.
371 * @return The type names
373 public Set
<String
> getTypeNames() {
374 return fTypes
.keySet();
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 (fTypes
.containsKey(name
)) {
389 fTypes
.put(name
, newType
);
391 throw new ParseException("Trace does not contain type:" + name
); //$NON-NLS-1$