Fix some null warnings
[deliverable/tracecompass.git] / ctf / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / ctf / core / event / types / StructDefinition.java
1 /*******************************************************************************
2 * Copyright (c) 2011, 2014 Ericsson, Ecole Polytechnique de Montreal and others
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 API and implementation
10 * Contributors: Simon Marchi - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.tracecompass.ctf.core.event.types;
14
15 import java.util.Collections;
16 import java.util.LinkedList;
17 import java.util.List;
18 import java.util.Map;
19
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;
24
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;
29
30 /**
31 * A CTF structure definition (similar to a C structure).
32 *
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.
36 *
37 * TODO: move me to internal
38 *
39 * @version 1.0
40 * @author Matthew Khouzam
41 * @author Simon Marchi
42 */
43 public final class StructDefinition extends ScopedDefinition implements ICompositeDefinition {
44
45 // ------------------------------------------------------------------------
46 // Attributes
47 // ------------------------------------------------------------------------
48
49 private final @NonNull List<String> fFieldNames;
50 private final Definition[] fDefinitions;
51 private Map<String, Definition> fDefinitionsMap = null;
52
53 // ------------------------------------------------------------------------
54 // Constructors
55 // ------------------------------------------------------------------------
56
57 /**
58 * Constructor
59 *
60 * @param declaration
61 * the parent declaration
62 * @param definitionScope
63 * the parent scope
64 * @param structFieldName
65 * the field name
66 * @param definitions
67 * the definitions
68 * @since 1.0
69 */
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;
79 }
80 }
81
82 /**
83 * Constructor This one takes the scope and thus speeds up definition
84 * creation
85 *
86 * @param declaration
87 * the parent declaration
88 * @param definitionScope
89 * the parent scope
90 * @param scope
91 * the scope of this variable
92 * @param structFieldName
93 * the field name
94 * @param fieldNames
95 * the list of fields
96 * @param definitions
97 * the definitions
98 * @since 1.0
99 */
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;
108 }
109 }
110
111 // ------------------------------------------------------------------------
112 // Getters/Setters/Predicates
113 // ------------------------------------------------------------------------
114
115 @Override
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]);
123 }
124 }
125 fDefinitionsMap = mapBuilder.build();
126 }
127 return fDefinitionsMap.get(fieldName);
128 }
129
130 @Override
131 public @NonNull List<String> getFieldNames() {
132 return fFieldNames;
133 }
134
135 @Override
136 public StructDeclaration getDeclaration() {
137 return (StructDeclaration) super.getDeclaration();
138 }
139
140 // ------------------------------------------------------------------------
141 // Operations
142 // ------------------------------------------------------------------------
143
144 @Override
145 public Definition lookupDefinition(String lookupPath) {
146 return lookupDefinition(lookupPath, null);
147 }
148
149 @Override
150 public String toString() {
151 StringBuilder builder = new StringBuilder();
152
153 builder.append("{ "); //$NON-NLS-1$
154
155 List<String> fields = new LinkedList<>();
156 for (String field : fFieldNames) {
157 String appendee = field + " = " + lookupDefinition(field).toString(); //$NON-NLS-1$
158 fields.add(appendee);
159 }
160 Joiner joiner = Joiner.on(", ").skipNulls(); //$NON-NLS-1$
161 builder.append(joiner.join(fields));
162
163 builder.append(" }"); //$NON-NLS-1$
164
165 return builder.toString();
166 }
167
168 /**
169 * Lookup definition while exclusing the caller
170 *
171 * @param lookupPath
172 * the path to lookup
173 * @param defintionToExclude
174 * the definition to exclude, can be null
175 * @return the definition or null
176 * @since 1.1
177 */
178 public Definition lookupDefinition(String lookupPath, ScopedDefinition defintionToExclude) {
179 /*
180 * The fields are created in order of appearance, so if a variant or
181 * sequence refers to a field that is after it, the field's definition
182 * will not be there yet in the hashmap.
183 */
184 int val = fFieldNames.indexOf(lookupPath);
185 if (val != -1) {
186 return fDefinitions[val];
187 }
188 String lookupUnderscored = "_" + lookupPath; //$NON-NLS-1$
189 val = fFieldNames.indexOf(lookupUnderscored);
190 if (val != -1) {
191 return fDefinitions[val];
192 }
193 for (IDefinition child : fDefinitions) {
194 if (child instanceof ScopedDefinition) {
195 if (!child.equals(defintionToExclude)) {
196 IDefinition def = ((ScopedDefinition) child).lookupDefinition(lookupPath);
197 if (def instanceof Definition) {
198 return (Definition) def;
199 }
200 }
201 }
202 }
203 if (getDefinitionScope() instanceof InternalDef) {
204 return (Definition) ((InternalDef) getDefinitionScope()).lookupDefinitionBreakLoop(lookupPath);
205 }
206 return (Definition) getDefinitionScope().lookupDefinition(lookupPath);
207 }
208
209 }
This page took 0.037855 seconds and 5 git commands to generate.