-
Notifications
You must be signed in to change notification settings - Fork 11
/
TypeAliasParser.java
148 lines (129 loc) · 6.61 KB
/
TypeAliasParser.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*******************************************************************************
* Copyright (c) 2015, 2023 Ericsson
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl;
import static org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.TsdlUtils.childTypeError;
import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.tracecompass.ctf.core.event.metadata.DeclarationScope;
import org.eclipse.tracecompass.ctf.core.event.types.IDeclaration;
import org.eclipse.tracecompass.ctf.core.event.types.VariantDeclaration;
import org.eclipse.tracecompass.ctf.core.trace.CTFTrace;
import org.eclipse.tracecompass.ctf.parser.CTFParser;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.AbstractScopedCommonTreeParser;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.JsonStructureFieldMemberMetadataNode;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.ParseException;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.enumeration.EnumParser;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.integer.IntegerDeclarationParser;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.string.StringDeclarationParser;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.variant.VariantParser;
import org.eclipse.tracecompass.internal.ctf.core.event.types.ICTFMetadataNode;
import org.eclipse.tracecompass.internal.ctf.core.utils.JsonMetadataStrings;
import com.google.gson.JsonObject;
/**
* The "typealias" declaration can be used to give a name (including pointer
* declarator specifier) to a type. It should also be used to map basic C types
* (float, int, unsigned long, ...) to a CTF type. Typealias is a superset of
* "typedef": it also allows assignment of a simple variable identifier to a
* type.
*
* @author Matthew Khouzam - Inital API and implementation
* @author Efficios - Documentation
*
*/
public final class TypeAliasParser extends AbstractScopedCommonTreeParser {
private static final String SIGNED = "signed"; //$NON-NLS-1$
/**
* Parameters for the typealias parser
*
* @author Matthew Khouzam
*
*/
@NonNullByDefault
public static final class Param implements ICommonTreeParserParameter {
private final DeclarationScope fDeclarationScope;
private final CTFTrace fTrace;
/**
* Parameter constructor
*
* @param trace
* the trace
* @param scope
* the scope
*/
public Param(CTFTrace trace, DeclarationScope scope) {
fTrace = trace;
fDeclarationScope = scope;
}
}
/**
* Instance
*/
public static final TypeAliasParser INSTANCE = new TypeAliasParser();
private TypeAliasParser() {
}
@Override
public IDeclaration parse(ICTFMetadataNode typealias, ICommonTreeParserParameter param) throws ParseException {
if (!(param instanceof Param)) {
throw new IllegalArgumentException("Param must be a " + Param.class.getCanonicalName()); //$NON-NLS-1$
}
DeclarationScope scope = ((Param) param).fDeclarationScope;
List<ICTFMetadataNode> children = typealias.getChildren();
ICTFMetadataNode target = null;
ICTFMetadataNode alias = null;
IDeclaration targetDeclaration = null;
CTFTrace trace = ((Param) param).fTrace;
String aliasString;
if (typealias instanceof JsonStructureFieldMemberMetadataNode) {
JsonStructureFieldMemberMetadataNode member = ((JsonStructureFieldMemberMetadataNode) typealias);
aliasString = member.getName();
String type = typealias.getType();
if (member.getFieldClass().isJsonObject()) {
JsonObject fieldClass = member.getFieldClass().getAsJsonObject();
if (JsonMetadataStrings.FIXED_UNSIGNED_INTEGER_FIELD.equals(type)) {
fieldClass.addProperty(SIGNED, false);
targetDeclaration = IntegerDeclarationParser.INSTANCE.parse(typealias, new IntegerDeclarationParser.Param(trace));
} else if (JsonMetadataStrings.STATIC_LENGTH_BLOB.equals(type)) {
targetDeclaration = BlobDeclarationParser.INSTANCE.parse(typealias, null);
} else if (JsonMetadataStrings.NULL_TERMINATED_STRING.equals(type)) {
targetDeclaration = StringDeclarationParser.INSTANCE.parse(typealias, null);
} else if (JsonMetadataStrings.VARIANT.equals(type)) {
targetDeclaration = VariantParser.INSTANCE.parse(typealias, new VariantParser.Param(trace, scope));
} else if (JsonMetadataStrings.FIXED_UNSIGNED_ENUMERATION.equals(type)) {
targetDeclaration = EnumParser.INSTANCE.parse(typealias, new EnumParser.Param(trace, scope));
} else {
throw new ParseException("Invalid field class: " + type); //$NON-NLS-1$
}
} else {
// TODO: Implement parsing of field class aliases
throw new ParseException("Field classes that are not Json Objects are not yet supported"); //$NON-NLS-1$
}
} else {
for (ICTFMetadataNode child : children) {
String type = child.getType();
if (CTFParser.tokenNames[CTFParser.TYPEALIAS_TARGET].equals(type)) {
target = child;
} else if (CTFParser.tokenNames[CTFParser.TYPEALIAS_ALIAS].equals(type)) {
alias = child;
} else {
throw childTypeError(child);
}
}
targetDeclaration = TypeAliasTargetParser.INSTANCE.parse(target, new TypeAliasTargetParser.Param(trace, scope));
if ((targetDeclaration instanceof VariantDeclaration)
&& ((VariantDeclaration) targetDeclaration).isTagged()) {
throw new ParseException("Typealias of untagged variant is not permitted"); //$NON-NLS-1$
}
aliasString = TypeAliasAliasParser.INSTANCE.parse(alias, null);
}
scope.registerType(aliasString, targetDeclaration);
return targetDeclaration;
}
}