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 API and implementation
10 * Contributors: Simon Marchi - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.ctf
.core
.event
.types
;
15 import java
.util
.Collections
;
16 import java
.util
.LinkedList
;
17 import java
.util
.List
;
20 import org
.eclipse
.jdt
.annotation
.NonNull
;
21 import org
.eclipse
.tracecompass
.ctf
.core
.event
.scope
.IDefinitionScope
;
22 import org
.eclipse
.tracecompass
.ctf
.core
.event
.scope
.ILexicalScope
;
23 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.StructDeclaration
.InternalDef
;
25 import com
.google
.common
.base
.Joiner
;
26 import com
.google
.common
.collect
.ImmutableList
;
27 import com
.google
.common
.collect
.ImmutableMap
;
28 import com
.google
.common
.collect
.ImmutableMap
.Builder
;
31 * A CTF structure definition (similar to a C structure).
33 * A structure is similar to a C structure, it is a compound data type that
34 * contains other datatypes in fields. they are stored in an hashmap and indexed
35 * by names which are strings.
37 * TODO: move me to internal
40 * @author Matthew Khouzam
41 * @author Simon Marchi
43 public final class StructDefinition
extends ScopedDefinition
implements ICompositeDefinition
{
45 // ------------------------------------------------------------------------
47 // ------------------------------------------------------------------------
49 private final ImmutableList
<String
> fFieldNames
;
50 private final Definition
[] fDefinitions
;
51 private Map
<String
, Definition
> fDefinitionsMap
= null;
53 // ------------------------------------------------------------------------
55 // ------------------------------------------------------------------------
61 * the parent declaration
62 * @param definitionScope
64 * @param structFieldName
70 public StructDefinition(@NonNull StructDeclaration declaration
,
71 IDefinitionScope definitionScope
,
72 @NonNull String structFieldName
,
73 Definition
[] definitions
) {
74 super(declaration
, definitionScope
, structFieldName
);
75 fFieldNames
= ImmutableList
.copyOf(declaration
.getFieldsList());
76 fDefinitions
= definitions
;
77 if (fFieldNames
.isEmpty()) {
78 fDefinitionsMap
= Collections
.EMPTY_MAP
;
83 * Constructor This one takes the scope and thus speeds up definition
87 * the parent declaration
88 * @param definitionScope
91 * the scope of this variable
92 * @param structFieldName
100 public StructDefinition(@NonNull StructDeclaration declaration
,
101 IDefinitionScope definitionScope
, @NonNull ILexicalScope scope
,
102 @NonNull String structFieldName
, @NonNull Iterable
<String
> fieldNames
, Definition
[] definitions
) {
103 super(declaration
, definitionScope
, structFieldName
, scope
);
104 fFieldNames
= ImmutableList
.copyOf(fieldNames
);
105 fDefinitions
= definitions
;
106 if (fFieldNames
.isEmpty()) {
107 fDefinitionsMap
= Collections
.EMPTY_MAP
;
111 // ------------------------------------------------------------------------
112 // Getters/Setters/Predicates
113 // ------------------------------------------------------------------------
116 public Definition
getDefinition(String fieldName
) {
117 if (fDefinitionsMap
== null) {
118 /* Build the definitions map */
119 Builder
<String
, Definition
> mapBuilder
= new ImmutableMap
.Builder
<>();
120 for (int i
= 0; i
< fFieldNames
.size(); i
++) {
121 if (fDefinitions
[i
] != null) {
122 mapBuilder
.put(fFieldNames
.get(i
), fDefinitions
[i
]);
125 fDefinitionsMap
= mapBuilder
.build();
127 return fDefinitionsMap
.get(fieldName
);
131 public List
<String
> getFieldNames() {
136 public StructDeclaration
getDeclaration() {
137 return (StructDeclaration
) super.getDeclaration();
140 // ------------------------------------------------------------------------
142 // ------------------------------------------------------------------------
145 public Definition
lookupDefinition(String lookupPath
) {
146 return lookupDefinition(lookupPath
, null);
150 public String
toString() {
151 StringBuilder builder
= new StringBuilder();
153 builder
.append("{ "); //$NON-NLS-1$
155 if (fFieldNames
!= null) {
156 List
<String
> fields
= new LinkedList
<>();
157 for (String field
: fFieldNames
) {
158 String appendee
= field
+ " = " + lookupDefinition(field
).toString(); //$NON-NLS-1$
159 fields
.add(appendee
);
161 Joiner joiner
= Joiner
.on(", ").skipNulls(); //$NON-NLS-1$
162 builder
.append(joiner
.join(fields
));
165 builder
.append(" }"); //$NON-NLS-1$
167 return builder
.toString();
171 * Lookup definition while exclusing the caller
175 * @param defintionToExclude
176 * the definition to exclude, can be null
177 * @return the definition or null
180 public Definition
lookupDefinition(String lookupPath
, ScopedDefinition defintionToExclude
) {
182 * The fields are created in order of appearance, so if a variant or
183 * sequence refers to a field that is after it, the field's definition
184 * will not be there yet in the hashmap.
186 int val
= fFieldNames
.indexOf(lookupPath
);
188 return fDefinitions
[val
];
190 String lookupUnderscored
= "_" + lookupPath
; //$NON-NLS-1$
191 val
= fFieldNames
.indexOf(lookupUnderscored
);
193 return fDefinitions
[val
];
195 for (IDefinition child
: fDefinitions
) {
196 if (child
instanceof ScopedDefinition
) {
197 if (!child
.equals(defintionToExclude
)) {
198 IDefinition def
= ((ScopedDefinition
) child
).lookupDefinition(lookupPath
);
199 if (def
instanceof Definition
) {
200 return (Definition
) def
;
205 if (getDefinitionScope() instanceof InternalDef
) {
206 return (Definition
) ((InternalDef
) getDefinitionScope()).lookupDefinitionBreakLoop(lookupPath
);
208 return (Definition
) getDefinitionScope().lookupDefinition(lookupPath
);