-
Notifications
You must be signed in to change notification settings - Fork 27
Ctf 2 fix draft #367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Ctf 2 fix draft #367
Conversation
📝 WalkthroughWalkthroughBumps bundle version and adds extensive JSON TSdl support: Gson-based metadata parsing with alias expansion, many JSON-aware parsers (strings, arrays, floats, structs), role-aware struct/variant lookups, interval-based integer mappings, new string/blob declarations, trace environment propagation, and multiple tests. Changes
Sequence Diagram(s)sequenceDiagram
participant JSON as JSON metadata (file)
participant Metadata as Metadata parser
participant Alias as expandAliases
participant TypeAlias as TypeAliasParser / field-class parsers
participant Scope as DeclarationScope
participant Trace as CTFTrace
JSON->>Metadata: read fragments (JsonElement per block)
Metadata->>Alias: collect FIELD_ALIAS entries and expandAliases(map)
Metadata->>TypeAlias: parse field-class elements -> IDeclaration
TypeAlias->>Scope: register types / declarations
Metadata->>Trace: extract JsonObject environment -> setEnvironment(map)
Note right of Trace: Registered declarations used later for createDefinition
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
f19df7b to
99a9d62
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 20
🧹 Nitpick comments (16)
ctf/org.eclipse.tracecompass.ctf.core/META-INF/MANIFEST.MF (1)
5-5: Version bump to 5.1.0.qualifier looks appropriateGiven the additive nature of the CTF core changes described in this PR, moving from 5.0.x to 5.1.0 is consistent with semantic versioning. Please just ensure:
- Any dependent bundles with tight
[5.0.2,5.1.0)ranges are checked/updated if needed.- Corresponding release notes/changelog entries are aligned with this new minor version.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (2)
194-197: Incorrect Javadoc comment for PATH constant.The Javadoc states "Type string for a structure field class" but
PATH = "path"represents a path field location, not a structure type. This appears to be copy-pasted from the STRUCTURE constant below.- /** - * Type string for a structure field class - */ + /** + * Path field within a field-class object + */ public static final String PATH = "path"; //$NON-NLS-1$
240-242: Missing Javadoc comments for MEMBER_CLASSES and MINIMUM_ALIGNMENT.These constants lack Javadoc comments, which is inconsistent with all other public constants in this file.
+ /** + * Member classes of a structure + */ public static final String MEMBER_CLASSES = "member-classes"; //$NON-NLS-1$ + /** + * Minimum alignment of a field class + */ public static final String MINIMUM_ALIGNMENT = "minimum-alignment"; //$NON-NLS-1$ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/BlobDeclaration.java (1)
89-95: Javadoc no longer reflects the implementation.The Javadoc states "Arbitrary decision to have maximum size as 1MB" but the implementation now returns
Math.min(fLength, 1000000), which returns the actual length when under 1MB. Consider updating the documentation to clarify the new semantics./** - * Arbitrary decision to have maximum size as 1MB + * Returns the effective size for this blob, capped at 1MB maximum. */ @Override public int getMaximumSize() { return Math.min(fLength, 1000000); }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java (1)
57-57: Unusedparamparameter.The
paramparameter is declared but never used in theparsemethod. Consider whether it's needed or if it should be used for validation.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition2.java (1)
34-52: Consider consolidating constructors.Both constructors have identical implementations, differing only in the declaration parameter type. Since
StringDeclarationextendsDeclaration, the more general constructor (lines 48-52) could handle both cases. Consider if theStringDeclaration-specific constructor is necessary for type safety elsewhere.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDefinition.java (1)
139-164: Significant code duplication betweenlookupDefinitionoverloads.The two
lookupDefinitionmethods share nearly identical logic. Consider extracting common logic to reduce duplication.Also applies to: 166-192
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.java (1)
216-219: Minor style: Consider usingrole != nullfor consistency.The condition
null != role(Yoda condition) is functionally correct but less common in this codebase. Considerrole != nullfor consistency.String role = declaration.getRole(); - if(null != role && !role.isEmpty()) { + if (role != null && !role.isEmpty()) { fRoles.put(role, declaration); }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicstring/DynamicLengthStringParser.java (1)
57-57: Unusedparamparameter.The
paramparameter is declared but never used. If theParamclass is intended for future use, consider documenting that; otherwise, this creates unnecessary API surface.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (3)
70-72: Use integer literal instead of scientific notation.The comparison uses
1e6(floating-point scientific notation) for an integer bound check. Use an integer literal for clarity.Apply this diff:
- if (rawLength > 1e6) { - throw new CTFException("Cannot have a length > 1000000, declared = " + rawLength); //$NON-NLS-1$ + if (rawLength > 1_000_000) { + throw new CTFException("Cannot have a length > 1,000,000, declared = " + rawLength); //$NON-NLS-1$ }
73-77: Optimize byte reading using BitBuffer.get(byte[]).Reading bytes one-by-one in a loop is inefficient. BitBuffer provides a
get(byte[] dst)method that reads multiple bytes at once.Apply this diff:
int length = (int) rawLength; byte[] bytes = new byte[length]; - for (int i = 0; i < length; i++) { - bytes[i] = (byte) input.get(Byte.SIZE, false); - } + input.get(bytes); String value = new String(bytes, fEncoding);
101-105: Incomplete implementation of isBinaryEquivalent.This method returns
falseunconditionally with a TODO comment. If binary equivalence checking is needed for static-length strings, this stub will produce incorrect results.Do you want me to generate a proper implementation or open an issue to track this as a follow-up task?
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/DynamicLengthStringDeclaration.java (4)
76-83: Use an integral literal for the max length bound
1e6is a double literal; the comparisonrawLength > 1e6performs an implicit widening conversion to double. It works in practice here but is atypical and may trigger static-analysis warnings.Consider switching to an integral literal:
- if (rawLength > 1e6) { + if (rawLength > 1_000_000L) { throw new CTFException("Cannot have a length > 1000000, declared = " + rawLength); //$NON-NLS-1$ }This keeps the check purely integral and matches the string literal in the error message.
84-88: Optional: bulk-read bytes and guard withcanReadFunctionally, reading each byte via
input.get(Byte.SIZE, false)works, but it is a tight per-byte loop and relies onBitBufferthrowing on out-of-bounds. You can make this both clearer and more efficient by checkingcanReadand using the bulkget(byte[])API.Example refactor:
- byte[] bytes = new byte[length]; - for (int i = 0; i < length; i++) { - bytes[i] = (byte) input.get(Byte.SIZE, false); - } + if (!input.canRead(length * Byte.SIZE)) { + throw new CTFException("Not enough data to read dynamic string of length " + length); //$NON-NLS-1$ + } + byte[] bytes = new byte[length]; + input.get(bytes);This assumes
alignRead(input)is called earlier (as suggested) so thatBitBuffer.get(byte[])starts on a byte boundary.
101-104: Consider aligninggetMaximumSize()with enforced max length
getMaximumSize()returnsInteger.MAX_VALUE, butcreateDefinitionenforcesrawLength <= 1_000_000. This discrepancy may confuse callers that rely ongetMaximumSize()to size buffers or for validation.If
1_000_000bytes is the intended hard cap, consider:
- Either documenting clearly that
getMaximumSize()is intentionally looser than the runtime guard, or- Adjusting
getMaximumSize()to reflect the same bound (in bytes or bits, depending on the contract used elsewhere in the hierarchy).Please cross-check how other dynamic-length declarations implement
getMaximumSize()for consistency.
111-115: ImplementisBinaryEquivalentinstead of always returningfalseLeaving
isBinaryEquivalentas a stub that always returnsfalsemay break reuse of declarations or type caching logic that depends on binary equivalence checks. For declarations with the same encoding and length-field name, it’s reasonable to treat them as equivalent.Possible implementation:
@Override public boolean isBinaryEquivalent(IDeclaration other) { - // TODO Auto-generated method stub - return false; + if (this == other) { + return true; + } + if (!(other instanceof DynamicLengthStringDeclaration)) { + return false; + } + DynamicLengthStringDeclaration o = (DynamicLengthStringDeclaration) other; + return fEncoding.equals(o.fEncoding) && fLengthName.equals(o.fLengthName); }If you prefer to support subclasses or nullable length names, you can relax the equality check accordingly.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (21)
ctf/org.eclipse.tracecompass.ctf.core/META-INF/MANIFEST.MF(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/BlobDeclaration.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/ScopedDefinition.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition2.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.java(5 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.java(4 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDefinition.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java(4 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicarray/DynamicLengthArrayParser.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicstring/DynamicLengthStringParser.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java(2 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/variant/VariantParser.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/DynamicLengthStringDeclaration.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java(4 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (6)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicstring/DynamicLengthStringParser.java (1)
DynamicLengthStringParser(46-102)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/enumeration/EnumParser.java (1)
EnumParser(97-266)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java (1)
StaticLengthArrayParser(33-112)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java (1)
StaticLengthStringParser(46-102)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java (1)
StructParser(95-285)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-244)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-244)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java (3)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMetadataNode.java (1)
JsonStructureFieldMetadataNode(29-89)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-244)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/DynamicLengthStringDeclaration.java (4)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/io/BitBuffer.java (1)
BitBuffer(32-743)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/Declaration.java (1)
Declaration(30-90)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDefinition.java (1)
IntegerDefinition(33-202)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition2.java (1)
StringDefinition2(22-72)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/variant/VariantParser.java (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-244)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (3)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/io/BitBuffer.java (1)
BitBuffer(32-743)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/Declaration.java (1)
Declaration(30-90)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition2.java (1)
StringDefinition2(22-72)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build / build
- GitHub Check: build / build
🔇 Additional comments (20)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java (2)
38-40: LGTM!The new imports are appropriate for the JSON element-based parsing and alias expansion functionality.
Also applies to: 78-80
268-291: LGTM!Using the pre-parsed and alias-expanded
JsonElementfor allfromJsoncalls is consistent and ensures the expanded aliases are correctly deserialized.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java (1)
131-135: LGTM!The updated logic correctly allows re-registration of the same declaration (idempotent behavior) while still detecting actual conflicts where a different declaration is being registered for the same field name. The null checks ensure safe comparison.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.java (1)
175-182: LGTM!Good improvements: early return for null/empty names prevents registering anonymous types, and
Objects.equals()provides null-safe comparison for declaration equality.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (1)
172-181: LGTM!The new type handling cases for dynamic/static length strings, arrays, and structures follow the established parsing pattern consistently. Each parser is invoked with the appropriate parameters.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java (1)
192-200: LGTM!The handling for
JsonStructureFieldMetadataNodecorrectly reads the minimum alignment and member classes, following the established pattern.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.java (1)
186-227: LGTM!The exclusion-aware lookup implementation is well-structured:
- Early exit for self-exclusion and null path prevents infinite recursion
- Role-based resolution short-circuits when declaration role matches
- Recursive calls correctly propagate the exclusion parameter
- Parent scope delegation appropriately uses
thisas the exclusionctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.java (1)
127-152: LGTM for the two-branch tag resolution logic.The implementation correctly handles both
IntegerDefinition(with mappings or numeric index) andEnumDefinition(with string value lookup) tag types. Error handling is appropriate with informative messages.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition2.java (1)
63-66:size()returns character count, not byte count.For strings with multi-byte encodings (e.g., UTF-8),
fString.length()returns the number of characters, not bytes. Ifsize()is expected to return the byte size (consistent with CTF field sizing), this could lead to incorrect calculations.Verify whether
size()should return the byte count based on the string's encoding, or if character count is intentional here.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDefinition.java (2)
45-69: LGTM for new constructor supportingSimpleDatatypeDefinition.The new constructor properly initializes the variant definition with the new tag type, enabling support for integer-based variant tags in addition to enum-based ones.
146-151: Potential issue with null role comparison.
getDeclaration().getRole()may returnnull. CallinglookupPath.equals(null)will always returnfalse, which is safe, but the intent may be clearer with a null check. More critically, iffTagDeforfDefinitioncould have a null declaration, this would NPE.Verify that
fTagDef.getDeclaration()andfDefinition.getDeclaration()are guaranteed to be non-null.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.java (3)
59-60: LGTM for role-based lookup mechanism.The
fRolesmap provides an efficient way to look up declarations by their semantic role, which is useful for CTF 2 metadata where roles like "packet-magic-number" or "event-record-id" need to be resolved.
348-352: LGTM for propagating role to self-registration.This ensures that when a struct has a role assigned, it registers itself in the roles map, enabling proper lookup of nested structures by role.
422-430: LGTM for role accessor.The
getRole(String)method provides clean access to child declarations by role.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicstring/DynamicLengthStringParser.java (1)
77-101:Paramclass is defined but unused within this parser.The
Paraminner class is defined but theparsemethod doesn't use theparamargument. Verify if this is intentional for API consistency with other parsers or if it should be removed.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicarray/DynamicLengthArrayParser.java (2)
78-114: LGTM!The Param inner class is well-structured with proper encapsulation and clear accessors.
72-73: Verify that empty string parameters are safe for element node creation.The JsonStructureFieldMemberMetadataNode is created with empty strings for the name, role, and other parameters. Ensure that TypeAliasParser and downstream code correctly handle these empty values without assuming they contain meaningful identifiers.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java (2)
75-111: LGTM!The Param inner class follows the same well-structured pattern as in DynamicLengthArrayParser.
69-70: The empty string parameters are safe and intentional.The
JsonStructureFieldMemberMetadataNodecreated with empty strings at lines 69-70 is a synthetic element node for array elements. TypeAliasParser.parse() explicitly handles this case: when the node's type is empty (line 143 of TypeAliasParser), it extracts the actual type from the field class JSON object. This same pattern is identically used in DynamicLengthArrayParser, confirming it is intentional design. No changes needed.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/DynamicLengthStringDeclaration.java (1)
25-94: Overall logic of dynamic string decoding looks solidAside from the points above (nullability, alignment, and minor style/robustness concerns), the core flow—lookup of a length field, validation, bounded read, charset-based decoding, and trimming at the first
'\0'—is clear and matches the intended semantics for a length-prefixed, null-terminated string.
...ecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.java
Outdated
Show resolved
Hide resolved
...racecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/ScopedDefinition.java
Outdated
Show resolved
Hide resolved
...acecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition2.java
Show resolved
Hide resolved
...cecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.java
Show resolved
Hide resolved
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java
Outdated
Show resolved
Hide resolved
...c/org/eclipse/tracecompass/internal/ctf/core/event/types/DynamicLengthStringDeclaration.java
Show resolved
Hide resolved
...c/org/eclipse/tracecompass/internal/ctf/core/event/types/DynamicLengthStringDeclaration.java
Show resolved
Hide resolved
...rc/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java
Show resolved
Hide resolved
...rc/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java
Show resolved
Hide resolved
...rc/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/BlobDeclaration.java (1)
64-76: Fix broken max-size enforcement (currentgetMaximumSize()makes the guard ineffective + risks OOM/DoS).With
getMaximumSize()returningfLength * 8(Line 91),createDefinition()’s check (Line 66) becomes non-protective for non-negative lengths and can also fail viaintoverflow. This allows huge allocations (new byte[fLength], Line 69) from untrusted trace data.Suggested direction (keeps “no arbitrary 1MB” while still preventing runaway allocations):
public class BlobDeclaration extends Declaration { + private static final int DEFAULT_MAX_BLOB_BYTES = + Integer.getInteger("org.eclipse.tracecompass.ctf.maxBlobBytes", 64 * 1024 * 1024); + private final int fLength; private final String fMediaType; @@ public @NonNull BlobDefinition createDefinition(IDefinitionScope definitionScope, @NonNull String fieldName, @NonNull BitBuffer input) throws CTFException { + if (fLength < 0) { + throw new CTFException("Negative blob length: " + fLength); //$NON-NLS-1$ + } if (fLength > getMaximumSize()) { throw new CTFException("Length asked: " + fLength + " is larger than the maximum blob size " + getMaximumSize()); //$NON-NLS-1$ //$NON-NLS-2$ } byte[] array = new byte[fLength]; @@ @Override public int getMaximumSize() { - return fLength*8; + return DEFAULT_MAX_BLOB_BYTES; }(If you don’t want a cap at all, then
getMaximumSize()should not be derived fromfLength, andcreateDefinition()should still hard-fail on negative lengths to avoidNegativeArraySizeException.)Also applies to: 89-92
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java (1)
566-577: Critical:hashCode()andequals()contract violation.The
equals()method now includesfMappingsandgetRole()in equality checks (Lines 603-608), buthashCode()(Lines 566-577) does not include these fields. This violates the Java contract: equal objects must have equal hash codes.Objects with identical base properties but different mappings/roles will have the same hash code but not be equal, causing incorrect behavior in hash-based collections like
HashMapandHashSet.Add
fMappingsand role tohashCode():@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (int) (fAlignment ^ (fAlignment >>> 32)); result = prime * result + fBase; result = prime * result + fByteOrder.toString().hashCode(); result = prime * result + fClock.hashCode(); result = prime * result + fEncoding.hashCode(); result = prime * result + fLength; result = prime * result + (fSigned ? 1231 : 1237); + result = prime * result + Objects.hashCode(fMappings); + result = prime * result + Objects.hashCode(getRole()); return result; }Also applies to: 603-608
🧹 Nitpick comments (4)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.java (2)
172-186:registerType: good idempotency + anonymous-type skip; consider enforcing non-null input contract
Skippingnull/empty names (Line 175) avoids polluting the registry with anonymous types, and theObjects.equalscomparison (Line 180) enables “same type, re-register is OK” semantics. Main watch-out: this behavior depends onIDeclaration.equals()being well-defined (structural vs reference).
198-206:registerIdentifier: add a guard for null/empty identifier names
UnlikeregisterType,registerIdentifierwill currently acceptname == nullorname.isEmpty(), which permitsnullkeys inHashMapand can cause hard-to-debug overwrites if the parser ever produces an unnamed identifier. Suggest throwingParseException(orIllegalArgumentException) early.public void registerIdentifier(String name, IDeclaration declaration) throws ParseException { + if (name == null || name.isEmpty()) { + throw new ParseException("Identifier name is null/empty"); //$NON-NLS-1$ + } /* Check if the type has been defined in the current scope */ IDeclaration iDeclaration = fIdentifiers.get(name); if (iDeclaration != null && !Objects.equals(iDeclaration, declaration)) { throw new ParseException("Identifier has already been defined:" + name); //$NON-NLS-1$ } /* Add it to the register. */ fIdentifiers.put(name, declaration); }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/BlobDeclaration.java (1)
35-62: Clarify whetherlenis “bits” or “bytes” (Javadoc vs implementation mismatch).Constructor docs say “length in bits” (Line 39, 51) but parsing/array allocation treats
fLengthas bytes (Line 69-73). This will confuse future changes and makes it hard to reason about size limits.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.java (1)
188-190: Prefer==for identity comparison.Using
this.equals(defintionToExclude)works but==is more idiomatic and efficient for checking object identity (i.e., same instance). Theequalsmethod may be overridden to compare content, which is not the intent here.- if (this.equals(defintionToExclude) || lookupPath == null) { + if (this == defintionToExclude || lookupPath == null) {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/BlobDeclaration.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java(8 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDefinition.java(2 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.java(4 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.java(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build / build
- GitHub Check: build / build
- GitHub Check: build / build
🔇 Additional comments (11)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.java (1)
20-20: Import addition is fine; keep an eye onequals()coverage
java.util.Objectsis now load-bearing for duplicate detection semantics; if anyIDeclarationsubclasses don’t implementequals()appropriately, this still degenerates to reference-identity checks.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDefinition.java (1)
109-114: Lazy initialization is not thread-safe, but impact is minimal.Multiple threads calling
getMappings()concurrently could compute the mapping redundantly. SinceStringassignment is atomic and the computation is deterministic, the worst outcome is wasted computation, not incorrect behavior. Consider usingvolatileor a synchronized block if this is called frequently in multi-threaded contexts.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.java (1)
264-269: Good fix: Corrected parameter order for mapped declarations.The first argument to
createDeclarationis now correctly(int) sizeinstead ofbase, aligning the mapped path (Line 265) with the non-mapped path (Line 268). This fixes a bug where mapped integer declarations would have been created with incorrect bit lengths.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java (2)
549-551: Good improvement: UsingLong.SIZEconstant.Replacing the hardcoded
64withLong.SIZEimproves readability and self-documents the intent.
134-146: Interval tree structure is appropriate for the mapping use case.The
IntervalNodeinner class and sorted list approach provide a reasonable foundation for mapping lookups. Note that the algorithm using this structure has issues (addressed separately).Also applies to: 372-387
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java (2)
23-26: LGTM!The new imports are necessary for the environment propagation logic and are used appropriately.
Also applies to: 52-52
161-162: The current implementation is correct. Environment values from JSON traces are intentionally stored in their JSON representation format (usingtoString()), and downstream code inLttngUstTraceandLttngKernelTraceexplicitly validates against this format by checking for literal"\"ust\""and"\"kernel\""strings with escaped quotes included.Likely an incorrect or invalid review comment.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.java (1)
19-19: Library migration is complete and properly configured.The migration from
org.json.JSONObjecttocom.google.gson.JsonObjectis consistent across import, field declaration, and getter return type. The@SerializedNameannotation is properly supported by Gson, and the dependency is correctly declared inMETA-INF/MANIFEST.MFunderImport-Package. All references in the codebase have been updated, including the usage inIOStructGen.javawheregetEnvironment().entrySet()is called.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.java (3)
205-219: Role-based lookup enhancement looks correct.The logic properly short-circuits when a child's declaration role matches the lookup path, avoiding unnecessary recursion. The exclusion propagation via
defintionToExcludecorrectly prevents infinite loops in cyclic references.
238-252: Null-safety and recursive traversal additions are correct.The early return for null role and the delegation to
lookupRoleRecursivefor nested structures follow a sound pattern.
254-266: Add null check before accessinggetCurrentField()result to prevent NullPointerException.On line 259,
getCurrentField()may return null if no field is currently selected. Accessingcurrent.getDeclaration()on line 260 without a null check can cause NPE. Add a guard before dereferencing:private IDefinition lookupRoleRecursive(IDefinition def, String role) { if (def instanceof StructDefinition) { return ((StructDefinition) def).lookupRole(role); } if (def instanceof VariantDefinition) { IDefinition current = ((VariantDefinition) def).getCurrentField(); + if (current == null) { + return null; + } if (role.equals(current.getDeclaration().getRole())) { return current; } return lookupRoleRecursive(current, role); } return null; }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventField.java (1)
121-130: Good:StringDefinition2is now parsed as a TMF string; consider null-safety + dedup.
- This mirrors the
StringDefinitionpath correctly.- Suggestion: defensively handle a potential
nullvalue (e.g., map to"") or enforce@NonNullinStringDefinition2(itssize()currently assumes non-null).- Optional: collapse the two branches to reduce duplication (e.g., helper
parseStringDefinition(...)/ common interface).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventField.java(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventField.java (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition2.java (1)
StringDefinition2(22-72)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build / build
- GitHub Check: build / build
🔇 Additional comments (1)
ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventField.java (1)
42-43: Import + new type dependency looks fine, but keep the surface area contained.
SinceStringDefinition2is new API in the CTF core, consider whether this file should be the only TMF-side “bridge” for it (vs. sprinklingStringDefinition2checks in multiple places).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (1)
144-148: Potential NullPointerException when accessing type from fieldClass.The call to
fieldClass.get(JsonMetadataStrings.TYPE).getAsString()will throw NPE if theTYPEkey is absent. Additionally, thefieldClass.isJsonObject()check on line 145 is redundant sincefieldClassis already aJsonObject(assigned viagetAsJsonObject()on line 113).Apply this diff to add null safety:
if (type.isEmpty()) { - if (fieldClass.isJsonObject()) { - type = fieldClass.get(JsonMetadataStrings.TYPE).getAsString(); + JsonElement typeElement = fieldClass.get(JsonMetadataStrings.TYPE); + if (typeElement != null && typeElement.isJsonPrimitive()) { + type = typeElement.getAsString(); } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java(5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build / build
- GitHub Check: build / build
- GitHub Check: build / build
🔇 Additional comments (2)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (1)
173-186: LGTM!The new type handling branches follow the established pattern in the file and correctly map each TSdl type to its corresponding parser with appropriate parameters.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
50-58: LGTM!The new constants are properly documented and follow the established naming conventions. The string values align with CTF2 specification terminology.
Also applies to: 160-167, 179-192, 224-247
...mpass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (3)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (3)
203-206: Incorrect Javadoc for PATH constant.Already flagged in previous review - the Javadoc incorrectly says "Type string for a structure field class" but the constant represents
"path".
220-222: UTF-32 charset JDK compatibility concern.Already flagged in previous review -
Charset.forName("UTF-32BE")andCharset.forName("UTF-32LE")may throwUnsupportedCharsetExceptionon JDKs prior to version 22.
249-251: Missing Javadoc for public constants.Already flagged in previous review -
MEMBER_CLASSESandMINIMUM_ALIGNMENTare missing Javadoc comments.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java(2 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java(5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build / build
- GitHub Check: build / build
- GitHub Check: build / build
🔇 Additional comments (6)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (3)
16-19: LGTM!Imports are appropriate for the new
ENCODINGSmap functionality.
50-60: LGTM!Constants are properly documented with Javadoc and follow the established conventions.
160-168: LGTM!Floating-point type constants are properly documented and follow the file conventions.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (3)
25-36: LGTM!Imports are appropriate for the new JSON-based metadata parsing functionality.
133-145: LGTM!The IEEE 754 size mappings are correct:
- 32-bit single precision: exponent=8, mantissa=24
- 64-bit double precision: exponent=11, mantissa=53
Clear error handling for unsupported sizes.
155-192: LGTM!The legacy parsing branch is well-structured with:
- Proper null check for children with clear error message
- Comprehensive handling of all float attributes (exp_dig, byte_order, mant_dig, align)
- Appropriate error handling for unknown attributes
...tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java
Show resolved
Hide resolved
...mpass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java
Show resolved
Hide resolved
...mpass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (2)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java (1)
19-20: Same blocker as above: Gson missing from test classpath.(See comment in
CTF2IntegrationTest.javaabout adding Gson toorg.eclipse.tracecompass.ctf.core.testsdependencies.)Also applies to: 24-58
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java (1)
24-26: Same blocker as above: Gson missing from test classpath.(See comment in
CTF2IntegrationTest.javaabout adding Gson toorg.eclipse.tracecompass.ctf.core.testsdependencies.)Also applies to: 30-89
🧹 Nitpick comments (4)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java (1)
77-116: Strengthen mapping assertions to validate ranges, not just keys.
testIntegerWithMappings()only checks map keys exist; it won’t catch wrong range parsing. Consider asserting the parsed ranges for"ZERO"and"ONE"are exactly[0,0]and[1,1](whatever the concreteIntegerDeclaration#getMappings()value type is).ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java (1)
33-37: Prefer Gson deserialization over reflection to set private fields.These tests are tightly coupled to private field names (
fEnvironment,fUid). If feasible, build JSON and deserialize intoJsonTraceMetadataNodewith Gson to better match production wiring and reduce brittleness.Also applies to: 50-54
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java (1)
30-52: Tighten assertions to validate parsed properties (not just non-null).For better regression protection, consider asserting key parsed attributes:
- float: expected length/byte-order-derived properties (or explicit exponent/mantissa expected for 32-bit if stable)
- strings: length (static case) and encoding for both static/dynamic cases (if accessible from the returned declaration).
Also applies to: 54-71, 73-89
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java (1)
30-48: Add missing assertion for default alignment in the 32-bit case
FloatDeclarationParsernormalizes missing alignment to1;testCTF2Float32Parsing()should assert it to lock the behavior.assertEquals(ByteOrder.LITTLE_ENDIAN, result.getByteOrder()); + assertEquals(1, result.getAlignment());
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java (4)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.java (1)
StructDeclaration(49-432)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/CTFTrace.java (1)
CTFTrace(81-1043)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.java (1)
IntegerDeclarationParser(81-271)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.java (1)
JsonTraceMetadataNode(28-87)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java (2)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (1)
TypeAliasParser(55-219)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java (2)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (1)
FloatDeclarationParser(66-206)
🪛 GitHub Actions: Continuous Integration (core tests only)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java
[error] 1-1: Compilation failed: The type com.google.gson.JsonObject cannot be resolved. Imports for Gson classes (JsonArray, JsonObject, JsonPrimitive) are failing, indicating a missing or unresolved Gson dependency during test compilation.
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java
[error] 1-1: Compilation failed: com.google.gson.JsonObject, JsonPrimitive cannot be resolved in tests importing Gson classes.
🪛 GitHub Actions: Continuous Integration (long-ui tests only)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java
[error] 1-1: Compilation failed: The type com.google.gson.JsonObject cannot be resolved. Gson dependencies are missing for CTF tests (CTF2IntegrationTest.java).
[error] 1-1: Compilation failed: Import com.google.gson.JsonArray cannot be resolved in CTF2IntegrationTest.java.
[error] 1-1: Compilation failed: Import com.google.gson.JsonPrimitive cannot be resolved in CTF2IntegrationTest.java.
[error] 1-1: The constructor JsonStructureFieldMemberMetadataNode(...) refers to missing type JsonObject (Gson types not resolved).
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java
[error] 1-1: Compilation failed: The type JsonObject cannot be resolved in JsonTraceMetadataNodeTest.java (imports of Gson types missing).
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java
[error] 1-1: Compilation failed: Gson-related classes not resolved in TypeAliasParserTest.java.
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java
[error] 1-1: Compilation failed: Gson types (JsonObject/JsonPrimitive) cannot be resolved in FloatDeclarationParserTest.java.
🪛 GitHub Actions: Continuous Integration (short-ui tests only)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java
[error] 1-1: Compilation failure: The type com.google.gson.JsonObject cannot be resolved. It is indirectly referenced from required type org.eclipse.tracecompass.ctf.core.trace.Metadata. Imports for com.google.gson.JsonArray, com.google.gson.JsonObject, and com.google.gson.JsonPrimitive cannot be resolved.
[error] 1-1: Compilation failure: JsonObject cannot be resolved to a type; JsonArray/JsonPrimitive also unresolved in test code.
[error] 1-1: The constructor JsonStructureFieldMemberMetadataNode(ICTFMetadataNode, String, String, String, JsonObject) refers to the missing type JsonObject.
[error] 1-1: CTF2IntegrationTest contains multiple references to Gson Json* classes (JsonObject, JsonArray, JsonPrimitive) that cannot be resolved due to missing Gson dependency in the test classpath.
[error] 1-1: Compilation failure: Unresolved references to JsonObject/JsonPrimitive in test code; likely due to missing Gson on test classpath.
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java
[error] 1-1: Compilation failure: JsonObject and JsonPrimitive types used in tests cannot be resolved due to missing Gson dependency.
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java
[error] 1-1: Compilation failure: Gson JsonObject/JsonPrimitive types cannot be resolved in TypeAliasParserTest.
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java
[error] 1-1: Compilation failure: The imports for com.google.gson.JsonObject and com.google.gson.JsonPrimitive cannot be resolved.
🔇 Additional comments (1)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java (1)
65-75: Verify API usage:StructDeclaration#getFields()andJsonStructureFieldMemberMetadataNode#setFieldClass(...)may be non-portable.
assertEquals(2, result.getFields().size())andnode.setFieldClass(...)assume APIs that may not exist (or may differ) across versions. IfStructDeclarationdoesn’t exposegetFields(), consider asserting viahasField(...)+ iteratinggetFieldsList()instead. IfJsonStructureFieldMemberMetadataNodedoesn’t support mutation, construct it with the field-class in the constructor instead.
...ss.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java
Show resolved
Hide resolved
...core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java
Show resolved
Hide resolved
| JsonObject fieldClass = new JsonObject(); | ||
| fieldClass.add("length", new JsonPrimitive(32)); | ||
| fieldClass.add("byte-order", new JsonPrimitive("le")); | ||
|
|
||
| JsonStructureFieldMemberMetadataNode node = new JsonStructureFieldMemberMetadataNode(null, "test", "test"); | ||
| node.setFieldClass(fieldClass); | ||
|
|
||
| FloatDeclaration result = FloatDeclarationParser.INSTANCE.parse(node, | ||
| new FloatDeclarationParser.Param(trace)); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CI blocker: JsonStructureFieldMemberMetadataNode is constructed/used with the wrong API
The test uses a 3-arg ctor + setFieldClass(...), but the provided class signature takes (parent, type, value, name, fieldClass) and the field class is final (no setter). This will fail compilation even after fixing Gson.
Suggested fix (also drops unnecessary JsonPrimitive usage):
- JsonObject fieldClass = new JsonObject();
- fieldClass.add("length", new JsonPrimitive(32));
- fieldClass.add("byte-order", new JsonPrimitive("le"));
+ JsonObject fieldClass = new JsonObject();
+ fieldClass.addProperty("length", 32);
+ fieldClass.addProperty("byte-order", "le");
- JsonStructureFieldMemberMetadataNode node = new JsonStructureFieldMemberMetadataNode(null, "test", "test");
- node.setFieldClass(fieldClass);
+ JsonStructureFieldMemberMetadataNode node =
+ new JsonStructureFieldMemberMetadataNode(null, "test", "test", "field", fieldClass);
@@
- JsonObject fieldClass = new JsonObject();
- fieldClass.add("length", new JsonPrimitive(64));
- fieldClass.add("byte-order", new JsonPrimitive("be"));
- fieldClass.add("alignment", new JsonPrimitive(8));
+ JsonObject fieldClass = new JsonObject();
+ fieldClass.addProperty("length", 64);
+ fieldClass.addProperty("byte-order", "be");
+ fieldClass.addProperty("alignment", 8);
- JsonStructureFieldMemberMetadataNode node = new JsonStructureFieldMemberMetadataNode(null, "test", "test");
- node.setFieldClass(fieldClass);
+ JsonStructureFieldMemberMetadataNode node =
+ new JsonStructureFieldMemberMetadataNode(null, "test", "test", "field", fieldClass);Also applies to: 54-64
🤖 Prompt for AI Agents
In
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java
around lines 34-43 (and likewise 54-64), the test constructs
JsonStructureFieldMemberMetadataNode with the old 3-arg ctor and calls
setFieldClass(...) which no longer exists; instead call the current constructor
that accepts (parent, type, value, name, fieldClass) and pass the JsonObject
fieldClass as the fifth argument, and simplify the JsonObject contents by adding
plain primitives (e.g., JsonObject.addProperty("length", 32) and
addProperty("byte-order", "le")) rather than wrapping values in JsonPrimitive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is better than claude!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MatthewKhouzam, thank you! I'm glad the analysis was helpful. Let me know if you need any clarification on the suggested constructor fix or run into any issues while implementing it. 😊
a278a00 to
8cbe6cf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (1)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java (1)
38-54: Tests look correct; please double-checkCTFTracelifecycle + Gson OSGi import
The updatedJsonStructureFieldMemberMetadataNode(..., name, fieldClass)construction matches the newer API and should compile cleanly.
- Verify whether
org.eclipse.tracecompass.ctf.core.trace.CTFTraceneeds explicit cleanup (e.g.,dispose()/close()) even when instantiated empty in tests.- Ensure the test bundle declares Gson as an OSGi import (if not already), since this class directly imports
com.google.gson.*.Also applies to: 62-80
🧹 Nitpick comments (2)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java (1)
24-26: PreferJsonObject#addProperty(...)over manualJsonPrimitivewrapping
This is more idiomatic Gson and reduces noise in the tests.-import com.google.gson.JsonPrimitive; @@ - fieldClass.add("length", new JsonPrimitive(32)); - fieldClass.add("byte-order", new JsonPrimitive("le")); + fieldClass.addProperty("length", 32); + fieldClass.addProperty("byte-order", "le"); @@ - fieldClass.add("length", new JsonPrimitive(64)); - fieldClass.add("byte-order", new JsonPrimitive("be")); - fieldClass.add("alignment", new JsonPrimitive(8)); + fieldClass.addProperty("length", 64); + fieldClass.addProperty("byte-order", "be"); + fieldClass.addProperty("alignment", 8);Also applies to: 41-44, 65-69
ctf/org.eclipse.tracecompass.ctf.core.tests/META-INF/MANIFEST.MF (1)
27-27: LGTM! Gson import added for JSON metadata parsing tests.The import is correctly placed and necessary for the JSON/TSdl metadata parsing capabilities introduced in this PR.
Optional improvement: Consider adding a version range to the Gson import for better dependency management, e.g.,
com.google.gson;version="[2.8.0,3.0.0)". This helps ensure compatibility and follows OSGi best practices, though the current approach is consistent with some other imports in this manifest (likecom.google.common.collect).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
ctf/org.eclipse.tracecompass.ctf.core.tests/META-INF/MANIFEST.MF(1 hunks)ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java
🧰 Additional context used
🧬 Code graph analysis (1)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.java (1)
JsonTraceMetadataNode(28-87)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build / build
- GitHub Check: build / build
- GitHub Check: build / build
🔇 Additional comments (1)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java (1)
33-50: Nice: focused assertions ongetEnvironment()andgetUid()outputs.The assertions are clear and validate the getters after
initialize().Also applies to: 60-69
....core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java
Show resolved
Hide resolved
| @Test | ||
| public void testUidAndPacketHeader() throws Exception { | ||
| JsonTraceMetadataNode node = new JsonTraceMetadataNode(null, "trace-class", "test"); | ||
|
|
||
| // Simulate Gson deserialization | ||
| java.lang.reflect.Field uidField = JsonTraceMetadataNode.class.getDeclaredField("fUid"); | ||
| uidField.setAccessible(true); | ||
| uidField.set(node, "test-uid-123"); | ||
|
|
||
| node.initialize(); | ||
|
|
||
| assertEquals("test-uid-123", node.getUid()); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test name doesn’t match coverage: no packet header is set/asserted.
testUidAndPacketHeader only asserts getUid(). Either rename to testUidParsing() or actually inject fPacketHeader (with a minimal JsonStructureFieldMetadataNode) and assert initialize() wires it (e.g., getPacketHeader() not null and/or child linkage if accessible).
🤖 Prompt for AI Agents
In
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java
around lines 58 to 70, the test named testUidAndPacketHeader only sets and
asserts the UID but does not set or assert any packet header; either rename the
test to testUidParsing() or modify it to inject a minimal fPacketHeader (create
a JsonStructureFieldMetadataNode instance, set it via reflection like fUid was
set), call initialize(), and add assertions that getPacketHeader() returns
non-null (and optionally verify the child linkage or expected type) to ensure
initialize() wires the packet header correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arfio, thank you for confirming!
Would you like to address this in the current PR by either:
- Renaming the test to
testUidParsing()to match what it actually tests, or - Adding packet header injection and assertions to truly cover both UID and packet header?
If you prefer to defer this to a follow-up, that works too—just let me know!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (6)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/CTFJsonMetadataNode.java (1)
CTFJsonMetadataNode(33-171)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/AlignmentParser.java (1)
AlignmentParser(51-117)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/ByteOrderParser.java (1)
ByteOrderParser(53-129)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/UnaryIntegerParser.java (1)
UnaryIntegerParser(28-68)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-257)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build / build
- GitHub Check: build / build
- GitHub Check: build / build
🔇 Additional comments (3)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (3)
25-36: Imports properly support JSON metadata parsing.The new imports for JSON-based metadata handling are appropriate and necessary for the dual-path (JSON and legacy AST) parsing approach.
133-145: LENGTH-to-exponent/mantissa mapping is correct.The mapping follows IEEE 754 standard for 32-bit (8 exponent, 24 mantissa) and 64-bit (11 exponent, 53 mantissa) floating-point numbers, with appropriate error handling for unsupported sizes.
155-192: Legacy parsing path properly preserved.The existing AST-based parsing logic is maintained in the else branch with proper validation and error handling, ensuring backward compatibility while adding JSON support.
...tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (1)
213-220: Redefinition guard is only applied to the non-JSON path; apply the same protection to JSON parsing too.
Right now, JSON-based aliases can still redefine an existing type (or rely onregisterTypebehavior), while the ANTLR path rejects duplicates. Consider moving thelookupTypecheck to just beforeregisterType(...)so both branches are protected consistently.- scope.registerType(aliasString, targetDeclaration); + if (scope.lookupType(aliasString) != null) { + throw new ParseException("Type has already been defined: " + aliasString); //$NON-NLS-1$ + } + scope.registerType(aliasString, targetDeclaration); return targetDeclaration;
♻️ Duplicate comments (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (1)
144-148: Fix possible NPE/IllegalStateException when readingfieldClass.TYPE.
fieldClass.get(JsonMetadataStrings.TYPE)can benull, andgetAsString()can throw if the element isn’t a primitive/string. This matches the previously reported issue.if (type.isEmpty()) { - if (fieldClass.isJsonObject()) { - type = fieldClass.get(JsonMetadataStrings.TYPE).getAsString(); - } + JsonElement typeElement = fieldClass.get(JsonMetadataStrings.TYPE); + if (typeElement != null && typeElement.isJsonPrimitive()) { + type = typeElement.getAsString(); + } }
🧹 Nitpick comments (3)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (1)
27-36: Good extension of JSON TSDL coverage; consider tightening validation/error messages for unsupportedtypevalues.
The new parser delegations for strings/arrays/struct/floats are a straightforward extension and keepTypeAliasParseras the central dispatcher. One small improvement: whentypeis present but not a JSON string (or is empty), fail with a targetedParseExceptionrather than letting downstream code trip over unexpected shapes.Also applies to: 173-187
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java (2)
29-30: Consider usingjava.util.Objects.equals()instead of Guava's deprecated method.The import uses Guava's
Objects.equal(), which has been deprecated in favor of the standard library'sjava.util.Objects.equals(). Consider switching to the JDK method for future maintainability.Apply this diff to use the standard library method:
-import com.google.common.base.Objects; +import java.util.Objects;Then update line 138:
- if (current != null && (ctf1 || !Objects.equal(decl, current))) { + if (current != null && (ctf1 || !Objects.equals(decl, current))) {
97-99: Consider a more descriptive variable name thanctf1.The boolean
ctf1distinguishes between CTFAntlr (strict duplicate checking) and JSON (lenient duplicate checking) parsing paths. A more descriptive name likeisStrictDuplicateCheck,isCTFAntlrPath, oruseStrictDuplicateDetectionwould improve readability.Example refactor:
- boolean ctf1 = false; + boolean useStrictDuplicateDetection = false; if (declaration instanceof CTFAntlrMetadataNode) { - ctf1= true; + useStrictDuplicateDetection = true;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java(4 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java
🧰 Additional context used
🧬 Code graph analysis (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (7)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicarray/DynamicLengthArrayParser.java (1)
DynamicLengthArrayParser(33-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicstring/DynamicLengthStringParser.java (1)
DynamicLengthStringParser(46-102)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (1)
FloatDeclarationParser(66-206)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.java (1)
IntegerDeclarationParser(81-271)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java (1)
StaticLengthArrayParser(33-112)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java (1)
StaticLengthStringParser(46-102)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java (1)
StructParser(95-285)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build / build
- GitHub Check: build / build
- GitHub Check: build / build
🔇 Additional comments (5)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.java (3)
20-20: LGTM!The import is necessary for the
Objects.equals()calls added inregisterTypeandregisterIdentifiermethods.
175-182: LGTM!The changes correctly implement duplicate-registration logic:
- Anonymous types (null/empty names) are skipped appropriately
- Existing declarations are retrieved by name and compared using
Objects.equals- Identical declarations can be re-registered (idempotent), while conflicting ones trigger a
ParseExceptionThis is a sound defensive approach for handling type registration.
200-201: LGTM! Critical bug fix confirmed.The changes correctly address the bug flagged in the past review comment:
- Now uses
fIdentifiers.get(name)instead of the incorrectfIdentifiers.get(declaration)- The map lookup uses the proper key type (String), making duplicate detection effective
- Identical declarations can be re-registered, while conflicts are properly caught
The implementation now matches the pattern used in
registerTypeand works as intended.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java (2)
143-145: The simplified null check assumes prior validation.The condition now only checks
fieldName != null, relying on the exception thrown at line 136 to ensuredeclis non-null. This is only safe after fixing the ordering issue flagged in lines 133-137. Once that critical issue is resolved, this simplification is appropriate.
138-141: The duplicate field detection logic is intentional but lacks documentation and test coverage.The code correctly allows CTF2 to idempotently redeclare fields with identical declarations (same name, same type), while CTF1 strictly rejects any duplicate field. This pattern is consistent with
DeclarationScope.registerIdentifier()andDeclarationScope.registerVariant(), which both use the sameObjects.equals()comparison to allow equal redeclarations.However, this significant behavioral difference should be documented with:
- A comment explaining why CTF2 allows idempotent field redeclarations while CTF1 does not
- A test case in
CTF2IntegrationTestverifying that duplicate fields with identical declarations are accepted in CTF2 metadataThis will clarify the intent and prevent future confusion about why the check uses
Objects.equal(decl, current)instead of always rejecting duplicates.
| scope.registerIdentifier(fieldName, decl); | ||
| if (struct.hasField(fieldName)) { | ||
| IDeclaration current = struct.getField(fieldName); | ||
| if (decl == null) { | ||
| throw new ParseException("struct: Cannot add null field " + fieldName); //$NON-NLS-1$ | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Null checks must occur before calling registerIdentifier and getField.
The current order performs operations with potentially null values before validation:
- Line 133 calls
scope.registerIdentifier(fieldName, decl)with potentially nullfieldName(when bothgetName()andgetRole()return null on lines 127-130) or nulldecl - Line 134 calls
struct.getField(fieldName)with potentially nullfieldName - Lines 135-137 check if
declis null, but by then it may already be registered in the scope
This can corrupt the scope state or cause NPEs. Move all null validations before line 133.
Apply this diff to fix the ordering:
scope.registerIdentifier(fieldName, decl);
- IDeclaration current = struct.getField(fieldName);
if (decl == null) {
throw new ParseException("struct: Cannot add null field " + fieldName); //$NON-NLS-1$
}
+ if (fieldName == null) {
+ throw new ParseException("struct: field name cannot be null"); //$NON-NLS-1$
+ }
+ IDeclaration current = struct.getField(fieldName);
if (current != null && (ctf1 || !Objects.equal(decl, current))) {
throw new ParseException("struct: duplicate field " //$NON-NLS-1$
+ fieldName);
}
-
- if (fieldName != null) {
- struct.addField(fieldName, decl);
- }
+ struct.addField(fieldName, decl);Note: You may also need to move the scope.registerIdentifier call after the null checks, depending on whether registering a null value is acceptable in the scope implementation.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java
around lines 133 to 137, the code calls scope.registerIdentifier(fieldName,
decl) and struct.getField(fieldName) before validating fieldName and decl; move
the null checks for fieldName (result of getName()/getRole()) and decl to before
any use of fieldName or decl, throw the ParseException if decl is null, and only
call scope.registerIdentifier(...) and struct.getField(...) after those
validations succeed (i.e., do not register or query with a null name or
declaration). Ensure registerIdentifier is moved after the null checks so the
scope is not corrupted by null entries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If fieldName is null the parser will just skip adding the item.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check DeclarationScope.registerIdentifier implementation to see if it handles null fieldName/decl
ast-grep --pattern $'class DeclarationScope {
$$$
registerIdentifier($$$) {
$$$
}
$$$
}'
Length of output: 0
🏁 Script executed:
#!/bin/bash
# Check StructDeclaration.getField implementation to see if it handles null fieldName
ast-grep --pattern $'class StructDeclaration {
$$$
getField($$$) {
$$$
}
$$$
}'
Length of output: 0
🏁 Script executed:
#!/bin/bash
# Also check if there are any null safety annotations on these methods
rg -n "registerIdentifier.*@Nullable|@NonNull.*registerIdentifier" --type java
Length of output: 0
🏁 Script executed:
#!/bin/bash
# Check getField method signatures
rg -n "getField.*@Nullable|@NonNull.*getField" --type java -A2 -B2
Length of output: 6860
🏁 Script executed:
#!/bin/bash
# Find DeclarationScope class file
fd -t f "DeclarationScope.java" --exec cat {}
Length of output: 20583
🏁 Script executed:
#!/bin/bash
# Find StructDeclaration.getField method implementation
rg -n "public.*getField\(" ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.java -A10
Length of output: 318
🏁 Script executed:
#!/bin/bash
# Also check if there's a hasField method in StructDeclaration
rg -n "hasField" ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.java -B2 -A5
Length of output: 623
@MatthewKhouzam, you're absolutely right that the struct itself won't be corrupted—the guard at line 143 (if (fieldName != null)) ensures addField is only called with a valid field name.
However, there's still a concern at line 133: scope.registerIdentifier(fieldName, decl) is called before any null checks. Looking at the implementation, while this won't throw an NPE (HashMap accepts null keys), it will add a null entry to the scope's identifier registry if fieldName is null, which could pollute the scope state.
Similarly, line 134 calls struct.getField(fieldName) with a potentially null fieldName, though this just returns null safely.
If the intention is to skip processing entirely when fieldName is null (as you've indicated), would it make sense to add an early return or null check before line 133 to avoid these unnecessary operations and keep the scope clean? Something like:
if (fieldName == null) {
return struct; // or log a warning if appropriate
}
scope.registerIdentifier(fieldName, decl);
// ... rest of the logicBut if having a null entry in the identifier map is acceptable/expected behavior in your design, then the current flow is fine for that use case.
🧬 Code Graph Analysis Results
StructDeclarationParser.java
-
Snippet 1 (excerpt showing conditional addition when fieldName is non-null)
File: ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java
Content:scope.registerIdentifier(fieldName, decl); IDeclaration current = struct.getField(fieldName); if (decl == null) { throw new ParseException("struct: Cannot add null field " + fieldName); //$NON-NLS-1$ } if (current != null && (ctf1 || !Objects.equal(decl, current))) { throw new ParseException("struct: duplicate field " //$NON-NLS-1$ + fieldName); } if (fieldName != null) { struct.addField(fieldName, decl); }Note: This area demonstrates that if fieldName is null, the addField call is skipped, aligning with the user comment about skipping when fieldName is null.
-
Snippet 2 (context where fieldName is assigned for the CTF1 path)
File: ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java
Content:for (ICTFMetadataNode typeDeclaratorNode : typeDeclaratorList) { decl = TypeDeclaratorParser.INSTANCE.parse(typeDeclaratorNode, new TypeDeclaratorParser.Param(trace, typeSpecifierListNode, scope, identifierSB)); } fieldName = identifierSB.toString();Note: This shows the path where fieldName is derived from the parsed identifier. If this results in null, the subsequent conditional addition would skip adding the field, consistent with the observed behavior described in the user comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
decl should be checked for null before it is registered.
But if it is null, the parser would throw which would then go up until the parser would throw a ctferror. I do not believe it would just ignore that value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
common/org.eclipse.tracecompass.common.core.tests/META-INF/MANIFEST.MF (1)
24-24: LGTM! Consider adding a version range for the Gson import.The addition of
com.google.gsoncorrectly supports the new JSON metadata parsing functionality introduced in this PR. However, OSGi best practice recommends specifying version ranges for imported packages to ensure compatibility and prevent runtime issues.Consider applying this diff to add a version range:
- com.google.gson, + com.google.gson;version="[2.8.0,3.0.0)",Adjust the version range to match the actual Gson version used in your project dependencies.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
common/org.eclipse.tracecompass.common.core.tests/META-INF/MANIFEST.MF(1 hunks)common/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.java(23 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build / build
- GitHub Check: build / build
- GitHub Check: build / build
🔇 Additional comments (2)
common/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.java (2)
129-597: Solid refactoring that improves test maintainability.The consistent replacement of hardcoded string assertions with structured JSON validation is a good improvement. This approach:
- Makes tests more resilient to formatting changes
- Validates the structure of log messages systematically
- Centralizes the validation logic for easier maintenance
34-35: Verify Gson version compatibility forparseString()usage.The code at line 108 uses
JsonParser.parseString(), which requires Gson 2.8.6 or later. The target platform defines Gson as a dependency, but the exact version cannot be determined from the repository artifacts. Confirm the project uses a compatible Gson version.
43b5e24 to
36c3178
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/BlobDeclaration.java (1)
65-68: Guard condition is always false for non-negative lengths.The condition
fLength > getMaximumSize()at line 66 checks iffLength > fLength * 8, which is always false for non-negativefLengthvalues (and could only be true due to integer overflow iffLength * 8wraps negative).If the intent was to remove the previous 1MB limit, consider removing the dead guard entirely. If some limit is still desired, the logic needs correction.
@Override public @NonNull BlobDefinition createDefinition(IDefinitionScope definitionScope, @NonNull String fieldName, @NonNull BitBuffer input) throws CTFException { - if (fLength > getMaximumSize()) { - throw new CTFException("Length asked: " + fLength + " is larger than the maximum blob size " + getMaximumSize()); //$NON-NLS-1$ //$NON-NLS-2$ - } byte[] array = new byte[fLength];Also applies to: 90-92
♻️ Duplicate comments (9)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java (1)
65-65: Length validation still missing.The past review comment correctly identified that the length should be validated before use to ensure it's positive and within reasonable bounds. This validation has not yet been implemented.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (3)
23-28: Fix class Javadoc to describe static-length string.The Javadoc still says "Dynamic-length string declaration", but this class is
StaticLengthStringDeclarationfor fixed-length strings. Please update the summary line accordingly while keeping the encoding mention and author.Suggested change:
-/** - * Dynamic-length string declaration with encoding support +/** + * Static-length string declaration with encoding support * * @author Matthew Khouzam */
33-44: Align constructor Javadoc with actual parameters.The Javadoc documents a
lengthNameparameter that does not exist; the constructor takesint length. This can mislead readers and tools relying on Javadoc.Suggested change:
/** * Constructor * - * @param lengthName - * the name of the length field + * @param length + * the fixed length of the string in bytes * @param encoding * the character encoding */
96-99: CorrecttoString()label to “static_string”.
toString()currently returns"dynamic_string[...]", which contradicts the static-length nature of this declaration.Suggested change:
@Override public String toString() { - return "dynamic_string[" + fLength + "]<" + fEncoding.name() + ">"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + return "static_string[" + fLength + "]<" + fEncoding.name() + ">"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java (1)
211-218: Missing null checks for JSON member properties (previously flagged).The code at lines 213-215 still lacks null checks before calling
getAsString()andgetAsJsonObject()on theNAMEandFIELD_CLASSelements, risking NullPointerException for malformed input.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/ScopedDefinition.java (1)
165-170: Infinite recursion bug (previously flagged).Line 169 calls
lookupDefinition(lookupPath, defintionToExclude)which is the same method, causing infinite recursion andStackOverflowError. This should delegate to the single-argument version:- return lookupDefinition(lookupPath, defintionToExclude); - }} + return lookupDefinition(lookupPath); + } +}ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.java (1)
49-49: Thread safety issue withfFieldArrayremains unaddressed.The past review correctly identified that
fFieldsis a synchronized map, butfFieldArrayis accessed and modified without synchronization. This can cause race conditions if multiple threads calladdFieldconcurrently.Additionally, there's a minor formatting issue on line 173.
public void addField(String fieldTag, IDeclaration declaration) { + synchronized (fFields) { fFields.put(fieldTag, declaration); int size = fFields.size(); fFieldArray = Arrays.copyOf(fFieldArray, size); - fFieldArray[size-1]=declaration; + fFieldArray[size - 1] = declaration; + } }Also applies to: 169-174
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (1)
152-154: Alignment validation missing in JSON parsing path.The past review correctly identified that alignment is read directly without validation in the JSON path, while the legacy path (line 184) uses
AlignmentParser.INSTANCE.parse()which validates that alignment is positive and a power of 2. This issue remains unaddressed.Apply this fix to validate alignment consistently:
if (fieldclass.has(JsonMetadataStrings.ALIGNMENT)) { - alignment = fieldclass.get(JsonMetadataStrings.ALIGNMENT).getAsInt(); + long alignmentValue = fieldclass.get(JsonMetadataStrings.ALIGNMENT).getAsLong(); + if (alignmentValue <= 0 || (alignmentValue & (alignmentValue - 1)) != 0) { + throw new ParseException("Invalid value for alignment: " + alignmentValue); + } + alignment = alignmentValue; }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/DynamicLengthStringDeclaration.java (1)
32-44: Enforce non‑null contract forlengthName/fLengthNameto avoid NPEs
lengthNameis annotated@Nullable, butfLengthNameis used everywhere as if non‑null (lookup, error message,toString) with no null checks. This creates a mismatch between the declared contract and actual usage and can lead to NPEs if a null ever gets passed.Since the parser always provides a valid name, it’s safer to enforce non‑null at the API boundary and on the field.
Suggested diff:
@@ -import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; @@ - private final Charset fEncoding; - private final String fLengthName; + private final Charset fEncoding; + private final @NonNull String fLengthName; @@ - * @param lengthName the name of the length field + * @param lengthName the name of the length field @@ - public DynamicLengthStringDeclaration(@Nullable String lengthName, Charset encoding) { + public DynamicLengthStringDeclaration(@NonNull String lengthName, Charset encoding) { fLengthName = lengthName; fEncoding = encoding; }After this change, please recompile with null‑analysis enabled to confirm there are no annotation conflicts with callers.
🧹 Nitpick comments (11)
common/org.eclipse.tracecompass.common.core.tests/META-INF/MANIFEST.MF (1)
24-24: LGTM. Optional: Consider adding a version range to match project practice.The Gson import is correct and properly formatted. However, there is precedent in the project for specifying versions on Gson imports:
doc/org.eclipse.tracecompass.examples.core/META-INF/MANIFEST.MFusescom.google.gson;version="2.8.2". Since this project does specify versions on other imports (e.g.,org.junit;bundle-version="4.0.0"), adding a version constraint would improve consistency.ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventField.java (1)
121-126:StringDefinition2handling is consistent; please confirm type hierarchy / orderingMapping
StringDefinition2toCTFStringFieldviagetValue()mirrors the existingStringDefinitionhandling and looks correct.One thing to double‑check: if
StringDefinition2were ever to extendStringDefinition, theinstanceof StringDefinitionbranch would catch it first and thisStringDefinition2branch would be unreachable. Today this is probably fine (and suggestsStringDefinition2is a separate type), but it may be worth confirming that there is no inheritance relationship, or documenting that assumption here to avoid future surprises if the hierarchy evolves.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java (1)
69-69: Consider adding a comment explaining the empty string parameters.The element node is constructed with empty strings for
type,value, andnameparameters. While this appears intentional (since the actual metadata is derived fromelementFieldClass), a brief comment explaining why these are empty would improve code clarity.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (1)
64-94: Use an integral max-length literal and double‑check maximum size semantics.Two small points here:
1e6is a double literal; using an integral literal avoids implicit widening/narrowing and better reflects the domain (byte length):
if (rawLength > 1e6) {
if (rawLength > 1_000_000L) {
getMaximumSize()returnsInteger.MAX_VALUEeven though this declaration has a fixed length. Consider whether this should instead reflectfLength(in whatever unitsgetMaximumSizeis defined for), or at least be consistent with how other string declarations implement it in this codebase.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDefinition.java (1)
44-44: Lazy initialization introduces a benign data race.The
fMappingfield is now non-final and lazily initialized ingetMappings()without synchronization. While this could result in redundant computation under concurrent access, the computation is idempotent (same result each time), so correctness is preserved. If this code is accessed from multiple threads, consider using a local variable pattern to avoid potential visibility issues:public String getMappings() { String mapping = fMapping; if (mapping == null) { mapping = getDeclaration().getMappingForValue(fValue); fMapping = mapping; } return mapping; }Also applies to: 110-113
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDefinition.java (1)
166-192: Consider reducing code duplication between lookup methods.The two
lookupDefinitionoverloads share nearly identical logic. The first method could delegate to the second to reduce duplication:@Override public IDefinition lookupDefinition(String lookupPath) { - if (lookupPath == null) { - return null; - } - if (lookupPath.equals(fFieldName)) { - return fDefinition; - } - if (lookupPath.equals(fTagDef.getDeclaration().getRole())) { - return fTagDef; - } - if (lookupPath.equals(fDefinition.getDeclaration().getRole())) { - return fDefinition; - } - if (fDefinition instanceof ScopedDefinition) { - IDefinition def = ((ScopedDefinition) fDefinition).lookupDefinition(lookupPath, this); - if (def != null) { - return def; - } - } - final IDefinitionScope definitionScope = getDefinitionScope(); - if (definitionScope instanceof StructDefinition) { - StructDefinition structDefinition = (StructDefinition) definitionScope; - return structDefinition.lookupDefinition(lookupPath, this); - } - return definitionScope.lookupDefinition(lookupPath); + return lookupDefinition(lookupPath, this); }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.java (1)
187-187: Typo in parameter name: "defintionToExclude"The parameter is misspelled as
defintionToExclude(missing 'i' in "definition"). While this doesn't affect functionality, it impacts code readability and should be corrected throughout the file for consistency.Apply this diff to fix the typo:
- public Definition lookupDefinition(String lookupPath, ScopedDefinition defintionToExclude) { - if (this.equals(defintionToExclude) || lookupPath == null) { + public Definition lookupDefinition(String lookupPath, ScopedDefinition definitionToExclude) { + if (this.equals(definitionToExclude) || lookupPath == null) { return null; } /* * The fields are created in order of appearance, so if a variant or * sequence refers to a field that is after it, the field's definition * will not be there yet in the hashmap. */ int val = fFieldNames.indexOf(lookupPath); if (val != -1) { return fDefinitions[val]; } String lookupUnderscored = "_" + lookupPath; //$NON-NLS-1$ val = fFieldNames.indexOf(lookupUnderscored); if (val != -1) { return fDefinitions[val]; } for (IDefinition child : fDefinitions) { if (child instanceof ScopedDefinition) { - if (!child.equals(defintionToExclude)) { + if (!child.equals(definitionToExclude)) { if (lookupPath.equals(child.getDeclaration().getRole())) { if (child instanceof Definition) { return (Definition) child; } } - IDefinition def = ((ScopedDefinition) child).lookupDefinition(lookupPath, defintionToExclude); + IDefinition def = ((ScopedDefinition) child).lookupDefinition(lookupPath, definitionToExclude); if (def instanceof Definition) { return (Definition) def; } } } }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.java (1)
422-430: Fix Javadoc for getRole methodThe
@returndocumentation states "the role" but the method actually returns theIDeclarationassociated with that role.Apply this diff to correct the Javadoc:
/** * Get the child with a role * @param role the role - * @return the role + * @return the declaration with the specified role, or null if not found * @since 5.1 */ public @Nullable IDeclaration getRole(String role) { return fRoles.get(role); }ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java (1)
66-81: Consider adding more specific assertionsThe test only verifies that the result is non-null. Consider adding assertions to validate specific properties of the parsed string declaration (e.g., length, encoding) to make the test more robust.
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java (2)
38-54: Past constructor issues are resolvedThe previous review comments flagged constructor signature mismatches, but the current code correctly uses the 5-parameter
JsonStructureFieldMemberMetadataNodeconstructor. The test logic and assertions are correct for IEEE 754 single-precision floats.Optionally, you could simplify the JsonObject construction by using
addPropertyinstead of wrapping primitives:JsonObject fieldClass = new JsonObject(); - fieldClass.add("length", new JsonPrimitive(32)); - fieldClass.add("byte-order", new JsonPrimitive("le")); + fieldClass.addProperty("length", 32); + fieldClass.addProperty("byte-order", "le");
62-80: LGTM: Correct 64-bit float test with proper constructor usageThe test correctly validates IEEE 754 double-precision parsing with the proper 5-parameter constructor. Assertions match the expected exponent (11), mantissa (53), byte order, and alignment values.
Same optional simplification applies here:
JsonObject fieldClass = new JsonObject(); - fieldClass.add("length", new JsonPrimitive(64)); - fieldClass.add("byte-order", new JsonPrimitive("be")); - fieldClass.add("alignment", new JsonPrimitive(8)); + fieldClass.addProperty("length", 64); + fieldClass.addProperty("byte-order", "be"); + fieldClass.addProperty("alignment", 8);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (35)
common/org.eclipse.tracecompass.common.core.tests/META-INF/MANIFEST.MF(1 hunks)common/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.java(23 hunks)ctf/org.eclipse.tracecompass.ctf.core.tests/META-INF/MANIFEST.MF(1 hunks)ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/META-INF/MANIFEST.MF(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/BlobDeclaration.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java(9 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDefinition.java(2 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/ScopedDefinition.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition2.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.java(5 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.java(4 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.java(4 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDefinition.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java(4 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java(4 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicarray/DynamicLengthArrayParser.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicstring/DynamicLengthStringParser.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java(2 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java(4 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java(2 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/variant/VariantParser.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/DynamicLengthStringDeclaration.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java(5 hunks)ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventField.java(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (13)
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/variant/VariantParser.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicstring/DynamicLengthStringParser.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicarray/DynamicLengthArrayParser.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition2.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java
- common/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.java
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.java
🧰 Additional context used
🧬 Code graph analysis (6)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java (4)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMetadataNode.java (1)
JsonStructureFieldMetadataNode(29-89)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/AlignmentParser.java (1)
AlignmentParser(51-117)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-257)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java (3)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (2)
NonNullByDefault(66-83)TypeAliasParser(55-222)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/ArrayDeclaration.java (1)
ArrayDeclaration(43-194)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-257)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java (2)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (1)
FloatDeclarationParser(66-206)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java (2)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (1)
TypeAliasParser(55-222)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (3)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/io/BitBuffer.java (1)
BitBuffer(32-743)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/Declaration.java (1)
Declaration(30-90)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition2.java (1)
StringDefinition2(22-72)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (5)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/CTFJsonMetadataNode.java (1)
CTFJsonMetadataNode(33-171)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/AlignmentParser.java (1)
AlignmentParser(51-117)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/UnaryIntegerParser.java (1)
UnaryIntegerParser(28-68)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-257)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build / build
- GitHub Check: build / build
- GitHub Check: build / build
🔇 Additional comments (19)
ctf/org.eclipse.tracecompass.ctf.core.tests/META-INF/MANIFEST.MF (1)
27-27: LGTM! Gson import aligns with JSON-based test additions.The addition of
com.google.gsonto the Import-Package section is consistent with the broader JSON/TSdl parsing changes and new test classes mentioned in the AI summary (e.g., JsonTraceMetadataNodeTest). The lack of version constraint matches the pattern used in the core bundle and other imports in this manifest.ctf/org.eclipse.tracecompass.ctf.core/META-INF/MANIFEST.MF (1)
5-5: LGTM! Minor version bump is appropriate for CTF 2 support.The version bump from 5.0.2 to 5.1.0 correctly reflects the addition of new functionality (LTTng 2.14.3 CTF 2 trace support) while maintaining backward compatibility. This aligns with OSGi semantic versioning conventions for feature additions without breaking API changes.
ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventField.java (1)
41-43: Import ofStringDefinition2is correct and usedThe new import cleanly integrates with the existing type imports and is used below in
parseField, so there’s no unused‑import or packaging concern here.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java (2)
635-660: LGTM on the mapping lookup fix.The backward iteration now correctly checks all candidates without early termination, ensuring intervals like
[0,100]are not missed when searching for values like 75. The logic is correct.Note: This approach is O(n) in the worst case when all intervals could potentially contain the value. For large mapping sets, consider an augmented interval tree, but this is likely acceptable for typical CTF use cases.
372-387: Consider thread safety for setMappings.The
setMappingsmethod modifiesfMappingsandfIntervalTreenon-atomically. If this method is called after construction whilegetMappingForValueis being invoked from another thread, it could result in inconsistent reads.If
setMappingsis guaranteed to be called only during construction (before the declaration is shared), this is fine. Otherwise, consider making the interval tree reference volatile or using copy-on-write semantics.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.java (1)
19-19: LGTM! Consistent library migration from org.json to Gson.The type change from
JSONObjecttoJsonObjectaligns with the Gson-based deserialization used throughout this class (via@SerializedNameannotations).Also applies to: 33-33, 65-65
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.java (1)
127-158: Two-branch tag resolution logic is well-implemented.The implementation correctly handles:
- IntegerDefinition with mappings or numeric index-based lookup
- EnumDefinition with the preserved existing string-based lookup
- Proper bounds checking at lines 136-138 prevents
ArrayIndexOutOfBoundsException- Clear error messages for undefined tags and unknown selectors
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDefinition.java (2)
39-39: LGTM! Good API versioning and backward compatibility.The type widening from
EnumDefinitiontoSimpleDatatypeDefinitionallows handling both integer-based and enum-based tag definitions. The new constructor is properly annotated with@since 5.1, and the existingEnumDefinitionconstructor is preserved for backward compatibility.Also applies to: 45-69, 89-96
138-164: Role-based lookup logic is well-structured.The extended
lookupDefinitionmethod properly:
- Resolves fields by role using
getDeclaration().getRole()- Delegates to nested
ScopedDefinitionwith exclusion to prevent infinite loops- Falls back through the scope hierarchy appropriately
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.java (1)
264-269: LGTM! Bug fix for mapped integer declaration creation.The fix correctly uses
(int) sizeas the first parameter for the mapped declaration path, aligning it with the non-mapped path on line 268. Previously usingbaseas the size would have created incorrectly-sized integer declarations.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (2)
133-145: LGTM! IEEE 754 size mapping is correct.The implementation correctly maps:
- 32-bit → exponent=8, mantissa=24 (IEEE 754 binary32/float)
- 64-bit → exponent=11, mantissa=53 (IEEE 754 binary64/double)
The error handling for unsupported sizes provides a clear message.
155-192: Legacy parsing path correctly preserved.The existing TSDL parsing logic is cleanly moved to the else branch, preserving all attribute parsing including proper alignment validation via
AlignmentParser.INSTANCE.parse().ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.java (3)
208-212: LGTM: Role-based lookup optimizationThe role-based short-circuit correctly checks if the
lookupPathmatches a child's declared role and returns it directly, avoiding unnecessary deep traversal.
223-225: LGTM: Cycle prevention in scope delegationThe addition of the exclusion parameter when delegating to the parent scope correctly prevents infinite recursion by passing
thisas the definition to exclude.
239-266: LGTM: Recursive role lookup with proper null safetyThe enhanced
lookupRolemethod correctly adds null-safety and introduces recursive traversal through nested structures (StructDefinition and VariantDefinition). The recursive helper properly handles the variant's current field selection.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.java (3)
59-60: LGTM: Role-to-declaration mappingThe addition of
fRolesmap provides efficient O(1) lookup for declarations by role. The field is appropriately marked as final and non-null.
348-352: LGTM: Self-registration for role-based navigationThe override correctly propagates the role to the superclass and registers the struct itself in
fRoles, enabling parent structures to locate this struct by its role.
216-219: Add duplicate role detection to prevent silent overwritesWhen adding fields with roles, the code silently overwrites any existing declaration with the same role. Unlike field names (which trigger a warning if duplicated), roles have no such check. Add validation to detect and handle duplicate roles consistently.
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java (1)
38-58: The type string"fixed-length-floating-point-number"in the test is correct and matchesJsonMetadataStrings.FIXED_LENGTH_FLOATING_POINTexactly. No changes needed.Likely an incorrect or invalid review comment.
| public void testDynamicLengthStringParsing() throws Exception { | ||
| // Test that the parser doesn't throw an exception for dynamic length strings | ||
| // The actual parsing logic may not be fully implemented yet | ||
| CTFTrace trace = new CTFTrace(); | ||
| DeclarationScope scope = new DeclarationScope(null, "test"); | ||
|
|
||
| JsonObject fieldClass = new JsonObject(); | ||
| fieldClass.add("type", new JsonPrimitive("dynamic-length-string")); | ||
| fieldClass.add("encoding", new JsonPrimitive("utf-8")); | ||
|
|
||
| JsonStructureFieldMemberMetadataNode node = new JsonStructureFieldMemberMetadataNode(null, "dynamic-length-string", "test", "dyn_string_field", fieldClass); | ||
|
|
||
| try { | ||
| IDeclaration result = TypeAliasParser.INSTANCE.parse(node, | ||
| new TypeAliasParser.Param(trace, scope)); | ||
| // If we get here without exception, the basic parsing works | ||
| assertNotNull(result); | ||
| } catch (Exception e) { | ||
| // For now, just verify the parser recognizes the type | ||
| assertTrue("Parser should handle dynamic-length-string type", | ||
| e.getMessage() == null || !e.getMessage().contains("Invalid field class")); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarify implementation status of dynamic-length string parsing
The comment and try-catch structure suggest the parsing logic "may not be fully implemented yet." If this feature is incomplete, consider:
- Marking the test with
@Ignoreand a TODO comment with a tracking issue - Or document the expected behavior more clearly in the test
- Or implement the missing functionality before merging
Tests that allow both success and certain failures make it difficult to detect regressions.
Do you want me to search the codebase to verify if DynamicLengthStringParser is fully implemented?
🤖 Prompt for AI Agents
In
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java
around lines 89-111, the test for dynamic-length-string currently swallows
failures in a try/catch which makes regressions undetectable; first check
whether DynamicLengthStringParser is implemented—if it is not, annotate the test
with @Ignore and add a one-line TODO with a tracking issue/PR number explaining
why it’s ignored; if the parser is implemented, remove the lenient try/catch,
assert the parsed result (assertNotNull) and/or assert specific expected
behavior, and fail the test on any exception so the test reliably detects
regressions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the assert in the catch clause, the test should throw in certain cases? If the parser fails, the test should also fail no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rate Limit Exceeded
@arfio have exceeded the limit for the number of chat messages per hour. Please wait 2 minutes and 23 seconds before sending another message.
...pass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java
Show resolved
Hide resolved
.../tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java
Outdated
Show resolved
Hide resolved
...rc/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java
Show resolved
Hide resolved
36c3178 to
c2cdf0c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
♻️ Duplicate comments (26)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java (2)
301-316: Previously flagged issues inexpandAliasesremain unaddressed.Per past review:
- ConcurrentModificationException risk (line 302): Iterating
obj.keySet()while callingobj.add()can fail depending on Gson's implementation. Iterate over a copy:new ArrayList<>(obj.keySet()).- String aliases in arrays not expanded (lines 309-312): Only
JsonObjectelements are recursed into; string alias references directly in arrays won't be resolved.
259-266:JsonParser.parseStringcan throwJsonSyntaxExceptionoutside the try-catch block.If
jsonBlocks[i]contains malformed JSON,JsonParser.parseString()at line 259 throwsJsonSyntaxException, but the try-catch at lines 269-273 only coversgson.fromJson(). This could cause an unhandled exception and abort trace parsing.for (int i = 1; i < jsonBlocks.length; i++) { - JsonElement element = JsonParser.parseString(jsonBlocks[i]); + JsonElement element; + try { + element = JsonParser.parseString(jsonBlocks[i]); + } catch (JsonSyntaxException e) { + throw new CTFException("Trace cannot be parsed as CTF2", e); //$NON-NLS-1$ + } if (element.isJsonObject()) {
Add null checks before accessing
NAMEandFIELD_CLASSproperties (lines 263-265).This was flagged in a previous review. Malformed
FIELD_ALIASfragments missing these properties will throw ongetAsString()orgetAsJsonObject().ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition2.java (1)
24-24: Potential null pointer exception ifvalueis null.The
valueparameter in both constructors lacks@NonNullannotation, andfStringis stored directly. If a null value is passed,size()andtoString()will throw NPE.Also applies to: 34-37, 48-51
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (1)
152-154: Alignment value not validated in JSON parsing path.The JSON path reads alignment directly without validation, while the legacy path (line 184) uses
AlignmentParser.INSTANCE.parse()which validates that alignment must be positive and a power of 2. Invalid alignment values from JSON metadata could bypass validation.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicstring/DynamicLengthStringParser.java (1)
65-74: Missing null-safety for chained JSON access.This issue was previously flagged. Line 70 chains multiple calls without null checks. If
lengthFieldLocationis not a JSON object or doesn't containPATH, this will throw an unchecked exception rather than a descriptiveParseException.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (4)
23-27: Fix incorrect class javadoc.The javadoc says "Dynamic-length string declaration" but this class is
StaticLengthStringDeclarationfor static-length strings.
33-44: Fix constructor javadoc parameter mismatch.The javadoc refers to parameter
lengthNameof type String, but the actual parameter islengthof type int.
96-99: Correct toString() to indicate static-length string.The toString() method returns "dynamic_string" but this class represents a static-length string.
101-105: ImplementisBinaryEquivalentinstead of returning a TODO stub.Leaving
isBinaryEquivalentas a stub that always returnsfalsebreaks semantic equivalence for identical static-length string declarations.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (5)
184-187: Incorrect Javadoc for DYNAMIC_LENGTH_STRING constant.The Javadoc says "Type string for a null terminated string field class" but this constant represents
"dynamic-length-string".
203-206: Incorrect Javadoc for PATH constant.The Javadoc says "Type string for a structure field class" but this constant represents
"path".
220-222: UTF-32 charset handling should account for JDK version compatibility.
Charset.forName("UTF-32BE")andCharset.forName("UTF-32LE")will throwUnsupportedCharsetExceptionat class loading time on JDKs prior to version 22.
249-251: Missing Javadoc for public constants.
MEMBER_CLASSESandMINIMUM_ALIGNMENTare missing Javadoc comments.
253-255: Missing Javadoc and externalized string markers.
ALIGNMENTandBYTE_ORDERconstants are missing Javadoc comments and//$NON-NLS-1$markers.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/variant/VariantParser.java (2)
269-271: Add defensive checks for JSON parsing to prevent unhelpful exceptions.Line 270 assumes
SELECTOR_FIELD_LOCATIONcontains a JSON object with aPATHfield that is an array. Thehas()check only verifies the key exists, not the structure.
365-374: Error message is misleading after adding IntegerDeclaration support.The code now accepts both
EnumDeclarationandIntegerDeclarationas valid tag types, but the error message at line 373 still says "Variant tag must be an enum".ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java (1)
165-167:JsonElement.toString()includes JSON quotes for string values.Using
entry.getValue().toString()on aJsonElementproduces the JSON representation, which includes quotes around strings. For example, a JSON string"hello"will become"\"hello\""as a Java String.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java (1)
211-217: Missing null checks for JSON member properties.
memberElement.getAsJsonObject().get(JsonMetadataStrings.NAME)andget(JsonMetadataStrings.FIELD_CLASS)can returnnull, causing NullPointerException whengetAsString()orgetAsJsonObject()is called.ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java (2)
31-51: Reflection-based injection offEnvironmentis brittleThis test directly sets
JsonTraceMetadataNode.fEnvironmentvia reflection. That’s fragile against refactors (field rename/visibility changes) and may eventually break under stricter module access. Prefer going through the actual Gson deserialization path or a package-private/testing seam (e.g., constructor or setter) to inject the environment.If reflection must stay, centralize it in a helper so failures are easier to diagnose.
53-70:testUidAndPacketHeaderonly asserts UID, not packet headerDespite the name, this test only sets and asserts the UID; no packet-header setup or assertion is performed. Either rename the test to reflect what it actually covers, or extend it to initialize a minimal
fPacketHeaderand verify thatinitialize()wires it correctly (e.g.,getPacketHeader()non-null and/or child linkage).ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (1)
144-187: Add null/type checks when inferringtypefromfieldClassHere:
if (type.isEmpty()) { if (fieldClass.isJsonObject()) { type = fieldClass.get(JsonMetadataStrings.TYPE).getAsString(); } }
fieldClass.get(JsonMetadataStrings.TYPE)can returnnullor a non‑primitive value, leading to aNullPointerExceptionorIllegalStateExceptionongetAsString(). This was already flagged in an earlier review.Consider guarding the access:
- if (type.isEmpty()) { - if (fieldClass.isJsonObject()) { - type = fieldClass.get(JsonMetadataStrings.TYPE).getAsString(); - } - } + if (type.isEmpty()) { + JsonElement typeElement = fieldClass.get(JsonMetadataStrings.TYPE); + if (typeElement != null && typeElement.isJsonPrimitive()) { + type = typeElement.getAsString(); + } + }The added branches for dynamic/static strings and arrays, structs, and floating point types, as well as the alias redefinition check, otherwise look consistent with the existing parser design.
Also applies to: 213-215
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/ScopedDefinition.java (1)
155-170: Fix infinite recursion inlookupDefinition(String, ScopedDefinition)The two-argument overload currently calls itself with identical parameters, causing infinite recursion and a
StackOverflowErrorat runtime.Replace the self-call with a delegation to the single-argument overload so the base behavior is preserved and subclasses can override the exclusion-aware form:
- public @Nullable IDefinition lookupDefinition(@Nullable String lookupPath, @Nullable ScopedDefinition defintionToExclude) { - if(defintionToExclude == this) { - return null; - } - return lookupDefinition(lookupPath, defintionToExclude); - }} + public @Nullable IDefinition lookupDefinition(@Nullable String lookupPath, @Nullable ScopedDefinition defintionToExclude) { + if (defintionToExclude == this) { + return null; + } + return lookupDefinition(lookupPath); + } +}ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java (1)
43-73: Harden JSON handling forfield-classand validate array lengthTwo robustness issues here (both previously raised):
- Potential NPE/ClassCastException on
getFieldClass().getAsJsonObject()JsonStructureFieldMemberMetadataNode member = (JsonStructureFieldMemberMetadataNode) node; JsonObject fieldClass = member.getFieldClass().getAsJsonObject();If
getFieldClass()is null or not a JSON object, this will fail at runtime. Consider:- JsonStructureFieldMemberMetadataNode member = (JsonStructureFieldMemberMetadataNode) node; - JsonObject fieldClass = member.getFieldClass().getAsJsonObject(); + JsonStructureFieldMemberMetadataNode member = (JsonStructureFieldMemberMetadataNode) node; + JsonElement fieldClassElement = member.getFieldClass(); + if (fieldClassElement == null || !fieldClassElement.isJsonObject()) { + throw new ParseException("Static-length array requires a valid field-class object"); //$NON-NLS-1$ + } + JsonObject fieldClass = fieldClassElement.getAsJsonObject();
- No validation of
lengthField.getAsInt()
lengthFieldis only checked for presence; negative or unreasonably large values are accepted:int length = lengthField.getAsInt();At minimum, enforce non-negative (and optionally a sane upper bound) to avoid malformed metadata causing pathological allocations:
- int length = lengthField.getAsInt(); + int length = lengthField.getAsInt(); + if (length < 0) { + throw new ParseException("Static-length array length must be non-negative, got: " + length); //$NON-NLS-1$ + }(If you have an agreed maximum length, you can also enforce it here.)
The rest of the parsing logic (element field class resolution via
TypeAliasParserand construction ofArrayDeclaration) looks good.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java (3)
29-45: Javadoc still describes dynamic-length instead of static-length.This documentation issue was already flagged in a previous review but remains unaddressed.
57-68: Error messages still reference "Dynamic-length" instead of "Static-length".The error messages at lines 59 and 67 incorrectly reference dynamic-length strings and wrong property names. This was previously flagged but not yet fixed.
77-79: Param Javadoc still references wrong parser type.This documentation issue was previously flagged but remains unaddressed.
🧹 Nitpick comments (7)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java (1)
24-26: Optional: Simplify JSON construction usingaddProperty.The current code uses
addwithJsonPrimitivewrappers, which works correctly. However,JsonObject.addPropertyis more idiomatic and eliminates the need for explicitJsonPrimitiveinstantiation.Apply this diff to simplify:
-import com.google.gson.JsonPrimitive; JsonObject fieldClass = new JsonObject(); - fieldClass.add("length", new JsonPrimitive(32)); - fieldClass.add("byte-order", new JsonPrimitive("le")); + fieldClass.addProperty("length", 32); + fieldClass.addProperty("byte-order", "le"); @@ JsonObject fieldClass = new JsonObject(); - fieldClass.add("length", new JsonPrimitive(64)); - fieldClass.add("byte-order", new JsonPrimitive("be")); - fieldClass.add("alignment", new JsonPrimitive(8)); + fieldClass.addProperty("length", 64); + fieldClass.addProperty("byte-order", "be"); + fieldClass.addProperty("alignment", 8);Also applies to: 42-43, 66-68
ctf/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/TestInvalidCtfTrace.java (1)
205-211: Consider making the label search loop more robustThe loop assumes the relevant text will always be found within the first few labels and may attempt to read beyond the “3 labels” mentioned in the comment if the message is ever missing or the dialog layout changes. A more defensive pattern (e.g., iterating up to
dialogBot.labels().size()or breaking onceireaches the last index) would make the test less brittle to UI changes, while still validating the same behavior.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java (1)
286-288: Prefer checking the parsedJsonObjectinstead of raw string contains.The string check
jsonBlocks[i].contains("id:")is fragile—it could match"id:"appearing in string values or other contexts. Since the JSON is already parsed at line 261, consider checking the parsed object instead.} else if (type.equals(JsonMetadataStrings.FRAGMENT_DATA_STREAM)) { fragment = Objects.requireNonNull(gson.fromJson(element, JsonDataStreamMetadataNode.class)); - if (!jsonBlocks[i].contains("id:")) { //$NON-NLS-1$ + JsonObject dsObj = element.getAsJsonObject(); + if (!dsObj.has("id")) { //$NON-NLS-1$ ((JsonDataStreamMetadataNode) fragment).setId(-1); }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition2.java (1)
34-52: Consider consolidating constructors or enforcing type safety.Both constructors perform identical logic, differing only in the declaration parameter type. The second constructor accepts any
Declaration, weakening type safety compared to the first which requiresStringDeclaration.If the intent is to support both
StringDeclarationandDynamicLengthStringDeclaration, consider using a common base type or interface that both implement, rather than accepting the genericDeclarationbase class.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicstring/DynamicLengthStringParser.java (1)
77-101: UnusedfTracefield inParamclass.The
Paramclass stores aCTFTracereference that is never used by theparse()method. Either this is dead code or the implementation is incomplete.Consider either removing the unused field or documenting why it's reserved for future use:
@NonNullByDefault public static final class Param implements ICommonTreeParserParameter { - private final CTFTrace fTrace; - /** * Parameter constructor - * - * @param trace the trace */ - public Param(CTFTrace trace) { - fTrace = trace; + public Param() { + // No parameters needed currently } - - /** - * Get the trace - * - * @return the trace - */ - public CTFTrace getTrace() { - return fTrace; - } }Alternatively, if the trace is needed for future enhancements, add a comment explaining the intent.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (1)
64-73: Redundant length validation and inconsistent type usage.Since
fLengthis already anint, the negative check on line 67 is only meaningful if the constructor receives a negative int. The assignment tolong rawLengthon line 66 is unnecessary indirection. Additionally, using1e6(a double) for comparison is unusual.@Override public StringDefinition2 createDefinition(@Nullable IDefinitionScope definitionScope, String fieldName, BitBuffer input) throws CTFException { - long rawLength = fLength; - if (rawLength < 0) { - throw new CTFException("Cannot have a length < 0, declared = " + rawLength); //$NON-NLS-1$ + if (fLength < 0) { + throw new CTFException("Cannot have a length < 0, declared = " + fLength); //$NON-NLS-1$ } - if (rawLength > 1e6) { - throw new CTFException("Cannot have a length > 1000000, declared = " + rawLength); //$NON-NLS-1$ + if (fLength > 1_000_000) { + throw new CTFException("Cannot have a length > 1000000, declared = " + fLength); //$NON-NLS-1$ } - int length = (int) rawLength; - byte[] bytes = new byte[length]; - for (int i = 0; i < length; i++) { + byte[] bytes = new byte[fLength]; + for (int i = 0; i < fLength; i++) { bytes[i] = (byte) input.get(Byte.SIZE, false); }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.java (1)
55-61: Role map wiring is reasonable; consider clarifying key semanticsStoring roles in
fRolesfrom bothaddField(per-field roles) andsetRole(struct’s own role) provides the necessary backing for role-based lookups. Behavior is “last write wins” if a struct and one of its fields share the same role string.If that overlap is either impossible by design or significant when it happens, it may be worth documenting the intended semantics (struct vs. field precedence) or asserting on duplicate role keys. Otherwise the current implementation is fine.
Also applies to: 202-221, 348-352, 422-430
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (36)
common/org.eclipse.tracecompass.common.core.tests/META-INF/MANIFEST.MF(1 hunks)common/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.java(23 hunks)ctf/org.eclipse.tracecompass.ctf.core.tests/META-INF/MANIFEST.MF(1 hunks)ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/META-INF/MANIFEST.MF(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/BlobDeclaration.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java(9 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDefinition.java(2 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/ScopedDefinition.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition2.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.java(5 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.java(4 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.java(4 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDefinition.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java(4 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java(4 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicarray/DynamicLengthArrayParser.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicstring/DynamicLengthStringParser.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java(2 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java(4 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java(2 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/variant/VariantParser.java(3 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/DynamicLengthStringDeclaration.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java(1 hunks)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java(5 hunks)ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventField.java(2 hunks)ctf/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/TestInvalidCtfTrace.java(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (12)
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.java
- ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventField.java
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java
- ctf/org.eclipse.tracecompass.ctf.core.tests/META-INF/MANIFEST.MF
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/DynamicLengthStringDeclaration.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicarray/DynamicLengthArrayParser.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDefinition.java
- common/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.java
🧰 Additional context used
🧬 Code graph analysis (8)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java (2)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (1)
FloatDeclarationParser(66-206)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java (4)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMetadataNode.java (1)
JsonStructureFieldMetadataNode(29-89)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/AlignmentParser.java (1)
AlignmentParser(51-117)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-257)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (7)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicarray/DynamicLengthArrayParser.java (1)
DynamicLengthArrayParser(33-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicstring/DynamicLengthStringParser.java (1)
DynamicLengthStringParser(46-102)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/enumeration/EnumParser.java (1)
EnumParser(97-266)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java (1)
StaticLengthArrayParser(33-112)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java (1)
StaticLengthStringParser(46-102)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java (1)
StructParser(95-285)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-257)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/variant/VariantParser.java (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-257)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicstring/DynamicLengthStringParser.java (3)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (1)
NonNullByDefault(66-83)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/DynamicLengthStringDeclaration.java (1)
DynamicLengthStringDeclaration(30-116)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-257)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.java (1)
JsonTraceMetadataNode(28-87)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-257)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java (2)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (2)
NonNullByDefault(66-83)TypeAliasParser(55-222)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-257)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build / build
- GitHub Check: build / build
- GitHub Check: build / build
🔇 Additional comments (17)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java (2)
45-53: Constructor fix confirmed—test correctly validates 32-bit float parsing.The constructor now correctly passes all 5 required parameters
(parent, type, value, name, fieldClass), resolving the critical compilation error flagged in previous reviews. The assertions properly verify thatFloatDeclarationParserinterpretslength: 32as 8-bit exponent and 24-bit mantissa with little-endian byte order.
70-79: Constructor fix confirmed—test correctly validates 64-bit float parsing.The constructor now correctly passes all 5 required parameters, resolving the critical issue from previous reviews. The assertions properly verify that
FloatDeclarationParserinterpretslength: 64as 11-bit exponent and 53-bit mantissa with big-endian byte order, plus the specified 8-byte alignment.ctf/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/TestInvalidCtfTrace.java (1)
89-89: Updated expected error string forstruct-duplicate-field-namelooks correctAligning the expected message with the new core duplicate-field wording (
"struct: duplicate field xxx") keeps this SWTBot test in sync with the parser’s behavior, and theassertContainsusage still gives a bit of flexibility. No further changes needed here.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java (1)
270-291: Element-based parsing after alias expansion is correctly implemented.The switch from
jsonBlocks[i]to the pre-parsed and alias-expandedelementensures that alias references are resolved before deserialization. The pattern is consistently applied across all fragment types.common/org.eclipse.tracecompass.common.core.tests/META-INF/MANIFEST.MF (1)
24-24: LGTM!The Gson import is correctly added to support the new JSON metadata handling in tests.
ctf/org.eclipse.tracecompass.ctf.core/META-INF/MANIFEST.MF (1)
5-5: LGTM!The minor version bump to 5.1.0 appropriately reflects the new CTF 2 support features being added.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (1)
155-192: Legacy parsing path correctly preserved.The existing non-JSON metadata parsing logic is properly maintained within the else block, preserving backward compatibility with traditional TSDL metadata.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/variant/VariantParser.java (1)
25-26: Good addition of IntegerDeclaration support for variant tags.The import and subsequent handling allow integer-based tags in addition to enum-based tags, which aligns with CTF 2 specification support.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java (1)
159-171: Good integration of JSON-based environment extraction.The logic correctly checks for
JsonTraceMetadataNode, extracts the environment, and propagates it to the trace. The null check on line 162 is appropriate.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java (1)
192-222: Good addition of JSON-based struct parsing paths.The new branches correctly handle
JsonStructureFieldMetadataNodeandJsonStructureFieldMemberMetadataNodewith appropriate type checks (isJsonObject(),isJsonArray()). The minimum alignment extraction and member class iteration logic is well-structured.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.java (1)
19-67: JsonObject migration for environment looks consistentSwitching
fEnvironmentandgetEnvironment()toJsonObjectmatches the Gson-based metadata model and keeps behavior unchanged apart from the type. No issues from this change alone.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.java (1)
264-269: Mapped integer creation now usessizeconsistentlyUsing
(int) sizeas the first parameter forcreateDeclarationin the mappings path aligns it with the unmapped path and the updatedIntegerDeclarationfactory signature. This fixes the previous base/size mismatch.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDefinition.java (1)
36-69: Variant tag widening and lookup integration look soundWidening
fTagDeftoSimpleDatatypeDefinitionwith a new constructor while retaining theEnumDefinitionconstructor keeps existing callers working and allows more generic tag types. The updatedlookupDefinitionmethods correctly:
- Match on the variant’s field name.
- Expose the tag and current field via their declaration roles.
- Delegate into the current field when it is a
ScopedDefinition, using the exclusion-aware overload.- Fall back to the enclosing
StructDefinition(or generic scope) while excluding this variant to avoid lookup loops.This is consistent with the new role-based lookup model.
Also applies to: 139-192
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java (4)
134-143: LGTM: IntervalNode structure is clean and appropriate.The inner class provides a clear representation of interval boundaries with associated mapping names.
378-387: LGTM: Interval tree construction is correct.The buildIntervalTree implementation properly flattens all mapping ranges into sorted IntervalNodes.
549-549: LGTM: Using Long.SIZE is more explicit than a SIZE_64 constant.This improves code clarity by directly referencing the platform's long size.
567-567: LGTM: equals/hashCode properly updated for new fields.The inclusion of
fMappingsandgetRole()in equality and hashing logic maintains consistency with the new mapping functionality.Also applies to: 594-599
...tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/BlobDeclaration.java
Show resolved
Hide resolved
...cecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java
Show resolved
Hide resolved
...cecompass/internal/ctf/core/event/metadata/tsdl/dynamicstring/DynamicLengthStringParser.java
Show resolved
Hide resolved
...tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java
Outdated
Show resolved
Hide resolved
|
@bhufmann @PatrickTasse Do you need any help for the review? |
Yes, if you could do the review that would be great. Then I can focus on some other tasks. @arfio thanks for offering. |
arfio
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This correctly reads a ctf2 example trace! I am sure a lot of people have been waiting for this addition, thank you!
Also it would be great if tests for role and lookup definitions would be added as a lot of complicated have been added there.
...ss.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java
Show resolved
Hide resolved
...tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/BlobDeclaration.java
Show resolved
Hide resolved
...cecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java
Show resolved
Hide resolved
...cecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java
Show resolved
Hide resolved
...racecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/ScopedDefinition.java
Outdated
Show resolved
Hide resolved
...cecompass/internal/ctf/core/event/metadata/tsdl/dynamicstring/DynamicLengthStringParser.java
Show resolved
Hide resolved
| public void testDynamicLengthStringParsing() throws Exception { | ||
| // Test that the parser doesn't throw an exception for dynamic length strings | ||
| // The actual parsing logic may not be fully implemented yet | ||
| CTFTrace trace = new CTFTrace(); | ||
| DeclarationScope scope = new DeclarationScope(null, "test"); | ||
|
|
||
| JsonObject fieldClass = new JsonObject(); | ||
| fieldClass.add("type", new JsonPrimitive("dynamic-length-string")); | ||
| fieldClass.add("encoding", new JsonPrimitive("utf-8")); | ||
|
|
||
| JsonStructureFieldMemberMetadataNode node = new JsonStructureFieldMemberMetadataNode(null, "dynamic-length-string", "test", "dyn_string_field", fieldClass); | ||
|
|
||
| try { | ||
| IDeclaration result = TypeAliasParser.INSTANCE.parse(node, | ||
| new TypeAliasParser.Param(trace, scope)); | ||
| // If we get here without exception, the basic parsing works | ||
| assertNotNull(result); | ||
| } catch (Exception e) { | ||
| // For now, just verify the parser recognizes the type | ||
| assertTrue("Parser should handle dynamic-length-string type", | ||
| e.getMessage() == null || !e.getMessage().contains("Invalid field class")); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the assert in the catch clause, the test should throw in certain cases? If the parser fails, the test should also fail no?
....core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java
Show resolved
Hide resolved
...core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java
Show resolved
Hide resolved
...compass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.java
Show resolved
Hide resolved
Change-Id: Ied093d7edf0e7de76e0dc637699711cf0653dc6b Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
c2cdf0c to
9dfa5a0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
Fix all issues with AI Agents 🤖
In
@common/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.java:
- Around line 105-115: The helper method assertLogMessage should be made
defensive: in assertLogMessage(String message, String expectedLevel, String
expectedPhase, String expectedName) first assert that message.split(":", 2)
produced two parts before accessing parts[0]/parts[1] with a clear failure
message, then wrap/parsing of parts[1] with a try/catch or an assertion that
JSON parsing succeeded; after obtaining the JsonObject validate each expected
JsonElement (e.g., "ph","tid","pid","name") is present and non-null before
calling getAsString()/getAsInt(), and replace bare assertTrue checks with
assertions that include descriptive messages (e.g., "tid should be > 0 but was
X") and use an assertion for expectedName only when expectedName != null.
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.java:
- Around line 169-174: The code uses an unordered HashMap (fFields) alongside a
positional array (fFieldArray) in VariantDeclaration.addField, which can make
numeric indexing inconsistent; change fFields to a LinkedHashMap to preserve
insertion order (update the fFields declaration and any initializations), keep
the addField logic that appends to fFieldArray unchanged so array order matches
map insertion order, and ensure any tests or code relying on map ordering still
function; alternatively, if numeric indexing is not supported, remove the
numeric fallback path and document that only named mappings are valid.
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java:
- Around line 255-266: The FIELD_ALIAS handling in the second-pass loop of
Metadata.java can NPE when NAME or FIELD_CLASS are missing; update the block
that checks JsonMetadataStrings.TYPE == JsonMetadataStrings.FRAGMENT_FIELD_ALIAS
to also verify obj.has(JsonMetadataStrings.NAME) and
obj.has(JsonMetadataStrings.FIELD_CLASS) before calling
getAsString()/getAsJsonObject(), and only then put into the metadata map; keep
the existing expandAliases(obj, metadata) call and the single-pass ordering
unchanged.
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java:
- Around line 73-74: Validate that elementFieldClass is a JSON object before
calling getAsJsonObject(): in StaticLengthArrayParser, check
elementFieldClass.isJsonObject() and only call
elementFieldClass.getAsJsonObject() when true; otherwise handle the non-object
case by constructing JsonStructureFieldMemberMetadataNode with the original
elementFieldClass (or return/throw a clear parse error) and then call
TypeAliasParser.INSTANCE.parse with that node and new
TypeAliasParser.Param(trace, scope) so primitives (alias strings) do not cause a
getAsJsonObject() exception.
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/DynamicLengthStringDeclaration.java:
- Around line 84-87: The loop in DynamicLengthStringDeclaration that fills the
byte[] bytes by calling input.get(Byte.SIZE, false) doesn't check BitBuffer
capacity first; before allocating/reading length bytes verify
input.canRead(Byte.SIZE * length) (or input.canRead(length) per BitBuffer API)
and if it cannot read, throw a clear CTFException indicating insufficient bits
for the requested length and include requested length and remaining capacity;
perform this check before the for-loop that uses input.get(...) to avoid
ambiguous exceptions at runtime.
♻️ Duplicate comments (31)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (4)
25-29: Class javadoc still incorrectly says "Dynamic-length".The past review comment on this javadoc was marked as addressed, but line 26 still describes this as "Dynamic-length string declaration" instead of "Static-length string declaration".
🔎 Apply this fix
/** - * Dynamic-length string declaration with encoding support + * Static-length string declaration with encoding support * * @author Matthew Khouzam */
98-101: toString() still incorrectly labels this as "dynamic_string".The past review comment on this method was marked as addressed, but line 100 still returns a string starting with "dynamic_string" instead of "static_string".
🔎 Apply this fix
@Override public String toString() { - return "dynamic_string[" + fLength + "]<" + fEncoding.name() + ">"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + return "static_string[" + fLength + "]<" + fEncoding.name() + ">"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ }
93-96: getMaximumSize() should reflect the actual enforced limit.As noted in an earlier comment,
getMaximumSize()returnsInteger.MAX_VALUEbut the validation at line 72 enforces a maximum of 1,000,000 bytes. These should be consistent.🔎 Align maximum size with validation
@Override public int getMaximumSize() { - return Integer.MAX_VALUE; + return 1_000_000; // matches validation limit at line 72 }
35-42: Constructor javadoc parameter description is incorrect.The past review comment on this constructor javadoc was marked as addressed, but lines 38-39 still describe the parameter as "the name of the length field" when it should document the
int lengthparameter as the fixed byte length of the string.🔎 Apply this fix
/** * Constructor * * @param length - * the name of the length field + * the fixed length of the string in bytes * @param encoding * the character encoding */ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition2.java (1)
24-52: Null safety issue remains unaddressed.The past review correctly identified that
fStringand the constructorvalueparameters lack null safety:
- Line 24:
fStringis not marked@NonNull- Lines 35 and 49: constructor
valueparameters are not marked@NonNull- Lines 37 and 51: no null validation before assignment
- Line 65 (
size()) and line 70 (toString()) will throw NPE iffStringis null🔎 Add null safety
+import java.util.Objects; + - private final String fString; + private final @NonNull String fString; public StringDefinition2(@NonNull StringDeclaration declaration, - IDefinitionScope definitionScope, @NonNull String fieldName, String value) { + IDefinitionScope definitionScope, @NonNull String fieldName, @NonNull String value) { super(declaration, definitionScope, fieldName); - fString = value; + fString = Objects.requireNonNull(value, "value cannot be null"); } public StringDefinition2(@NonNull Declaration declaration, - IDefinitionScope definitionScope, @NonNull String fieldName, String value) { + IDefinitionScope definitionScope, @NonNull String fieldName, @NonNull String value) { super(declaration, definitionScope, fieldName); - fString = value; + fString = Objects.requireNonNull(value, "value cannot be null"); }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java (1)
301-316: ConcurrentModificationException risk remains despite past review.The past review comment indicated this was "✅ Addressed in commits de42c12 to c2cdf0c", but the current code still has the issues:
Line 302: Iterating over
obj.keySet()while line 305 modifiesobjviaobj.add(key, ...)can causeConcurrentModificationExceptiondepending on Gson's JsonObject implementation.Lines 309-313: String aliases inside arrays are not expanded—only objects within arrays are recursed into. If CTF 2 allows
{"field-class": ["alias-name"]}patterns, they won't be resolved.🔎 Proposed fix
private static void expandAliases(JsonObject obj, Map<String, JsonObject> metadata) { - for (String key : obj.keySet()) { + for (String key : new java.util.ArrayList<>(obj.keySet())) { JsonElement value = obj.get(key); if (value.isJsonPrimitive() && value.getAsJsonPrimitive().isString() && metadata.containsKey(value.getAsString())) { obj.add(key, metadata.get(value.getAsString())); } else if (value.isJsonObject()) { expandAliases(value.getAsJsonObject(), metadata); } else if (value.isJsonArray()) { - for (JsonElement elem : value.getAsJsonArray()) { - if (elem.isJsonObject()) { - expandAliases(elem.getAsJsonObject(), metadata); + com.google.gson.JsonArray arr = value.getAsJsonArray(); + for (int i = 0; i < arr.size(); i++) { + JsonElement elem = arr.get(i); + if (elem.isJsonPrimitive() && elem.getAsJsonPrimitive().isString() && metadata.containsKey(elem.getAsString())) { + arr.set(i, metadata.get(elem.getAsString())); + } else if (elem.isJsonObject()) { + expandAliases(elem.getAsJsonObject(), metadata); } } } } }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/DynamicLengthStringDeclaration.java (4)
41-43: Change@Nullable String lengthNameto@NonNull String lengthNameand add the import.The constructor parameter is still annotated
@Nullable, butfLengthNameis used without null guards at lines 68, 71, and 108, creating a contract violation. Since the call site never passes null, the parameter should be@NonNull.Add
import org.eclipse.jdt.annotation.NonNull;and update the constructor signature.🔎 Proposed fix
Add the import:
+import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable;Update the constructor:
- public DynamicLengthStringDeclaration(@Nullable String lengthName, Charset encoding) { + public DynamicLengthStringDeclaration(@NonNull String lengthName, Charset encoding) {
64-69: AddalignRead(input)before reading from BitBuffer.The method declares byte-level alignment via
getAlignment()returningByte.SIZE, but doesn't callalignRead(input)before reading. This breaks parsing when the BitBuffer position is not byte-aligned.All comparable Declaration types (StringDeclaration, IntegerDeclaration, etc.) call
alignRead()before reading.🔎 Proposed fix
@Override public StringDefinition2 createDefinition(@Nullable IDefinitionScope definitionScope, String fieldName, BitBuffer input) throws CTFException { + alignRead(input); IDefinition lenDef = null; if (definitionScope != null) { lenDef = definitionScope.lookupDefinition(fLengthName);
80-81: Replace magic number with constant orgetMaximumSize().The hardcoded
1e6(1,000,000) limit is duplicated between this validation and the intended maximum size. This should be defined once to maintain consistency.🔎 Proposed fix using a constant
At the class level:
public class DynamicLengthStringDeclaration extends Declaration { + private static final int MAX_STRING_LENGTH = 1_000_000; private final Charset fEncoding; private final String fLengthName;In the validation:
- if (rawLength > 1e6) { - throw new CTFException("Cannot have a length > 1000000, declared = " + rawLength); //$NON-NLS-1$ + if (rawLength > MAX_STRING_LENGTH) { + throw new CTFException("Cannot have a length > " + MAX_STRING_LENGTH + ", declared = " + rawLength); //$NON-NLS-1$In getMaximumSize():
@Override public int getMaximumSize() { - return Integer.MAX_VALUE; + return MAX_STRING_LENGTH;Based on learnings, line 103 should return this constant and line 81 should use it for the error message.
111-115: ImplementisBinaryEquivalentor remove the TODO comment.The method currently returns
falsefor all comparisons, which is safe but potentially inefficient. For proper binary equivalence checking, compare whetherotheris aDynamicLengthStringDeclarationwith matchingfLengthNameandfEncoding.🔎 Proposed implementation
@Override public boolean isBinaryEquivalent(IDeclaration other) { - // TODO Auto-generated method stub - return false; + if (!(other instanceof DynamicLengthStringDeclaration)) { + return false; + } + DynamicLengthStringDeclaration otherDecl = (DynamicLengthStringDeclaration) other; + return fLengthName.equals(otherDecl.fLengthName) && fEncoding.equals(otherDecl.fEncoding); }Would you like me to open an issue to track this implementation?
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/BlobDeclaration.java (1)
86-89: Clarify rationale for removing the size limit or reintroduce bounds checking.The previous implementation had a hard-coded maximum size of 1,000,000 that protected against excessively large allocations from malformed or malicious trace data. With this change,
getMaximumSize()now returnsfLength * 8without an upper bound, and the pre-flight guard increateDefinition(line 66) was also removed.This means
new byte[fLength]will attempt to allocate whatever size is specified in the trace metadata without bounds checking, potentially causingOutOfMemoryErroron corrupted or adversarial input.Can you provide the rationale for removing this safeguard? If dynamic sizing is required for CTF 2 traces, consider reintroducing a configurable or reasonable upper bound to prevent resource exhaustion attacks.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java (1)
211-217: Verify null safety for JSON member properties.Lines 213-214 access
memberElement.getAsJsonObject().get(JsonMetadataStrings.NAME)and.get(JsonMetadataStrings.FIELD_CLASS)without null checks. If these properties are missing or have unexpected types,getAsString()orgetAsJsonObject()will throw an exception.A past review comment indicated this was addressed in commits
de42c12 to c2cdf0c, but the current code still shows direct property access without validation. If the fix was applied in a different commit range or file version, please confirm. Otherwise, add defensive checks as originally suggested.Run the following script to verify if null checks were added in recent commits:
#!/bin/bash # Check if defensive null checks exist in the commit history git log --oneline --all -S "JsonMetadataStrings.NAME" --grep="null" -- "**/StructParser.java" | head -10ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java (1)
672-697: Verify interval tree logic doesn't produce duplicate mapping names.The interval tree binary search correctly finds the rightmost node with
start <= value, then iterates backward to collect overlapping intervals. However, if a single mapping name has multiple ranges that overlap with the queried value, that name will be added tomatchesmultiple times.Based on learnings, integer field class mappings should not have overlapping ranges for the same name. Consider adding validation when building the interval tree in
buildIntervalTree()to detect and reject (or warn about) such cases, ensuring the assumption holds at construction time rather than silently producing duplicate names at lookup time.🔎 Proposed validation in buildIntervalTree
private void buildIntervalTree() { fIntervalTree.clear(); + Map<String, List<IntervalNode>> nodesByName = new HashMap<>(); for (Map.Entry<String, List<IntegerRange>> entry : fMappings.entrySet()) { String name = entry.getKey(); for (IntegerRange range : entry.getValue()) { fIntervalTree.add(new IntervalNode(range.getStart(), range.getEnd(), name)); + nodesByName.computeIfAbsent(name, k -> new ArrayList<>()).add( + new IntervalNode(range.getStart(), range.getEnd(), name)); } } Collections.sort(fIntervalTree, Comparator.comparingLong(n -> n.start)); + // Validate no overlapping intervals for the same name + for (Map.Entry<String, List<IntervalNode>> entry : nodesByName.entrySet()) { + List<IntervalNode> nodes = entry.getValue(); + Collections.sort(nodes, Comparator.comparingLong(n -> n.start)); + for (int i = 1; i < nodes.size(); i++) { + if (nodes.get(i - 1).end >= nodes.get(i).start) { + throw new IllegalStateException("Overlapping ranges for mapping: " + entry.getKey()); + } + } + } }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/variant/VariantParser.java (2)
269-271: Add defensive checks for JSON parsing to prevent unhelpful exceptions.Line 270 assumes
SELECTOR_FIELD_LOCATIONcontains a JSON object with aPATHfield that is an array, but there are no type or null checks. If the structure is malformed,getAsJsonObject()orget(JsonMetadataStrings.PATH)will throw an unhelpful exception. Additionally, line 271 accesses the last element without verifying the array is non-empty.🔎 Proposed defensive checks
if (variant instanceof JsonStructureFieldMemberMetadataNode) { JsonObject fieldClass = ((JsonStructureFieldMemberMetadataNode) variant).getFieldClass().getAsJsonObject(); if (fieldClass.has(SELECTOR_FIELD_LOCATION)) { - JsonArray location = (fieldClass.get(SELECTOR_FIELD_LOCATION).getAsJsonObject().get(JsonMetadataStrings.PATH)).getAsJsonArray(); - variantTag = location.get(location.size() - 1).getAsString(); - hasTag = true; + JsonElement selectorElement = fieldClass.get(SELECTOR_FIELD_LOCATION); + if (selectorElement != null && selectorElement.isJsonObject()) { + JsonElement pathElement = selectorElement.getAsJsonObject().get(JsonMetadataStrings.PATH); + if (pathElement != null && pathElement.isJsonArray()) { + JsonArray location = pathElement.getAsJsonArray(); + if (location.size() > 0) { + variantTag = location.get(location.size() - 1).getAsString(); + hasTag = true; + } else { + throw new ParseException("Selector field location path is empty"); + } + } else { + throw new ParseException("Invalid selector field location: missing or invalid PATH"); + } + } else { + throw new ParseException("Invalid selector field location structure"); + } }
365-374: Update error message to reflect both allowed tag types.The error message at line 373 states "Variant tag must be an enum" but the code now accepts both
EnumDeclarationandIntegerDeclarationas valid tag types. This is misleading for users encountering the error.🔎 Proposed fix
} else if (decl instanceof IntegerDeclaration) { // do nothing } else { - throw new ParseException("Variant tag must be an enum: " + variantTag);//$NON-NLS-1$ + throw new ParseException("Variant tag must be an enum or integer: " + variantTag);//$NON-NLS-1$ }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.java (2)
187-187: Typo in parameter name:defintionToExcludeshould bedefinitionToExclude.The parameter name is missing an 'i'. This affects readability and consistency across the codebase.
Suggested fix
- public Definition lookupDefinition(String lookupPath, ScopedDefinition defintionToExclude) { + public Definition lookupDefinition(String lookupPath, ScopedDefinition definitionToExclude) {Note: This rename should be applied consistently throughout the method body.
207-212: Consider reordering conditions for efficiency.The role-matching condition at line 208 could be evaluated before the exclusion check at line 207 to potentially short-circuit earlier when the role matches.
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java (1)
30-80: Test coverage is incomplete for CTF 2 floating point sizes.The tests cover 32-bit and 64-bit floating point parsing, but CTF 2 specification also requires support for 16-bit, 128-bit, and extended sizes (K > 128, multiples of 32). Consider adding tests for these additional sizes once the parser supports them.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (2)
136-144: CTF 2 specification requires additional floating point sizes.The current implementation only supports 32-bit and 64-bit floating point sizes. According to the CTF 2 specification, support is required for 16-bit, 32-bit, 64-bit, 128-bit, and arbitrary K-bit (where K > 128 and is a multiple of 32) field classes.
Suggested expansion for additional sizes
if (fieldclass.has(JsonMetadataStrings.LENGTH)) { int size = fieldclass.get(JsonMetadataStrings.LENGTH).getAsInt(); // Standard IEEE 754 sizes - if (size == 32) { + if (size == 16) { + exponent = 5; + mantissa = 11; + } else if (size == 32) { exponent = 8; mantissa = 24; } else if (size == 64) { exponent = 11; mantissa = 53; + } else if (size == 128) { + exponent = 15; + mantissa = 113; + } else if (size > 128 && size % 32 == 0) { + exponent = 15; + mantissa = size - 1 - exponent; } else { throw new ParseException("Unsupported floating point size: " + size); } }
152-154: Alignment value lacks validation in JSON parsing path.The JSON path reads alignment directly without validating that it's positive and a power of 2, unlike the legacy path which uses
AlignmentParser.INSTANCE.parse(). Invalid alignment values could cause issues downstream.Suggested fix using inline validation
if (fieldclass.has(JsonMetadataStrings.ALIGNMENT)) { - alignment = fieldclass.get(JsonMetadataStrings.ALIGNMENT).getAsInt(); + long alignmentValue = fieldclass.get(JsonMetadataStrings.ALIGNMENT).getAsLong(); + if (alignmentValue <= 0 || (alignmentValue & (alignmentValue - 1)) != 0) { + throw new ParseException("Invalid value for alignment: " + alignmentValue); + } + alignment = alignmentValue; }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (1)
144-148: Potential NullPointerException when accessing type from fieldClass.Line 146 calls
fieldClass.get(JsonMetadataStrings.TYPE).getAsString()without checking if the returnedJsonElementis null. This will throw a NullPointerException if the "type" field is missing from the JSON object.Suggested fix with null safety
if (fieldClass != null) { - if (type.isEmpty()) { - if (fieldClass.isJsonObject()) { - type = fieldClass.get(JsonMetadataStrings.TYPE).getAsString(); - } - } + if (type.isEmpty() && fieldClass.isJsonObject() && fieldClass.has(JsonMetadataStrings.TYPE)) { + JsonElement typeElement = fieldClass.get(JsonMetadataStrings.TYPE); + if (typeElement != null && typeElement.isJsonPrimitive()) { + type = typeElement.getAsString(); + } + }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java (1)
69-69: Validate array length before use.The length value is extracted without validating that it's non-negative or within reasonable bounds. Negative or excessively large values could cause runtime issues.
Suggested validation
int length = lengthField.getAsInt(); + if (length < 0) { + throw new ParseException("Static-length array length must be non-negative, got: " + length); + } CTFTrace trace = ((Param) param).getTrace();ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java (1)
137-146: Order of operations: registration before validation.The code registers the identifier at line 137 before validating that
declis non-null (line 139). Ifdeclis null, the exception will be thrown, but a null entry may have already been added to the scope's identifier registry.Consider reordering to validate before registering:
Suggested reordering
- scope.registerIdentifier(fieldName, decl); - IDeclaration current = struct.getField(fieldName); if (decl == null) { throw new ParseException("struct: Cannot add null field " + fieldName); //$NON-NLS-1$ } + scope.registerIdentifier(fieldName, decl); + IDeclaration current = struct.getField(fieldName); if (current != null && !Objects.equal(decl, current)) {ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java (4)
29-45: The Javadoc still describes dynamic-length strings instead of static-length strings.This issue was previously flagged and marked as addressed, but the documentation in the current code still incorrectly describes dynamic-length string behavior. The class name is
StaticLengthStringParser, but the Javadoc discusses "dynamic-length string field class," length fields from other locations, and the "length-field-location property"—none of which apply to static-length strings.
57-68: Error messages and null-safety issues require attention.Multiple issues in this segment:
- Line 59: Error message incorrectly states "Dynamic-length string" (should be "Static-length string")
- Line 67: Error message incorrectly references "Dynamic-length" and "length-field-location property" (should reference "Static-length" and "length property")
- Line 63:
member.getFieldClass().getAsJsonObject()lacks null-checking before callinggetAsJsonObject()—ifgetFieldClass()returns null, this will throwNullPointerExceptionAdditional null-safety concern (new)
Consider adding a null check before line 63:
JsonStructureFieldMemberMetadataNode member = (JsonStructureFieldMemberMetadataNode) node; +JsonElement fieldClassElement = member.getFieldClass(); +if (fieldClassElement == null || !fieldClassElement.isJsonObject()) { + throw new ParseException("Static-length string requires a valid field class"); +} -JsonObject fieldClass = member.getFieldClass().getAsJsonObject(); +JsonObject fieldClass = fieldClassElement.getAsJsonObject();
77-79: Param class Javadoc references the wrong parser type.The Javadoc states "Parameters for the dynamic-length string parser" but this is the
StaticLengthStringParser.
70-74: Validate length before construction.Line 70 extracts the length without validation. While
StaticLengthStringDeclarationdoes validate bounds (< 0 or > 1000000), failing late complicates error attribution. Additionally,getAsInt()will throwNumberFormatExceptionorUnsupportedOperationExceptionif the JSON element is not a valid integer—this should be caught and wrapped in aParseException.Proposed validation and error handling
-int length = lengthField.getAsInt(); +int length; +try { + length = lengthField.getAsInt(); +} catch (NumberFormatException | UnsupportedOperationException e) { + throw new ParseException("Static-length string 'length' must be a valid integer", e); +} +if (length < 0 || length > 1_000_000) { + throw new ParseException("Static-length string 'length' must be between 0 and 1,000,000, got: " + length); +} Charset encoding = encodingField != null ? JsonMetadataStrings.ENCODINGS.getOrDefault(encodingField.getAsString(), StandardCharsets.UTF_8) : StandardCharsets.UTF_8;Based on past review comment by arfio at line 70.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (4)
179-192: Javadoc for DYNAMIC_LENGTH_STRING is still incorrect.Line 185-186: The Javadoc states "Type string for a null terminated string field class" but this constant represents
"dynamic-length-string", not a null-terminated string. This appears to be a copy-paste error from theNULL_TERMINATED_STRINGconstant above.The issue was previously flagged and marked as addressed by arfio, but the code still contains the incorrect documentation.
203-206: PATH constant has misleading Javadoc.The Javadoc describes this as "Type string for a structure field class" but the constant represents
"path", which is a field reference key, not a type string.
213-222: UTF-32 charset initialization will fail on JDK versions prior to 22.Lines 220-222 use
Charset.forName("UTF-32BE")andCharset.forName("UTF-32LE")in a static initializer. These charsets were added toStandardCharsetsonly in JDK 22, so on earlier JDK versions,Charset.forName()will throwUnsupportedCharsetExceptionat class-loading time, causing the entire class to fail to load.If this project must support JDK versions prior to 22, the
ENCODINGSmap should be initialized using a static block withCharset.isSupported()checks or exception handling to gracefully exclude unsupported charsets.If the project targets JDK 22+, replace with
StandardCharsets.UTF_32BEandStandardCharsets.UTF_32LE.#!/bin/bash # Check the project's minimum JDK version requirement echo "Checking Maven compiler configuration..." fd -e xml pom.xml --exec grep -A 5 "maven.compiler" {} echo -e "\nChecking MANIFEST.MF for Bundle-RequiredExecutionEnvironment..." fd -e MF MANIFEST.MF --exec grep "Bundle-RequiredExecutionEnvironment" {} echo -e "\nChecking for any .java-version or similar files..." fd -t f "^\\.java-version$|^java\\.version$"
249-255: Missing Javadoc and //$NON-NLS-1$ markers on several constants.Lines 249, 251, 253, and 255 declare public constants but are missing:
- Javadoc comments (inconsistent with the rest of the file)
//$NON-NLS-1$externalization markers on lines 253 and 255This reduces maintainability and violates the consistent documentation style established throughout the file.
🧹 Nitpick comments (7)
ctf/org.eclipse.tracecompass.ctf.core.tests/META-INF/MANIFEST.MF (1)
27-27: LGTM! Gson import correctly added for CTF 2 trace parsing tests.The addition of
com.google.gsonto Import-Package is necessary for the new JSON-based CTF 2 metadata parsing functionality described in the AI summary. The import is properly formatted and maintains alphabetical order.Consider specifying a version range for better dependency management, e.g.,
com.google.gson;version="[2.8.0,3.0.0)", though this is optional given the existing inconsistent versioning pattern in this manifest.Optional: Verify Gson usage in new test classes
#!/bin/bash # Verify that Gson is actually imported and used in test classes rg -n --type java -C3 'import.*gson' ctf/org.eclipse.tracecompass.ctf.core.tests/ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (1)
67-86: Validation is appropriate defensive programming.Responding to the earlier question on line 73: even if length is validated during metadata parsing, this runtime validation is good defensive programming to prevent corrupted data from causing issues.
Optional: Consider bulk byte reading for performance.
The byte-by-byte loop (lines 77-79) could be replaced with a single bulk read for better performance:
🔎 Potential optimization
- byte[] bytes = new byte[length]; - for (int i = 0; i < length; i++) { - bytes[i] = (byte) input.get(Byte.SIZE, false); - } + byte[] bytes = new byte[length]; + input.get(bytes, 0, length);Note: Only apply this if
BitBuffer.get(byte[], int, int)method exists and is semantically equivalent to reading length bytes.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java (1)
67-156: Clarify the purpose of deprecated constants.Multiple public constants (
UINT_32L_DECL,INT_32L_DECL,UINT_64L_DECL, etc.) have been marked as@Deprecatedwith a note to "use the standard constructor instead."Based on learnings, there's a question about whether these declarations are still used or kept solely for API compatibility. If they're retained for backward compatibility, this should be documented explicitly in the deprecation notice (e.g., "Deprecated for removal in version X.Y"). If they're no longer needed, consider removing them in a separate cleanup task.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.java (1)
127-152: Review variant resolution logic for correctness and clarity.The two-branch resolution logic is complex. When the tag is an
IntegerDefinition, the code attempts to resolve the variant field either by mappings or by using the tag value as a direct index intofFieldArray.A few observations:
Index-based lookup risk: Lines 136-139 use
tagValueas an array index, assuming variant fields are numbered sequentially from 0. This works only if the variant's field order matches the integer range [0, N-1]. Verify that this assumption holds for all CTF 2 traces or add documentation explaining when numeric indexing is valid.Error handling: The error messages at lines 137, 144, 148-149, and 154 could be more descriptive. Consider including the tag name, tag value (if applicable), and available field names to aid debugging.
Mapping resolution: Line 132 retrieves mappings from the
IntegerDefinition, but if mappings is non-null and doesn't match any field name, the code falls through to line 153 and throws "Unknown enum selector". This error message is confusing for integer-based tags.💡 Suggestions for improvement
- Add documentation clarifying when numeric indexing is appropriate.
- Improve error messages to distinguish between integer-based and enum-based resolution failures.
- Consider adding validation during variant construction to ensure fields match expected integer ranges if numeric indexing is intended.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java (1)
192-221: Consider using pattern matching for cleaner type checks.Based on learnings, there's a suggestion to use Java pattern matching for the
instanceofchecks at lines 192 and 201. This would make the code more concise and eliminate redundant casts.🔎 Example using pattern matching
- } else if (struct instanceof JsonStructureFieldMetadataNode) { - JsonStructureFieldMetadataNode structNode = (JsonStructureFieldMetadataNode) struct; + } else if (struct instanceof JsonStructureFieldMetadataNode structNode) { if (structNode.getMinimumAlignment() != 0) { structAlign = AlignmentParser.INSTANCE.parse(struct, null); } if (structNode.getMemberClasses() != null) { hasBody = true; structBody = struct; } - } else if (struct instanceof JsonStructureFieldMemberMetadataNode) { - JsonStructureFieldMemberMetadataNode memberNode = (JsonStructureFieldMemberMetadataNode) struct; + } else if (struct instanceof JsonStructureFieldMemberMetadataNode memberNode) { // ... rest of the codeNote: This requires Java 16+ with pattern matching for
instanceof.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (1)
213-215: Good addition for type redefinition check, but missing space.The redefinition check correctly prevents duplicate type definitions. However, there's a minor style issue with missing whitespace.
Note: This check is only applied in the non-JSON path. Verify if the JSON path (lines 108-192) should also have a similar redefinition check before
scope.registerType()at line 218.Suggested fix for spacing
- if (scope.lookupType(aliasString)!= null) { + if (scope.lookupType(aliasString) != null) {ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java (1)
41-44: Consider usingaddPropertyfor cleaner JSON construction.Using
addPropertyis simpler and more readable thanaddwithnew JsonPrimitive(...).Example simplification
JsonObject fieldClass = new JsonObject(); - fieldClass.add("length", new JsonPrimitive(32)); - fieldClass.add("byte-order", new JsonPrimitive("le")); + fieldClass.addProperty("length", 32); + fieldClass.addProperty("byte-order", "le");
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (36)
common/org.eclipse.tracecompass.common.core.tests/META-INF/MANIFEST.MFcommon/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.javactf/org.eclipse.tracecompass.ctf.core.tests/META-INF/MANIFEST.MFctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.javactf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.javactf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.javactf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.javactf/org.eclipse.tracecompass.ctf.core/META-INF/MANIFEST.MFctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/BlobDeclaration.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDefinition.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/ScopedDefinition.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition2.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDefinition.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicarray/DynamicLengthArrayParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicstring/DynamicLengthStringParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/variant/VariantParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/DynamicLengthStringDeclaration.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.javactf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventField.javactf/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/TestInvalidCtfTrace.java
🚧 Files skipped from review as they are similar to previous changes (15)
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java
- ctf/org.eclipse.tracecompass.ctf.core/META-INF/MANIFEST.MF
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicarray/DynamicLengthArrayParser.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicstring/DynamicLengthStringParser.java
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDefinition.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/ScopedDefinition.java
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.java
- ctf/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/TestInvalidCtfTrace.java
- ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventField.java
- common/org.eclipse.tracecompass.common.core.tests/META-INF/MANIFEST.MF
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.java
🧰 Additional context used
🧬 Code graph analysis (4)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java (3)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (1)
StaticLengthStringDeclaration(30-111)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-257)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java (3)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/CTFTrace.java (1)
CTFTrace(81-1043)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (1)
FloatDeclarationParser(66-206)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java (3)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (2)
NonNullByDefault(66-83)TypeAliasParser(55-222)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/ArrayDeclaration.java (1)
ArrayDeclaration(43-194)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-257)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/variant/VariantParser.java (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-257)
🔇 Additional comments (18)
common/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.java (2)
1-1: Clarify whether this file belongs in this PR.A previous review comment questioned whether this commit should be in this patch. Given that the PR objectives focus on implementing LTTng 2.14.3 CTF 2 trace support, this logging utility test file appears unrelated to CTF parsing functionality. Please confirm whether these logging test changes are intentional or should be moved to a separate PR.
129-131: Good refactoring to JSON-based assertions.The refactoring from exact string matching to JSON field validation improves test maintainability. By parsing the JSON payload and asserting on semantic fields (level, phase, name) rather than exact formatting, the tests are more resilient to non-breaking formatting changes while still validating the correct behavior.
Also applies to: 149-153, 195-199, 241-247
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (1)
103-110: LGTM - isBinaryEquivalent is properly implemented.The method correctly checks type compatibility, compares the defining fields (length and encoding), and uses null-safe comparison for the encoding field.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition2.java (1)
54-71: Methods are correctly implemented given non-null fString.The
getValue(),size(), andtoString()methods are properly implemented. They will function correctly once the null safety issue in the constructors (flagged above) is addressed.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java (2)
38-38: LGTM!The new imports are necessary for the metadata map and JSON element-based parsing.
Also applies to: 40-40, 78-80
270-270: LGTM!Correctly changed to parse from the already-parsed
elementinstead of re-parsingjsonBlocks[i]. This eliminates redundant parsing and ensures alias expansion is applied.Also applies to: 277-277, 279-279, 281-281, 283-283, 285-285, 290-290
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/DynamicLengthStringDeclaration.java (2)
46-62: LGTM!The getter methods correctly expose the encoding and length field name.
96-99: LGTM!The byte-level alignment is correct for string types.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.java (1)
254-266: LGTM on the recursive role lookup helper.The
lookupRoleRecursivemethod correctly traverses nestedStructDefinitionandVariantDefinitiontypes to find definitions by role. The recursion is bounded by the structure depth.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (1)
155-192: LGTM on the legacy parsing path refactoring.The legacy TSDL parsing path is correctly preserved in the else branch, maintaining backward compatibility while adding JSON support.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (1)
173-186: LGTM on new type routing.The new routing for dynamic/static length strings and arrays, structures, and floating point types follows the established patterns and provides appropriate parameters to each parser.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDefinition.java (2)
45-69: LGTM on the new constructor.The new constructor accepting
SimpleDatatypeDefinitionfor the tag definition provides more flexibility while maintaining consistency with the existing constructor pattern.
166-192: LGTM on the lookup with exclusion overload.The new
lookupDefinition(String, ScopedDefinition)overload correctly handles exclusion to prevent circular lookups. Passingthisat line 189 when delegating toStructDefinitionis appropriate to break potential cycles.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java (1)
125-128: Duplicate field check added for CTF1 path.Good addition for early detection of duplicate fields in the CTF1 parsing path. Note that this duplicates the check at line 143, which will also catch duplicates for both paths. The redundancy is harmless but could be consolidated.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java (1)
79-115: LGTM on the Param class and overall structure.The
Paramclass follows the established pattern used by other parsers in the codebase, with appropriate@NonNullByDefaultannotation and accessor methods.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (2)
50-58: LGTM—new constants are well-documented.The
FIELD_CLASSandNAMEconstants are properly documented and formatted consistently with the rest of the file.
160-167: LGTM—floating point constants are correctly defined.The
FIXED_LENGTH_FLOATING_POINTandVARIABLE_LENGTH_FLOATING_POINTconstants follow the established pattern and are properly documented.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.java (1)
19-19: Library migration to Gson is complete and correct.The migration from
org.json.JSONObjecttocom.google.gson.JsonObjectis properly implemented. All consumers handle the JsonObject API correctly:
JsonTraceMetadataNodeTest.javademonstrates correct usage with.getAsString()callsIOStructGen.javaproperly converts the JsonObject toMap<String, String>using Gson'sentrySet()with appropriate type checking- Gson is declared in the bundle's
MANIFEST.MFunderImport-Package
| private static void assertLogMessage(String message, String expectedLevel, String expectedPhase, String expectedName) { | ||
| String[] parts = message.split(":", 2); | ||
| assertEquals(expectedLevel, parts[0]); | ||
| JsonObject json = JsonParser.parseString(parts[1].trim()).getAsJsonObject(); | ||
| assertEquals(expectedPhase, json.get("ph").getAsString()); | ||
| assertTrue(json.get("tid").getAsInt() > 0); | ||
| assertTrue(json.get("pid").getAsInt() > 0); | ||
| if (expectedName != null) { | ||
| assertEquals(expectedName, json.get("name").getAsString()); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add defensive checks for clearer test failure diagnostics.
The helper method still lacks the defensive checks that were suggested in a previous review (marked as "Addressed" but not present in current code). Without bounds checking and null validation, malformed log messages will cause unclear exceptions (NPE, ArrayIndexOutOfBoundsException) instead of descriptive assertion failures.
Add the following defensive improvements:
- Validate that
splitproduces 2 parts before array access - Check for null before calling
.getAsString()or.getAsInt() - Use descriptive assertion messages for
assertTruechecks - Add error handling or assertions around JSON parsing
🔎 Proposed defensive improvements
private static void assertLogMessage(String message, String expectedLevel, String expectedPhase, String expectedName) {
String[] parts = message.split(":", 2);
+ assertEquals("Message should have level and JSON parts", 2, parts.length);
assertEquals(expectedLevel, parts[0]);
+
JsonObject json = JsonParser.parseString(parts[1].trim()).getAsJsonObject();
+ assertNotNull("JSON should have 'ph' field", json.get("ph"));
assertEquals(expectedPhase, json.get("ph").getAsString());
- assertTrue(json.get("tid").getAsInt() > 0);
- assertTrue(json.get("pid").getAsInt() > 0);
+
+ assertNotNull("JSON should have 'tid' field", json.get("tid"));
+ assertTrue("tid should be positive", json.get("tid").getAsInt() > 0);
+
+ assertNotNull("JSON should have 'pid' field", json.get("pid"));
+ assertTrue("pid should be positive", json.get("pid").getAsInt() > 0);
+
if (expectedName != null) {
+ assertNotNull("JSON should have 'name' field when expectedName is provided", json.get("name"));
assertEquals(expectedName, json.get("name").getAsString());
}
}🤖 Prompt for AI Agents
In
@common/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.java
around lines 105-115, The helper method assertLogMessage should be made
defensive: in assertLogMessage(String message, String expectedLevel, String
expectedPhase, String expectedName) first assert that message.split(":", 2)
produced two parts before accessing parts[0]/parts[1] with a clear failure
message, then wrap/parsing of parts[1] with a try/catch or an assertion that
JSON parsing succeeded; after obtaining the JsonObject validate each expected
JsonElement (e.g., "ph","tid","pid","name") is present and non-null before
calling getAsString()/getAsInt(), and replace bare assertTrue checks with
assertions that include descriptive messages (e.g., "tid should be > 0 but was
X") and use an assertion for expectedName only when expectedName != null.
| Map<String, JsonObject> metadata = new HashMap<>(); | ||
|
|
||
| // Second pass: expand string references and parse | ||
| for (int i = 1; i < jsonBlocks.length; i++) { | ||
| JsonElement element = JsonParser.parseString(jsonBlocks[i]); | ||
| if (element.isJsonObject()) { | ||
| JsonObject obj = element.getAsJsonObject(); | ||
| expandAliases(obj, metadata); | ||
| if (obj.has(JsonMetadataStrings.TYPE) && obj.get(JsonMetadataStrings.TYPE).getAsString().equals(JsonMetadataStrings.FRAGMENT_FIELD_ALIAS)) { | ||
| metadata.put(obj.get(JsonMetadataStrings.NAME).getAsString(), obj.get(JsonMetadataStrings.FIELD_CLASS).getAsJsonObject()); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for CTF 2 specification or documentation comments about alias ordering
rg -i -C3 'forward.{0,20}reference|alias.{0,20}order|field.{0,10}alias' --type javaRepository: eclipse-tracecompass/org.eclipse.tracecompass
Length of output: 24734
🏁 Script executed:
#!/bin/bash
# Search for null checks around getAsString and getAsJsonObject calls in the same file
rg -B3 -A3 'getAsString|getAsJsonObject' ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java | head -100Repository: eclipse-tracecompass/org.eclipse.tracecompass
Length of output: 1470
🏁 Script executed:
#!/bin/bash
# Look for validation methods or null checks related to JSON metadata properties
rg -i 'has\(.*NAME|has\(.*FIELD_CLASS' --type java | head -20Repository: eclipse-tracecompass/org.eclipse.tracecompass
Length of output: 254
🏁 Script executed:
#!/bin/bash
# Check if there are null checks or validation for metadata entries in the file
fd 'Metadata.java' | xargs cat -n | grep -A5 -B5 'NAME\|FIELD_CLASS' | head -60Repository: eclipse-tracecompass/org.eclipse.tracecompass
Length of output: 2903
Add null checks for required FIELD_ALIAS properties.
Lines 264-265 access NAME and FIELD_CLASS properties without null checks. If a malformed FIELD_ALIAS fragment is missing these properties, getAsString() or getAsJsonObject() will throw. Add defensive checks:
if (obj.has(JsonMetadataStrings.TYPE) && obj.get(JsonMetadataStrings.TYPE).getAsString().equals(JsonMetadataStrings.FRAGMENT_FIELD_ALIAS)) {
if (obj.has(JsonMetadataStrings.NAME) && obj.has(JsonMetadataStrings.FIELD_CLASS)) {
metadata.put(obj.get(JsonMetadataStrings.NAME).getAsString(), obj.get(JsonMetadataStrings.FIELD_CLASS).getAsJsonObject());
}
}Note: The single-pass expansion at line 262 is intentional—the CTF 2 specification requires aliases to reference only "previously occurring" aliases (no forward references), as confirmed by error handling in TypeAliasParser.java.
🤖 Prompt for AI Agents
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/Metadata.java
around lines 255-266, The FIELD_ALIAS handling in the second-pass loop of
Metadata.java can NPE when NAME or FIELD_CLASS are missing; update the block
that checks JsonMetadataStrings.TYPE == JsonMetadataStrings.FRAGMENT_FIELD_ALIAS
to also verify obj.has(JsonMetadataStrings.NAME) and
obj.has(JsonMetadataStrings.FIELD_CLASS) before calling
getAsString()/getAsJsonObject(), and only then put into the metadata map; keep
the existing expandAliases(obj, metadata) call and the single-pass ordering
unchanged.
| JsonStructureFieldMemberMetadataNode elementNode = new JsonStructureFieldMemberMetadataNode(node, "", "", "", elementFieldClass.getAsJsonObject()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | ||
| IDeclaration elementDeclaration = TypeAliasParser.INSTANCE.parse(elementNode, new TypeAliasParser.Param(trace, scope)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Validate element-field-class is a JSON object before conversion.
Line 73 calls elementFieldClass.getAsJsonObject() without verifying the element is actually a JSON object. If the element-field-class is a primitive (e.g., an alias string reference), this will throw an exception.
Suggested fix
- JsonStructureFieldMemberMetadataNode elementNode = new JsonStructureFieldMemberMetadataNode(node, "", "", "", elementFieldClass.getAsJsonObject()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ if (!elementFieldClass.isJsonObject()) {
+ throw new ParseException("Static-length array element-field-class must be a JSON object");
+ }
+ JsonStructureFieldMemberMetadataNode elementNode = new JsonStructureFieldMemberMetadataNode(node, "", "", "", elementFieldClass.getAsJsonObject()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$🤖 Prompt for AI Agents
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java
around lines 73-74, Validate that elementFieldClass is a JSON object before
calling getAsJsonObject(): in StaticLengthArrayParser, check
elementFieldClass.isJsonObject() and only call
elementFieldClass.getAsJsonObject() when true; otherwise handle the non-object
case by constructing JsonStructureFieldMemberMetadataNode with the original
elementFieldClass (or return/throw a clear parse error) and then call
TypeAliasParser.INSTANCE.parse with that node and new
TypeAliasParser.Param(trace, scope) so primitives (alias strings) do not cause a
getAsJsonObject() exception.
| byte[] bytes = new byte[length]; | ||
| for (int i = 0; i < length; i++) { | ||
| bytes[i] = (byte) input.get(Byte.SIZE, false); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check BitBuffer capacity before reading bytes.
The code reads length bytes without verifying that the BitBuffer has sufficient remaining data. If the buffer is exhausted, input.get() will throw a CTFException with a less informative message.
🔎 Proposed fix
int length = (int)rawLength;
+ int requiredBits = length * Byte.SIZE;
+ if (!input.canRead(requiredBits)) {
+ throw new CTFException("Insufficient buffer capacity. Required: " + length + " bytes, available: " + ((input.capacity() - input.position()) / Byte.SIZE) + " bytes");
+ }
byte[] bytes = new byte[length];
for (int i = 0; i < length; i++) {Note: The BitBuffer snippet from relevant_code_snippets confirms the canRead(int length) method exists and checks (fPosition + length) <= fBitCapacity.
🤖 Prompt for AI Agents
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/DynamicLengthStringDeclaration.java
around lines 84-87, The loop in DynamicLengthStringDeclaration that fills the
byte[] bytes by calling input.get(Byte.SIZE, false) doesn't check BitBuffer
capacity first; before allocating/reading length bytes verify
input.canRead(Byte.SIZE * length) (or input.canRead(length) per BitBuffer API)
and if it cannot read, throw a clear CTFException indicating insufficient bits
for the requested length and include requested length and remaining capacity;
perform this check before the for-loop that uses input.get(...) to avoid
ambiguous exceptions at runtime.
9dfa5a0 to
e622814
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Fix all issues with AI Agents 🤖
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java:
- Around line 213-215: The JSON path is missing the redefinition guard: before
calling scope.registerType(...) ensure you check if
scope.lookupType(aliasString) != null and throw the same ParseException("Type
has already been defined: " + aliasString) to avoid overwriting aliases; move or
add this check so it runs for both the legacy and JSON branches (i.e., after the
if/else that builds aliasString but before scope.registerType), and also correct
the minor style by adding a space before the != in the existing lookupType
check.
♻️ Duplicate comments (9)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (4)
184-187: Incorrect Javadoc for DYNAMIC_LENGTH_STRING.This was already flagged in a previous review. The Javadoc says "null terminated string" but should say "dynamic length string".
203-206: Incorrect Javadoc for PATH constant.This was already flagged in a previous review. The Javadoc says "structure field class" but should describe a path reference.
217-222: UTF-32 charset JDK compatibility concern.This was already flagged in a previous review.
Charset.forName("UTF-32BE")andCharset.forName("UTF-32LE")may throwUnsupportedCharsetExceptionon JDKs prior to version 22.
249-255: Missing Javadoc and NLS markers for final constants.These issues were already flagged in previous reviews:
MEMBER_CLASSESandMINIMUM_ALIGNMENTare missing Javadoc commentsALIGNMENTandBYTE_ORDERare missing both Javadoc comments and//$NON-NLS-1$markersctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (1)
144-148: Potential NullPointerException when accessing type from fieldClass.The call to
fieldClass.get(JsonMetadataStrings.TYPE).getAsString()on line 146 can throw NPE if theTYPEkey is absent. As previously discussed, the null check should be added and the conditions merged.🔎 Proposed fix
- if (type.isEmpty()) { - if (fieldClass.isJsonObject()) { - type = fieldClass.get(JsonMetadataStrings.TYPE).getAsString(); - } - } + if (type.isEmpty() && fieldClass.isJsonObject()) { + JsonElement typeElement = fieldClass.get(JsonMetadataStrings.TYPE); + if (typeElement != null && typeElement.isJsonPrimitive()) { + type = typeElement.getAsString(); + } + }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (2)
133-145: JSON parsing path is overly restrictive for CTF 2 specification compliance.As previously noted, the code only supports 32-bit and 64-bit floating point sizes. CTF 2 specification requires support for 16-bit, 32-bit, 64-bit, 128-bit, and arbitrary K-bit (where K > 128 and is a multiple of 32) field classes.
152-154: Alignment value is not validated in JSON parsing path.As previously noted, the JSON path reads alignment directly without validation, while the legacy path uses
AlignmentParser.INSTANCE.parse()which validates that alignment must be positive and a power of 2. Per the earlier discussion, theAlignmentParsershould be used here for consistency.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java (1)
137-146: Critical: Null checks must occur beforescope.registerIdentifiercall.The current code calls
scope.registerIdentifier(fieldName, decl)at line 137 before validating thatdeclis non-null (checked at lines 139-141). Ifdeclis null, it will be registered in the scope before theParseExceptionis thrown, potentially corrupting the scope state.Additionally, in the non-CTF1 path,
fieldNamecan benullif bothgetName()andgetRole()returnnull(lines 131-134). This would register anullkey in the scope's identifier map.The null validations should occur before any registration or field operations.
🔎 Proposed fix to reorder null checks before registration
+ // Validate fieldName and decl before any operations + if (decl == null) { + throw new ParseException("struct: Cannot add null field " + fieldName); //$NON-NLS-1$ + } + if (fieldName == null) { + // Skip processing for anonymous/unnamed fields + return struct; + } + scope.registerIdentifier(fieldName, decl); IDeclaration current = struct.getField(fieldName); - if (decl == null) { - throw new ParseException("struct: Cannot add null field " + fieldName); //$NON-NLS-1$ - } if (current != null && !Objects.equal(decl, current)) { throw new ParseException("struct: duplicate field " //$NON-NLS-1$ + fieldName); } - if (fieldName != null) { - struct.addField(fieldName, decl); - } + struct.addField(fieldName, decl);Note: Based on the past review comments, there's clarification needed on whether
nullfieldName should be silently skipped (as suggested by returning early) or should throw an exception. The proposed fix assumes skipping is the intended behavior. IfnullfieldName should be an error, replace the early return with aParseException.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java (1)
672-697: The duplicate name issue from the previous review remains unresolved.As noted in the previous review, when a single mapping name has multiple overlapping ranges, that name will be added to
matchesmultiple times, resulting in duplicate names in the output string.Example:
- Mapping:
"ERROR": [0-10], [5-15]- Query:
value = 7- Result:
["ERROR", "ERROR"]→"ERROR ERROR"The previous review suggested using
LinkedHashSet<String>instead ofList<String>to preserve insertion order while deduplicating names. Based on the discussion, consider adding validation when building the interval tree to confirm that mappings don't have overlapping ranges for the same name, or implement the deduplication fix.🔎 Proposed fix using LinkedHashSet
- List<String> matches = new ArrayList<>(); + Set<String> matches = new LinkedHashSet<>(); // Binary search for rightmost node with start <= value int left = 0, right = fIntervalTree.size() - 1; int lastValid = -1; while (left <= right) { int mid = (left + right) / 2; if (fIntervalTree.get(mid).start <= value) { lastValid = mid; left = mid + 1; } else { right = mid - 1; } } // Check all nodes from lastValid backwards for overlaps for (int i = lastValid; i >= 0; i--) { IntervalNode node = fIntervalTree.get(i); if (node.end >= value) { matches.add(node.name); } } return matches.isEmpty() ? "" : Objects.requireNonNull(String.join(" ", matches)); //$NON-NLS-1$ //$NON-NLS-2$
🧹 Nitpick comments (6)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (2)
160-168: Minor formatting inconsistency.There's no blank line between the
FIXED_LENGTH_FLOATING_POINTconstant and the Javadoc forVARIABLE_LENGTH_FLOATING_POINT, which is inconsistent with the rest of the file.Suggested fix
public static final String FIXED_LENGTH_FLOATING_POINT = "fixed-length-floating-point-number"; //$NON-NLS-1$ + /** * Type string for a variable length floating point field class */
189-193: Minor formatting: missing blank line.There's no blank line between
LENGTH_FIELD_LOCATIONand the next constant's Javadoc.Suggested fix
public static final String LENGTH_FIELD_LOCATION = "length-field-location"; //$NON-NLS-1$ + /** * Type string for a fixed length unsigned enumeration field class */ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java (1)
125-128: Optional: Redundant duplicate check for CTF1 path.This duplicate check at lines 125-128 ensures that for the CTF1 path,
struct.getField(fieldName)will returnnullat line 138. This makes the subsequent check at line 143 redundant for CTF1, as it will never throw.While this doesn't cause incorrect behavior, consider whether the early check here is necessary, or if the unified check at line 143 could handle both CTF1 and CTF2 cases. The current structure is safe but results in two checks for CTF1.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java (1)
171-180: Consider adding invariant validation to IntervalNode.The
IntervalNodeconstructor acceptsstart,end, andnamebut doesn't validate thatstart <= end. While this may be enforced by the calling code inbuildIntervalTree(), adding an assertion or precondition check would make the invariant explicit and catch bugs earlier.🔎 Proposed validation
IntervalNode(long start, long end, String name) { + if (start > end) { + throw new IllegalArgumentException("start must be <= end"); + } this.start = start; this.end = end; this.name = name; }ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java (2)
37-74: Expand test coverage to validate mapping lookup behavior.The test successfully verifies that the parser creates an
IntegerDeclarationwith the correct structure, but it doesn't test the actual mapping lookup functionality. Consider adding assertions that callgetMappingForValue()(if accessible) to verify:
- Value 0 maps to "ZERO"
- Value 1 maps to "ONE"
- Value 2 returns empty string (no mapping)
This would provide more comprehensive integration testing of the interval tree lookup logic.
🔎 Example test expansion
// After line 73, add: // Test mapping lookups (if getMappingForValue is accessible) assertEquals("ZERO", result.getMappingForValue(0)); assertEquals("ONE", result.getMappingForValue(1)); assertEquals("", result.getMappingForValue(2)); assertEquals("", result.getMappingForValue(-1));Note: This assumes
getMappingForValueis accessible from the test. If it's package-private, the test may need to be in the same package or use reflection.
40-61: Consider adding test cases for edge cases and the duplicate name issue.The current test uses simple non-overlapping single-value ranges. To improve test coverage and catch potential issues like the duplicate name bug, consider adding additional test methods for:
- Overlapping ranges for the same name (e.g.,
"ERROR": [[0, 10], [5, 15]]with value 7) - this would catch the duplicate name issue identified in the previous review- Multiple mappings with overlapping ranges (e.g.,
"LOW": [0, 5],"MEDIUM": [3, 8]with value 4)- Gaps in mappings (values that don't map to any name)
- Signed integers with negative ranges
These tests would help ensure the interval tree implementation handles all scenarios correctly.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
common/org.eclipse.tracecompass.common.core.tests/META-INF/MANIFEST.MFcommon/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.javactf/org.eclipse.tracecompass.ctf.core.tests/META-INF/MANIFEST.MFctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.javactf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.javactf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.javactf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.javactf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventField.java
🚧 Files skipped from review as they are similar to previous changes (10)
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.java
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java
- common/org.eclipse.tracecompass.common.core.tests/META-INF/MANIFEST.MF
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.java
- ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventField.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java
- ctf/org.eclipse.tracecompass.ctf.core.tests/META-INF/MANIFEST.MF
- common/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.java
🧰 Additional context used
🧬 Code graph analysis (1)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.java (1)
IntegerDeclarationParser(81-271)
🔇 Additional comments (12)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (5)
16-19: LGTM!The imports are appropriate for supporting the
ENCODINGSmap with charset definitions.
50-60: LGTM!Constants are properly documented and follow the file's conventions.
179-183: LGTM!The
LENGTHconstant is properly documented and follows conventions.
208-216: LGTM!The
STRUCTUREandSTRUCTconstants are properly documented.
224-247: LGTM!The
ENCODING,STATIC_LENGTH_STRING,STATIC_LENGTH_ARRAY,DYNAMIC_LENGTH_ARRAY, andELEMENT_FIELD_CLASSconstants are properly documented and follow conventions.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (1)
173-186: LGTM!The new type routing to dedicated parsers is well-structured and follows the existing pattern. Each parser receives the appropriate parameter object.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (1)
155-192: LGTM!The legacy parsing path is correctly preserved in the else block with unchanged logic and error handling.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java (2)
29-29: LGTM: Appropriate import for null-safe equality checking.The Guava
Objects.equal()import is correctly used at line 143 for comparing declarations safely.
97-98: LGTM: Clear branching for CTF 1.x vs CTF 2.x metadata formats.The
instanceofcheck provides a clean separation between ANTLR-based (CTF1) and JSON-based (CTF2) parsing paths.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java (3)
43-44: Deprecated constants documented for API compatibility.The comment on lines 43-44 clarifies that these basic declarations are retained for API compatibility reasons, which addresses the previous review concern. This is an appropriate approach for maintaining backward compatibility while guiding users toward the standard constructor.
Also applies to: 67-156
182-183: LGTM: Interval tree construction is correct.The implementation correctly builds the interval tree:
- Uses
TreeMapfor consistent mapping order- Clears and rebuilds the tree when mappings change
- Creates nodes for all ranges across all mapping names
- Sorts by start position for efficient binary search
The centralized rebuild approach in
setMappings()ensures the interval tree stays synchronized with the mappings.Also applies to: 409-424
604-604: LGTM: equals/hashCode correctly updated to include mappings and role.The changes properly maintain the equals/hashCode contract by including
fMappingsandgetRole()in both methods. This ensures thatIntegerDeclarationinstances with different mappings or roles are correctly distinguished when used in hash-based collections.Also applies to: 631-636
...tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java
Show resolved
Hide resolved
...core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java
Show resolved
Hide resolved
e622814 to
2aeb3d6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java (2)
115-116: Add@deprecatedJavadoc tag with deprecation reason.The
@Deprecatedannotation should be accompanied by a@deprecatedJavadoc tag explaining why this constant is deprecated and what to use instead.🔎 Suggested improvement
/** - * Unsigned 5 bit int, used for event headers + * Unsigned 27 bit int, used for event headers + * @deprecated This declaration is no longer needed. Use a custom declaration instead. */ @Deprecated public static final IntegerDeclaration UINT_27L_DECL = new IntegerDeclaration(27, false, 10, ByteOrder.LITTLE_ENDIAN, Encoding.NONE, "", 1); //$NON-NLS-1$
139-151: Consider renamingfIntervalTreefor clarity.The field
fIntervalTreeis a sorted list of intervals, not an actual interval tree data structure. Consider renaming tofSortedIntervalsorfIntervalListto avoid confusion with the interval tree data structure which has different complexity guarantees.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
common/org.eclipse.tracecompass.common.core.tests/META-INF/MANIFEST.MFcommon/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java
🚧 Files skipped from review as they are similar to previous changes (2)
- common/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.java
- common/org.eclipse.tracecompass.common.core.tests/META-INF/MANIFEST.MF
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build / build
- GitHub Check: build / build
- GitHub Check: build / build
🔇 Additional comments (2)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java (2)
377-392: LGTM!The
setMappingsandbuildIntervalTreemethods correctly populate and sort the interval list for efficient lookup.
476-483: LGTM!The simplification to always create
IntegerDefinitionwithout inline mapping resolution is a cleaner separation of concerns.
a3d8a6f to
49eb341
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java (1)
120-128: Fix loop to process all declarators, not just the last one.The loop iterates over
typeDeclaratorListbut reuses the shareddeclvariable, so only the final declarator's declaration is retained. Earlier declarators are silently discarded.Compare with
VariantDeclarationParserandTypedefParser, which correctly handle multiple declarators by creating a new declaration variable per iteration and processing it immediately within the loop. The loop here should do the same: create freshidentifierSBanddeclvariables per iteration, validate each declarator, and add it to the struct within the loop.
🤖 Fix all issues with AI agents
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition.java:
- Line 29: The class Javadoc's @apiNote for StringDefinition is an incomplete
sentence and lacks cross-reference and deprecation metadata; update the Javadoc
for StringDefinition to complete the @apiNote (e.g., "Avoid using this class as
it is too coupled to StringDeclaration; use StringDefinition2 instead."), add a
@see StringDefinition2 tag for discoverability, and if the intention is to
discourage use, add a @deprecated annotation and a short @deprecated Javadoc
explaining the preferred alternative.
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java:
- Around line 159-161: In FloatDeclarationParser (method parsing structure field
members), replace the ambiguous variable passed to
AlignmentParser.INSTANCE.parse: use the local
JsonStructureFieldMemberMetadataNode variable named "member" instead of
"floatingPoint" when calling AlignmentParser.INSTANCE.parse inside the
instanceof block that checks for JsonStructureFieldMemberMetadataNode; update
the call so alignment = AlignmentParser.INSTANCE.parse(member, null) to make
intent clear and match the aliased variable.
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java:
- Around line 64-74: The code calls elementFieldClass.getAsJsonObject() without
ensuring elementFieldClass is a JsonObject, which can throw
IllegalStateException when element-field-class is a string alias; before
creating the JsonStructureFieldMemberMetadataNode, verify elementFieldClass is
non-null and isJsonObject (or handle isJsonPrimitive/string alias) and if it's
not an object either resolve the alias form or throw a ParseException; update
the block around elementFieldClass, JsonStructureFieldMemberMetadataNode, and
the subsequent TypeAliasParser.INSTANCE.parse(...) to branch on
elementFieldClass.isJsonObject() and only call getAsJsonObject() for that case
(or convert/resolve the alias to an object form) so parsing never calls
getAsJsonObject() on a non-object.
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java:
- Around line 57-71: In parse(ICTFMetadataNode node, ICommonTreeParserParameter
param) of StaticLengthStringParser, update the incorrect error message strings
that reference "Dynamic-length string" to "Static-length string" (specifically
the message thrown when node is not a JsonStructureFieldMemberMetadataNode and
the message thrown when lengthField is null) so the exceptions reflect this
class's responsibility.
- Around line 29-44: The class Javadoc for StaticLengthStringParser incorrectly
describes dynamic-length strings; update the comment for
StaticLengthStringParser to describe static-length string fields: explain they
are fixed-size sequences of encoded Unicode codepoints of a specified byte
length, how padding/NULL handling works for static-length strings (e.g.,
trailing bytes beyond the first NUL are padding), and reference that the length
is inherent to the field rather than coming from another length field; keep the
author tag and adjust wording to match the behavior implemented in
StaticLengthStringParser.
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java:
- Around line 201-226: The code in StructParser.java redundantly checks for null
after isJsonObject() on memberNode.getFieldClass() and lacks null-safety when
accessing memberElement fields; change to call JsonObject outerFieldClass =
memberNode.getFieldClass().getAsJsonObject() (remove the unreachable null check)
and guard accesses: check
outerFieldClass.has(JsonMetadataStrings.MINIMUM_ALIGNMENT) before calling
getAsLong(), and for each memberElement ensure memberElement.isJsonObject() and
that its JsonObject has(JsonMetadataStrings.NAME) and
has(JsonMetadataStrings.FIELD_CLASS) and that those entries are non-null (and
FIELD_CLASS is a JSON object) before calling getAsString()/getAsJsonObject(); on
missing required fields either throw a ParseException with a clear message or
skip that member, and use those safe values to construct
JsonStructureFieldMemberMetadataNode and addChild.
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java:
- Around line 25-30: The class Javadoc incorrectly says "Dynamic-length string
declaration"; update the documentation for StaticLengthStringDeclaration to
accurately describe it as a static-length string declaration (e.g.,
"Static-length string declaration with encoding support") so the comment matches
the class name StaticLengthStringDeclaration and avoid copy-paste confusion.
- Around line 93-96: The getMaximumSize() implementation in
StaticLengthStringDeclaration incorrectly returns Integer.MAX_VALUE; update
StaticLengthStringDeclaration.getMaximumSize() to return the actual declared
maximum in bits by computing fLength * Byte.SIZE (matching the approach used by
IntegerDeclaration and ArrayDeclaration) so the fixed-length string reports its
true maximum size based on the fLength field.
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java:
- Around line 259-261: Add Javadoc comments for the ALIGNMENT and BYTE_ORDER
constants (public static final String ALIGNMENT and BYTE_ORDER) matching the
style used for other constants in JsonMetadataStrings.java: include a brief
description of what each constant represents in the JSON metadata (e.g.,
alignment of a type and byte order/endianess), annotate with the //$NON-NLS-1$
suffix as present, and place the Javadoc immediately above each constant
declaration.
🧹 Nitpick comments (7)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (1)
67-85: Simplify:fLengthis alreadyint, no need forlongconversion.The
rawLengthvariable and subsequent cast back tointare unnecessary sincefLengthis already anint. Also consider using an integer literal1_000_000instead of1e6for clarity.♻️ Proposed simplification
@Override public StringDefinition2 createDefinition(@Nullable IDefinitionScope definitionScope, String fieldName, BitBuffer input) throws CTFException { - long rawLength = fLength; - if (rawLength < 0) { - throw new CTFException("Cannot have a length < 0, declared = " + rawLength); //$NON-NLS-1$ + if (fLength < 0) { + throw new CTFException("Cannot have a length < 0, declared = " + fLength); //$NON-NLS-1$ } - if (rawLength > 1e6) { - throw new CTFException("Cannot have a length > 1000000, declared = " + rawLength); //$NON-NLS-1$ + if (fLength > 1_000_000) { + throw new CTFException("Cannot have a length > 1000000, declared = " + fLength); //$NON-NLS-1$ } - int length = (int) rawLength; - byte[] bytes = new byte[length]; - for (int i = 0; i < length; i++) { + byte[] bytes = new byte[fLength]; + for (int i = 0; i < fLength; i++) { bytes[i] = (byte) input.get(Byte.SIZE, false); }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java (1)
138-150: Asymmetric duplicate-field handling between CTF1 and CTF2 paths.
- CTF1 path (lines 125-128): Throws unconditionally if field already exists
- CTF2 path: Allows re-adding the same declaration silently (line 143 only throws if declarations differ)
If this asymmetry is intentional for CTF2 compatibility, consider adding a brief comment explaining the design rationale.
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java (2)
58-70: Test name is misleading: only UID is tested, not packet header.The method
testUidAndPacketHeaderonly verifiesgetUid(). The packet header field (fPacketHeader) is not set or validated. Consider either:
- Renaming to
testUidParsing()- Adding packet header verification to complete the test
♻️ Option 1: Rename the test
- public void testUidAndPacketHeader() throws Exception { + public void testUidParsing() throws Exception {
31-51: Consider testing via Gson deserialization instead of reflection.Directly setting private fields via reflection is fragile—tests will break silently if field names are refactored. Using actual Gson deserialization would better validate the integration:
Gson gson = new Gson(); String json = "{\"environment\":{\"hostname\":\"test-host\"}}"; JsonTraceMetadataNode node = gson.fromJson(json, JsonTraceMetadataNode.class);If reflection is preferred for isolation, this is acceptable but worth noting the trade-off.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (1)
227-229: Redefinition check added for non-JSON path; consider parity for JSON path.The new guard prevents duplicate type registration in the non-JSON path. However, the JSON path (lines 143-206) proceeds directly to
scope.registerTypeat line 232 without a similar check. If redefinition should be an error for both paths, consider adding the check before line 232 as well.Proposed fix for parity
+ if (aliasString != null && scope.lookupType(aliasString) != null) { + throw new ParseException("Type has already been defined: " + aliasString); //$NON-NLS-1$ + } scope.registerType(aliasString, targetDeclaration);ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java (1)
80-104:Paramclass is defined but never used inparse().The
parse()method doesn't validate or use theparamargument as aParaminstance. The trace is never accessed. Either remove the unusedParamclass or add validation similar toStaticLengthArrayParser:♻️ Option 1: Add param validation if trace is needed later
@Override public IDeclaration parse(ICTFMetadataNode node, ICommonTreeParserParameter param) throws ParseException { if (!(node instanceof JsonStructureFieldMemberMetadataNode)) { throw new ParseException("Static-length string only supported in JSON metadata"); //$NON-NLS-1$ } + if (!(param instanceof Param)) { + throw new IllegalArgumentException("Param must be a " + Param.class.getCanonicalName()); //$NON-NLS-1$ + }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java (1)
672-697: Binary search followed by linear scan has O(n) worst case.The current algorithm correctly uses binary search to find the starting point, but the backwards scan (lines 690-695) degrades to O(n) when many intervals overlap or start at similar values. For typical CTF mappings with few entries, this is acceptable.
Consider documenting this trade-off or using an interval tree data structure if large mapping sets become common:
+ // Note: For small mapping sets (typical in CTF), linear scan after binary search + // is acceptable. For large sets, consider using a proper interval tree. String getMappingForValue(long value) {
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (32)
common/org.eclipse.tracecompass.common.core.tests/META-INF/MANIFEST.MFcommon/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.javactf/org.eclipse.tracecompass.ctf.core.tests/META-INF/MANIFEST.MFctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.javactf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.javactf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.javactf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/BlobDeclaration.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDefinition.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/ScopedDefinition.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDefinition.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/AlignmentParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicarray/DynamicLengthArrayParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.javactf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventField.javactf/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/TestInvalidCtfTrace.java
🚧 Files skipped from review as they are similar to previous changes (11)
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.java
- common/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.java
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.java
- ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventField.java
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/BlobDeclaration.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicarray/DynamicLengthArrayParser.java
🧰 Additional context used
🧬 Code graph analysis (3)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (7)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicarray/DynamicLengthArrayParser.java (1)
DynamicLengthArrayParser(33-121)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicstring/DynamicLengthStringParser.java (1)
DynamicLengthStringParser(46-106)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (1)
FloatDeclarationParser(67-213)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java (1)
StaticLengthArrayParser(33-116)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java (1)
StructParser(96-289)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-263)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/variant/VariantParser.java (1)
VariantParser(200-400)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java (3)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (1)
StaticLengthStringDeclaration(30-111)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-263)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.java (1)
JsonTraceMetadataNode(28-87)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build / build
- GitHub Check: build / build
- GitHub Check: build / build
🔇 Additional comments (27)
ctf/org.eclipse.tracecompass.ctf.core.tests/META-INF/MANIFEST.MF (1)
27-27: LGTM!The
com.google.gsonimport is correctly placed alphabetically and follows the existing pattern for Google library imports in this manifest (no version constraints). This aligns with the project-wide move to Gson-based JSON handling for CTF metadata parsing.common/org.eclipse.tracecompass.common.core.tests/META-INF/MANIFEST.MF (1)
24-24: LGTM!The
com.google.gsonimport is correctly positioned alphabetically after the othercom.google.common.*imports and follows the existing pattern (no version constraints). This addition properly supports the Gson-based JSON metadata handling introduced across the project.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (2)
43-64: LGTM!Constructor and getters are straightforward. The validation in
createDefinition()handles edge cases.
98-110: LGTM!The
toString()provides a clear representation, andisBinaryEquivalent()correctly compares both length and encoding using null-safe comparison.ctf/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/TestInvalidCtfTrace.java (1)
89-89: LGTM!The updated error message expectation correctly aligns with the new
ParseExceptionmessage format inStructDeclarationParser.java(lines 126-127 and 144-145).ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDefinition.java (2)
109-114: LGTM! Lazy initialization is correctly implemented.The pattern is safe because
fValueis immutable andgetMappingForValue()is deterministic—concurrent calls will compute the same result. The benign race onfMappingis acceptable here.
62-67: LGTM!Constructor correctly initializes
fMappingtonullto enable lazy computation ingetMappings().ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/AlignmentParser.java (1)
107-126: LGTM! JSON-based alignment parsing for structure field members.The validation flow is correct: null-check → JSON object check → alignment key presence → primitive check → value extraction with validation.
One note: if
fieldclassexists but has noALIGNMENTkey, the method falls through to throw a generic error at line 128. This appears intentional as alignment is a required attribute, but consider if a default value would be more appropriate in the JSON path (similar to how the legacy path handles defaults).ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.java (2)
155-160: LGTM! Proper null and type validation for JSON fieldClass.The pattern-matched instanceof with subsequent null/type validation is consistent with the validation pattern used across other TSDL parsers in this PR.
267-270: LGTM! Correct parameter fix for createDeclaration with mappings.The change from using
baseto(int) sizeas the first parameter aligns with line 272 (the non-mappings path) and matches the expected method signature where size is the first parameter.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.java (3)
128-139: LGTM! Integer-based variant tag lookup via mappings or array index.The logic correctly handles two cases:
- If mappings exist, resolve field by mapping name
- Otherwise, use the tag value as an index into
fFieldArrayThe bounds check at line 135 properly guards against invalid indices.
170-172: Array resizing on every addField call is acceptable for typical use.
Arrays.copyOfcreates a new array on each call, resulting in O(n²) total time for n fields. This is acceptable given CTF variants typically have few fields. If performance becomes a concern, consider using anArrayListinternally.
47-48: The thread-safety concern about removingCollections.synchronizedMapis unfounded.
VariantDeclaration.addField()is called only during metadata parsing (a single-threaded phase). Once parsing completes, the declaration instances become effectively immutable—createDefinition()only readsfFieldsandfFieldArrayduring event processing and never modifies them. The concurrent event reading phase only accesses declarations for reading, never for writing. Removing synchronization is a valid performance optimization without thread-safety implications.Likely an incorrect or invalid review comment.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.java (2)
186-225: LGTM! Enhanced lookup with exclusion and role-based matching.The updated
lookupDefinitionmethod correctly:
- Exits early for self-exclusion to prevent infinite loops
- Checks direct field matches first
- Falls back to role-based matching on child declarations
- Recursively searches through nested
ScopedDefinitionchildren- Properly delegates to parent scope while passing exclusion context
252-264: LGTM! Recursive role lookup through nested structures.The helper method correctly traverses nested
StructDefinitionandVariantDefinitiontypes to find fields by role. The recursion through variant's current field ensures dynamic variant selections are properly searched.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java (1)
144-203: LGTM! Comprehensive field class type dispatch with clean switch structure.The switch statement properly handles all CTF2 JSON field class types with appropriate parser delegation. Each case correctly constructs the necessary parser parameters.
Minor note: Line 193 passes
nullfor the identifier parameter toStructParser.Param- verify this is intentional for anonymous/inline struct definitions.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (1)
130-161: LGTM! JSON-based floating point parsing with IEEE 754 size mapping.The JSON parsing branch correctly:
- Validates fieldClass as a JSON object
- Maps standard IEEE 754 sizes (32-bit, 64-bit) to exponent/mantissa values
- Properly rejects unsupported but valid sizes with a TODO for future work
- Parses byte order and alignment from JSON fields
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDefinition.java (3)
45-69: New constructor with SimpleDatatypeDefinition looks good.The new constructor properly generalizes the tag definition type from
EnumDefinitiontoSimpleDatatypeDefinition, enabling broader CTF2 support. The@since 5.1annotation is appropriate for the API addition.
139-164: Enhanced lookupDefinition with role-based resolution is well-structured.The method now supports role-based lookups for CTF2 compatibility. The null-safety is maintained since
String.equals(null)returnsfalse. The delegation pattern to nestedScopedDefinitionand parentStructDefinitionproperly handles hierarchical lookups.
166-192: Overloaded lookupDefinition correctly propagates exclusion context.The method properly passes
definitionToExcludeto nested scoped definitions while passingthisto the parent struct definition, maintaining consistent exclusion semantics to prevent infinite recursion.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java (2)
43-77: Parse method implementation is well-structured.The method properly validates inputs, extracts required properties, and delegates element type resolution to
TypeAliasParser. The error messages are clear and specific.
79-115: Param class is well-defined and properly utilized.Unlike
StaticLengthStringParser.Param, this class is correctly validated and its fields are used in theparse()method.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java (4)
140-143: Deprecation ofUINT_27L_DECLis properly documented.The
@Deprecatedannotation with guidance to use the factory method is appropriate.
170-179:IntervalNodeinner class is appropriately designed.Simple data holder for interval-based mapping lookups. The package-private visibility is suitable for internal use.
603-637: UpdatedhashCodeandequalscorrectly include new state.The inclusion of
fMappingsandgetRole()ensures that declarations with different mappings or roles are correctly distinguished.
507-515: SimplifiedcreateDefinitiondefers mapping resolution.The method now always creates a base
IntegerDefinition, with mapping resolution handled separately. This is a cleaner separation of concerns.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
220-222: ENCODINGS map is well-defined with common UTF charsets.The use of
Map.of()ensures immutability. The supported encodings cover standard UTF variants.
...racecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition.java
Show resolved
Hide resolved
...tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java
Show resolved
Hide resolved
| JsonElement elementFieldClass = fieldClass.get(JsonMetadataStrings.ELEMENT_FIELD_CLASS); | ||
| if (elementFieldClass == null) { | ||
| throw new ParseException("Static-length array requires element-field-class property"); //$NON-NLS-1$ | ||
| } | ||
|
|
||
| int length = lengthField.getAsInt(); | ||
| CTFTrace trace = ((Param) param).getTrace(); | ||
| DeclarationScope scope = ((Param) param).getScope(); | ||
|
|
||
| JsonStructureFieldMemberMetadataNode elementNode = new JsonStructureFieldMemberMetadataNode(node, "", "", "", elementFieldClass.getAsJsonObject()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | ||
| IDeclaration elementDeclaration = TypeAliasParser.INSTANCE.parse(elementNode, new TypeAliasParser.Param(trace, scope)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# Search for element-field-class usage patterns
rg -n "element-field-class|ELEMENT_FIELD_CLASS" --type=java -B2 -A5Repository: eclipse-tracecompass/org.eclipse.tracecompass
Length of output: 5297
🏁 Script executed:
# Look for similar getAsJsonObject() calls and how they're handled
rg -n "getAsJsonObject\(\)" --type=java -B3 -A2Repository: eclipse-tracecompass/org.eclipse.tracecompass
Length of output: 36518
🏁 Script executed:
# Check TypeAliasParser to understand what it expects as input
fd "TypeAliasParser.java" --type fRepository: eclipse-tracecompass/org.eclipse.tracecompass
Length of output: 214
🏁 Script executed:
# Look for JsonStructureFieldMemberMetadataNode usage patterns
rg -n "JsonStructureFieldMemberMetadataNode" --type=java -B2 -A2Repository: eclipse-tracecompass/org.eclipse.tracecompass
Length of output: 50401
Add type check before calling getAsJsonObject() on elementFieldClass.
The code at line 73 calls elementFieldClass.getAsJsonObject() without verifying it's actually a JsonObject. Since element-field-class can be a string alias reference (like other field-class properties in the codebase), this will throw IllegalStateException for non-object values. Add a null and type check before the call, similar to the validation already done for the outer fieldClass at line 54.
🤖 Prompt for AI Agents
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java
around lines 64 - 74, The code calls elementFieldClass.getAsJsonObject() without
ensuring elementFieldClass is a JsonObject, which can throw
IllegalStateException when element-field-class is a string alias; before
creating the JsonStructureFieldMemberMetadataNode, verify elementFieldClass is
non-null and isJsonObject (or handle isJsonPrimitive/string alias) and if it's
not an object either resolve the alias form or throw a ParseException; update
the block around elementFieldClass, JsonStructureFieldMemberMetadataNode, and
the subsequent TypeAliasParser.INSTANCE.parse(...) to branch on
elementFieldClass.isJsonObject() and only call getAsJsonObject() for that case
(or convert/resolve the alias to an object form) so parsing never calls
getAsJsonObject() on a non-object.
| /** | ||
| * A dynamic-length string field class is an abstract string field class which | ||
| * describes dynamic-length string fields. | ||
| * | ||
| * A dynamic-length string field is a sequence of zero or more contiguous | ||
| * encoded Unicode codepoints. All the encoded codepoints of a dynamic-length | ||
| * string field before the first "NULL" (U+0000) codepoint, if any, form the | ||
| * resulting string value. The first U+0000 codepoint, if any, and all the | ||
| * following bytes are considered padding (garbage data). | ||
| * | ||
| * The length, or number of bytes, of a dynamic-length string field is the | ||
| * value of another, anterior (already encoded/decoded) length field. A | ||
| * consumer can locate this length field thanks to the length-field-location | ||
| * property of the dynamic-length string field class. | ||
| * | ||
| * @author Matthew Khouzam |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Javadoc describes dynamic-length string but this is StaticLengthStringParser.
The class documentation appears to be copied from DynamicLengthStringParser. It should describe static-length string fields instead.
📝 Suggested documentation fix
/**
- * A dynamic-length string field class is an abstract string field class which
- * describes dynamic-length string fields.
+ * A static-length string field class describes static-length string fields.
*
- * A dynamic-length string field is a sequence of zero or more contiguous
+ * A static-length string field is a sequence of zero or more contiguous
* encoded Unicode codepoints. All the encoded codepoints of a dynamic-length
* string field before the first "NULL" (U+0000) codepoint, if any, form the
* resulting string value. The first U+0000 codepoint, if any, and all the
* following bytes are considered padding (garbage data).
*
- * The length, or number of bytes, of a dynamic-length string field is the
- * value of another, anterior (already encoded/decoded) length field. A
- * consumer can locate this length field thanks to the length-field-location
- * property of the dynamic-length string field class.
+ * The length, or number of bytes, of a static-length string field is a
+ * fixed value specified in the field class's length property.
*
* @author Matthew Khouzam
*/🤖 Prompt for AI Agents
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java
around lines 29 - 44, The class Javadoc for StaticLengthStringParser incorrectly
describes dynamic-length strings; update the comment for
StaticLengthStringParser to describe static-length string fields: explain they
are fixed-size sequences of encoded Unicode codepoints of a specified byte
length, how padding/NULL handling works for static-length strings (e.g.,
trailing bytes beyond the first NUL are padding), and reference that the length
is inherent to the field rather than coming from another length field; keep the
author tag and adjust wording to match the behavior implemented in
StaticLengthStringParser.
| public IDeclaration parse(ICTFMetadataNode node, ICommonTreeParserParameter param) throws ParseException { | ||
| if (!(node instanceof JsonStructureFieldMemberMetadataNode)) { | ||
| throw new ParseException("Dynamic-length string only supported in JSON metadata"); //$NON-NLS-1$ | ||
| } | ||
|
|
||
| JsonStructureFieldMemberMetadataNode member = (JsonStructureFieldMemberMetadataNode) node; | ||
| JsonElement fieldClassElement = member.getFieldClass(); | ||
| if (fieldClassElement == null || !fieldClassElement.isJsonObject()) { | ||
| throw new ParseException(getClass().getName() + " fieldclass must be a json object."); //$NON-NLS-1$ | ||
| } | ||
| JsonObject fieldClass = fieldClassElement.getAsJsonObject(); | ||
| JsonElement lengthField = fieldClass.get(JsonMetadataStrings.LENGTH); | ||
| if (lengthField == null) { | ||
| throw new ParseException("Dynamic-length string requires length-field-location property"); //$NON-NLS-1$ | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error messages reference "Dynamic-length string" instead of "Static-length string".
The error messages appear to be copied from DynamicLengthStringParser and should be updated for consistency.
📝 Suggested fix
if (!(node instanceof JsonStructureFieldMemberMetadataNode)) {
- throw new ParseException("Dynamic-length string only supported in JSON metadata"); //$NON-NLS-1$
+ throw new ParseException("Static-length string only supported in JSON metadata"); //$NON-NLS-1$
}
...
if (lengthField == null) {
- throw new ParseException("Dynamic-length string requires length-field-location property"); //$NON-NLS-1$
+ throw new ParseException("Static-length string requires length property"); //$NON-NLS-1$
}🤖 Prompt for AI Agents
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java
around lines 57 - 71, In parse(ICTFMetadataNode node, ICommonTreeParserParameter
param) of StaticLengthStringParser, update the incorrect error message strings
that reference "Dynamic-length string" to "Static-length string" (specifically
the message thrown when node is not a JsonStructureFieldMemberMetadataNode and
the message thrown when lengthField is null) so the exceptions reflect this
class's responsibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment was already there and duplicating it makes addressing the review harder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arfio, I apologize for the duplication. You're right that duplicate comments make reviews harder to manage. I'll avoid repeating the same issue if it's already been flagged elsewhere. Thank you for the feedback!
| } else if (struct instanceof JsonStructureFieldMemberMetadataNode memberNode) { | ||
| if (memberNode.getFieldClass().isJsonObject()) { | ||
| JsonElement fieldClassElement = memberNode.getFieldClass(); | ||
| if (fieldClassElement == null || !fieldClassElement.isJsonObject()) { | ||
| throw new ParseException(getClass().getName() + " fieldclass must be a json object."); //$NON-NLS-1$ | ||
| } | ||
| JsonObject outerFieldClass = fieldClassElement.getAsJsonObject(); | ||
| JsonElement minimumAlignment = outerFieldClass.get(JsonMetadataStrings.MINIMUM_ALIGNMENT); | ||
| if (minimumAlignment != null) { | ||
| structAlign = minimumAlignment.getAsLong(); | ||
| } | ||
| JsonElement memberClasses = outerFieldClass.get(JsonMetadataStrings.MEMBER_CLASSES); | ||
| if (memberClasses != null && memberClasses.isJsonArray()) { | ||
| hasBody = true; | ||
| for (JsonElement memberElement : memberClasses.getAsJsonArray()) { | ||
| if (memberElement.isJsonObject()) { | ||
| String name = memberElement.getAsJsonObject().get(JsonMetadataStrings.NAME).getAsString(); | ||
| JsonElement fieldClass = memberElement.getAsJsonObject().get(JsonMetadataStrings.FIELD_CLASS); | ||
| JsonStructureFieldMemberMetadataNode childNode = new JsonStructureFieldMemberMetadataNode(memberNode, "", "", name, fieldClass.getAsJsonObject()); //$NON-NLS-1$ //$NON-NLS-2$ | ||
| memberNode.addChild(childNode); | ||
| } | ||
| } | ||
| structBody = memberNode; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant null check and missing null-safety on JSON element access.
-
Lines 203-206 are unreachable: line 202 already confirms
isJsonObject()is true, sofieldClassElementcannot be null and must be a JSON object. -
Lines 217-218 lack null checks:
memberElement.getAsJsonObject().get(...)could return null, and subsequentgetAsString()/getAsJsonObject()would throw.
Proposed fix
} else if (struct instanceof JsonStructureFieldMemberMetadataNode memberNode) {
- if (memberNode.getFieldClass().isJsonObject()) {
- JsonElement fieldClassElement = memberNode.getFieldClass();
- if (fieldClassElement == null || !fieldClassElement.isJsonObject()) {
- throw new ParseException(getClass().getName() + " fieldclass must be a json object."); //$NON-NLS-1$
- }
- JsonObject outerFieldClass = fieldClassElement.getAsJsonObject();
+ JsonElement fieldClassElement = memberNode.getFieldClass();
+ if (fieldClassElement != null && fieldClassElement.isJsonObject()) {
+ JsonObject outerFieldClass = fieldClassElement.getAsJsonObject();
JsonElement minimumAlignment = outerFieldClass.get(JsonMetadataStrings.MINIMUM_ALIGNMENT);
if (minimumAlignment != null) {
structAlign = minimumAlignment.getAsLong();
}
JsonElement memberClasses = outerFieldClass.get(JsonMetadataStrings.MEMBER_CLASSES);
if (memberClasses != null && memberClasses.isJsonArray()) {
hasBody = true;
for (JsonElement memberElement : memberClasses.getAsJsonArray()) {
if (memberElement.isJsonObject()) {
- String name = memberElement.getAsJsonObject().get(JsonMetadataStrings.NAME).getAsString();
- JsonElement fieldClass = memberElement.getAsJsonObject().get(JsonMetadataStrings.FIELD_CLASS);
- JsonStructureFieldMemberMetadataNode childNode = new JsonStructureFieldMemberMetadataNode(memberNode, "", "", name, fieldClass.getAsJsonObject()); //$NON-NLS-1$ //$NON-NLS-2$
+ JsonObject memberObj = memberElement.getAsJsonObject();
+ JsonElement nameElement = memberObj.get(JsonMetadataStrings.NAME);
+ JsonElement fieldClass = memberObj.get(JsonMetadataStrings.FIELD_CLASS);
+ if (nameElement == null || fieldClass == null || !fieldClass.isJsonObject()) {
+ continue; // or throw ParseException
+ }
+ String name = nameElement.getAsString();
+ JsonStructureFieldMemberMetadataNode childNode = new JsonStructureFieldMemberMetadataNode(memberNode, "", "", name, fieldClass.getAsJsonObject()); //$NON-NLS-1$ //$NON-NLS-2$
memberNode.addChild(childNode);
}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| } else if (struct instanceof JsonStructureFieldMemberMetadataNode memberNode) { | |
| if (memberNode.getFieldClass().isJsonObject()) { | |
| JsonElement fieldClassElement = memberNode.getFieldClass(); | |
| if (fieldClassElement == null || !fieldClassElement.isJsonObject()) { | |
| throw new ParseException(getClass().getName() + " fieldclass must be a json object."); //$NON-NLS-1$ | |
| } | |
| JsonObject outerFieldClass = fieldClassElement.getAsJsonObject(); | |
| JsonElement minimumAlignment = outerFieldClass.get(JsonMetadataStrings.MINIMUM_ALIGNMENT); | |
| if (minimumAlignment != null) { | |
| structAlign = minimumAlignment.getAsLong(); | |
| } | |
| JsonElement memberClasses = outerFieldClass.get(JsonMetadataStrings.MEMBER_CLASSES); | |
| if (memberClasses != null && memberClasses.isJsonArray()) { | |
| hasBody = true; | |
| for (JsonElement memberElement : memberClasses.getAsJsonArray()) { | |
| if (memberElement.isJsonObject()) { | |
| String name = memberElement.getAsJsonObject().get(JsonMetadataStrings.NAME).getAsString(); | |
| JsonElement fieldClass = memberElement.getAsJsonObject().get(JsonMetadataStrings.FIELD_CLASS); | |
| JsonStructureFieldMemberMetadataNode childNode = new JsonStructureFieldMemberMetadataNode(memberNode, "", "", name, fieldClass.getAsJsonObject()); //$NON-NLS-1$ //$NON-NLS-2$ | |
| memberNode.addChild(childNode); | |
| } | |
| } | |
| structBody = memberNode; | |
| } | |
| } | |
| } | |
| } else if (struct instanceof JsonStructureFieldMemberMetadataNode memberNode) { | |
| JsonElement fieldClassElement = memberNode.getFieldClass(); | |
| if (fieldClassElement != null && fieldClassElement.isJsonObject()) { | |
| JsonObject outerFieldClass = fieldClassElement.getAsJsonObject(); | |
| JsonElement minimumAlignment = outerFieldClass.get(JsonMetadataStrings.MINIMUM_ALIGNMENT); | |
| if (minimumAlignment != null) { | |
| structAlign = minimumAlignment.getAsLong(); | |
| } | |
| JsonElement memberClasses = outerFieldClass.get(JsonMetadataStrings.MEMBER_CLASSES); | |
| if (memberClasses != null && memberClasses.isJsonArray()) { | |
| hasBody = true; | |
| for (JsonElement memberElement : memberClasses.getAsJsonArray()) { | |
| if (memberElement.isJsonObject()) { | |
| JsonObject memberObj = memberElement.getAsJsonObject(); | |
| JsonElement nameElement = memberObj.get(JsonMetadataStrings.NAME); | |
| JsonElement fieldClass = memberObj.get(JsonMetadataStrings.FIELD_CLASS); | |
| if (nameElement == null || fieldClass == null || !fieldClass.isJsonObject()) { | |
| continue; // or throw ParseException | |
| } | |
| String name = nameElement.getAsString(); | |
| JsonStructureFieldMemberMetadataNode childNode = new JsonStructureFieldMemberMetadataNode(memberNode, "", "", name, fieldClass.getAsJsonObject()); //$NON-NLS-1$ //$NON-NLS-2$ | |
| memberNode.addChild(childNode); | |
| } | |
| } | |
| structBody = memberNode; | |
| } | |
| } | |
| } |
🤖 Prompt for AI Agents
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java
around lines 201 - 226, The code in StructParser.java redundantly checks for
null after isJsonObject() on memberNode.getFieldClass() and lacks null-safety
when accessing memberElement fields; change to call JsonObject outerFieldClass =
memberNode.getFieldClass().getAsJsonObject() (remove the unreachable null check)
and guard accesses: check
outerFieldClass.has(JsonMetadataStrings.MINIMUM_ALIGNMENT) before calling
getAsLong(), and for each memberElement ensure memberElement.isJsonObject() and
that its JsonObject has(JsonMetadataStrings.NAME) and
has(JsonMetadataStrings.FIELD_CLASS) and that those entries are non-null (and
FIELD_CLASS is a JSON object) before calling getAsString()/getAsJsonObject(); on
missing required fields either throw a ParseException with a clear message or
skip that member, and use those safe values to construct
JsonStructureFieldMemberMetadataNode and addChild.
...rc/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java
Show resolved
Hide resolved
...mpass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java
Show resolved
Hide resolved
Code assisted by CodeRabbit (GPT 5) for javadoc Change-Id: Iaf2558ab50b1f47604da28f4529bd094135a4ce5 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Change-Id: Ic10d79e4e72a043e9116d554f5dffacd34013fa6 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Change-Id: Ib3654d5468236a9e3ab1a2a2b0cb49dbfc76e251 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Change-Id: I724d84c0b1f5c300ee73c4f2c2b0b9fa3f4ca3d1 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Change-Id: Icb35ac1c931e398be30debfa45c539f8c9fcd245 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Change-Id: I30afb71bbcf7ff688590b95b7f48caf53b9d3ed4 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Change-Id: Ie35533f33a482aff519f9472b0a34b088be1506e Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Change-Id: I8a1408772b8e1ca2e634fa892e7d8a3c05349877 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Needed for expanding aliases Change-Id: I97039e706002602347cb6d06fbcfecbbd084b55d Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Add variant definition constructor for CTF2 Change-Id: I21f56a284c6fcee147d3714445ed30d81b706c1a Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Change-Id: Ief637e1c6bc49aca4bed87b586224df9383c1a9e Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Remove infinite recurstion if something is not found. (due to roles in ctf2) Change-Id: Ifa62ed5807a17e307c044e066399cf15fae2bc74 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
O(log(n)) instead of O(n) This patch was made with the assistance of Claude Sonnet 4.5 Change-Id: Ic46ff28a84e45beb8462f642340db19d04fa40fc Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Found with CodeRabbit. Change-Id: Ifa4be68a71fc98e6ca4604c290d50d6840746451 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Change-Id: I600c3d760717956097e41cb2db44de0cc58086ce Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Change-Id: I60f3854afcdf4454847ca49bfdee0ca7d89f9601 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
optimizations negatively affect ctf2. Roles do not work with it. Change-Id: I34812fe76934c62f00ae3de10cdfad074e996f7f Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Change-Id: If58b118283f9a5e3778e832edd94e358c23cded8 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Change-Id: I40faac6cc2590480c061824beb952d6a19cb2f12 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Change-Id: I018e6cfa1f3e7aeed14953de76d6d9f34adf8e64 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
made in part by claude sonnet 4.5. Many bad hallucinations needed to be manually fixed. Corrected by CodeRabbit (GPT5) Change-Id: Ibee4b0cf144f2afa922ae968fd17d6065e18b257 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Generated by Claude Sonnet 4.5, manually fixed by me. Change-Id: Ieec23f0b0f783775a166b530c9c5c75bc0190c53 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Do not accept double typealiases with the same value. Change-Id: I2affb15f6faf83cd0292a7310febbad8ae657513 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Clean up the hashcode. Fix a corner case in getMappings Change-Id: Iec698c9761fde045a0b9945e65ebcda97fa99cb4 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Add verification to AlignmentParser to match CTF2 specs here. https://diamon.org/ctf/ Change-Id: I86b1ede3f0b74ae9f9dd40087580013c13a092a7 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
With Java 25, flows can go to different TIDs. This allows the tests to pass. Change-Id: Ic26850e16ce813ba2c70b0af71b9caa6af0805f2 Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
49eb341 to
d62c3d1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 12
🤖 Fix all issues with AI agents
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/ScopedDefinition.java:
- Around line 163-168: The method lookupDefinition(@Nullable String lookupPath,
@Nullable ScopedDefinition definitionToExclude) currently calls itself causing
infinite recursion and has an extra closing brace; change the call to delegate
to the single-parameter overload lookupDefinition(lookupPath) instead of
lookupDefinition(lookupPath, definitionToExclude) and remove the stray extra '}'
so the method returns the result of the single-parameter overload when
definitionToExclude != this.
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.java:
- Around line 168-173: addField currently always appends to fFieldArray after
fFields.put, so overwriting an existing fieldTag makes fFieldArray inconsistent
with fFields and breaks index-based lookups in createDefinition; change addField
to detect whether the key already existed (e.g. check
fFields.containsKey(fieldTag) or capture the previous value from fFields.put)
and if it did, find and replace the existing entry in fFieldArray (or rebuild
fFieldArray from fFields.values()) instead of blindly growing the array; ensure
createDefinition continues to rely on the corrected fFieldArray ordering.
- Around line 128-139: The IntegerDefinition branch in VariantDeclaration (where
def instanceof IntegerDefinition, tagDef, getMappings(), getIntegerValue())
doesn't handle the case where both mappings and tagValue are null, so
fDeclarationToPopulate can remain unset and later produce a misleading "Unknown
enum selector" error; update that branch to explicitly detect mappings==null &&
tagValue==null and throw a CTFException with a clear message (e.g., "Missing
integer tag value or mappings for variant " + toString()) or otherwise set
fDeclarationToPopulate to a sensible default before falling through, ensuring
the exception refers to an integer-based tag and using the existing identifiers
tagDef, fDeclarationToPopulate, getMappings(), and getIntegerValue().
- Around line 47-49: The field fDeclarationToPopulate is used only within
createDefinition and causes a race when multiple threads call createDefinition
on the same VariantDeclaration; make fDeclarationToPopulate a local variable
inside createDefinition (replace uses of fDeclarationToPopulate with a local
IDeclaration declarationToPopulate) and update all assignments and references in
that method accordingly; also review the change from a synchronized map to a
plain HashMap for fFields and, if concurrent access is expected, restore
thread-safety (e.g., use Collections.synchronizedMap, ConcurrentHashMap, or
synchronize access around fFields) to avoid concurrent modification issues.
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/AlignmentParser.java:
- Around line 107-126: In the JsonStructureFieldMemberMetadataNode branch of
AlignmentParser (the else-if handling JsonStructureFieldMemberMetadataNode), add
a return of the default alignment when the fieldclass does not contain
JsonMetadataStrings.ALIGNMENT instead of falling through to the ParseException;
specifically: if fieldclass.has(JsonMetadataStrings.ALIGNMENT) remains as-is for
parsing/validation, but after that conditional return a sensible default (match
the default used by JsonStructureFieldMetadataNode — e.g., 1) so optional
alignment is handled correctly.
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicarray/DynamicLengthArrayParser.java:
- Around line 69-72: Null-check the result of
lengthFieldLocation.getAsJsonObject().get(JsonMetadataStrings.PATH) and validate
that when pathElement.isJsonArray() the array size is > 0 before accessing
get(size()-1); if PATH is missing or the array is empty, throw a clear
IllegalArgumentException (or return a sensible default) with context including
the metadata location, and otherwise extract the last element safely to assign
to lengthName; update the logic around lengthFieldLocation, pathElement, and
lengthName in DynamicLengthArrayParser to perform these checks and produce a
meaningful error when the PATH is absent or empty.
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java:
- Around line 58-70: The thrown ParseException messages in
StaticLengthStringParser reference "Dynamic-length string" incorrectly; update
the three error strings used around the node and fieldClass checks (the messages
thrown when node is not a JsonStructureFieldMemberMetadataNode, when
fieldClassElement is null or not a JsonObject, and when lengthField is null) to
say "Static-length string" (e.g., "Static-length string only supported in JSON
metadata", "Static-length string fieldclass must be a json object.", and
"Static-length string requires length-field-location property") so the messages
correctly reflect the StaticLengthStringParser class.
- Around line 29-43: The class Javadoc is describing dynamic-length strings but
the class is StaticLengthStringParser; update the Javadoc text for
StaticLengthStringParser to describe static-length string fields (fixed byte
length determined by the length property, how NULL bytes are handled as
padding/truncation, and the relation to the length-field-location property if
applicable), making sure the description and examples use the class name
StaticLengthStringParser and reflect static-length semantics instead of
dynamic-length ones.
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java:
- Around line 201-225: The loop that builds child
JsonStructureFieldMemberMetadataNode instances assumes each memberElement
contains NAME and FIELD_CLASS; add null checks for
memberElement.getAsJsonObject().get(JsonMetadataStrings.NAME) and
.get(JsonMetadataStrings.FIELD_CLASS) and for fieldClass.isJsonObject() before
calling getAsString()/getAsJsonObject(); if any required property is missing or
of the wrong type, throw a ParseException with a clear message; update the
construction site of JsonStructureFieldMemberMetadataNode (in the loop over
memberClasses) to only create and add childNode when those validations pass.
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java:
- Around line 93-96: The getMaximumSize() implementation in
StaticLengthStringDeclaration is wrong: it returns Integer.MAX_VALUE causing
struct size computations to overflow; change it to return the actual fixed size
(use the declaration's fLength multiplied by Byte.SIZE) so
StaticLengthStringDeclaration#getMaximumSize() mirrors BlobDeclaration's
behavior and makes StructDeclaration.getMaximumSize() sum correct field sizes;
update the method to compute and return fLength * Byte.SIZE.
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java:
- Around line 203-206: The Javadoc for the PATH constant is incorrect (it
currently reads "Type string for a structure field class"); update the comment
above the public static final String PATH to accurately describe its purpose as
the JSON key for field location paths (used to represent a field's location
path), not a structure field class—use wording consistent with the STRUCTURE
constant comment to avoid the copy/paste error.
🧹 Nitpick comments (17)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition.java (1)
29-29: Incomplete@apiNoteand consider formal deprecation.The annotation text is grammatically incomplete (starts with "as it is"). If the intent is to discourage use of this class, consider:
- Fixing the grammar: "This class is too tightly coupled to StringDeclaration. Use StringDefinition2 instead."
- Adding a formal
@Deprecatedannotation if this class should no longer be used, which provides IDE warnings.📝 Suggested improvement
* @author Matthew Khouzam * @author Simon Marchi -* @apiNote as it is too coupled to the StringDeclaration class. Use StringDefinition2 +* @apiNote This class is tightly coupled to {@link StringDeclaration}. Consider using {@link StringDefinition2} instead. */Or, if you want to formally deprecate:
* @author Matthew Khouzam * @author Simon Marchi +* @deprecated This class is tightly coupled to {@link StringDeclaration}. Use {@link StringDefinition2} instead. */ +@Deprecated public final class StringDefinition extends Definition {ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.java (1)
198-206: Consider adding null/empty name guard for consistency withregisterType.The
Objects.equals()change is correct. However,registerTypenow includes a null/empty name check (lines 175-178), whileregisterIdentifierdoes not. If a null or empty name is passed here, it will still be inserted intofIdentifiers, potentially causing unexpected behavior.If anonymous identifiers are not expected, a similar guard would improve consistency and robustness:
Suggested fix
public void registerIdentifier(String name, IDeclaration declaration) throws ParseException { + if (name == null || name.isEmpty()) { + // don't register anonymous identifiers + return; + } /* Check if the type has been defined in the current scope */ IDeclaration iDeclaration = fIdentifiers.get(name); if (iDeclaration != null && !Objects.equals(iDeclaration, declaration)) { throw new ParseException("Identifier has already been defined:" + name); //$NON-NLS-1$ } /* Add it to the register. */ fIdentifiers.put(name, declaration); }ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.java (1)
135-138: Potential integer overflow when convertingLongtoint.Line 135 validates
tagValueagainstfFieldArray.lengthusing theLongvalue, but line 138 converts tointviatagValue.intValue(). IftagValueexceedsInteger.MAX_VALUE, the bounds check passes butintValue()silently truncates, potentially causing an incorrect array index orArrayIndexOutOfBoundsException.Given that
fFieldArray.lengthis bounded byint, values ≥Integer.MAX_VALUEshould fail the bounds check in practice, but the logic is fragile. Consider usingMath.toIntExact()for safer conversion.Suggested fix
- fDeclarationToPopulate = fFieldArray[(tagValue.intValue())]; + fDeclarationToPopulate = fFieldArray[Math.toIntExact(tagValue)];ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (2)
43-46: Move validation to constructor for fail-fast behavior.Length bounds checking (lines 69-74) and null-checking
encodingshould be done here rather than deferring failure tocreateDefinition(). This prevents creation of invalid declaration objects and provides clearer error attribution.♻️ Suggested refactor
public StaticLengthStringDeclaration(int length, Charset encoding) { + if (length < 0) { + throw new IllegalArgumentException("Length cannot be negative: " + length); //$NON-NLS-1$ + } + if (length > 1_000_000) { + throw new IllegalArgumentException("Length cannot exceed 1000000: " + length); //$NON-NLS-1$ + } + if (encoding == null) { + throw new IllegalArgumentException("Encoding cannot be null"); //$NON-NLS-1$ + } fLength = length; fEncoding = encoding; }
67-86: Prefer bulk byte reading for efficiency and clarity.The per-byte loop (lines 77-79) can be replaced with
BitBuffer.get(byte[])which handles bulk transfer. Additionally, therawLengthvariable and itslongcast are redundant sincefLengthis already anint.♻️ Suggested refactor
@Override public StringDefinition2 createDefinition(@Nullable IDefinitionScope definitionScope, String fieldName, BitBuffer input) throws CTFException { - long rawLength = fLength; - if (rawLength < 0) { - throw new CTFException("Cannot have a length < 0, declared = " + rawLength); //$NON-NLS-1$ - } - if (rawLength > 1e6) { - throw new CTFException("Cannot have a length > 1000000, declared = " + rawLength); //$NON-NLS-1$ - } - int length = (int) rawLength; - byte[] bytes = new byte[length]; - for (int i = 0; i < length; i++) { - bytes[i] = (byte) input.get(Byte.SIZE, false); - } + byte[] bytes = new byte[fLength]; + input.get(bytes); String value = new String(bytes, fEncoding); int nullIndex = value.indexOf('\0'); if (nullIndex >= 0) { value = value.substring(0, nullIndex); } return new StringDefinition2(this, definitionScope, fieldName, value); }Note: This assumes validation is moved to the constructor as suggested. The
BitBuffer.get(byte[])method performs bulk transfer efficiently.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.java (2)
348-352: Consider null-safety for role parameter.The
setRoleoverride stores the role infRoleswithout checking ifroleis null. Ifsuper.setRole(role)accepts null, this could insert a null key into the HashMap.♻️ Suggested defensive check
@Override public void setRole(String role) { super.setRole(role); - fRoles.put(role, this); + if (role != null) { + fRoles.put(role, this); + } }
422-430: Minor: Javadoc return description is imprecise.The
@returnsays "the role" but should say "the declaration with the specified role" for clarity.📝 Suggested Javadoc fix
/** * Get the child with a role * @param role the role - * @return the role + * @return the declaration with the specified role, or null if not found * @since 5.1 */ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java (1)
202-206: Redundant null/type check.Line 202 checks
memberNode.getFieldClass().isJsonObject(), but lines 203-206 immediately retrievefieldClassElementand check if it's null or not a JSON object again. This is redundant.♻️ Suggested simplification
- } else if (struct instanceof JsonStructureFieldMemberMetadataNode memberNode) { - if (memberNode.getFieldClass().isJsonObject()) { - JsonElement fieldClassElement = memberNode.getFieldClass(); - if (fieldClassElement == null || !fieldClassElement.isJsonObject()) { - throw new ParseException(getClass().getName() + " fieldclass must be a json object."); //$NON-NLS-1$ - } - JsonObject outerFieldClass = fieldClassElement.getAsJsonObject(); + } else if (struct instanceof JsonStructureFieldMemberMetadataNode memberNode) { + JsonElement fieldClassElement = memberNode.getFieldClass(); + if (fieldClassElement == null || !fieldClassElement.isJsonObject()) { + throw new ParseException(getClass().getName() + " fieldclass must be a json object."); //$NON-NLS-1$ + } + JsonObject outerFieldClass = fieldClassElement.getAsJsonObject();ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java (3)
672-697: Binary search optimization is partially effective.The binary search finds the rightmost node with
start <= value, but then the backward linear scan fromlastValidto 0 (line 690) is O(n) in the worst case (e.g., when all intervals start at 0). This negates the benefit of the binary search for overlapping interval queries.Consider either:
- Breaking early in the backward loop when
node.startis far enough belowvaluethat no more overlaps are possible- Using an interval tree data structure (augmented BST with max endpoint tracking)
For typical CTF2 enumeration mappings with non-overlapping ranges, this may be acceptable.
170-179: Consider making IntervalNode fields final.The
start,end, andnamefields are set only in the constructor and never modified. Marking themfinalwould make the immutability explicit.private static class IntervalNode { - final long start, end; - final String name; + private final long start; + private final long end; + private final String name; IntervalNode(long start, long end, String name) {Note: The fields are already marked
finalon a single line - just suggesting splitting for clarity.
140-143: Deprecation message could be clearer.The deprecation notice says to use
createDeclaration(...)but doesn't explain why or what specific signature to use. Consider adding@deprecatedJavadoc with the specific factory method signature./** * Unsigned 5 bit int, used for event headers - * @deprecated use the {@link #createDeclaration(int, boolean, int, ByteOrder, Encoding, String, long, String, Map)} instead + * @deprecated Use {@link #createDeclaration(int, boolean, int, ByteOrder, Encoding, String, long, String)} + * or the Map overload to create new IntegerDeclaration instances. + * This constant is deprecated to avoid confusion with dynamic declaration creation. */ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.java (2)
155-160: Minor inefficiency: redundantgetFieldClass()call.Line 160 calls
member.getFieldClass().getAsJsonObject()again after already validating and extracting it tofieldClassElementon lines 156-159. Consider reusingfieldClassElement:♻️ Suggested fix
if (fieldClassElement == null || !fieldClassElement.isJsonObject()) { throw new ParseException(getClass().getName() + " fieldclass must be a json object."); //$NON-NLS-1$ } - JsonObject fieldclass = member.getFieldClass().getAsJsonObject(); + JsonObject fieldclass = fieldClassElement.getAsJsonObject();
267-270: LGTM with minor nit: unnecessary blank line.The updated
createDeclarationcall with(int) sizeas the first parameter aligns with the updated method signature.Consider removing the blank line 268 for consistency with the surrounding code.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java (1)
80-104: UnusedParamclass.The
Paramclass is defined but never used in theparsemethod. Consider either:
- Removing it if not needed, or
- Using it for trace context if required for future enhancements
This appears to follow the pattern of similar parsers for consistency. If kept for consistency, consider adding a brief comment explaining the intent.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (2)
130-135: Minor inefficiency: redundantgetFieldClass()call.Same issue as in
IntegerDeclarationParser- line 135 callsmember.getFieldClass().getAsJsonObject()again after already validating it on lines 131-134.♻️ Suggested fix
if (fieldClassElement == null || !fieldClassElement.isJsonObject()) { throw new ParseException(getClass().getName() + " fieldclass must be a json object."); //$NON-NLS-1$ } - JsonObject fieldclass = member.getFieldClass().getAsJsonObject(); + JsonObject fieldclass = fieldClassElement.getAsJsonObject();
159-161: Consider passingmemberinstead offloatingPointfor clarity.While
floatingPointandmemberreference the same object in this branch, passingmemberwould be more consistent with the pattern and make the code clearer.if (fieldclass.has(JsonMetadataStrings.ALIGNMENT)) { - alignment = AlignmentParser.INSTANCE.parse(floatingPoint, null); + alignment = AlignmentParser.INSTANCE.parse(member, null); }ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java (1)
65-66: Consider using imports for cleaner code.The fully qualified class names work but reduce readability. Consider importing the classes.
♻️ Suggested refactor
Add imports:
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.integer.IntegerDeclarationParser;Then simplify the usage:
- IntegerDeclaration result = org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.integer.IntegerDeclarationParser.INSTANCE.parse(node, - new org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.integer.IntegerDeclarationParser.Param(trace)); + IntegerDeclaration result = IntegerDeclarationParser.INSTANCE.parse(node, + new IntegerDeclarationParser.Param(trace));
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (32)
common/org.eclipse.tracecompass.common.core.tests/META-INF/MANIFEST.MFcommon/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.javactf/org.eclipse.tracecompass.ctf.core.tests/META-INF/MANIFEST.MFctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.javactf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.javactf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.javactf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/BlobDeclaration.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDefinition.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/ScopedDefinition.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDefinition.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/AlignmentParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicarray/DynamicLengthArrayParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.javactf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.javactf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventField.javactf/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/TestInvalidCtfTrace.java
🚧 Files skipped from review as they are similar to previous changes (13)
- common/org.eclipse.tracecompass.common.core.tests/src/org/eclipse/tracecompass/common/core/tests/log/LoggerTest.java
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/TypeAliasParserTest.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDefinition.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructDeclarationParser.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/TypeAliasParser.java
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/FloatDeclarationParserTest.java
- ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/JsonTraceMetadataNodeTest.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java
- ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/event/CtfTmfEventField.java
- common/org.eclipse.tracecompass.common.core.tests/META-INF/MANIFEST.MF
- ctf/org.eclipse.tracecompass.tmf.ctf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ctf/ui/swtbot/tests/TestInvalidCtfTrace.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticarray/StaticLengthArrayParser.java
- ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/BlobDeclaration.java
🧰 Additional context used
🧬 Code graph analysis (6)
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java (2)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.java (1)
IntegerDeclarationParser(81-275)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (3)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/io/BitBuffer.java (1)
BitBuffer(32-743)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/Declaration.java (1)
Declaration(30-90)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StringDefinition2.java (1)
StringDefinition2(22-72)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.java (1)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/AlignmentParser.java (1)
AlignmentParser(56-142)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java (3)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMetadataNode.java (1)
JsonStructureFieldMetadataNode(29-89)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-269)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java (3)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (1)
StaticLengthStringDeclaration(30-111)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-269)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/AlignmentParser.java (3)
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMemberMetadataNode.java (1)
JsonStructureFieldMemberMetadataNode(31-115)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonStructureFieldMetadataNode.java (1)
JsonStructureFieldMetadataNode(29-89)ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
JsonMetadataStrings(25-269)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build / build
- GitHub Check: build / build
- GitHub Check: build / build
🔇 Additional comments (24)
ctf/org.eclipse.tracecompass.ctf.core.tests/META-INF/MANIFEST.MF (1)
26-31: LGTM!The
com.google.gsonimport is correctly added to support the new Gson-based JSON parsing for CTF 2 traces. The formatting follows the existing pattern, and omitting the version constraint is consistent with howcom.google.common.collectis handled in the same manifest.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/metadata/DeclarationScope.java (1)
175-182: LGTM! Good defensive improvements to type registration.The null/empty name guard for anonymous types and the idempotent registration pattern using
Objects.equals()are solid improvements. This aligns with the existingregisterVariant()pattern and supports CTF 2 metadata parsing where the same type definition may be encountered multiple times.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java (1)
103-110: LGTM!The
isBinaryEquivalentimplementation correctly compares both length and encoding. UsingObjects.equal()for the encoding comparison handles null safety appropriately.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/JsonTraceMetadataNode.java (1)
19-19: LGTM! Clean migration from org.json to Gson.The type change from
JSONObjecttoJsonObjectis consistent across the import, field declaration, and getter method. This aligns with the PR's broader adoption of Gson for JSON-based metadata handling.Also applies to: 33-33, 65-66
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.java (2)
186-225: LGTM! Well-structured lookup with proper loop prevention.The enhanced
lookupDefinitioncorrectly:
- Handles null checks and self-exclusion (lines 188-190)
- Uses pattern matching for cleaner instanceof checks (line 206)
- Supports role-based lookup via
getDeclaration().getRole()(line 208)- Properly passes
thiswhen delegating to parent scope (line 222), preventing infinite recursion
236-264: LGTM! Role-based lookup with proper nested structure traversal.The
lookupRolemethod provides a clean way to find definitions by their role, with:
- Null safety for the role parameter
- Direct child lookup followed by recursive search
- Proper handling of nested
StructDefinitionandVariantDefinitiontypesctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.java (2)
59-60: LGTM! Role-based declaration storage.The new
fRolesmap enables efficient role-based lookup of child declarations, complementing the existing name-based field access.
216-219: Good role population logic.Correctly stores declarations by role when a field with a non-null, non-empty role is added.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDefinition.java (4)
45-69: LGTM! New constructor for flexible tag types.The new constructor properly accepts
SimpleDatatypeDefinitionand follows the same initialization pattern as the existingEnumDefinitionconstructor. The@since 5.1annotation correctly documents the API addition.
138-164: LGTM! Enhanced lookup with role-based resolution.The enhanced
lookupDefinitioncorrectly:
- Maintains null-safety (line 140-142)
- Adds role-based lookup for
fTagDefandfDefinition(lines 146-151)- Properly delegates to child
ScopedDefinitionwith exclusion (lines 152-157)- Passes
thiswhen delegating to parentStructDefinitionto prevent infinite loops (line 161)
166-192: LGTM! Overload maintains consistent lookup semantics.The new overload correctly propagates the
definitionToExcludeparameter through the lookup chain and mirrors the single-argument version's behavior.
39-39: Field type broadened to support non-enum tags.Changing
fTagDeffromEnumDefinitiontoSimpleDatatypeDefinitionenables more flexible tag types while maintaining backward compatibility.EnumDefinitionextendsSimpleDatatypeDefinition, so existing code using theEnumDefinitionconstructor remains compatible.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java (1)
16-268: LGTM overall for the new constants.The new string constants for CTF2 field classes (floating point, strings, arrays, encoding, alignment, byte order) are well-organized and properly documented with Javadoc. These provide a clean centralized location for JSON metadata keys.
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/AlignmentParser.java (1)
99-106: LGTM for JsonStructureFieldMetadataNode handling.The pattern matching with
instanceofis clean and properly validates alignment before returning.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java (1)
193-200: LGTM for JsonStructureFieldMetadataNode branch.The handling for
JsonStructureFieldMetadataNodecorrectly extracts minimum alignment and sets up the struct body when member classes are present.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/dynamicarray/DynamicLengthArrayParser.java (1)
44-80: LGTM for overall parser structure.The parser follows the established singleton pattern with a
Paramclass, validates input types appropriately, and correctly delegates element type resolution toTypeAliasParser. The error messages are descriptive and helpful for debugging.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/IntegerDeclaration.java (2)
408-424: LGTM for setMappings and buildIntervalTree.The implementation correctly clears existing mappings before adding new ones, and builds the interval tree sorted by start position for efficient lookup.
586-588: LGTM for the refactoring changes.
- Using
Long.SIZEinstead of a magic number improves readability- Including
fMappingsandgetRole()inhashCode/equalsensures proper equality semantics for the new mapping featureAlso applies to: 604-604, 631-636
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/integer/IntegerDeclarationParser.java (1)
198-200: LGTM!The delegation to
AlignmentParser.INSTANCE.parse(member, null)is correct. TheAlignmentParserhandlesJsonStructureFieldMemberMetadataNodeand extracts alignment from the field class internally.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java (1)
72-77: LGTM!The encoding handling with fallback to UTF-8 and the
StaticLengthStringDeclarationconstruction are correct.ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/floatingpoint/FloatDeclarationParser.java (3)
137-152: LGTM!The IEEE 754 size mappings are correct:
- 32-bit (single precision): exponent=8, mantissa=24
- 64-bit (double precision): exponent=11, mantissa=53
The TODO for 16-bit (half precision) and extended precision formats is appropriately documented.
162-199: LGTM!The legacy (non-JSON) parsing path is correctly preserved within the else branch.
200-211: LGTM!The final size validation and default alignment handling are correct.
ctf/org.eclipse.tracecompass.ctf.core.tests/src/org/eclipse/tracecompass/ctf/core/tests/types/CTF2IntegrationTest.java (1)
37-74: LGTM!Good integration test that validates the JSON-based integer parsing with mappings. The test properly:
- Constructs the JSON structure matching CTF2 format
- Verifies the parsed result has correct length, mappings count, and mapping keys
...racecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/ScopedDefinition.java
Show resolved
Hide resolved
| private final Map<String, IDeclaration> fFields = new HashMap<>(); | ||
| private IDeclaration[] fFieldArray = new IDeclaration[0]; | ||
| private IDeclaration fDeclarationToPopulate; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Race condition: fDeclarationToPopulate should be a local variable.
fDeclarationToPopulate is an instance field that gets assigned during createDefinition (lines 133, 138, 150). If two threads call createDefinition concurrently on the same VariantDeclaration instance, they will overwrite each other's value, causing incorrect field resolution.
This should be refactored to a local variable within createDefinition.
Additionally, changing from a synchronized HashMap to a plain HashMap removes thread-safety guarantees. Verify whether concurrent access to this class is expected.
Proposed fix for the race condition
- private IDeclaration fDeclarationToPopulate;Then in createDefinition, declare it as a local variable:
IDeclaration declarationToPopulate = null;
// ... use declarationToPopulate instead of fDeclarationToPopulate throughout the method🤖 Prompt for AI Agents
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.java
around lines 47 - 49, The field fDeclarationToPopulate is used only within
createDefinition and causes a race when multiple threads call createDefinition
on the same VariantDeclaration; make fDeclarationToPopulate a local variable
inside createDefinition (replace uses of fDeclarationToPopulate with a local
IDeclaration declarationToPopulate) and update all assignments and references in
that method accordingly; also review the change from a synchronized map to a
plain HashMap for fFields and, if concurrent access is expected, restore
thread-safety (e.g., use Collections.synchronizedMap, ConcurrentHashMap, or
synchronize access around fFields) to avoid concurrent modification issues.
| if (def instanceof IntegerDefinition) { | ||
| tagDef = (SimpleDatatypeDefinition) def; | ||
| Long tagValue = ((IntegerDefinition) tagDef).getIntegerValue(); | ||
| String mappings = ((IntegerDefinition) tagDef).getMappings(); | ||
| if (mappings != null) { | ||
| fDeclarationToPopulate = fFields.get(mappings); | ||
| } else if (tagValue != null) { | ||
| if (tagValue < 0 || tagValue >= fFieldArray.length) { | ||
| throw new CTFException("Unknown value of " + tagValue + " for the variant " + toString()); //$NON-NLS-1$ //$NON-NLS-2$ | ||
| } | ||
| fDeclarationToPopulate = fFieldArray[(tagValue.intValue())]; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing handling when both mappings and tagValue are null.
If def is an IntegerDefinition but both getMappings() returns null and getIntegerValue() returns null, then fDeclarationToPopulate is never assigned in this branch. The code falls through to line 152 which throws an exception with "Unknown enum selector" — a misleading message for an integer-based tag.
Consider adding explicit handling or an appropriate error message for this edge case.
Suggested fix
if (mappings != null) {
fDeclarationToPopulate = fFields.get(mappings);
} else if (tagValue != null) {
if (tagValue < 0 || tagValue >= fFieldArray.length) {
throw new CTFException("Unknown value of " + tagValue + " for the variant " + toString()); //$NON-NLS-1$ //$NON-NLS-2$
}
fDeclarationToPopulate = fFieldArray[(tagValue.intValue())];
+ } else {
+ throw new CTFException("Integer tag has no value or mappings for variant " + toString()); //$NON-NLS-1$
}🤖 Prompt for AI Agents
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.java
around lines 128 - 139, The IntegerDefinition branch in VariantDeclaration
(where def instanceof IntegerDefinition, tagDef, getMappings(),
getIntegerValue()) doesn't handle the case where both mappings and tagValue are
null, so fDeclarationToPopulate can remain unset and later produce a misleading
"Unknown enum selector" error; update that branch to explicitly detect
mappings==null && tagValue==null and throw a CTFException with a clear message
(e.g., "Missing integer tag value or mappings for variant " + toString()) or
otherwise set fDeclarationToPopulate to a sensible default before falling
through, ensuring the exception refers to an integer-based tag and using the
existing identifiers tagDef, fDeclarationToPopulate, getMappings(), and
getIntegerValue().
| public void addField(String fieldTag, IDeclaration declaration) { | ||
| fFields.put(fieldTag, declaration); | ||
| int size = fFields.size(); | ||
| fFieldArray = Arrays.copyOf(fFieldArray, size); | ||
| fFieldArray[size - 1] = declaration; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: fFieldArray becomes inconsistent when a field is overwritten.
If addField is called with a fieldTag that already exists in fFields, HashMap.put() replaces the value but fFields.size() remains unchanged. However, the code still appends to fFieldArray, causing:
fFieldArraygrows larger thanfFields.size()- The old declaration remains in
fFieldArrayat its original index - Index-based lookups in
createDefinitionmay return stale declarations
Example sequence:
addField("a", decl1); // fFields={"a":decl1}, fFieldArray=[decl1]
addField("b", decl2); // fFields={"a":decl1,"b":decl2}, fFieldArray=[decl1,decl2]
addField("a", decl3); // fFields={"a":decl3,"b":decl2}, fFieldArray=[decl1,decl2,decl3]
// Index 0 lookup returns decl1, but fFields.get("a") returns decl3Suggested fix
public void addField(String fieldTag, IDeclaration declaration) {
+ boolean isNewField = !fFields.containsKey(fieldTag);
fFields.put(fieldTag, declaration);
- int size = fFields.size();
- fFieldArray = Arrays.copyOf(fFieldArray, size);
- fFieldArray[size - 1] = declaration;
+ if (isNewField) {
+ int size = fFields.size();
+ fFieldArray = Arrays.copyOf(fFieldArray, size);
+ fFieldArray[size - 1] = declaration;
+ }
}Note: This fix only handles new fields. If overwriting is expected, you'll need to track indices or use a LinkedHashMap to maintain consistent ordering.
🤖 Prompt for AI Agents
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/VariantDeclaration.java
around lines 168 - 173, addField currently always appends to fFieldArray after
fFields.put, so overwriting an existing fieldTag makes fFieldArray inconsistent
with fFields and breaks index-based lookups in createDefinition; change addField
to detect whether the key already existed (e.g. check
fFields.containsKey(fieldTag) or capture the previous value from fFields.put)
and if it did, find and replace the existing entry in fFieldArray (or rebuild
fFieldArray from fFields.values()) instead of blindly growing the array; ensure
createDefinition continues to rely on the corrected fFieldArray ordering.
| } else if (tree instanceof JsonStructureFieldMemberMetadataNode structTree) { | ||
| JsonElement fieldClassElement = structTree.getFieldClass(); | ||
| if (fieldClassElement == null || !fieldClassElement.isJsonObject()) { | ||
| throw new ParseException(getClass().getName() + " fieldclass must be a json object."); //$NON-NLS-1$ | ||
| } | ||
| JsonObject fieldclass = fieldClassElement.getAsJsonObject(); | ||
| if (fieldclass.has(JsonMetadataStrings.ALIGNMENT)) { | ||
| JsonElement alignmentElement = fieldclass.get(JsonMetadataStrings.ALIGNMENT); | ||
| if (alignmentElement == null || !alignmentElement.isJsonPrimitive()) { | ||
| throw new ParseException(INVALID_VALUE_FOR_ALIGNMENT + " : " //$NON-NLS-1$ | ||
| + alignmentElement); | ||
| } | ||
| long alignment = alignmentElement.getAsLong(); | ||
| if (!isValidAlignment(alignment)) { | ||
| throw new ParseException(INVALID_VALUE_FOR_ALIGNMENT + " : " //$NON-NLS-1$ | ||
| + alignment); | ||
| } | ||
| return alignment; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing return for optional alignment case.
When parsing a JsonStructureFieldMemberMetadataNode, if the ALIGNMENT field is not present in the field class, the method falls through to throw a ParseException at line 128. However, alignment may be optional in CTF2 metadata, with a default value (typically 1 or 8 depending on context).
Consider returning a default alignment when the field is absent, similar to how JsonStructureFieldMetadataNode handles minimum alignment:
if (fieldclass.has(JsonMetadataStrings.ALIGNMENT)) {
JsonElement alignmentElement = fieldclass.get(JsonMetadataStrings.ALIGNMENT);
if (alignmentElement == null || !alignmentElement.isJsonPrimitive()) {
throw new ParseException(INVALID_VALUE_FOR_ALIGNMENT + " : " //$NON-NLS-1$
+ alignmentElement);
}
long alignment = alignmentElement.getAsLong();
if (!isValidAlignment(alignment)) {
throw new ParseException(INVALID_VALUE_FOR_ALIGNMENT + " : " //$NON-NLS-1$
+ alignment);
}
return alignment;
}
+ // Return default alignment when not specified
+ return 1L;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| } else if (tree instanceof JsonStructureFieldMemberMetadataNode structTree) { | |
| JsonElement fieldClassElement = structTree.getFieldClass(); | |
| if (fieldClassElement == null || !fieldClassElement.isJsonObject()) { | |
| throw new ParseException(getClass().getName() + " fieldclass must be a json object."); //$NON-NLS-1$ | |
| } | |
| JsonObject fieldclass = fieldClassElement.getAsJsonObject(); | |
| if (fieldclass.has(JsonMetadataStrings.ALIGNMENT)) { | |
| JsonElement alignmentElement = fieldclass.get(JsonMetadataStrings.ALIGNMENT); | |
| if (alignmentElement == null || !alignmentElement.isJsonPrimitive()) { | |
| throw new ParseException(INVALID_VALUE_FOR_ALIGNMENT + " : " //$NON-NLS-1$ | |
| + alignmentElement); | |
| } | |
| long alignment = alignmentElement.getAsLong(); | |
| if (!isValidAlignment(alignment)) { | |
| throw new ParseException(INVALID_VALUE_FOR_ALIGNMENT + " : " //$NON-NLS-1$ | |
| + alignment); | |
| } | |
| return alignment; | |
| } | |
| } | |
| } else if (tree instanceof JsonStructureFieldMemberMetadataNode structTree) { | |
| JsonElement fieldClassElement = structTree.getFieldClass(); | |
| if (fieldClassElement == null || !fieldClassElement.isJsonObject()) { | |
| throw new ParseException(getClass().getName() + " fieldclass must be a json object."); //$NON-NLS-1$ | |
| } | |
| JsonObject fieldclass = fieldClassElement.getAsJsonObject(); | |
| if (fieldclass.has(JsonMetadataStrings.ALIGNMENT)) { | |
| JsonElement alignmentElement = fieldclass.get(JsonMetadataStrings.ALIGNMENT); | |
| if (alignmentElement == null || !alignmentElement.isJsonPrimitive()) { | |
| throw new ParseException(INVALID_VALUE_FOR_ALIGNMENT + " : " //$NON-NLS-1$ | |
| alignmentElement); | |
| } | |
| long alignment = alignmentElement.getAsLong(); | |
| if (!isValidAlignment(alignment)) { | |
| throw new ParseException(INVALID_VALUE_FOR_ALIGNMENT + " : " //$NON-NLS-1$ | |
| alignment); | |
| } | |
| return alignment; | |
| } | |
| // Return default alignment when not specified | |
| return 1L; | |
| } |
🤖 Prompt for AI Agents
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/AlignmentParser.java
around lines 107 - 126, In the JsonStructureFieldMemberMetadataNode branch of
AlignmentParser (the else-if handling JsonStructureFieldMemberMetadataNode), add
a return of the default alignment when the fieldclass does not contain
JsonMetadataStrings.ALIGNMENT instead of falling through to the ParseException;
specifically: if fieldclass.has(JsonMetadataStrings.ALIGNMENT) remains as-is for
parsing/validation, but after that conditional return a sensible default (match
the default used by JsonStructureFieldMetadataNode — e.g., 1) so optional
alignment is handled correctly.
| if (!(node instanceof JsonStructureFieldMemberMetadataNode)) { | ||
| throw new ParseException("Dynamic-length string only supported in JSON metadata"); //$NON-NLS-1$ | ||
| } | ||
|
|
||
| JsonStructureFieldMemberMetadataNode member = (JsonStructureFieldMemberMetadataNode) node; | ||
| JsonElement fieldClassElement = member.getFieldClass(); | ||
| if (fieldClassElement == null || !fieldClassElement.isJsonObject()) { | ||
| throw new ParseException(getClass().getName() + " fieldclass must be a json object."); //$NON-NLS-1$ | ||
| } | ||
| JsonObject fieldClass = fieldClassElement.getAsJsonObject(); | ||
| JsonElement lengthField = fieldClass.get(JsonMetadataStrings.LENGTH); | ||
| if (lengthField == null) { | ||
| throw new ParseException("Dynamic-length string requires length-field-location property"); //$NON-NLS-1$ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix error messages: reference static-length, not dynamic-length.
The error messages incorrectly reference "Dynamic-length string" but this is a static-length string parser.
📝 Suggested fix
if (!(node instanceof JsonStructureFieldMemberMetadataNode)) {
- throw new ParseException("Dynamic-length string only supported in JSON metadata"); //$NON-NLS-1$
+ throw new ParseException("Static-length string only supported in JSON metadata"); //$NON-NLS-1$
}
// ...
if (lengthField == null) {
- throw new ParseException("Dynamic-length string requires length-field-location property"); //$NON-NLS-1$
+ throw new ParseException("Static-length string requires length property"); //$NON-NLS-1$
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (!(node instanceof JsonStructureFieldMemberMetadataNode)) { | |
| throw new ParseException("Dynamic-length string only supported in JSON metadata"); //$NON-NLS-1$ | |
| } | |
| JsonStructureFieldMemberMetadataNode member = (JsonStructureFieldMemberMetadataNode) node; | |
| JsonElement fieldClassElement = member.getFieldClass(); | |
| if (fieldClassElement == null || !fieldClassElement.isJsonObject()) { | |
| throw new ParseException(getClass().getName() + " fieldclass must be a json object."); //$NON-NLS-1$ | |
| } | |
| JsonObject fieldClass = fieldClassElement.getAsJsonObject(); | |
| JsonElement lengthField = fieldClass.get(JsonMetadataStrings.LENGTH); | |
| if (lengthField == null) { | |
| throw new ParseException("Dynamic-length string requires length-field-location property"); //$NON-NLS-1$ | |
| if (!(node instanceof JsonStructureFieldMemberMetadataNode)) { | |
| throw new ParseException("Static-length string only supported in JSON metadata"); //$NON-NLS-1$ | |
| } | |
| JsonStructureFieldMemberMetadataNode member = (JsonStructureFieldMemberMetadataNode) node; | |
| JsonElement fieldClassElement = member.getFieldClass(); | |
| if (fieldClassElement == null || !fieldClassElement.isJsonObject()) { | |
| throw new ParseException(getClass().getName() + " fieldclass must be a json object."); //$NON-NLS-1$ | |
| } | |
| JsonObject fieldClass = fieldClassElement.getAsJsonObject(); | |
| JsonElement lengthField = fieldClass.get(JsonMetadataStrings.LENGTH); | |
| if (lengthField == null) { | |
| throw new ParseException("Static-length string requires length property"); //$NON-NLS-1$ |
🤖 Prompt for AI Agents
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/staticstring/StaticLengthStringParser.java
around lines 58 - 70, The thrown ParseException messages in
StaticLengthStringParser reference "Dynamic-length string" incorrectly; update
the three error strings used around the node and fieldClass checks (the messages
thrown when node is not a JsonStructureFieldMemberMetadataNode, when
fieldClassElement is null or not a JsonObject, and when lengthField is null) to
say "Static-length string" (e.g., "Static-length string only supported in JSON
metadata", "Static-length string fieldclass must be a json object.", and
"Static-length string requires length-field-location property") so the messages
correctly reflect the StaticLengthStringParser class.
| } else if (struct instanceof JsonStructureFieldMemberMetadataNode memberNode) { | ||
| if (memberNode.getFieldClass().isJsonObject()) { | ||
| JsonElement fieldClassElement = memberNode.getFieldClass(); | ||
| if (fieldClassElement == null || !fieldClassElement.isJsonObject()) { | ||
| throw new ParseException(getClass().getName() + " fieldclass must be a json object."); //$NON-NLS-1$ | ||
| } | ||
| JsonObject outerFieldClass = fieldClassElement.getAsJsonObject(); | ||
| JsonElement minimumAlignment = outerFieldClass.get(JsonMetadataStrings.MINIMUM_ALIGNMENT); | ||
| if (minimumAlignment != null) { | ||
| structAlign = minimumAlignment.getAsLong(); | ||
| } | ||
| JsonElement memberClasses = outerFieldClass.get(JsonMetadataStrings.MEMBER_CLASSES); | ||
| if (memberClasses != null && memberClasses.isJsonArray()) { | ||
| hasBody = true; | ||
| for (JsonElement memberElement : memberClasses.getAsJsonArray()) { | ||
| if (memberElement.isJsonObject()) { | ||
| String name = memberElement.getAsJsonObject().get(JsonMetadataStrings.NAME).getAsString(); | ||
| JsonElement fieldClass = memberElement.getAsJsonObject().get(JsonMetadataStrings.FIELD_CLASS); | ||
| JsonStructureFieldMemberMetadataNode childNode = new JsonStructureFieldMemberMetadataNode(memberNode, "", "", name, fieldClass.getAsJsonObject()); //$NON-NLS-1$ //$NON-NLS-2$ | ||
| memberNode.addChild(childNode); | ||
| } | ||
| } | ||
| structBody = memberNode; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing null checks for required JSON properties.
The code assumes NAME and FIELD_CLASS properties always exist in each member element without validation. This could cause NullPointerException if either property is missing from malformed metadata.
🔧 Suggested fix with null checks
if (memberClasses != null && memberClasses.isJsonArray()) {
hasBody = true;
for (JsonElement memberElement : memberClasses.getAsJsonArray()) {
if (memberElement.isJsonObject()) {
- String name = memberElement.getAsJsonObject().get(JsonMetadataStrings.NAME).getAsString();
- JsonElement fieldClass = memberElement.getAsJsonObject().get(JsonMetadataStrings.FIELD_CLASS);
- JsonStructureFieldMemberMetadataNode childNode = new JsonStructureFieldMemberMetadataNode(memberNode, "", "", name, fieldClass.getAsJsonObject()); //$NON-NLS-1$ //$NON-NLS-2$
+ JsonObject memberObj = memberElement.getAsJsonObject();
+ JsonElement nameElement = memberObj.get(JsonMetadataStrings.NAME);
+ JsonElement fieldClass = memberObj.get(JsonMetadataStrings.FIELD_CLASS);
+ if (nameElement == null || fieldClass == null || !fieldClass.isJsonObject()) {
+ throw new ParseException("Member class requires 'name' and 'field-class' properties"); //$NON-NLS-1$
+ }
+ String name = nameElement.getAsString();
+ JsonStructureFieldMemberMetadataNode childNode = new JsonStructureFieldMemberMetadataNode(memberNode, "", "", name, fieldClass.getAsJsonObject()); //$NON-NLS-1$ //$NON-NLS-2$
memberNode.addChild(childNode);
}
}🤖 Prompt for AI Agents
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/tsdl/struct/StructParser.java
around lines 201 - 225, The loop that builds child
JsonStructureFieldMemberMetadataNode instances assumes each memberElement
contains NAME and FIELD_CLASS; add null checks for
memberElement.getAsJsonObject().get(JsonMetadataStrings.NAME) and
.get(JsonMetadataStrings.FIELD_CLASS) and for fieldClass.isJsonObject() before
calling getAsString()/getAsJsonObject(); if any required property is missing or
of the wrong type, throw a ParseException with a clear message; update the
construction site of JsonStructureFieldMemberMetadataNode (in the loop over
memberClasses) to only create and add childNode when those validations pass.
...rc/org/eclipse/tracecompass/internal/ctf/core/event/types/StaticLengthStringDeclaration.java
Show resolved
Hide resolved
| /** | ||
| * Type string for a structure field class | ||
| */ | ||
| public static final String PATH = "path"; //$NON-NLS-1$ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect Javadoc for PATH constant.
The Javadoc comment says "Type string for a structure field class" but PATH is used for field location paths, not structure field classes. This appears to be a copy-paste error from the STRUCTURE constant below it.
- /**
- * Type string for a structure field class
- */
+ /**
+ * Field string for the path property in field locations
+ */
public static final String PATH = "path"; //$NON-NLS-1$📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /** | |
| * Type string for a structure field class | |
| */ | |
| public static final String PATH = "path"; //$NON-NLS-1$ | |
| /** | |
| * Field string for the path property in field locations | |
| */ | |
| public static final String PATH = "path"; //$NON-NLS-1$ |
🤖 Prompt for AI Agents
In
@ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/utils/JsonMetadataStrings.java
around lines 203 - 206, The Javadoc for the PATH constant is incorrect (it
currently reads "Type string for a structure field class"); update the comment
above the public static final String PATH to accurately describe its purpose as
the JSON key for field location paths (used to represent a field's location
path), not a structure field class—use wording consistent with the STRUCTURE
constant comment to avoid the copy/paste error.
| public static final Map<String, Charset> ENCODINGS = Map.of("utf-8",StandardCharsets.UTF_8, //$NON-NLS-1$ | ||
| "utf-16be",StandardCharsets.UTF_16BE,"utf-16le",StandardCharsets.UTF_16LE, //$NON-NLS-1$ //$NON-NLS-2$ | ||
| "utf-32be", Charset.forName("UTF-32BE"),"utf-32le", Charset.forName("UTF-32LE")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
Java UTF-32 charset support specification mandatory optional
💡 Result:
Short answer: Historically UTF‑32 was optional; recent Java SE docs list UTF‑32 (and UTF‑32BE/LE and BOM variants) among the standard charsets that implementations must support. See the Charset API in older JDK docs (required set did not include UTF‑32) vs current API/docs which include UTF‑32. [1][2]
Sources:
- Charset API (Java SE 11) — standard required charsets (no UTF‑32 listed). [1]
- Charset API (Java SE 24 / 24+ JDK docs) — lists UTF‑32, UTF‑32BE and UTF‑32LE as standard charsets required of every implementation. [2]
References:
[1] java.nio.charset.Charset (Java SE 11) — Standard charsets.
[2] java.nio.charset.Charset (Java SE 24 / JDK 24) — Standard charsets (includes UTF‑32 variants).
🌐 Web query:
Charset.forName UTF-32BE UTF-32LE UnsupportedCharsetException Java implementations
💡 Result:
Short answer: Charset.forName("UTF-32BE") and Charset.forName("UTF-32LE") will work on modern Oracle/OpenJDK builds (they are listed as standard/available encodings), but they can throw UnsupportedCharsetException on older JVMs where UTF-32 charsets were not provided. You should check at runtime with Charset.isSupported(...) or catch UnsupportedCharsetException if you must run on varied/older JREs. [1][2][3]
References
- Java Charset spec / list of standard charsets (shows UTF-32BE/UTF-32LE). [1]
- Oracle "Supported Encodings" page listing UTF-32BE/UTF-32LE entries. [2]
- OpenJDK bug/CSR showing UTF-32 charsets were added to the JDK (track/fix). [3]
Links:
[1] Oracle Charset API (Java SE).
[2] Oracle Supported Encodings (JDK 22/21 pages).
[3] OpenJDK bug JDK-8310047 (UTF-32 charset addition).
🌐 Web query:
Java character encoding mandatory charsets specification StandardCharsets
💡 Result:
Java requires that every Java platform implementation support these standard charsets (available as constants in java.nio.charset.StandardCharsets):
- US-ASCII
- ISO-8859-1
- UTF-8
- UTF-16BE
- UTF-16LE
- UTF-16
(These are the "standard charsets" guaranteed on every implementation; see StandardCharsets and Charset documentation.) [1][2]
Sources:
[1] Java SE Charset — standard charsets list (Oracle Javadoc).
[2] java.nio.charset.StandardCharsets (Oracle Javadoc).
Ensure UTF-32 charset availability before class loading or add defensive handling.
Charset.forName("UTF-32BE") and Charset.forName("UTF-32LE") may throw UnsupportedCharsetException on Java SE 11 and earlier, where UTF-32 support is not guaranteed by the specification. While Java SE 24+ mandates UTF-32 support, this code's static initializer will cause class loading failure if the charset is unavailable on older JVMs.
Consider either:
- Adding a static initializer block with try-catch and fallback
- Using lazy initialization instead of static initializer
- Documenting the minimum Java version requirement (Java SE 24+, or check for older versions)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a problem for future iterations. I am willing to bet nobody will use utf-32
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MatthewKhouzam, understood! That's a reasonable pragmatic choice given the low likelihood of UTF-32 usage in practice. The static initialization will work fine on modern JVMs, and if it becomes an issue in the future, you can address it then.
Thanks for the clarification!
What it does
How to test
Try to open eclipse-tracecompass/tracecompass-test-traces#12 the traces there
Follow-ups
Review checklist
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.