OMG IDL 4.2 — Spec Coverage
Spec: OMG Interface Definition Language 4.2 — formal/18-01-05 (March 2018, 132 pages) →
Item-by-item audit against the spec; every requirement with a spec
citation, a repo path, a test path and a status (done / partial /
open / n/a).
Context: The IDL front end is spread across six crates:
crates/idl-cst/· docs.rs — lexer and CST: tokens, trivia, spans, tree.crates/idl-parse/· docs.rs — preprocessor per ISO/IEC 14882:2003, parser, declarations, type specs, vendor dialects.crates/ast/· docs.rs — the model: nodes, facets, builtin annotations, profiles, resolve.crates/idl-lower/· docs.rs — lowering, annotations, scope, validation, repository ids.crates/idl-compose/· docs.rs — the stage that joins front end and model and detects the inadmissible cycle.crates/ccm/· docs.rs — the IDL→IDL rewrite of the CCM constructs;crates/corba-codegen/— repository ids, stubs, skeletons, Annex A1 traits.
tools/idlc/ is the compiler driver. The full negative list on the
grammar (357 probes, nine columns per subcommand) stands in
idl-4.2.gaps.en.md; this page is the positive
list.
Open items: see idl-4.2.open.en.md.
§7.1 Overview
§7.1 Overview
Spec: §7.1, p. 13–14 — the clause introduces the components of an IDL specification and establishes that the rules are grouped into atomic building blocks which are only used in a profile.
Repo: crates/idl-parse/src/, crates/idl-lower/src/,
crates/idl-cst/src/.
Tests: —
Status: n/a (informative) — §7.1 structures the specification and
sets no requirement on an implementation. The building blocks are audited
one by one in §7.4.x.
§7.2 Lexical Conventions
§7.2.1 Tokens
Spec: §7.2.1, p. 17 — “There are five kinds of tokens: identifiers, keywords, literals, operators, and other separators”; “the next token is taken to be the longest string of characters that could possibly constitute a token”.
Repo: crates/idl-cst/src/token.rs::TokenKind,
crates/idl-cst/src/lex.rs::next_token.
Tests: crates/idl-cst/tests/lexer.rs::an_empty_file_yields_one_eof_token,
crates/idl-cst/tests/lexer.rs::every_byte_is_reachable_for_a_realistic_file,
crates/idl-cst/tests/lexer.rs::spans_never_run_past_the_input,
crates/idl-cst/tests/lexer.rs::a_span_covers_what_it_claims,
crates/idl-cst/tests/tree.rs::a_flat_tree_reproduces_its_source_byte_for_byte —
lexer.rs:390: assert_eq!(Span::new(0, 6).slice(source), Some("module"));.
Status: done
§7.2.2 Comments
Spec: §7.2.2, p. 17 — “The characters /* start a comment, which terminates with the characters */. These comments do not nest.”; “The characters // start a comment, which terminates at the end of the line on which they occur.”
Repo: crates/idl-cst/src/lex.rs::scan_trivia; the trivia rides on the
next token, and the tree carries it along.
Tests: crates/idl-cst/tests/lexer.rs::a_comment_before_a_token_is_that_tokens_leading_trivia,
crates/idl-cst/tests/lexer.rs::the_eof_token_carries_the_files_trailing_trivia,
crates/idl-cst/tests/lexer.rs::a_block_comment_is_one_piece_of_trivia_even_across_lines,
crates/idl-cst/tests/lexer.rs::an_unterminated_block_comment_runs_to_end_of_file_rather_than_failing,
crates/idl-cst/tests/tree.rs::a_tree_over_comments_and_spacing_reproduces_them_too,
crates/idl-cst/tests/tree.rs::a_leading_comment_is_not_part_of_it_either —
lexer.rs:274: assert_eq!(comments.len(), 1);.
Status: done
§7.2.3 Identifiers
Spec: §7.2.3, p. 18 — “An identifier is an arbitrarily long sequence of ASCII alphabetic, digit and underscore (_) characters. The first character must be an ASCII alphabetic character.”; “IDL identifiers are case insensitive.”
Repo: crates/idl-cst/src/lex.rs::lex_word,
crates/idl-cst/src/token.rs::identifier_name.
Tests: crates/idl-cst/tests/lexer.rs::an_ordinary_identifier_is_not_marked_escaped,
crates/idl-cst/tests/lexer.rs::an_identifier_that_differs_from_a_keyword_only_in_case_is_named_with_it —
lexer.rs:87: assert_eq!(zerodds_idl_cst::keyword_collision("CUSTOM"), Some("custom"));.
Status: done
§7.2.3.1 Collision Rules
Spec: §7.2.3.1, p. 18 — “Upper- and lower-case letters are treated as the same letter”; “There is only one namespace for IDL identifiers in each scope. Using the same identifier for a constant and an interface, for example, produces a compilation error.”
Repo: crates/idl-cst/src/token.rs::keyword_collision,
crates/idl-lower/src/lower.rs::identifiers_do_not_collide_with_keywords,
crates/idl-lower/src/scope.rs::ScopeStack.
Tests: crates/idl-lower/tests/validation.rs::two_names_differing_only_by_case_collide,
crates/idl-lower/tests/validation.rs::the_same_name_in_two_scopes_does_not_collide,
crates/idl-lower/tests/validation.rs::two_members_of_one_aggregate_differing_only_by_case_collide,
crates/idl-lower/tests/validation.rs::an_identifier_differing_from_a_keyword_only_in_case_is_refused,
crates/idl-lower/tests/validation.rs::a_name_that_collides_with_no_keyword_is_left_alone,
crates/idl-lower/tests/lowering.rs::a_name_declared_in_two_openings_of_one_module_collides —
lowering.rs:122: .any(|d| d.code == DiagnosticCode::DuplicateName),.
Status: done
§7.2.3.2 Escaped Identifiers
Spec: §7.2.3.2, p. 18 — “users may lexically”escape” identifiers by prepending an underscore (_) to an identifier. This is a purely lexical convention that ONLY turns off keyword checking.”
Repo: crates/idl-cst/src/token.rs::identifier_name (the leading _
is not part of the name), crates/idl-lower/src/lower.rs::identifiers_do_not_collide_with_keywords.
Tests: crates/idl-cst/tests/lexer.rs::an_escaped_identifier_is_the_name_without_the_underscore,
crates/idl-cst/tests/lexer.rs::an_underscore_prefixed_non_keyword_is_still_an_escaped_identifier,
crates/idl-lower/tests/validation.rs::the_underscore_escape_turns_the_keyword_check_off,
crates/idl-parse/tests/parse.rs::a_name_colliding_with_a_keyword_parses_as_a_name_and_is_refused_a_layer_up —
validation.rs:643: assert_clean("enum Ee { AA, _custom, BB };");.
Status: done
§7.2.4 Keywords (Table 7-6)
Spec: §7.2.4, p. 19 — “The identifiers listed in Table 7-6 are reserved
for use as keywords and may not be used for another purpose, unless
escaped with a leading underscore.”; Table 7-6 names 84 keywords including
the four capitalised TRUE, FALSE, Object, ValueBase.
Repo: crates/idl-cst/src/token.rs::KEYWORDS (the table itself),
crates/idl-cst/src/token.rs::keyword_collision.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier,
crates/idl-cst/tests/lexer.rs::a_keyword_is_recognised_only_in_the_spelling_table_7_6_gives,
crates/idl-cst/tests/lexer.rs::the_four_keywords_table_7_6_capitalises_are_spelled_as_it_spells_them,
crates/idl-lower/tests/validation.rs::the_diagnostic_names_the_keyword_and_the_clause —
lexer.rs:30: for (text, expected) in KEYWORDS {.
Status: done — the test iterates over every entry of the table, not over a sample.
§7.2.5 Other Characters Recognized by IDL (Punctuation)
Spec: §7.2.5, p. 20 — Table 7-7 (punctuation) and Table 7-8 (the
preprocessor tokens #, ##, !, ||, &&).
Repo: crates/idl-cst/src/lex.rs::lex_punct,
crates/idl-parse/src/preprocess/pptoken.rs::PUNCTUATORS.
Tests: crates/idl-cst/tests/lexer.rs::a_hash_that_is_not_at_the_start_of_a_line_is_punctuation,
crates/idl-cst/tests/lexer.rs::an_illegal_byte_run_produces_one_error_token_not_one_per_byte,
crates/idl-parse/tests/parse.rs::every_operator_of_the_ladder_parses,
crates/idl-parse/tests/parse.rs::a_leading_double_colon_is_the_global_scope.
Status: partial — the operator ladder and # are covered one by one;
no test covers all 28 characters of Table 7-7 or all five of Table 7-8.
The iso-8859-1 letters of Table 7-2 are not probed either.
§7.2.6 Literals
Spec: §7.2.6, p. 20 — the clause names integer, character, floating-point, string and fixed-point literals.
Repo: crates/idl-cst/src/lex.rs::lex_number (integer, floating point,
fixed), crates/idl-cst/src/lex.rs::lex_char, crates/idl-cst/src/lex.rs::lex_string.
Tests: crates/idl-cst/tests/lexer.rs::a_literal_value_is_recovered_from_the_token_text_alone,
crates/idl-cst/tests/lexer.rs::text_that_is_not_one_whole_token_of_that_kind_has_no_value,
crates/idl-cst/tests/lexer.rs::a_literal_too_large_for_i128_is_an_error_not_a_wrapped_value —
lexer.rs:165: assert_eq!(kinds(&huge)[0], TokenKind::Error);.
Status: done
§7.2.6.1 Integer Literals
Spec: §7.2.6.1, p. 20–21 — decimal, octal (0 prefixed) and
hexadecimal (0x/0X) forms; the spelling is kept.
Repo: crates/idl-cst/src/lex.rs::lex_number, crates/idl-cst/src/token.rs::IntLiteral.
Tests: crates/idl-cst/tests/lexer.rs::every_radix_reaches_the_same_value_and_keeps_how_it_was_written,
crates/idl-cst/tests/lexer.rs::a_leading_zero_before_a_point_is_a_decimal_number_and_not_an_octal_one,
crates/idl-cst/tests/lexer.rs::a_literal_too_large_for_i128_is_an_error_not_a_wrapped_value —
lexer.rs:132: assert_eq!(tokens[0].kind, TokenKind::IntLiteral, "{text}");.
Status: done
§7.2.6.2 Character Literals
Spec: §7.2.6.2, p. 21–22 — a character literal is a single quotation mark, exactly one character, a single quotation mark.
Repo: crates/idl-cst/src/lex.rs::lex_char.
Tests: crates/idl-cst/tests/lexer.rs::character_and_string_literals_resolve_their_escapes,
crates/idl-cst/tests/lexer.rs::a_raw_non_ascii_char_literal_is_its_code_point_and_not_its_last_octet,
crates/idl-cst/tests/lexer.rs::a_char_literal_the_type_cannot_hold_is_an_error_token —
lexer.rs:495: assert_eq!(lex("'ab'")[0].kind, TokenKind::Error);.
Status: done
§7.2.6.2.1 Wide and Non-wide Characters
Spec: §7.2.6.2.1, p. 21 — the L prefix (L'x') denotes a wide
character; the range is ISO 10646.
Repo: crates/idl-cst/src/lex.rs::next_token (TokenKind::WCharLiteral).
Tests: crates/idl-cst/tests/lexer.rs::wide_literals_are_their_own_kinds,
crates/idl-cst/tests/lexer.rs::a_char_literal_the_type_cannot_hold_is_an_error_token,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends —
lexer.rs:203: assert_eq!(kinds("L'x'")[0], TokenKind::WCharLiteral);.
Status: done
§7.2.6.2.2 Escape Sequences
Spec: §7.2.6.2.2, p. 21–22 — the escape sequences the clause names for
character literals: decimal, octal and hexadecimal form, plus the \u/\U
form for wide characters.
Repo: crates/idl-cst/src/lex.rs::scan_escape.
Tests: crates/idl-cst/tests/lexer.rs::character_and_string_literals_resolve_their_escapes,
crates/idl-cst/tests/lexer.rs::a_string_literal_value_has_its_escapes_resolved,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(lex-7.2.6.2-char-escape-octal, lex-7.2.6.2-char-escape-hex,
lex-7.2.6.2-wchar-escape-unicode).
Status: partial — the decimal and hexadecimal forms are covered in
the lexer test, the \u/\U form only as an .idl fixture under
tools/idlc/tests/idl-4.2-gaps/, not as a Rust test.
§7.2.6.3 String Literals and Adjacent Concatenation
Spec: §7.2.6.3, p. 22 — “Adjacent string literals are concatenated. Characters in concatenated strings are kept distinct.”; “Attempts to assign a wide string literal to a non-wide string constant or to assign a non-wide string literal to a wide string constant result in a compile-time diagnostic.”
Repo: crates/idl-parse/src/parser.rs::eat_adjacent_string_literals,
crates/idl-cst/src/lex.rs::lex_string.
Tests: crates/idl-lower/tests/idl_4_2_grammar.rs::adjacent_string_literals_are_one_literal,
crates/idl-lower/tests/idl_4_2_grammar.rs::the_characters_of_concatenated_strings_are_kept_distinct,
crates/idl-lower/tests/idl_4_2_grammar.rs::adjacent_wide_string_literals_are_one_literal,
crates/idl-lower/tests/idl_4_2_grammar.rs::a_narrow_and_a_wide_literal_are_not_concatenated,
crates/idl-lower/tests/idl_4_2_grammar.rs::an_annotation_argument_takes_the_whole_concatenated_literal,
crates/idl-lower/tests/idl_4_2_grammar.rs::a_typeid_takes_the_whole_concatenated_literal,
crates/idl-lower/tests/validation.rs::the_wide_and_narrow_string_pair_is_the_case_the_clause_names —
idl_4_2_grammar.rs:54: assert_eq!(constant(&ast, "K"), ConstValue::String("abcd".to_string()));.
Status: done
§7.2.6.4 Floating-point Literals
Spec: §7.2.6.4, p. 22–23 — the floating-point literals with and without an exponent and with a leading or trailing point.
Repo: crates/idl-cst/src/lex.rs::lex_number,
crates/idl-lower/src/expr.rs.
Tests: crates/idl-cst/tests/lexer.rs::float_forms_stay_distinguishable_from_one_another,
crates/idl-cst/tests/lexer.rs::a_leading_zero_before_a_point_is_a_decimal_number_and_not_an_octal_one,
crates/idl-lower/tests/floating_constant_arithmetic.rs::a_difference_of_two_literals_evaluates,
crates/idl-lower/tests/floating_constant_arithmetic.rs::the_arithmetic_is_double,
crates/idl-lower/tests/floating_constant_arithmetic.rs::a_large_value_keeps_its_exponent,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(lex-7.2.6.4-float-leading-dot, lex-7.2.6.4-float-trailing-dot) —
lexer.rs:144: assert_eq!(kinds(text)[0], TokenKind::FloatLiteral, "{text}");.
Status: done
§7.2.6.5 Fixed-point Literals
Spec: §7.2.6.5, p. 23 — the d/D suffix form is the fixed-point
literal; f/F is the floating-point form.
Repo: crates/idl-cst/src/lex.rs::lex_number (the d branch),
crates/idl-lower/src/expr.rs (evaluation as fixed<digits, scale>).
Tests: crates/idl-cst/tests/lexer.rs::a_d_suffix_makes_a_fixed_point_literal,
crates/idl-lower/tests/lowering.rs::a_fixed_constant_takes_its_type_from_its_literal,
crates/idl-lower/tests/completion.rs::a_fixed_type_carries_its_digits_and_scale,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(lex-7.2.6.5-fixed-literal) —
lexer.rs:157: assert_eq!(kinds(text)[0], TokenKind::FixedLiteral, "{text}");.
Status: done
§7.3 Preprocessing
§7.3 Preprocessing (ISO/IEC 14882:2003)
Spec: §7.3, p. 23 — “IDL shall be preprocessed according to the specification of the preprocessor in ISO/IEC 14882:2003.”
Repo: crates/idl-parse/src/preprocess/mod.rs (the directive run),
crates/idl-parse/src/preprocess/condition.rs (#if evaluation),
crates/idl-parse/src/preprocess/macro_.rs (the macro table),
crates/idl-parse/src/preprocess/pptoken.rs (preprocessor tokens).
Tests: crates/idl-parse/tests/preprocess.rs::a_macro_is_expanded_before_the_parser_sees_it,
crates/idl-parse/tests/preprocess.rs::the_expanded_text_is_itself_lexable,
crates/idl-parse/tests/preprocess.rs::the_expanded_stream_carries_no_directive_tokens,
crates/idl-parse/tests/preprocessor_iso_14882.rs::the_diagnostic_code_is_stable —
preprocess.rs:493: assert!(text.contains('8'), "the macro was not expanded: {text}");.
Status: done
§7.3 Line Continuation with Backslash
Spec: §7.3, p. 23 — “A preprocessing directive (or any line) may be continued on the next line in a source file by placing a backslash character (), immediately before the newline at the end of the line to be continued.”
Repo: crates/idl-parse/src/preprocess/mod.rs::splice (at the head of
directive), crates/idl-cst/src/lex.rs::scan_trivia on the preprocessor
level.
Tests: crates/idl-parse/tests/preprocessor_iso_14882.rs::a_backslash_continues_a_directive,
crates/idl-cst/tests/lexer.rs::a_preprocessor_line_is_trivia_including_its_continuations —
lexer.rs:296: assert_eq!(reconstruct(source), source);.
Status: done
§7.3 Macro Expansion and Rescan with a Hide Set
Spec: §7.3, p. 23 (taken over from ISO/IEC 14882:2003 §16.3) — a macro that expands to itself does not expand again; the rescan reaches the tokens after the invocation.
Repo: crates/idl-parse/src/preprocess/mod.rs::run and
substitute, crates/idl-parse/src/preprocess/macro_.rs::MacroTable.
Tests: crates/idl-parse/tests/preprocess.rs::a_defined_name_is_replaced_by_its_body,
crates/idl-parse/tests/preprocess.rs::a_macro_expanding_to_another_macro_is_rescanned,
crates/idl-parse/tests/preprocessor_iso_14882.rs::a_macro_does_not_expand_inside_its_own_expansion,
crates/idl-parse/tests/preprocessor_iso_14882.rs::the_rescan_reaches_the_tokens_after_the_invocation,
crates/idl-parse/tests/preprocessor_iso_14882.rs::an_argument_is_expanded_before_it_is_substituted,
crates/idl-parse/tests/preprocessor_iso_14882.rs::an_expansion_that_is_not_an_idl_token_is_reported —
preprocess.rs:67: assert!(result.text.contains("= 1"), "{}", result.text);.
Status: done
§7.3 Function-like Macros, Stringize #, Token-Paste ##
Spec: §7.3 together with ISO/IEC 14882:2003 §16.3.1 and §16.3.2 —
object-like and function-like macros, # as the stringize operator, ##
as token paste.
Repo: crates/idl-parse/src/preprocess/mod.rs::substitute and
arguments, crates/idl-parse/src/preprocess/pptoken.rs (punctuators).
Tests: crates/idl-parse/tests/preprocessor_iso_14882.rs::a_function_like_macro_substitutes_its_arguments,
crates/idl-parse/tests/preprocessor_iso_14882.rs::stringize_spells_the_argument,
crates/idl-parse/tests/preprocessor_iso_14882.rs::token_paste_joins_two_tokens,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(lex-7.3-define-function, lex-7.3-token-paste) —
preprocessor_iso_14882.rs:137: "struct Sa { long m ; } ;".
Status: done
§7.3 #include
Spec: §7.3, p. 23 — “Text in files included with a #include directive is treated as if it appeared in the including file.”
Repo: crates/idl-parse/src/preprocess/mod.rs::include with the bound
MAX_INCLUDE_DEPTH.
Tests: crates/idl-parse/tests/preprocess.rs::an_included_file_contributes_its_declarations,
crates/idl-parse/tests/preprocess.rs::both_include_spellings_resolve,
crates/idl-parse/tests/preprocess.rs::an_include_cycle_is_diagnosed_and_not_followed,
crates/idl-parse/tests/preprocess.rs::an_include_chain_past_the_nesting_bound_is_refused,
crates/idl-parse/tests/source_map.rs::a_token_from_an_include_names_that_file,
crates/idl-lower/tests/conformance.rs::a_fixture_with_an_include_gains_the_declarations_it_includes —
preprocess.rs:206: assert!(result.text.contains("Common"));.
Status: done
§7.3 #define and #undef
Spec: §7.3, p. 23 — #define and #undef with an object-like name;
the reserved names of the ISO standard may not be redefined.
Repo: crates/idl-parse/src/preprocess/mod.rs::directive,
crates/idl-parse/src/preprocess/macro_.rs::MacroTable::define and
undefine.
Tests: crates/idl-parse/tests/preprocess.rs::a_redefinition_replaces_the_earlier_one,
crates/idl-parse/tests/preprocess.rs::a_define_without_a_name_is_diagnosed,
crates/idl-parse/tests/preprocess.rs::an_undefined_name_is_left_alone,
crates/idl-parse/tests/preprocessor_iso_14882.rs::the_predefined_names_cannot_be_defined,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(lex-7.3-undef) —
preprocess.rs:41: assert!(expanded.contains("MAX"), "{expanded}");.
Status: done
§7.3 Conditionals #if / #ifdef / #ifndef / #else / #elif / #endif
Spec: §7.3 together with ISO/IEC 14882:2003 §16.1 — the condition is
evaluated over a constant expression, defined(X) asks whether the name is
defined.
Repo: crates/idl-parse/src/preprocess/mod.rs::directive and
evaluate_condition, crates/idl-parse/src/preprocess/condition.rs::evaluate.
Tests: crates/idl-parse/tests/preprocess.rs::ifdef_keeps_only_the_taken_branch,
crates/idl-parse/tests/preprocess.rs::ifndef_is_the_other_way_round,
crates/idl-parse/tests/preprocess.rs::elif_takes_the_first_true_branch_and_no_later_one,
crates/idl-parse/tests/preprocess.rs::else_is_taken_only_when_nothing_before_it_was,
crates/idl-parse/tests/preprocess.rs::conditionals_nest,
crates/idl-parse/tests/preprocess.rs::a_define_inside_a_dropped_branch_does_not_take_effect,
crates/idl-parse/tests/preprocess.rs::an_if_with_a_literal_works_and_an_unevaluable_one_is_reported,
crates/idl-parse/tests/preprocessor_iso_14882.rs::if_evaluates_an_arithmetic_expression,
crates/idl-parse/tests/preprocessor_iso_14882.rs::a_division_by_zero_in_a_live_condition_is_an_error —
preprocess.rs:76: assert!(expanded.contains("Kept"), "{expanded}");.
Status: done
§7.3 #line
Spec: §7.3 together with ISO/IEC 14882:2003 §16.4 — #line sets the
line number and the file name for the following tokens.
Repo: crates/idl-parse/src/preprocess/mod.rs::line_control.
Tests: crates/idl-parse/tests/preprocessor_iso_14882.rs::hash_line_renumbers_and_renames,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(lex-7.3-line-directive) —
preprocessor_iso_14882.rs:259: "const long K = 100 ; const string F = \"robot.idl\" ;".
Status: done
§7.3 #pragma and #pragma once
Spec: §7.3, p. 23 — “The textual location of IDL-specific pragmas may be semantically constrained.”
Repo: crates/idl-parse/src/preprocess/mod.rs::directive and
flush_trailing_pragmas; a #pragma line is interpreted in
crates/idl-lower/src/complete.rs.
Tests: crates/idl-parse/tests/preprocess.rs::a_pragma_is_not_the_preprocessors_business,
crates/idl-parse/tests/preprocess.rs::a_pragma_the_preprocessor_does_not_own_still_reaches_the_stream,
crates/idl-parse/tests/preprocess.rs::pragma_once_holds_the_way_an_ifndef_guard_does,
crates/idl-parse/tests/preprocess.rs::a_pragma_once_in_a_branch_that_is_cut_out_does_not_guard,
crates/idl-lower/tests/dialects.rs::a_pragma_id_sets_the_repository_id_like_typeid_does,
crates/idl-lower/tests/dialects.rs::a_cyclone_pragma_keylist_reaches_the_same_field_as_rtis_keylist,
crates/idl-lower/tests/dialects.rs::the_opendds_pragmas_reach_the_opendds_facet —
preprocess.rs:332: assert_eq!(kept, 1, "the keylist pragma did not survive");.
Status: done
§7.3 #error
Spec: §7.3 together with ISO/IEC 14882:2003 §16.5 — “#error causes the implementation to produce a diagnostic message that includes the specified sequence of preprocessing tokens.”
Repo: crates/idl-parse/src/preprocess/mod.rs::directive, arm error
(DiagnosticCode::ErrorDirective).
Tests: crates/idl-parse/tests/preprocess.rs::an_error_directive_is_a_diagnostic_and_carries_its_text,
crates/idl-parse/tests/preprocess.rs::an_error_directive_in_a_branch_that_is_cut_out_says_nothing,
crates/idl-parse/tests/preprocess.rs::a_bare_error_directive_is_still_a_diagnostic —
preprocess.rs:732: out.diagnostics.iter().any(|d| d.code.as_str() == "IDL0020"),.
Status: done
§7.3 LINE and FILE
Spec: §7.3 together with ISO/IEC 14882:2003 §16.10 — the predefined
names __LINE__ and __FILE__.
Repo: crates/idl-parse/src/preprocess/mod.rs::predefined.
Tests: crates/idl-parse/tests/preprocessor_iso_14882.rs::line_and_file_name_where_they_stand,
crates/idl-parse/tests/preprocessor_iso_14882.rs::line_inside_a_macro_is_the_line_of_the_invocation,
crates/idl-parse/tests/preprocessor_iso_14882.rs::the_predefined_names_cannot_be_defined —
preprocessor_iso_14882.rs:239: "const long K = 3 ;".
Status: done
§7.4 IDL Grammar
§7.4 Grammar Frame and Pre-existing Non-terminals
Spec: §7.4, p. 24 — “The grammar for a well-formed IDL specification is
described by rules expressed in Extended Backus Naur Form (EBNF) completed
to support rule extensions as explained in clause 7.1”; Table 7-10 lists
<identifier>, <integer_literal>, <string_literal>,
<wide_string_literal>, <character_literal>, <wide_character_literal>,
<fixed_pt_literal>, <floating_pt_literal> as pre-existing
non-terminals.
Repo: crates/idl-parse/src/parser.rs,
crates/idl-parse/src/type_spec.rs::is_primitive_keyword,
crates/idl-parse/src/decl.rs::parse_definition.
Tests: crates/idl-parse/tests/parse.rs::a_file_using_most_of_the_grammar_parses_cleanly_and_round_trips,
crates/idl-parse/tests/parse.rs::the_multi_word_primitive_types_parse_as_one_type_each,
crates/idl-lower/tests/validation.rs::a_file_using_the_whole_language_reports_nothing —
parse.rs:449: assert_eq!(result.text(), source);.
Status: done
§7.4.1 Building Block Core Data Types
§7.4.1.1 Purpose
Spec: §7.4.1.1, p. 24 — “The Core Data Types are the data types that must be supported by every profile.”
Repo: crates/idl-lower/src/lower.rs::lower,
crates/ast/src/model.rs::Ast.
Tests: —
Status: n/a (informative) — the clause motivates the building block
and demands nothing about its form; the individual types are audited in
§7.4.1.4.4.2.
§7.4.1.3 Syntax (Productions 1–68)
Spec: §7.4.1.3, p. 24–30 — the productions of the EBNF table:
specification, definition, module_dcl, const_dcl, const_type,
const_expr, type_dcl, typedef_dcl, type_declarator, constr_type_dcl,
struct_dcl, member, union_dcl, switch_type, case, case_label,
enum_dcl, enumerator, array_declarator, simple_type_spec,
native_type, forward_dcl.
Repo: crates/idl-parse/src/decl.rs::parse_definition and the
production functions beside it (parse_module, parse_const,
parse_typedef, parse_struct_def, parse_union_case, parse_enum_def,
parse_native), crates/idl-parse/src/type_spec.rs::parse_type_spec.
Tests: crates/idl-parse/tests/parse.rs::each_declaration_form_is_recognised,
crates/idl-parse/tests/parse.rs::several_declarators_share_one_type,
crates/idl-parse/tests/parse.rs::a_forward_declaration_is_its_own_form,
crates/idl-parse/tests/parse.rs::an_array_declarator_is_only_known_at_the_bracket,
crates/idl-lower/tests/validation.rs::an_enumeration_with_no_enumerator_is_refused,
crates/idl-lower/tests/validation.rs::a_bitmask_with_no_bit_value_is_refused,
crates/idl-lower/tests/validation.rs::a_union_with_no_case_is_refused,
crates/idl-lower/tests/validation.rs::the_two_bodies_the_grammar_does_let_be_empty_stay_empty,
crates/idl-lower/tests/idl_4_2_grammar.rs::every_constructed_form_can_be_defined_inside_a_typedef.
Status: partial — the productions are recognised, but production 62
allows native_type as a member type spec too
(<type_spec> ::+ <native_type> | …); struct S { native H; }; is not
covered, parse_type_spec has no Native branch. The gap is measured in
idl-4.2.gaps.md §A.
§7.4.1.4.1 IDL Specification
Spec: §7.4.1.4.1, p. 30 — an IDL specification consists of declarations; the included files count towards it.
Repo: crates/idl-lower/src/lower.rs::lower.
Tests: crates/idl-lower/tests/conformance.rs::every_fixture_parses_with_no_diagnostics_beyond_the_extensions_it_declares,
crates/idl-lower/tests/conformance.rs::every_fixture_produces_a_model_with_declarations_in_it,
crates/idl-lower/tests/conformance.rs::every_node_of_every_fixture_names_the_file_it_came_from,
crates/idl-lower/tests/conformance.rs::a_fixture_with_an_include_gains_the_declarations_it_includes —
conformance.rs:202: ast.types().count() > 0 || ast.interfaces().count() > 0,.
Status: done
§7.4.1.4.2 Modules
Spec: §7.4.1.4.2, p. 30–31 — a module opens a scope that reaches
to the closing }.
Repo: crates/idl-lower/src/lower.rs::module,
crates/idl-lower/src/scope.rs::ScopeStack::push_container.
Tests: crates/idl-lower/tests/lowering.rs::a_module_becomes_a_module_node,
crates/idl-lower/tests/lowering.rs::nested_modules_nest_in_the_model_too,
crates/idl-lower/tests/conformance.rs::a_conditional_in_a_fixture_keeps_the_branch_out_of_the_model,
crates/ast/tests/node_space.rs::nested_modules_are_addressable_by_path,
crates/ast/tests/node_space.rs::a_fresh_model_has_an_anonymous_root_module —
lowering.rs:51: assert!(ast.module_by_path(&scoped(&["Robot"])).is_some());.
Status: done
§7.4.1.4.3 Constants
Spec: §7.4.1.4.3, p. 37 — a constant declaration consists, among other
things, of “a value expression (<const_expr>), which shall be consistent
with the type declared for the constant”.
Repo: crates/idl-lower/src/lower.rs::value_disagrees_with and
check_const_value_form, crates/idl-lower/src/expr.rs (evaluation).
Tests: crates/idl-lower/tests/validation.rs::a_constant_whose_value_is_not_of_its_declared_type_is_refused,
crates/idl-lower/tests/validation.rs::every_form_the_specification_admits_still_gets_through,
crates/idl-lower/tests/completion.rs::a_constant_takes_its_declared_type_not_the_expressions,
crates/idl-lower/tests/lowering.rs::a_string_constant_evaluates_even_though_no_integer_holds_it,
crates/idl-lower/tests/lowering.rs::eval_const_follows_a_reference_and_keeps_arithmetic_integral,
crates/ast/tests/node_space.rs::every_operator_of_idl_4_2_is_representable,
crates/ast/tests/node_space.rs::division_by_zero_is_an_error_not_a_panic —
validation.rs:701: assert_trips("const long K = \"x\";", DiagnosticCode::TypeMismatch);.
Status: done
§7.4.1.4.4 Data Types (Frame)
Spec: §7.4.1.4.4, p. 38 — the clause divides the data types into
referencing, basic, template and constructed.
Repo: crates/idl-lower/src/validate.rs::validate_type.
Tests: crates/idl-lower/tests/validation.rs::a_file_using_the_whole_language_reports_nothing,
crates/idl-lower/tests/lowering.rs::each_primitive_keyword_reaches_its_model_kind —
lowering.rs:347: TypeKind::Primitive(expected),.
Status: done
§7.4.1.4.4.1 Referencing Types
Spec: §7.4.1.4.4.1, p. 38 — a referencing type is a qualified name; it may point at a definition declared later.
Repo: crates/idl-lower/src/lower.rs::named_type_ref,
crates/idl-lower/src/scope.rs::ScopeStack::lookup_candidates.
Tests: crates/idl-lower/tests/lowering.rs::a_reference_to_a_type_declared_later_is_pending_not_an_error,
crates/idl-lower/tests/lowering.rs::a_reference_to_a_type_declared_earlier_resolves_immediately,
crates/idl-lower/tests/lowering.rs::a_pending_reference_resolves_once_the_name_arrives,
crates/idl-lower/tests/lowering.rs::a_name_that_never_arrives_ends_up_broken_rather_than_pending,
crates/idl-lower/tests/reported_idl.rs::a_fully_qualified_scoped_name_resolves,
crates/ast/tests/node_space.rs::an_unknown_path_resolves_to_nothing —
lowering.rs:381: assert!(report.resolved >= 1, "nothing resolved: {report:?}");.
Status: done
§7.4.1.4.4.2 Basic Types
Spec: §7.4.1.4.4.2, p. 38–39 — the basic types of productions 30–37.
Repo: crates/idl-lower/src/lower.rs::primitive_of,
crates/ast/src/node/type_.rs::PrimitiveKind.
Tests: crates/idl-lower/tests/lowering.rs::each_primitive_keyword_reaches_its_model_kind,
crates/ast/tests/node_space.rs::every_primitive_of_the_spec_table_is_representable —
node_space.rs:86: assert_eq!(PrimitiveKind::ALL.len(), 15);.
Status: done
§7.4.1.4.4.2.1 Integer Types
Spec: §7.4.1.4.4.2.1, p. 38–39 — short, long, long long,
unsigned short, unsigned long, unsigned long long.
Repo: crates/idl-lower/src/lower.rs::primitive_of,
crates/idl-parse/src/type_spec.rs::is_primitive_keyword.
Tests: crates/idl-lower/tests/lowering.rs::each_primitive_keyword_reaches_its_model_kind,
crates/idl-parse/tests/parse.rs::the_multi_word_primitive_types_parse_as_one_type_each,
crates/idl-lower/tests/validation.rs::every_form_the_specification_admits_still_gets_through —
lowering.rs:327: ("unsigned long long", PrimitiveKind::UInt64),.
Status: done
§7.4.1.4.4.2.2 Floating-Point Types
Spec: §7.4.1.4.4.2.2, p. 34 — “IDL floating-point types are float, double, and long double. The float type represents IEEE single-precision floating point numbers; the double type represents IEEE double-precision floating point numbers. The long double data type represents an IEEE double-extended floating-point number”.
Repo: crates/idl-lower/src/lower.rs::primitive_of (the Float32,
Float64, Float128 arms), crates/float128/src/lib.rs::Float128.
Tests: crates/idl-lower/tests/lowering.rs::each_primitive_keyword_reaches_its_model_kind,
crates/idl-lower/tests/floating_constant_arithmetic.rs::long_double_arithmetic_is_refused_and_a_long_double_literal_is_not.
Status: partial — float and double are modelled and tested. long double is modelled as Float128; the arithmetic of a long double expression is refused (EvalError::LongDouble), own item.
§7.4.1.4.4.2.2 long double as IEEE double-extended
Spec: §7.4.1.4.4.2.2, p. 34 — “The long double data type represents an IEEE double-extended floating-point number, which has an exponent of at least 15 bits in length and a signed fraction of at least 64 bits”.
Repo: crates/float128/src/lib.rs (Float128), crates/idl-lower/src/lower.rs (primitive_of, arm Float128)
Tests: crates/idl-lower/tests/floating_constant_arithmetic.rs::long_double_arithmetic_is_refused_and_a_long_double_literal_is_not
Status: blocked — Rust stable has no type f128 (rust-lang/rust#116909); lifted once f128 is available in Rust stable. Until then the constant evaluation refuses long double arithmetic with EvalError::LongDouble.
§7.4.1.4.4.2.3 char Type
Spec: §7.4.1.4.4.2.3, p. 39 — the type char, ISO Latin-1, one byte.
Repo: crates/idl-lower/src/lower.rs::value_disagrees_with (the
PrimitiveKind::Char arm), crates/idl-cst/src/lex.rs::lex_char.
Tests: crates/idl-lower/tests/validation.rs::a_constant_whose_value_is_not_of_its_declared_type_is_refused,
crates/idl-lower/tests/validation.rs::every_form_the_specification_admits_still_gets_through,
crates/idl-cst/tests/lexer.rs::a_raw_non_ascii_char_literal_is_its_code_point_and_not_its_last_octet —
lexer.rs:473: assert_eq!(tokens[0].value, TokenValue::Char { value: 0x00E4 });.
Status: done
§7.4.1.4.4.2.4 Wide Char Type
Spec: §7.4.1.4.4.2.4, p. 39 — the type wchar, ISO 10646.
Repo: crates/idl-lower/src/lower.rs::value_disagrees_with (the
PrimitiveKind::WChar arm), crates/idl-cst/src/lex.rs::next_token.
Tests: crates/idl-lower/tests/validation.rs::a_constant_whose_value_is_not_of_its_declared_type_is_refused,
crates/idl-lower/tests/validation.rs::the_wide_and_narrow_string_pair_is_the_case_the_clause_names,
crates/idl-cst/tests/lexer.rs::wide_literals_are_their_own_kinds —
lexer.rs:203: assert_eq!(kinds("L'x'")[0], TokenKind::WCharLiteral);.
Status: done
§7.4.1.4.4.2.5 Boolean Type
Spec: §7.4.1.4.4.2.5, p. 39 — the type boolean, value range 0/1,
constant values TRUE/FALSE.
Repo: crates/idl-lower/src/validate.rs::primitive_range (the
PrimitiveKind::Boolean arm).
Tests: crates/idl-lower/tests/validation.rs::every_form_the_specification_admits_still_gets_through,
crates/idl-lower/tests/validation.rs::a_constant_whose_value_is_not_of_its_declared_type_is_refused,
crates/idl-lower/tests/validation.rs::a_boolean_discriminator_admits_only_zero_and_one —
validation.rs:281: "union U switch (boolean) { case 0: long a; case 1: long b; };",.
Status: done
§7.4.1.4.4.2.6 Octet Type
Spec: §7.4.1.4.4.2.6, p. 39 — the type octet, an unsigned byte.
Repo: crates/idl-lower/src/validate.rs::primitive_range (the
Octet | UInt8 arm).
Tests: crates/idl-lower/tests/lowering.rs::each_primitive_keyword_reaches_its_model_kind,
crates/idl-lower/tests/completion.rs::a_constant_takes_its_declared_type_not_the_expressions,
crates/idl-lower/tests/validation.rs::every_form_the_specification_admits_still_gets_through —
completion.rs:320: TypeKind::Primitive(zerodds_ast::PrimitiveKind::Octet).
Status: done
§7.4.1.4.4.3 Template Types
Spec: §7.4.1.4.4.3, p. 39–41 — sequences, strings, wstrings and fixed as template types with an optional bound.
Repo: crates/idl-parse/src/type_spec.rs (parse_sequence_type,
parse_string_type), crates/idl-lower/src/validate.rs::validate_type.
Tests: crates/idl-lower/tests/lowering.rs::a_sequence_member_carries_its_element_type,
crates/idl-lower/tests/completion.rs::a_bounded_string_and_sequence_carry_their_bound_expressions,
crates/idl-lower/tests/completion.rs::an_unbounded_collection_says_so_rather_than_carrying_a_zero —
completion.rs:418: assert!(!bound.is_bounded(), "{name} gained a bound");.
Status: done
§7.4.1.4.4.3.1 Sequences
Spec: §7.4.1.4.4.3.1, p. 39–40 — sequence < <positive_int_const> > < type_spec >; the bound must be positive.
Repo: crates/idl-parse/src/type_spec.rs::parse_sequence_type,
crates/idl-lower/src/validate.rs::validate_type.
Tests: crates/idl-lower/tests/validation.rs::a_negative_sequence_bound_is_rejected,
crates/idl-lower/tests/validation.rs::a_positive_bound_is_accepted,
crates/idl-lower/tests/lowering.rs::a_sequence_member_carries_its_element_type —
validation.rs:481: "struct S { sequence<long, -1> a; };",.
Status: done
§7.4.1.4.4.3.2 Strings
Spec: §7.4.1.4.4.3.2, p. 40 — string < <positive_int_const> >.
Repo: crates/idl-parse/src/type_spec.rs::parse_string_type.
Tests: crates/idl-lower/tests/validation.rs::a_zero_string_bound_is_rejected,
crates/idl-lower/tests/completion.rs::a_bounded_string_and_sequence_carry_their_bound_expressions,
crates/ast/tests/node_space.rs::narrow_and_wide_strings_are_distinct_kinds —
validation.rs:475: assert_trips("struct S { string<0> a; };", DiagnosticCode::InvalidBound);.
Status: done
§7.4.1.4.4.3.3 Wstrings
Spec: §7.4.1.4.4.3.3, p. 40 — wstring < <positive_int_const> >,
ISO 10646.
Repo: crates/idl-parse/src/type_spec.rs::parse_string_type (the
TokenKind::Wstring branch).
Tests: crates/idl-lower/tests/validation.rs::a_zero_string_bound_is_rejected,
crates/idl-lower/tests/idl_4_2_grammar.rs::adjacent_wide_string_literals_are_one_literal,
crates/ast/tests/node_space.rs::narrow_and_wide_strings_are_distinct_kinds,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(bb1-006-const-wstring) —
idl_4_2_grammar.rs:74: ConstValue::WString("abcd".chars().map(u32::from).collect()).
Status: done
§7.4.1.4.4.3.4 Fixed Type
Spec: §7.4.1.4.4.3.4, p. 40–41 — fixed < <positive_int_const> , <positive_int_const> > with at most 31 digits; the scale may not exceed
the number of digits.
Repo: crates/idl-lower/src/validate.rs::fixed_rules with
MAX_FIXED_DIGITS, crates/idl-lower/src/expr.rs (fixed arithmetic).
Tests: crates/idl-lower/tests/validation.rs::a_fixed_with_more_than_thirty_one_digits_is_rejected,
crates/idl-lower/tests/validation.rs::a_fixed_whose_scale_exceeds_its_digits_is_rejected,
crates/idl-lower/tests/validation.rs::a_fixed_within_its_ranges_is_accepted,
crates/idl-lower/tests/fixed_constant_arithmetic.rs::a_sum_lines_the_points_up_and_drops_the_insignificant_zero,
crates/idl-lower/tests/fixed_constant_arithmetic.rs::a_product_carries_both_scales,
crates/idl-lower/tests/fixed_constant_arithmetic.rs::a_quotient_is_exact_or_cut_without_rounding,
crates/idl-lower/tests/lowering.rs::table_7_11_decides_the_type_of_a_fixed_expression,
crates/ast/tests/node_space.rs::fixed_retains_digits_and_scale —
validation.rs:503: assert_trips("struct S { fixed<32,2> a; };", DiagnosticCode::InvalidBound);.
Status: done
§7.4.1.4.4.4 Constructed Types
Spec: §7.4.1.4.4.4, p. 41–43 — structures, unions, enumerations, forward declarations and native as constructed types.
Repo: crates/idl-lower/src/lower.rs (structure, union,
enumeration, native), crates/idl-lower/src/validate.rs::union_rules.
Tests: crates/idl-lower/tests/lowering.rs::a_struct_carries_its_members_in_order,
crates/idl-lower/tests/lowering.rs::an_enum_carries_its_enumerators_in_order,
crates/ast/tests/node_space.rs::struct_members_land_in_declaration_order_with_the_right_parent,
crates/idl-lower/tests/spans.rs::a_struct_member_names_its_declarator_and_not_the_space_before_it —
lowering.rs:492: assert_eq!(names, vec!["IDLE", "ACTIVE", "FAULT"]);.
Status: done
§7.4.1.4.4.4.1 Structures
Spec: §7.4.1.4.4.4.1, p. 41–42 — struct <identifier> { <member> * },
a list of <member>, each with its own declarator.
Repo: crates/idl-lower/src/lower.rs::structure.
Tests: crates/idl-lower/tests/lowering.rs::a_struct_carries_its_members_in_order,
crates/idl-lower/tests/lowering.rs::several_declarators_share_the_type_and_become_separate_members,
crates/idl-lower/tests/lowering.rs::an_exception_carries_its_members,
crates/idl-lower/tests/spans.rs::the_second_declarator_of_a_list_names_its_own_line —
lowering.rs:304: assert_eq!(names, vec!["x", "y", "z"]);.
Status: done
§7.4.1.4.4.4.2 Unions and the Rules on Case Labels
Spec: §7.4.1.4.4.4.2, p. 42 — “If the discriminator value was
explicitly listed in a case statement, the value of the element associated
with the case label is the discriminator”; further: no label may occur
twice, and there may be at most one default.
Repo: crates/idl-lower/src/validate.rs::union_rules,
crates/idl-lower/src/lower.rs::union.
Tests: crates/idl-lower/tests/lowering.rs::a_union_over_an_enumeration_lowers_with_its_labels_evaluated,
crates/idl-lower/tests/lowering.rs::a_case_label_may_name_its_enumerator_by_a_qualified_name,
crates/idl-lower/tests/validation.rs::a_repeated_case_label_is_rejected,
crates/idl-lower/tests/validation.rs::distinct_case_labels_are_accepted,
crates/idl-lower/tests/validation.rs::two_default_cases_are_rejected,
crates/idl-lower/tests/spans.rs::a_repeated_case_label_is_reported_on_the_branch_that_repeats_it,
crates/ast/tests/node_space.rs::a_default_case_is_recorded_on_the_union_as_well_as_in_the_case_list,
crates/ast/tests/node_space.rs::a_case_may_carry_several_labels —
lowering.rs:193: assert_eq!(labels, [0, 1, 2]);.
Status: done
§7.4.1.4.4.4.3 Enumerations
Spec: §7.4.1.4.4.4.3, p. 42 — enum <identifier> { <enumerator> { "," <enumerator> } * }; an enumerator may carry an explicit value, and
the following ones continue from there.
Repo: crates/ast/src/query.rs::effective_enumerator_value,
crates/idl-lower/src/lower.rs::enumeration.
Tests: crates/idl-lower/tests/lowering.rs::an_enum_carries_its_enumerators_in_order,
crates/idl-lower/tests/lowering.rs::an_enumerator_evaluates_inside_a_larger_expression,
crates/idl-lower/tests/completion.rs::enumerators_without_values_run_from_zero_upwards,
crates/idl-lower/tests/completion.rs::an_explicit_enumerator_value_shifts_the_ones_after_it,
crates/ast/tests/node_space.rs::a_positional_enumerator_and_an_explicit_value_are_distinguishable —
completion.rs:271: assert_eq!(ast.effective_enumerator_value(enumerators[2]), Some(11));.
Status: done
§7.4.1.4.4.4.4 Constructed Recursive Types and Forward Declarations
Spec: §7.4.1.4.4.4.4, p. 42–43 — a structure may contain itself only
through an element that terminates a value; the forward declaration
struct <identifier> ; is completed by the definition.
Repo: crates/idl-lower/src/validate.rs::forward_declarations_are_defined,
crates/ast-layout/src/xcdr.rs::types_that_close_an_inadmissible_cycle,
crates/idl-compose/src/lib.rs::compose_source_with.
Tests: crates/idl-compose/tests/recursion.rs::a_cycle_with_no_terminator_on_it_is_refused,
crates/idl-compose/tests/recursion.rs::a_cycle_with_a_terminator_on_it_is_admitted,
crates/idl-compose/tests/recursion.rs::the_diagnostic_names_the_type_and_the_clause,
crates/idl-compose/tests/recursion.rs::the_interop_corpus_case_for_this_is_refused_and_its_neighbours_are_not,
crates/idl-compose/tests/recursion.rs::a_forward_declared_cycle_is_reported_once,
crates/idl-lower/tests/lowering.rs::a_forward_declaration_on_its_own_is_forward,
crates/idl-lower/tests/lowering.rs::the_definition_completes_the_forward_node_rather_than_adding_a_second,
crates/idl-lower/tests/validation.rs::a_forward_declaration_never_defined_is_rejected,
crates/idl-lower/tests/validation.rs::a_forward_declaration_that_is_defined_is_accepted —
recursion.rs:104: assert!(message.contains("Ma::Sa"), "{message}");.
Status: done
§7.4.1.4.4.6 Native Types
Spec: §7.4.1.4.4.6, p. 43 — native <identifier> ; declares a native
type; the use as a member type spec stands in production 62.
Repo: crates/idl-lower/src/lower.rs::native,
crates/idl-parse/src/decl.rs::parse_native.
Tests: crates/idl-lower/tests/lowering.rs::a_native_declaration_becomes_a_native_type,
crates/idl-parse/tests/parse.rs::each_declaration_form_is_recognised.
Status: partial — the declaration is covered, the use as a member
type (struct S { native H; };) is not; see the item on §7.4.1.3.
§7.4.1.4.4.7 Naming Data Types (Production 64)
Spec: §7.4.1.4.4.7, p. 43 — (64) <type_declarator> ::= { <simple_type_spec> | <template_type_spec> | <constr_type_dcl> } <any_declarators>; the third alternative allows the construction in the
typedef itself.
Repo: crates/idl-parse/src/decl.rs::parse_typedef,
crates/idl-lower/src/lower.rs::typedef.
Tests: crates/idl-lower/tests/idl_4_2_grammar.rs::a_struct_defined_inside_a_typedef_is_declared_and_aliased,
crates/idl-lower/tests/idl_4_2_grammar.rs::every_constructed_form_can_be_defined_inside_a_typedef,
crates/idl-lower/tests/lowering.rs::a_typedef_becomes_an_alias_to_its_target,
crates/idl-lower/tests/lowering.rs::one_typedef_may_declare_several_names,
crates/idl-lower/tests/lowering.rs::a_typedef_declarator_keeps_its_array_dimensions,
crates/idl-lower/tests/lowering.rs::dimensions_belong_to_the_declarator_and_not_to_the_typedef —
idl_4_2_grammar.rs:153: TypeKind::Alias { aliased } => assert_eq!(aliased.resolved(), Some(inline)),.
Status: done
§7.4.1.5 Specific Keywords
Spec: §7.4.1.5, p. 43–44 — Table 7-27: the keywords of this building block.
Repo: crates/idl-cst/src/token.rs::KEYWORDS,
crates/idl-lower/src/lower.rs::identifiers_do_not_collide_with_keywords.
Tests: crates/idl-lower/tests/validation.rs::an_identifier_differing_from_a_keyword_only_in_case_is_refused,
crates/idl-lower/tests/validation.rs::the_diagnostic_names_the_keyword_and_the_clause,
crates/idl-lower/tests/validation.rs::the_underscore_escape_turns_the_keyword_check_off —
validation.rs:619: DiagnosticCode::KeywordCollision,.
Status: done
§7.4.2 Building Block Any
§7.4.2.1 Purpose and §7.4.2.2 Dependencies
Spec: §7.4.2.1 / §7.4.2.2, p. 43–44 — the building block introduces
any and relies on the Building Block Core Data Types.
Repo: crates/idl-parse/src/type_spec.rs,
crates/ast/src/node/type_.rs::TypeKind.
Tests: —
Status: n/a (informative) — the two clauses motivate and name the
dependency; the type itself stands in §7.4.2.3.
§7.4.2.3 Syntax — the Type any
Spec: §7.4.2.3, p. 44 — (69) <type_spec> ::+ <any_type>,
(70) <type_declarator> ::= <simple_type_spec> <any_declarators>;
any stands wherever <type_spec> stands.
Repo: crates/ast/src/node/type_.rs::TypeKind::Any,
crates/idl-lower/src/lower.rs::primitive_of.
Tests: crates/idl-lower/tests/lowering.rs::an_any_member_reaches_the_model_as_a_type_rather_than_a_broken_reference,
crates/idl-lower/tests/lowering.rs::every_any_in_a_file_shares_one_built_in_node,
crates/idl-lower/tests/lowering.rs::any_is_reachable_in_every_position_the_grammar_gives_it —
lowering.rs:702: assert_eq!(lowered.ast.type_(type_).expect("any").kind, TypeKind::Any);.
Status: done — the model carries any; no language backend emits a
language form for it (NoLanguageForm { construct: "any" }, see
idl-4.2.gaps.md §C).
§7.4.2.5 Specific Keywords — any, Object, ValueBase
Spec: §7.4.2.5, p. 44 — the keywords of the building block are any,
Object, ValueBase; all three are built-in type names.
Repo: crates/idl-cst/src/token.rs::TokenKind,
crates/ast/src/node/type_.rs::TypeKind.
Tests: crates/idl-lower/tests/lowering.rs::none_of_the_three_built_in_type_names_leaves_a_broken_reference,
crates/idl-lower/tests/lowering.rs::an_object_parameter_reaches_the_model_as_an_object_reference,
crates/idl-lower/tests/lowering.rs::object_is_reachable_in_every_position_rule_118_gives_it,
crates/idl-lower/tests/lowering.rs::a_valuebase_parameter_reaches_the_model_as_valuebase,
crates/idl-lower/tests/lowering.rs::valuebase_is_reachable_in_every_position_rule_132_gives_it —
lowering.rs:768: TypeKind::ObjectRef { interface: None }.
Status: done
§7.4.3 Building Block Interfaces – Basic
§7.4.3.3 Syntax — interface, exception, forward
Spec: §7.4.3.3, p. 45–47 — (73)–(85): interface_dcl,
interface_header, interface_body, export, interface_forward_dcl,
exception_dcl.
Repo: crates/idl-parse/src/decl.rs::parse_interface,
crates/idl-lower/src/lower.rs::interface.
Tests: crates/idl-parse/tests/parse.rs::each_declaration_form_is_recognised,
crates/idl-parse/tests/parse.rs::an_interface_with_operations_and_attributes_parses,
crates/idl-lower/tests/lowering.rs::an_exception_carries_its_members,
crates/idl-lower/tests/conformance.rs::every_fixture_parses_with_no_diagnostics_beyond_the_extensions_it_declares —
parse.rs:156: assert!(found.contains(&CstKind::Operation));.
Status: done
§7.4.3.4.2 Exceptions
Spec: §7.4.3.4.2, p. 48–49 — an exception is an aggregate with members; its name is introduced into the enclosing scope.
Repo: crates/idl-lower/src/lower.rs::structure (the exception branch),
crates/idl-lower/src/scope.rs::ScopeStack.
Tests: crates/idl-lower/tests/lowering.rs::an_exception_carries_its_members,
crates/idl-parse/tests/parse.rs::each_declaration_form_is_recognised —
lowering.rs:571: assert_eq!(any.kind(), zerodds_ast::NodeKind::Exception);.
Status: done
§7.4.3.4.3.1 Interface Header
Spec: §7.4.3.4.3.1, p. 49 — interface <identifier> [ : <interface_name> { "," <interface_name> } * ].
Repo: crates/idl-lower/src/lower.rs::interface_bases.
Tests: crates/idl-lower/tests/lowering.rs::a_component_keeps_its_supports_clause_apart_from_its_base,
crates/idl-lower/tests/conformance.rs::every_fixture_produces_a_model_with_declarations_in_it —
lowering.rs:1392: assert_eq!(component.bases.len(), 1, "the base list took the supports");.
Status: done
§7.4.3.4.3.2 Interface Inheritance
Spec: §7.4.3.4.3.2, p. 49 — base interfaces are named in the header; every inherited element is visible in the derived interface.
Repo: crates/idl-lower/src/lower.rs::interface_bases,
crates/ast/src/node/interface.rs::InterfaceNode.
Tests: crates/lang-rules/tests/inherited_operations.rs::the_cpp_class_reaches_the_bases_operation_through_its_base_clause,
crates/lang-rules/tests/inherited_operations.rs::the_java_interface_reaches_the_bases_operation_through_extends,
crates/lang-rules/tests/inherited_operations.rs::the_rust_trait_reaches_the_bases_operation_through_a_supertrait,
crates/lang-rules/tests/inherited_operations.rs::every_incomplete_language_refuses_rather_than_flattens_or_drops —
inherited_operations.rs:102: assert!(out.contains("class Derived : public Base {"), "{out}");.
Status: done
§7.4.3.4.3.2.1 Inheritance Rules
Spec: §7.4.3.4.3.2.1, p. 49–50 — the list of base interfaces may not
name one name twice; inheritance is transitive; virtual and non-virtual
are distinguished.
Repo: —
Tests: —
Status: open — there is neither a diagnostic for a base interface
named twice nor a transitive walk in the front end; the check
inheritance_rules in crates/idl-lower/src/validate.rs applies only to
TypeKind::Structure. The keyword virtual occurs nowhere in today’s
tree. The flattening in crates/lang-rules happens per column, not in the
front end.
§7.4.3.4.3.3.1 Operations
Spec: §7.4.3.4.3.3.1, p. 50–51 — <parameter_dcl> with in, out,
inout; oneway; raises ( <exception_identifier> { "," … } * );
context ( "<string_literal>" { "," … } * ).
Repo: crates/idl-lower/src/lower.rs::operation,
crates/ast/src/model.rs::add_context,
crates/ast/src/node/interface.rs::OperationNode.
Tests: crates/idl-lower/tests/conformance.rs::every_fixture_lowers_to_exactly_the_diagnostics_it_should,
crates/idl-lower/tests/conformance.rs::the_expected_diagnostics_are_the_ones_the_fixtures_actually_earn,
crates/corba-codegen/tests/model_connection.rs::oneway_survives_lowering,
crates/corba-codegen/tests/model_connection.rs::a_raises_clause_reaches_the_stub,
crates/ast/tests/node_space.rs::a_oneway_operation_is_flagged_and_a_normal_one_is_not.
Status: partial — oneway and raises are tested. For the
directions in/out/inout and for the context (…) clause there is no
test that goes through the front end: the context clause is parsed and
lowered (OperationNode::contexts), but no committed .idl file of the
tree contains one, and ParamDirection is checked only in hand-built model
tests.
§7.4.3.4.3.3.2 Attributes
Spec: §7.4.3.4.3.3.2, p. 51–52 — attribute <parameter_mode> <type_spec> <identifier> ; with readonly, as well as getraises/setraises
as their own attribute forms.
Repo: crates/idl-lower/src/lower.rs::attribute,
crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-parse/tests/parse.rs::an_interface_with_operations_and_attributes_parses,
crates/idl-lower/tests/validation.rs::an_attribute_named_like_its_type_collides,
crates/lang-rules/tests/interface_bindings.rs::an_attribute_implies_the_operations_of_seven_five_one_one_three,
crates/idl-lower/tests/conformance.rs::every_fixture_parses_with_no_diagnostics_beyond_the_extensions_it_declares.
Status: partial — readonly attribute and the derivation of the
operations are covered; getraises and setraises are parsed and lowered
(add_attribute_raises), but no test asserts anything about them. Only the
fixture crates/idl-parse/tests/fixtures/spec_features/attr_raises.idl
drives them through the pipeline, without a statement about the result.
§7.4.3.4.3.4 Forward Declaration
Spec: §7.4.3.4.3.4, p. 52 — interface <identifier> ; is the forward
declaration; the later definition completes the same node.
Repo: crates/idl-lower/src/lower.rs::forward_interface_kind,
crates/ast/src/model.rs::add_forward_interface.
Tests: crates/idl-lower/tests/lowering.rs::a_forward_declared_interface_is_completed_by_its_definition,
crates/idl-lower/tests/lowering.rs::a_forward_interface_keeps_the_form_its_header_wrote,
crates/idl-lower/tests/lowering.rs::an_interface_forward_that_is_never_defined_is_still_reported,
crates/idl-lower/tests/lowering.rs::a_reference_taken_against_a_forward_interface_survives_the_definition,
crates/idl-lower/tests/lowering.rs::a_second_full_interface_definition_is_a_duplicate_not_a_completion,
crates/idl-lower/tests/spans.rs::an_unfinished_forward_interface_points_at_the_declaration_too,
crates/lang-rules/tests/interface_bindings.rs::a_forward_declaration_without_a_definition_is_e002 —
lowering.rs:1070: assert_eq!(lowered.ast.operations_of(id).len(), 1);.
Status: done
§7.4.3.5 Specific Keywords
Spec: §7.4.3.5, p. 52–53 — the keywords of the building block.
Repo: crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier,
crates/idl-cst/tests/lexer.rs::a_keyword_is_recognised_only_in_the_spelling_table_7_6_gives —
lexer.rs:59: assert_eq!(kinds("custom")[0], TokenKind::Custom);.
Status: done
§7.4.4 Building Block Interfaces – Full
§7.4.4.4 An Interface as a Type
Spec: §7.4.4.4, p. 53 — an interface name may stand wherever
<type_spec> stands, and resolves to an object reference.
Repo: crates/idl-lower/src/lower.rs::type_ref_from_scoped_name,
crates/idl-lower/tests/interface_as_type.rs.
Tests: crates/idl-lower/tests/interface_as_type.rs::an_interface_used_as_a_type_resolves_in_every_spelling,
crates/idl-lower/tests/interface_as_type.rs::what_it_resolves_to_is_an_object_reference_and_not_the_interface,
crates/idl-lower/tests/interface_as_type.rs::the_key_is_the_declaration_s_own_scoped_name_and_not_the_written_segment,
crates/idl-lower/tests/interface_as_type.rs::a_name_that_is_not_declared_still_breaks —
interface_as_type.rs:109: assert_eq!(ast.interface(interface).expect("I").name, "I");.
Status: done
§7.4.4.4 Multiple Inheritance and Ambiguity
Spec: §7.4.4.4, p. 53 — an element inherited through two paths does not count as ambiguous; two different declarations of the same name in the visibility, on the other hand, do.
Repo: crates/lang-rules/src/adapter/interface.rs::Service::is_remote,
crates/idl-lower/src/scope.rs::ScopeStack::lookup_candidates.
Tests: crates/lang-rules/tests/interface_bindings.rs::all_operations_flattened_keeps_a_non_readonly_attributes_setter,
crates/ast/tests/resolve_profile_query.rs::an_ambiguous_name_reports_every_candidate,
crates/ast/tests/resolve_profile_query.rs::a_duplicate_scoped_name_is_reported_as_ambiguous_with_both_nodes.
Status: partial — the flattening over a diamond and the ambiguity
report on the model level are covered. A front-end diagnostic for the
ambiguity from two inherited, differently declared elements does not
exist: inheritance_rules in crates/idl-lower/src/validate.rs knows only
TypeKind::Structure as an inheritance carrier.
§7.4.4.4 Attribute and Operation with the Same Name
Spec: §7.4.4.4, p. 53 — attribute and operation names share one namespace within the interface body.
Repo: —
Tests: —
Status: open — code exists: one_namespace_per_scope (crates/idl-lower/src/lower.rs) collects attribute and operation names into one name list; no test creates an attribute and an operation of the same name in one interface.
§7.4.4.5 Specific Keywords
Spec: §7.4.4.5, p. 53 — “There are no additional keywords with this building block.”
Repo: crates/idl-cst/src/token.rs::KEYWORDS.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier.
Status: n/a (informative) — the clause itself says there are no
additional keywords; there is nothing to check.
§7.4.5 Building Block Value Types
§7.4.5.3 Syntax
Spec: §7.4.5.3, p. 54 — (125)–(131): valuetype_dcl,
valuetype_header, valuetype_body, state_member, init_dcl.
Repo: crates/idl-lower/src/lower.rs::valuetype,
crates/idl-lower/src/lower.rs::valuetype_kind.
Tests: crates/idl-lower/tests/dialects.rs::a_valuetype_keeps_its_modifier_bases_and_supported_interfaces,
crates/idl-parse/tests/parse.rs::each_declaration_form_is_recognised,
crates/idl-lower/tests/conformance.rs::every_fixture_lowers_to_exactly_the_diagnostics_it_should —
dialects.rs:550: assert_eq!(state.len(), 2, "a state member was lost");.
Status: done
§7.4.5.4.1 Concrete (Stateful) Value Types
Spec: §7.4.5.4.1, p. 55 — a concrete value type carries state members
and modifiers (custom, abstract, truncatable).
Repo: crates/idl-lower/src/lower.rs::valuetype,
crates/ast/src/node/type_.rs::ValuetypeKind.
Tests: crates/idl-lower/tests/dialects.rs::a_valuetype_keeps_its_modifier_bases_and_supported_interfaces,
crates/idl-lower/tests/lowering.rs::an_abstract_valuetype_parses_as_a_valuetype,
crates/ccm/tests/equivalent_idl.rs::a_plain_valuetype_is_not_an_event_type —
lowering.rs:1316: assert_eq!(kind, zerodds_ast::ValuetypeKind::Abstract);.
Status: done
§7.4.5.4.1.2 Value Inheritance Specification
Spec: §7.4.5.4.1.2, p. 55 — the header allows a base
(: supports
Repo: crates/idl-lower/src/lower.rs::interface_bases (the supports
alternative).
Tests: crates/idl-lower/tests/dialects.rs::a_valuetype_keeps_its_modifier_bases_and_supported_interfaces,
crates/idl-lower/tests/lowering.rs::a_component_keeps_its_supports_clause_apart_from_its_base —
lowering.rs:1398: assert_eq!(supports, 2, "the supports clause was dropped");.
Status: done
§7.4.5.4.1.3.1 State Members
Spec: §7.4.5.4.1.3.1, p. 55 — public <member_type_spec> <simple_declarator> and private …; the visibility belongs to the value
type, not to the struct member.
Repo: crates/idl-lower/src/lower.rs::valuetype (the state member
branch), crates/ast/src/facet/corba.rs::state_visibility.
Tests: crates/idl-lower/tests/lowering.rs::a_state_member_keeps_the_keyword_it_was_written_with,
crates/idl-lower/tests/lowering.rs::a_struct_member_has_no_state_visibility —
lowering.rs:1414: Some(zerodds_ast::StateVisibility::Public),.
Status: done
§7.4.5.4.1.3.2 Initializers
Spec: §7.4.5.4.1.3.2, p. 55–56 — factory <identifier> ( … ) ; becomes
an operation of the value type.
Repo: crates/idl-lower/src/lower.rs::template_formals (the initialiser
in the valuetype branch), crates/idl-parse/src/decl.rs::parse_factory.
Tests: crates/idl-lower/tests/dialects.rs::a_valuetype_initialiser_becomes_an_operation_of_it,
crates/ccm/tests/equivalent_idl.rs::a_factory_is_emitted_with_create_failure_first_in_its_raises —
dialects.rs:569: assert_eq!(state.len(), 1, "the operation was counted as state");.
Status: partial — no test checks that the factory declaration
appears as an operation of the value type; the cited test only checks
that it is not counted as a state member.
§7.4.5.4.2 Forward Declarations
Spec: §7.4.5.4.2, p. 56 — valuetype <identifier> ; is completed by
the definition.
Repo: crates/idl-lower/src/lower.rs::valuetype_kind,
crates/ast/src/model.rs::add_forward_interface.
Tests: crates/idl-lower/tests/lowering.rs::a_forward_declared_valuetype_is_completed_by_its_definition,
crates/idl-lower/tests/lowering.rs::a_valuetype_forward_that_is_never_defined_is_still_reported,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(bb5-110-value-forward) —
lowering.rs:1361: assert_eq!(declared.len(), 1, "{source:?}: two nodes for one name");.
Status: done
§7.4.5.5 Specific Keywords
Spec: §7.4.5.5, p. 56 — the keywords of the building block.
Repo: crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier —
lexer.rs:73: assert_eq!(kinds("TRUE")[0], TokenKind::True);.
Status: done
§7.4.6 Building Block CORBA-Specific – Interfaces
§7.4.6.3 Syntax — repository directives, local, native
Spec: §7.4.6.3, p. 58–59 — (112)–(124): type_id_dcl,
type_prefix_dcl, import_dcl, local, native, context_dcl,
context_spec, op_oneway_dcl.
Repo: crates/idl-lower/src/complete.rs::apply_repository_directives,
crates/idl-parse/src/decl.rs (the typeid, typeprefix, import
branches).
Tests: crates/idl-lower/tests/idl_4_2_grammar.rs::typeprefix_and_import_inside_an_interface_body_parse,
crates/idl-lower/tests/lowering.rs::a_native_declaration_becomes_a_native_type,
crates/idl-parse/tests/parse.rs::each_declaration_form_is_recognised —
lowering.rs:578: assert_eq!(ast.type_(handle).expect("Handle").kind, TypeKind::Native);.
Status: done
§7.4.6.4.1.1 Repository Identity Declaration (typeid)
Spec: §7.4.6.4.1.1, p. 59 — typeid <identifier> <string_literal> ;
sets the repository id outright.
Repo: crates/idl-lower/src/complete.rs::derive_repository_ids,
crates/corba-codegen/src/repository_id.rs.
Tests: crates/idl-lower/tests/dialects.rs::a_typeid_directive_sets_the_id_outright,
crates/idl-lower/tests/idl_4_2_grammar.rs::a_typeid_inside_an_interface_body_sets_the_id,
crates/idl-lower/tests/dialects.rs::a_pragma_id_sets_the_repository_id_like_typeid_does,
crates/corba-codegen/tests/model_connection.rs::an_interfaces_repository_id_comes_from_the_model —
idl_4_2_grammar.rs:188: Some("IDL:Ia:2.0").
Status: done
§7.4.6.4.1.2 Repository Identifier Prefix Declaration (typeprefix)
Spec: §7.4.6.4.1.2, p. 59–60 — typeprefix <scoped_name> <string_literal> ; preforms all ids derived beneath it.
Repo: crates/idl-lower/src/complete.rs::apply_repository_directives
and derived_repository_id, crates/corba-codegen/src/repository_id.rs.
Tests: crates/idl-lower/tests/dialects.rs::a_typeprefix_directive_prefixes_the_ids_derived_below_it,
crates/idl-lower/tests/dialects.rs::a_typeprefix_may_name_the_module_it_is_written_in,
crates/idl-lower/tests/dialects.rs::the_root_anchored_spelling_names_the_same_module,
crates/idl-lower/tests/dialects.rs::a_sibling_declaration_wins_over_one_further_out,
crates/idl-lower/tests/dialects.rs::a_directive_naming_nothing_is_still_reported,
crates/idl-lower/tests/dialects.rs::a_pragma_prefix_prefixes_the_ids_of_its_module,
crates/corba-codegen/tests/model_connection.rs::a_prefix_reaches_an_interface_and_an_exception —
model_connection.rs:447: assert_eq!(resolved.id, "IDL:omg.org/CosNaming/NamingContext:1.0");.
Status: done
§7.4.6.4.1.3 Repository Id Conflict
Spec: §7.4.6.4.1.3, p. 60 — two declarations that yield the same repository id are a conflict.
Repo: crates/idl-lower/src/complete.rs::derived_repository_id,
crates/corba-codegen/src/repository_id.rs.
Tests: crates/idl-lower/tests/dialects.rs::a_directive_naming_nothing_is_still_reported,
crates/corba-codegen/tests/model_connection.rs::a_types_repository_id_is_the_models_and_not_a_second_derivation.
Status: partial — the derivation is unique (one prefix, one
typeid); a dedicated conflict test for two declarations with the same
derived id does not exist. The present test checks the negative side (a
reference to nothing is reported).
§7.4.6.4.1.4 Imports
Spec: §7.4.6.4.1.4, p. 60–61 — import <scoped_name> ; stays in the
model as written.
Repo: crates/idl-lower/src/lower.rs::interface (the import branch),
crates/idl-parse/src/decl.rs.
Tests: crates/idl-lower/tests/dialects.rs::an_import_is_kept_as_written,
crates/idl-lower/tests/dialects.rs::a_declaration_in_an_interface_is_named_through_it,
crates/idl-lower/tests/idl_4_2_grammar.rs::typeprefix_and_import_inside_an_interface_body_parse —
dialects.rs:349: assert_eq!(imports, vec!["IDL:Other:1.0".to_string()]);.
Status: done
§7.4.6.4.3 Local Interfaces
Spec: §7.4.6.4.3, p. 62 — local interface <identifier> … is an
interface without endpoints.
Repo: crates/idl-lower/src/lower.rs::interface_bases (setting
InterfaceKind::Local), crates/lang-rules/src/adapter/interface.rs::Service::is_remote.
Tests: crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/idl-lower/tests/lowering.rs::a_forward_interface_keeps_the_form_its_header_wrote,
crates/corba-codegen/tests/annex_a1_traits.rs::table_a2_reads_local_and_abstract_off_the_interface_declaration,
crates/lang-rules/tests/interface_bindings.rs::a_local_interface_is_refused_by_the_seam —
interface_bindings.rs:742: assert!(interface_cpp::cpp_interface_items(&ast).is_err());.
Status: done — a local interface has no endpoints: the service binding refuses it (DDS-RPC 1.0 §7.3.1.1 production 7) and no language writes a class for it.
§7.4.6.4.4 Use of Native Types
Spec: §7.4.6.4.4, p. 62–63 — a native type may stand wherever a type is demanded.
Repo: crates/idl-parse/src/decl.rs::parse_native,
crates/idl-lower/src/lower.rs::native.
Tests: crates/idl-lower/tests/lowering.rs::a_native_declaration_becomes_a_native_type,
crates/idl-lower/tests/conformance.rs::the_xtypes_specifications_own_idl_lowers_completely.
Status: partial — the declaration is covered, the use as a member
type spec (production 62) is not; see the item on §7.4.1.3.
§7.4.6.4.6 Context Expressions
Spec: §7.4.6.4.6, p. 63 — context ( "<string>" { "," <string> } * )
on an operation; the strings are expressions.
Repo: —
Tests: —
Status: open — code exists: parsed and lowered (crates/idl-lower/src/lower.rs::operation, OperationNode::contexts); no test, no committed .idl file writes a context, the probe bb6-123-op-with-context in tools/idl-4.2-gap-scan/ has fixtures = 0.
§7.4.6.4.7 CORBA Module
Spec: §7.4.6.4.7, p. 63–64 — the module CORBA is predefined; it
carries Object, ValueBase and the standard exceptions.
Repo: —
Tests: —
Status: open — there is no module CORBA in any committed .idl
file of the tree, no symbol in crates/idl-parse/src or
crates/idl-lower/src and no probe. Object and ValueBase are reachable
as built-in type names (§7.4.2.5), but not through a module whose content
one could resolve.
§7.4.6.5 Specific Keywords
Spec: §7.4.6.5, p. 64 — the keywords of the building block.
Repo: crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier —
lexer.rs:73: assert_eq!(kinds("TRUE")[0], TokenKind::True);.
Status: done
§7.4.7 Building Block CORBA-Specific – Value Types
§7.4.7.3 Syntax
Spec: §7.4.7.3, p. 64–65 — the value type productions with custom,
abstract, truncatable, the value box and the ValueBase.
Repo: crates/idl-lower/src/lower.rs::valuetype_kind,
crates/idl-lower/src/lower.rs::value_box.
Tests: crates/idl-lower/tests/lowering.rs::a_value_box_reaches_the_model_as_one,
crates/idl-lower/tests/lowering.rs::a_value_box_may_box_any_type_spec,
crates/idl-lower/tests/lowering.rs::the_other_valuetype_forms_are_unaffected_by_the_box,
crates/idl-lower/tests/lowering.rs::an_abstract_valuetype_parses_as_a_valuetype —
lowering.rs:1224: TypeKind::Primitive(PrimitiveKind::Int32).
Status: done
§7.4.7.4.1 Boxed Value Types
Spec: §7.4.7.4.1, p. 65–66 — the value box is a state without a
public/private marking and with a box variable.
Repo: crates/idl-lower/src/lower.rs::value_box,
crates/corba-codegen/src/traits.rs.
Tests: crates/idl-lower/tests/lowering.rs::a_value_box_reaches_the_model_as_one,
crates/idl-lower/tests/lowering.rs::a_value_box_may_box_any_type_spec,
crates/idl-lower/tests/lowering.rs::a_value_box_round_trips_byte_for_byte,
crates/corba-codegen/tests/annex_a1_traits.rs::table_a9_gives_a_valuebox_its_boxed_trait —
annex_a1_traits.rs:281: Some(TraitDefinition::TraitsOf("long".to_string())).
Status: done
§7.4.7.4.2 Abstract Value Types and Abstract Interfaces
Spec: §7.4.7.4.2, p. 66–67 — abstract valuetype and abstract interface.
Repo: crates/idl-lower/src/lower.rs::valuetype_kind,
crates/ast/src/node/type_.rs::ValuetypeKind.
Tests: crates/idl-lower/tests/lowering.rs::an_abstract_valuetype_parses_as_a_valuetype,
crates/idl-lower/tests/lowering.rs::abstract_still_reaches_the_interface_header_it_also_belongs_to,
crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/corba-codegen/tests/annex_a1_traits.rs::table_a8_reads_abstract_and_truncatable_off_the_declaration —
annex_a1_traits.rs:269: Some(TraitDefinition::Flag(true)).
Status: done
§7.4.7.4.3 Value Inheritance Rules
Spec: §7.4.7.4.3, p. 67–68 — the rules for which combinations of
abstract, custom, truncatable, base and supports are admissible.
Repo: —
Tests: —
Status: open — there is no check of these combinations. The only
comparison of inheritance in the front end, inheritance_rules in
crates/idl-lower/src/validate.rs, applies exclusively to
TypeKind::Structure { base }; a Valuetype carries no base there.
§7.4.7.4.4 Custom Marshaling
Spec: §7.4.7.4.4, p. 68–69 — custom valuetype; the marshaling
operations are part of the definition.
Repo: crates/idl-lower/src/lower.rs::valuetype_kind (sets
ValuetypeKind::Custom), crates/corba-codegen/src/skeleton.rs.
Tests: crates/idl-lower/tests/dialects.rs::a_valuetype_keeps_its_modifier_bases_and_supported_interfaces,
crates/idl-lower/tests/lowering.rs::the_other_valuetype_forms_are_unaffected_by_the_box.
Status: partial — the keyword custom is recognised and carried in
the model as ValuetypeKind::Custom. The marshal/unmarshal operations are
not recognised as such and not mapped onto skeleton operations; the test
checks the variant, not the rule.
§7.4.7.4.5 Truncatable
Spec: §7.4.7.4.5, p. 69 — truncatable allows an unknown extension to
be cut when marshaling.
Repo: crates/idl-lower/src/lower.rs::valuetype_kind,
crates/corba-codegen/src/traits.rs.
Tests: crates/idl-lower/tests/dialects.rs::a_valuetype_keeps_its_modifier_bases_and_supported_interfaces,
crates/corba-codegen/tests/annex_a1_traits.rs::table_a8_reads_abstract_and_truncatable_off_the_declaration.
Status: partial — truncatable is recorded as a modifier and
evaluated in Table A.8. The truncation itself is not carried as such in
crates/corba-codegen/src/skeleton.rs and has no test.
§7.4.7.4.6 Value Base
Spec: §7.4.7.4.6, p. 69–70 — ValueBase is the built-in base type of
a custom valuetype.
Repo: crates/ast/src/node/type_.rs::TypeKind::ValueBase,
crates/corba-codegen/tests/orb_agreement.rs.
Tests: crates/idl-lower/tests/lowering.rs::a_valuebase_parameter_reaches_the_model_as_valuebase,
crates/idl-lower/tests/lowering.rs::valuebase_is_reachable_in_every_position_rule_132_gives_it,
crates/idl-lower/tests/lowering.rs::none_of_the_three_built_in_type_names_leaves_a_broken_reference.
Status: partial — in the model ValueBase is present and reachable
in every position; no language backend emits a form for it. The probe
bb7-132-valuebase stands in expected.tsv for Rust and C on err
(NoLanguageForm { construct: "ValueBase" }).
§7.4.8 Building Block Components – Basic
§7.4.8.3 Syntax
Spec: §7.4.8.3, p. 70–71 — (135)–(144): component_dcl,
component_header, component_body, export, provides_dcl,
uses_dcl, port_dcl.
Repo: crates/idl-parse/src/decl.rs::parse_port and
parse_component, crates/idl-lower/src/lower.rs::interface and port.
Tests: crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/idl-lower/tests/dialects.rs::each_port_form_reaches_its_own_component_role,
crates/idl-lower/tests/conformance.rs::every_fixture_parses_with_no_diagnostics_beyond_the_extensions_it_declares,
tools/idlc/tests/idl_4_2_gaps.rs::the_fixture_directory_holds_exactly_the_named_fixtures —
dialects.rs:103: ComponentRole::Receptacle { multiple, .. } => assert!(!multiple),.
Status: done
§7.4.8.4.1 Component Header
Spec: §7.4.8.4.1, p. 71 — component <identifier> [ : <component_name> { "," … } * ] [ supports <interface_identifier> { "," … } * ].
Repo: crates/idl-lower/src/lower.rs::interface_bases.
Tests: crates/idl-lower/tests/lowering.rs::a_component_keeps_its_supports_clause_apart_from_its_base,
crates/ccm/tests/equivalent_idl.rs::a_component_with_supports_inherits_ccmobject_and_the_supported_ones,
crates/ccm/tests/equivalent_idl.rs::a_derived_component_with_supports_lists_the_base_first_and_then_the_supported —
equivalent_idl.rs:169: assert_eq!(base_names(&ast, component), ["B", "I1", "I2"]);.
Status: done
§7.4.8.4.2.1 Facets and §7.4.8.4.2.2 Receptacles
Spec: §7.4.8.4.2.1 / §7.4.8.4.2.2, p. 71–72 — provides yields a
facet, uses a receptacle; both name the interface they carry.
Repo: crates/idl-lower/src/lower.rs::port,
crates/ast/src/facet/corba.rs::ComponentRole::{Facet, Receptacle},
crates/ccm/src/transform.rs::transform_component.
Tests: crates/idl-lower/tests/dialects.rs::each_port_form_reaches_its_own_component_role,
crates/idl-lower/tests/lowering.rs::a_ports_role_resolves_the_interface_or_event_behind_it,
crates/ccm/tests/equivalent_idl.rs::provides_yields_a_provide_operation_returning_the_facet,
crates/ccm/tests/equivalent_idl.rs::uses_simplex_yields_connect_disconnect_and_get_connection,
crates/ccm/tests/equivalent_idl.rs::uses_multiple_returns_a_cookie_and_the_plural_getter.
Status: partial — tested in the model and in the CCM rewrite. Both
backends refuse the construct because the Object type carried by a port
has no language form (NoLanguageForm { construct: "Object", language: "Rust" }, the same message for C); that is recorded in
idl-4.2.gaps.md §C.2.
§7.4.8.4.2.3 Component Attributes
Spec: §7.4.8.4.2.3, p. 72 — attribute <param_mode> <type_spec> <identifier> ; in the component body.
Repo: crates/idl-lower/src/lower.rs::attribute.
Tests: crates/ccm/tests/equivalent_idl.rs::a_basic_component_carries_its_attributes_and_no_port_operation,
crates/ccm/tests/equivalent_idl.rs::a_component_attribute_is_left_alone —
equivalent_idl.rs:324: assert_eq!(ast.attribute(attributes[0]).expect("rate").name, "rate");.
Status: done
§7.4.8.4.3 Forward Declaration
Spec: §7.4.8.4.3, p. 73 — component <identifier> ;.
Repo: crates/idl-lower/src/lower.rs::forward_interface_kind,
crates/ast/src/model.rs::add_forward_interface.
Tests: crates/idl-lower/tests/lowering.rs::a_forward_declared_component_is_completed_by_its_definition,
crates/idl-lower/tests/lowering.rs::a_component_forward_that_is_never_defined_is_still_reported,
crates/idl-lower/tests/lowering.rs::every_component_model_forward_keeps_its_own_form —
lowering.rs:1195: assert_eq!(node.kind, expected, "{source:?}");.
Status: done
§7.4.8.5 Specific Keywords
Spec: §7.4.8.5, p. 73 — the keywords of the building block.
Repo: crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier —
lexer.rs:73: assert_eq!(kinds("TRUE")[0], TokenKind::True);.
Status: done
§7.4.9 Building Block Components – Homes
§7.4.9.3 Syntax
Spec: §7.4.9.3, p. 74–75 — (145)–(154): home_dcl, home_header,
home_body, manages_dcl, primarykey_dcl, factory_dcl,
finder_dcl.
Repo: crates/idl-parse/src/decl.rs::parse_factory,
crates/idl-lower/src/lower.rs::manages_clause.
Tests: crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/idl-lower/tests/dialects.rs::a_home_records_what_it_manages_and_the_key_it_does_so_by,
crates/idl-lower/tests/conformance.rs::every_fixture_parses_with_no_diagnostics_beyond_the_extensions_it_declares —
dialects.rs:146: assert!(manages.component.is_resolved(), "the component was lost");.
Status: done
§7.4.9.4.1 Home Header
Spec: §7.4.9.4.1, p. 75 — abstract home <identifier> …,
home <identifier> …, home <identifier> for <scoped_name> … and the
clause manages <component> ;.
Repo: crates/idl-lower/src/lower.rs::manages_clause
(zerodds_ast::HomeManages).
Tests: crates/idl-lower/tests/lowering.rs::a_home_resolves_what_it_manages_and_the_key_it_manages_by,
crates/idl-lower/tests/dialects.rs::a_home_records_what_it_manages_and_the_key_it_does_so_by,
crates/ccm/tests/equivalent_idl.rs::a_keyless_home_yields_an_implicit_inheriting_keylesscmhome,
crates/ccm/tests/equivalent_idl.rs::a_keyed_home_yields_the_four_operations_and_inherits_nothing.
Status: partial — home with manages and the inheritance are
covered. abstract home and home <identifier> for <scoped_name> are not:
the keyword abstract reaches an expect(TokenKind::Interface) spot in
crates/idl-parse/src/decl.rs::parse_interface, and the string home for
does not occur in the tree.
§7.4.9.4.2 Home Body — factory, finder, primarykey
Spec: §7.4.9.4.2, p. 75–76 — factory and finder become operations
of the home; primary key names the key type.
Repo: crates/idl-lower/src/lower.rs::manages_clause,
crates/ccm/src/transform.rs::transform_home,
crates/ccm/src/validate.rs::validate_primary_key.
Tests: crates/ccm/tests/equivalent_idl.rs::a_factory_is_emitted_with_create_failure_first_in_its_raises,
crates/ccm/tests/equivalent_idl.rs::a_finder_is_emitted_with_finder_failure_and_the_callers_own_raises,
crates/ccm/tests/equivalent_idl.rs::a_primary_key_with_a_public_scalar_member_is_accepted,
crates/ccm/tests/equivalent_idl.rs::a_primary_key_without_the_base_is_rejected,
crates/ccm/tests/equivalent_idl.rs::a_primary_key_with_a_private_member_is_rejected,
crates/ccm/tests/equivalent_idl.rs::a_primary_key_holding_an_object_reference_is_rejected,
crates/ccm/tests/equivalent_idl.rs::a_primary_key_holding_a_nested_struct_is_accepted —
equivalent_idl.rs:691: assert_eq!(raises.len(), 2, "FinderFailure plus the caller's own");.
Status: done
§7.4.9.5 Specific Keywords
Spec: §7.4.9.5, p. 76 — the keywords of the building block.
Repo: crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier —
lexer.rs:73: assert_eq!(kinds("TRUE")[0], TokenKind::True);.
Status: done
§7.4.10 Building Block CCM-Specific
§7.4.10.3 Syntax — eventtype and Event Ports
Spec: §7.4.10.3, p. 77–78 — (166)–(172): eventtype_dcl,
eventtype_header, eventtype_body, eventtype_forward_dcl,
emits_dcl, publishes_dcl, consumes_dcl.
Repo: crates/idl-lower/src/lower.rs::valuetype and port,
crates/ccm/src/transform.rs::transform_event_type.
Tests: crates/idl-lower/tests/dialects.rs::each_port_form_reaches_its_own_component_role,
crates/idl-lower/tests/dialects.rs::each_template_parameter_kind_is_distinguished,
crates/ccm/tests/equivalent_idl.rs::the_first_event_type_of_a_chain_inherits_event_base,
crates/ccm/tests/equivalent_idl.rs::one_event_type_yields_one_consumer_interface_however_many_ports_name_it,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends —
equivalent_idl.rs:492: assert_eq!(bases.len(), 1, "EventBase was not added");.
Status: done
§7.4.10.4.1.2 Event Ports
Spec: §7.4.10.4.1.2, p. 78–79 — emits, publishes and consumes
differ in whether a cookie comes back.
Repo: crates/idl-lower/src/lower.rs::port
(ComponentRole::EventSource with publisher),
crates/ccm/src/transform.rs::transform_component.
Tests: crates/idl-lower/tests/dialects.rs::each_port_form_reaches_its_own_component_role,
crates/ccm/tests/equivalent_idl.rs::emits_yields_connect_and_disconnect_and_the_consumer_interface,
crates/ccm/tests/equivalent_idl.rs::publishes_yields_subscribe_returning_a_cookie,
crates/ccm/tests/equivalent_idl.rs::consumes_yields_a_get_consumer_operation —
equivalent_idl.rs:283: assert!(names.contains(&"unsubscribe_ticker".to_string()));.
Status: done
§7.4.10.4.2.1 Supported Interfaces
Spec: §7.4.10.4.2.1, p. 79 — supports in the component and in the
home header.
Repo: crates/idl-lower/src/lower.rs::interface_bases,
crates/ccm/src/transform.rs.
Tests: crates/idl-lower/tests/lowering.rs::a_component_keeps_its_supports_clause_apart_from_its_base,
crates/ccm/tests/equivalent_idl.rs::a_component_with_supports_inherits_ccmobject_and_the_supported_ones,
crates/ccm/tests/equivalent_idl.rs::a_home_with_supports_puts_the_supported_interfaces_on_its_explicit,
crates/ccm/tests/equivalent_idl.rs::a_derived_home_with_supports_extends_the_base_explicit —
equivalent_idl.rs:476: ["CManagerBaseExplicit", "IExtra"].
Status: done
§7.4.10.4.3 Multiple Uses
Spec: §7.4.10.4.3, p. 80 — uses <type> <name> for <multiport_type> ; allows several ports under one name.
Repo: crates/idl-lower/src/lower.rs::port
(ComponentRole::Receptacle { multiple }),
crates/ccm/src/transform.rs::transform_component.
Tests: crates/idl-lower/tests/dialects.rs::each_port_form_reaches_its_own_component_role,
crates/ccm/tests/equivalent_idl.rs::uses_multiple_returns_a_cookie_and_the_plural_getter —
equivalent_idl.rs:250: assert!(names.contains(&"get_connections_managers".to_string()));.
Status: done
§7.4.10.4.4.2 Object Root
Spec: §7.4.10.4.4.2, p. 80 — a component may carry Object as its
object root.
Repo: —
Tests: —
Status: open — code exists: the form is parsed and lowered (crates/idl-parse/src/decl.rs::parse_port, ComponentRole::Facet with Ref::Broken); no test, the fixture crates/idl-parse/tests/fixtures/spec_features/ccm_components.idl is only checked for parse diagnostics. Both backends refuse the probe bb8-141-provides because Object has no language form.
§7.4.10.5 Specific Keywords
Spec: §7.4.10.5, p. 80 — the keywords of the building block.
Repo: crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier —
lexer.rs:73: assert_eq!(kinds("TRUE")[0], TokenKind::True);.
Status: done
§7.4.11 Building Block Components – Ports and Connectors
§7.4.11.3 Syntax
Spec: §7.4.11.3, p. 83–84 — (173)–(183): porttype_dcl,
porttype_header, porttype_body, connector_dcl, connector_header,
connector_body, bridge_dcl, provides_dcl, uses_dcl.
Repo: crates/idl-parse/src/decl.rs, crates/idl-lower/src/lower.rs::port.
Tests: crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/idl-lower/tests/lowering.rs::every_component_model_forward_keeps_its_own_form —
dialects.rs:67: ("connector K { };", "K", InterfaceKind::Connector),.
Status: done
§7.4.11.4.1.1 Port Type Declaration
Spec: §7.4.11.4.1.1, p. 83 — porttype <identifier> [ : <porttype_name> … ] { <porttype_export> * }.
Repo: crates/idl-lower/src/lower.rs::interface (InterfaceKind::PortType),
crates/lang-rules/src/adapter/interface.rs::Service::is_remote.
Tests: crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/idl-lower/tests/lowering.rs::every_component_model_forward_keeps_its_own_form.
Status: partial — present in the model and tested as
InterfaceKind::PortType; Service::is_remote excludes PortType from
every DDS-RPC binding. No language backend emits a port type binding (the
probes bb11-173 and bb11-174 stand on err), and there is no test that
asserts ComponentRole::PortTypeRole reaches the model.
§7.4.11.4.3 Connectors
Spec: §7.4.11.4.3, p. 84 — connector <identifier> … describes a
bridge; <provides>/<uses> with port/mirrorport form it.
Repo: crates/idl-lower/src/lower.rs::port
(ComponentRole::ConnectorRole), crates/ccm/src/transform.rs::transform_component.
Tests: crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/idl-lower/tests/lowering.rs::every_component_model_forward_keeps_its_own_form,
tools/idlc/tests/idl_4_2_gaps.rs::the_fixture_directory_holds_exactly_the_named_fixtures.
Status: partial — connector is present in the model as
InterfaceKind::Connector; the port/mirrorport members are parsed and
lowered, but the CCM rewrite deliberately discards them
(crates/ccm/src/transform.rs, line 255 ff., with the comment that the
mapping through the port type is not §6 of this specification). No test
asserts anything about ComponentRole::ConnectorRole.
§7.4.11.5 Specific Keywords
Spec: §7.4.11.5, p. 84 — the keywords of the building block.
Repo: crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier —
lexer.rs:73: assert_eq!(kinds("TRUE")[0], TokenKind::True);.
Status: done
§7.4.12 Building Block Template Modules
§7.4.12.3 Syntax
Spec: §7.4.12.3, p. 86–87 — (186)–(194): template_dcl,
formal_parameters, formal_parameter, actual_parameters,
actual_parameter, template_module_instantiation,
template_module_ref.
Repo: crates/idl-lower/src/lower.rs::template_module_inst,
crates/idl-lower/src/lower.rs::template_formals,
crates/idl-parse/src/decl.rs::at_template_module_inst.
Tests: crates/idl-lower/tests/dialects.rs::a_template_modules_parameters_reach_its_facet,
crates/idl-lower/tests/dialects.rs::each_template_parameter_kind_is_distinguished,
crates/idl-lower/tests/conformance.rs::every_fixture_parses_with_no_diagnostics_beyond_the_extensions_it_declares,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(bb12-185-template-module) —
dialects.rs:170: assert_eq!(params.len(), 2);.
Status: done
§7.4.12.4.1 Template Module Declaration
Spec: §7.4.12.4.1, p. 87–88 — module <identifier> < formal_parameters > { … }; the formal types are typename, struct,
union, enum, exception, interface, valuetype, eventtype and
sequence.
Repo: crates/idl-lower/src/lower.rs::template_formals,
crates/ast/src/facet/corba.rs::TemplateParamKind.
Tests: crates/idl-lower/tests/dialects.rs::each_template_parameter_kind_is_distinguished,
crates/idl-lower/tests/dialects.rs::a_sequence_type_formal_parameter_parses_and_carries_its_element,
crates/idl-lower/tests/dialects.rs::the_bare_sequence_classifier_still_parses_as_itself,
crates/idl-lower/tests/dialects.rs::a_bounded_sequence_parameter_keeps_its_bound,
crates/idl-lower/tests/dialects.rs::a_template_module_declares_no_types_of_its_own —
dialects.rs:205: assert_eq!(params.first().map(|p| p.kind), Some(expected), "{written}");.
Status: done
§7.4.12.4.2 Template Module Instantiation
Spec: §7.4.12.4.2, p. 88–89 — module <identifier> < actual_parameters > <identifier> ;; alias passes a formal type on.
Repo: crates/idl-lower/src/lower.rs::template_module_inst,
crates/idl-lower/src/lower.rs::template_body.
Tests: crates/idl-lower/tests/dialects.rs::an_instantiation_lowers_the_body_with_the_actual_substituted,
crates/idl-lower/tests/dialects.rs::two_instantiations_of_one_template_are_two_independent_modules,
crates/idl-lower/tests/dialects.rs::a_const_actual_parameter_becomes_a_constant_of_the_instance,
crates/idl-lower/tests/dialects.rs::an_alias_hands_the_enclosing_templates_parameter_on,
crates/idl-lower/tests/dialects.rs::an_instantiation_of_a_template_nobody_declared_is_reported_by_name,
crates/idl-lower/tests/dialects.rs::an_instantiation_with_the_wrong_number_of_actuals_is_reported,
crates/idl-lower/tests/dialects.rs::a_plain_module_is_untouched_by_the_instantiation_lookahead —
dialects.rs:1462: zerodds_ast::TypeKind::Primitive(zerodds_ast::PrimitiveKind::Int32).
Status: done
§7.4.12.5 Specific Keywords
Spec: §7.4.12.5, p. 89 — the only additional keyword of the building
block is alias.
Repo: crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier,
crates/idl-lower/tests/dialects.rs::an_alias_hands_the_enclosing_templates_parameter_on —
dialects.rs:1516: assert!(names.contains(&"Concrete::S".to_string()), "{names:?}");.
Status: done
§7.4.13 Building Block Extended Data Types
§7.4.13.4.1 Structures with Single Inheritance
Spec: §7.4.13.4.1, p. 89 — a structure may inherit from at most one
other; the extensibility of the base continues, and an @id newly given in
the derived structure is correct.
Repo: crates/ast/src/node/type_.rs::TypeKind::Structure { base },
crates/idl-lower/src/validate.rs::inheritance_rules.
Tests: crates/idl-lower/tests/lowering.rs::a_struct_with_a_base_records_it,
crates/idl-parse/tests/parse.rs::a_struct_with_a_base_records_its_inheritance,
crates/idl-lower/tests/keys_and_inheritance.rs::a_derived_structure_with_another_extensibility_than_its_base_is_refused,
crates/idl-lower/tests/keys_and_inheritance.rs::a_member_name_of_the_base_chain_cannot_be_declared_again,
crates/idl-lower/tests/keys_and_inheritance.rs::a_member_id_of_the_base_chain_cannot_be_given_again,
crates/idl-lower/tests/completion.rs::a_derived_structure_that_said_nothing_has_its_bases_extensibility,
crates/idl-lower/tests/completion.rs::the_callers_default_extensibility_does_not_override_a_bases —
keys_and_inheritance.rs:95: assert_eq!(out.ast.effective_extensibility(id), Extensibility::Mutable);.
Status: done
§7.4.13.4.1 Void Content
Spec: §7.4.13.4.1, p. 89 — a structure without members (struct S { };)
is admissible in this building block.
Repo: crates/ast/src/node/type_.rs::TypeKind::Structure,
crates/idl-lower/src/validate.rs::validate_type.
Tests: crates/idl-lower/tests/validation.rs::the_two_bodies_the_grammar_does_let_be_empty_stay_empty,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends.
Status: partial — the empty struct is accepted and the model carries
it; the C backend refuses it (NoLanguageForm, C23 §6.7.2.1p8 leaves a
structure without a named member undefined). Rust emits it.
§7.4.13.4.2 Union Discriminators
Spec: §7.4.13.4.2, p. 89–90 — the admissible types are the integer
types, boolean, char, octet and an enumeration; a case label must lie
in the value range of the discriminator.
Repo: crates/idl-lower/src/validate.rs::is_legal_discriminator,
crates/idl-lower/src/validate.rs::label_is_in_range.
Tests: crates/idl-lower/tests/validation.rs::each_legal_discriminator_type_is_accepted,
crates/idl-lower/tests/validation.rs::an_enum_discriminator_is_accepted,
crates/idl-lower/tests/validation.rs::a_typedef_to_a_legal_discriminator_is_accepted,
crates/idl-lower/tests/validation.rs::a_float_discriminator_is_rejected,
crates/idl-lower/tests/validation.rs::a_string_discriminator_is_rejected,
crates/idl-lower/tests/validation.rs::a_struct_discriminator_is_rejected,
crates/idl-lower/tests/validation.rs::a_case_label_outside_the_discriminators_range_is_rejected,
crates/idl-lower/tests/validation.rs::a_case_label_inside_the_range_is_accepted,
crates/idl-lower/tests/validation.rs::a_boolean_discriminator_admits_only_zero_and_one,
crates/idl-lower/tests/validation.rs::only_a_unions_discriminator_may_be_a_key,
crates/idl-lower/tests/validation.rs::no_union_member_is_optional,
crates/idl-lower/tests/annotations.rs::a_key_on_a_union_discriminator_is_refused_with_the_clause_that_permits_it —
validation.rs:184: assert!(!trips(&source, DiagnosticCode::InvalidDiscriminator),.
Status: done
§7.4.13.4.3.1 Maps
Spec: §7.4.13.4.3.1, p. 90 — map < key_type , value_type > < bound >; a map may not be part of a key.
Repo: crates/idl-parse/src/type_spec.rs::parse_map_type,
crates/idl-lower/src/validate.rs::validate_type.
Tests: crates/idl-lower/tests/validation.rs::a_map_cannot_be_part_of_a_key,
crates/idl-lower/tests/annotations.rs::a_map_key_may_only_be_discard,
crates/idl-lower/tests/annotations.rs::external_on_an_element_a_map_key_or_a_map_value_is_carried,
crates/idl-lower/tests/annotations.rs::only_try_construct_is_accepted_on_a_collection_element,
crates/idl-lower/tests/conformance.rs::the_xtypes_specifications_own_idl_lowers_completely —
validation.rs:340: assert_trips(source, DiagnosticCode::InvalidAnnotation);.
Status: done
§7.4.13.4.3.2 Bit Sets (including Bit Fields)
Spec: §7.4.13.4.3.2, p. 90–91 — bitfield < width > [ , type_spec ];
“The maximum value is 64”; “When the destination type is given, the
number of stored bits cannot exceed its size (i.e., 1 for boolean, 8 for
octet, …)”.
Repo: crates/idl-lower/src/complete.rs::check_bitset_bounds and
holder_width, crates/idl-lower/src/complete.rs::MAX_BITFIELD_BITS.
Tests: crates/idl-lower/tests/validation.rs::a_bitfield_wider_than_sixty_four_bits_is_refused,
crates/idl-lower/tests/validation.rs::a_bitfield_wider_than_its_destination_type_is_refused,
crates/idl-lower/tests/validation.rs::the_bit_forms_the_specification_admits_still_get_through,
crates/idl-lower/tests/conformance.rs::the_xtypes_specifications_own_idl_lowers_completely,
crates/ast/tests/node_space.rs::an_anonymous_bitfield_carries_no_name —
validation.rs:785: assert_clean("bitset Ba { bitfield<64> f1; };");.
Status: done
§7.4.13.4.3.3 Bit Masks and their Annotation Constraints
Spec: §7.4.13.4.3.3, p. 91–94 — “By default, the size of a bit mask is
32”; “A bit mask must contain at least one value and no more than its size
expressed in bits”; @bit_bound “must be lower than or equal to 64”;
@position “Possible positions range from 0 … up to (size – 1)”.
Repo: crates/idl-lower/src/complete.rs::check_bitmask_bounds and
check_bit_bounds, crates/idl-lower/src/complete.rs::MAX_BIT_BOUND.
Tests: crates/idl-lower/tests/validation.rs::a_bit_bound_over_sixty_four_is_refused,
crates/idl-lower/tests/validation.rs::a_bitmask_with_more_values_than_its_size_is_refused,
crates/idl-lower/tests/validation.rs::a_bitmask_with_no_bit_value_is_refused,
crates/idl-lower/tests/validation.rs::a_bit_position_outside_the_bitmasks_size_is_refused,
crates/idl-lower/tests/completion.rs::bit_positions_run_from_zero_and_an_explicit_one_shifts_the_rest,
crates/idl-lower/tests/completion.rs::a_written_bit_bound_is_what_the_rule_reports,
crates/idl-lower/tests/annotations.rs::an_explicit_bit_position_reaches_the_bit —
validation.rs:813: assert_clean("@bit_bound(64) bitmask Ba { F1 };");.
Status: done
§7.4.13.4.3.3 Duplicate @position
Spec: §7.4.13.4.3.3, p. 92 — the notes of the clause record that annotated bit values may be unordered, but no duplicates.
Repo: —
Tests: —
Status: open — check_bitmask_bounds (crates/idl-lower/src/complete.rs) checks @bit_bound, the number of values and the range of @position, but not that two @position values are equal. bitmask B { @position(1) A, @position(1) C }; is accepted; the later value overwrites the earlier one in the model.
§7.4.13.4.4 Integers restricted to holding 8-bits of information
Spec: §7.4.13.4.4, p. 94 — (212) introduces int8 and uint8 as their
own types with the value range ±2^7 or 0..2^8−1 respectively.
Repo: crates/idl-lower/src/lower.rs::primitive_of,
crates/idl-parse/src/type_spec.rs::is_primitive_keyword.
Tests: crates/idl-lower/tests/lowering.rs::each_primitive_keyword_reaches_its_model_kind,
crates/ast/tests/node_space.rs::every_primitive_of_the_spec_table_is_representable,
crates/idl-lower/tests/validation.rs::every_form_the_specification_admits_still_gets_through —
validation.rs:732: "const int8 K = 1;",.
Status: done
§7.4.13.4.5 Explicitly-named Integer Types
Spec: §7.4.13.4.5, p. 94 — (213)–(215) introduce int16/int32/int64
and uint16/uint32/uint64 as aliases of the classical spellings with
the same value range.
Repo: crates/idl-parse/src/type_spec.rs::is_primitive_keyword,
crates/idl-lower/src/lower.rs::primitive_of.
Tests: crates/idl-lower/tests/lowering.rs::each_primitive_keyword_reaches_its_model_kind,
crates/ast/tests/node_space.rs::every_primitive_of_the_spec_table_is_representable,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(bb13-212-int64) —
lowering.rs:333: ("int64", PrimitiveKind::Int64),.
Status: done
§7.4.13.4.6 Ranges for all Integer Types (Table 7-26)
Spec: §7.4.13.4.6, p. 94–95 — Table 7-26 names the value range and the
equivalent core type for every integer type; int8/uint8 have no core
counterpart (column “N/A”).
Repo: crates/idl-lower/src/validate.rs::primitive_range.
Tests: crates/idl-lower/tests/validation.rs::a_case_label_outside_the_discriminators_range_is_rejected,
crates/idl-lower/tests/validation.rs::a_case_label_inside_the_range_is_accepted,
crates/idl-lower/tests/floating_constant_arithmetic.rs::a_value_beyond_the_declared_range_is_refused.
Status: partial — the table primitive_range mirrors exactly the
columns of Table 7-26, but it is read only for case labels of a
discriminator. The value range of a constant is not checked:
value_disagrees_with compares only the form of the literal value, not its
numeric value; const octet K = 300; and const int8 K = 200; go through.
§7.4.13.5 Specific Keywords
Spec: §7.4.13.5, p. 95–96 — Table 7-27 names bitfield, bitmask,
bitset, map, int8, uint8, int16, int32, int64, uint16,
uint32, uint64.
Repo: crates/idl-cst/src/token.rs::KEYWORDS,
crates/idl-parse/src/type_spec.rs::is_primitive_keyword.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier,
crates/idl-lower/tests/lowering.rs::each_primitive_keyword_reaches_its_model_kind,
crates/idl-parse/tests/parse.rs::each_declaration_form_is_recognised —
lowering.rs:331: ("int8", PrimitiveKind::Int8),.
Status: done
§7.4.14 Building Block Anonymous Types
§7.4.14.3 Rule (216) — template_type_spec as type_spec
Spec: §7.4.14.3, p. 97 — (216) <type_spec> ::+ <template_type_spec>
allows sequence<…> and string<…> where a type is demanded.
Repo: —
Tests: —
Status: open — the clause is not checked as a form of its own. The path it opens (struct S { sequence<long> m; };) is not reachable in the parser (crates/idl-parse/src/type_spec.rs::parse_type_spec, crates/idl-parse/src/decl.rs::parse_member_list): parse_member requires a Declarator, and sequence<long> m; is read as a declarator. The tests of sequence parameters and a_sequence_member_carries_its_element_type check the template-module form, not the anonymous one.
§7.4.14.3 Rule (217) — array_declarator as declarator
Spec: §7.4.14.3, p. 97 — (217) <declarator> ::= <complex_declarator> | <array_declarator>, so that long a[3][4]; arises
without typedef.
Repo: crates/idl-parse/src/decl.rs::parse_member_list,
crates/idl-parse/src/parser.rs (array declarator recognition at the
square bracket).
Tests: crates/idl-parse/tests/parse.rs::an_array_declarator_is_only_known_at_the_bracket,
crates/idl-lower/tests/lowering.rs::a_typedef_declarator_keeps_its_array_dimensions,
crates/idl-lower/tests/lowering.rs::dimensions_belong_to_the_declarator_and_not_to_the_typedef.
Status: partial — the array dimensions are recognised at the
declarator and assigned to it; that is tested through the typedef path.
The anonymous form struct S { long arr[3]; }; has no test of its own.
§7.4.14.4 Nested Templates and >>
Spec: §7.4.14.4, p. 97 — “For those nested template declarations,
white space must be used to separate the two > tokens ending the
declaration so they are not parsed as a single >> token.”
Repo: crates/idl-parse/src/parser.rs::split_shift_right,
crates/idl-parse/src/type_spec.rs::close_type_arguments.
Tests: crates/idl-parse/tests/parse.rs::a_nested_sequence_splits_the_shift_token_and_still_round_trips,
crates/idl-parse/tests/parse.rs::three_deep_nesting_splits_as_far_as_it_needs_to,
crates/idl-parse/tests/parse.rs::shift_right_in_an_expression_is_not_split.
Status: partial — the nesting also works without whitespace
(sequence<sequence<long>>), which the clause does not demand. The reverse
case, the spelling with whitespace the spec demands
(sequence<sequence<long> >), is touched by no test: the split branch is
triggered only for the single >> token.
§7.4.14.5 Specific keywords
Spec: §7.4.14.5, p. 97 — “There are no additional keywords with this building block.”
Repo: crates/idl-cst/src/token.rs::KEYWORDS.
Tests: —
Status: n/a (informative) — the clause itself says there are no
additional keywords; there is nothing to check.
§7.4.15 Building Block Annotations
§7.4.15.1 Purpose
Spec: §7.4.15.1, p. 97 — “This building block defines a framework to add meta-data to IDL constructs, by means of annotations.”
Repo: crates/idl-parse/src/decl.rs::parse_annotation_decl,
crates/idl-lower/src/annotation.rs::apply_one.
Tests: —
Status: n/a (informative) — the clause motivates the building block;
the productions stand in §7.4.15.3.
§7.4.15.2 Dependencies
Spec: §7.4.15.2, p. 97 — “This building block only relies on Building Block Core Data Types. It is actually orthogonal to all others.”
Repo: crates/idl-lower/src/annotation.rs::enumerated_parameter.
Tests: tools/idlc/tests/annotation_arguments.rs::a_builtin_with_an_enumerated_parameter_reads_it_without_resolving_it,
tools/idlc/tests/annotation_arguments.rs::a_verbatim_directive_still_reaches_the_model_whole,
tools/idlc/tests/annotation_arguments.rs::the_rti_fixture_that_carried_both_defects_now_passes —
annotation_arguments.rs:145: assert!(found.is_empty(), "{source:?} was refused: {found:?}");.
Status: done
§7.4.15.3 Rules (218)–(227)
Spec: §7.4.15.3, p. 98 — (218) <definition> ::+ <annotation_dcl> ";";
(219) <annotation_dcl>; (220) <annotation_header>; (221)
<annotation_body> = { <annotation_member> | <enum_dcl> ";" | <const_dcl> ";" | <typedef_dcl> ";" }*; (222) <annotation_member>;
(223) <annotation_member_type>; (224) <any_const_type>; (225)
<annotation_appl>; (226) <annotation_appl_params>; (227)
<annotation_appl_param>.
Repo: crates/idl-parse/src/decl.rs::parse_annotation_decl and
parse_annotation_tail, crates/idl-lower/src/annotation.rs::apply_one.
Tests: crates/idl-parse/tests/parse.rs::an_annotation_body_admits_only_what_rule_221_lists,
crates/idl-parse/tests/parse.rs::the_declarations_rule_221_does_list_are_still_taken,
crates/idl-parse/tests/parse.rs::annotations_bind_to_the_declaration_that_follows,
crates/idl-parse/tests/parse.rs::an_annotation_takes_arguments_in_both_forms,
crates/idl-lower/tests/annotations.rs::a_root_anchored_annotation_name_reaches_the_builtin_it_names,
crates/idl-lower/tests/annotations.rs::a_qualified_annotation_name_reaches_its_declaration,
crates/idl-lower/tests/annotations.rs::every_spelling_of_one_builtin_says_the_same_thing,
crates/idl-lower/tests/annotations.rs::an_annotation_name_that_is_a_keyword_still_works_qualified,
crates/idl-lower/tests/annotations.rs::an_annotation_with_no_name_at_all_is_still_refused —
parse.rs:481: DiagnosticCode::UnexpectedToken,.
Status: done
§7.4.15.4.1 Defining Annotations
Spec: §7.4.15.4.1, p. 99 — the body of an annotation is a scope of its own; at the application site “Members with no default value must be given a value”.
Repo: crates/idl-parse/src/decl.rs::parse_annotation_decl (the four
admissible declaration forms), crates/idl-lower/src/scope.rs::ScopeStack::push_container,
crates/idl-lower/src/annotation.rs::check_annotation_application.
Tests: tools/idlc/tests/annotation_arguments.rs::an_annotation_body_may_declare_the_types_its_members_use,
tools/idlc/tests/annotation_arguments.rs::the_user_annotation_fixture_passes,
crates/idl-lower/tests/validation.rs::an_annotation_member_with_no_default_takes_the_default_of_its_type,
crates/idl-lower/tests/validation.rs::an_annotations_declared_members_reach_the_model,
crates/idl-parse/tests/parse.rs::the_declarations_rule_221_does_list_are_still_taken,
crates/idl-parse/tests/parse.rs::an_annotation_body_admits_only_what_rule_221_lists —
validation.rs:883: "@annotation Aa { long v; };\n@Aa struct Sa { long m; };",.
Status: partial — the front end gives an annotation member with no default and
no value the default of its type (XTypes 1.3 §7.3.1.2.5); IDL 4.2 requires a
value here. The two specifications contradict each other; an issue draft for
it is still missing.
§7.4.15.4.2 Applying Annotations
Spec: §7.4.15.4.2, p. 100–101 — “in case an unknown annotation is encountered, it should be ignored by the IDL-processing tools”; “A constant expression, whose type must be compatible with the member’s declaration”; “In case there is only one member, the annotation application may be shortened to the name of the annotation prefixed with @ and followed with the constant value of that unique member”; “malformed definitions shall be treated as an error”.
Repo: crates/idl-lower/src/annotation.rs::check_annotation_application
and apply_one (called only for resolved declarations).
Tests: crates/idl-lower/tests/validation.rs::an_annotation_argument_has_to_have_the_members_type,
crates/idl-lower/tests/validation.rs::an_argument_naming_no_member_is_refused,
crates/idl-lower/tests/validation.rs::the_short_form_is_only_for_an_annotation_with_one_member,
crates/idl-lower/tests/validation.rs::none_of_the_four_rules_reaches_an_unknown_annotation,
tools/idlc/tests/annotation_arguments.rs::an_unknown_annotation_is_ignored_whatever_it_is_given,
tools/idlc/tests/annotation_arguments.rs::a_name_outside_an_unknown_annotation_still_has_to_resolve,
tools/idlc/tests/annotation_arguments.rs::a_literal_argument_of_an_unknown_annotation_still_reaches_the_model,
tools/idlc/tests/strict.rs::strict_does_not_refuse_an_unknown_annotation,
crates/idl-lower/tests/dialects.rs::strict_does_not_refuse_an_unknown_annotation,
crates/ast/tests/node_space.rs::the_value_member_shorthand_is_recorded —
validation.rs:915: "@annotation Aa { long v default 0; };\n@Aa(nosuch = 1) struct Sa { long m; };",.
Status: done
§7.4.15.5 Specific Keywords
Spec: §7.4.15.5, p. 102 — the syntax uses @ as a punctuator;
@annotation is the head token, not a keyword.
Repo: crates/idl-cst/src/token.rs::TokenKind::Annotation,
crates/idl-cst/src/tree.rs::CstKind::AnnotationDecl.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier,
crates/idl-parse/tests/parse.rs::each_declaration_form_is_recognised —
parse.rs:88: assert!(parses_cleanly(source), "{source:?} produced diagnostics");.
Status: done
§7.4.16 Relationships between the Building Blocks
§7.4.16 Dependency Lattice (Figure 7-2)
Spec: §7.4.16, p. 102 — “Even if the building blocks have been designed as independent as possible, they are linked by some dependencies. The following figure represents the graph of their relationships (actually a lattice).”
Repo: —
Tests: —
Status: open — there is no mapping of this lattice in today’s tree.
crates/ast/src/profile/mod.rs::Profile is a flat enumeration of other
specifications (Idl42Core, XTypes13, Corba33, Ros2, DdsXml,
FlatData, Vendor), and there is no edge between the profiles. The only
place the names of the building blocks occur is the prose in
docs/idl-building-blocks.md.
§7.5 Names and Scoping
§7.5 Visibility Rules across all Building Blocks
Spec: §7.5, p. 102 — “This clause defines the visibility rules that apply to names. Those rules are considering the whole IDL grammar (i.e., the union of all building blocks).”
Repo: crates/idl-lower/src/scope.rs::ScopeStack,
crates/ast/src/resolve.rs.
Tests: crates/idl-lower/tests/lowering.rs::a_constant_resolves_by_its_simple_name_in_its_own_scope,
crates/ast/tests/resolve_profile_query.rs::every_profile_accepts_a_model_of_plain_primitives,
crates/ast/tests/profile_table.rs::the_construct_table_is_total_over_profiles_and_constructs,
crates/ast/tests/profile_table.rs::the_facet_table_is_total_over_profiles_and_properties —
lowering.rs:1568: ast.eval_integral(bound).expect("the bound evaluates"),.
Status: done
§7.5.1 Qualified Names
Spec: §7.5.1, p. 102–103 — “A qualified name (one of the form
<scoped_name>::<identifier>) is resolved by first resolving the qualifier
<scoped_name> to a scope S, and then locating the definition of
<identifier> within S. The <identifier> is not searched for in enclosing
scopes.”; “When a qualified name begins with '::', the resolution process
starts with the file scope”.
Repo: crates/idl-lower/src/scope.rs::ScopeStack::lookup_candidates,
crates/idl-lower/src/expr.rs::lookup_name.
Tests: crates/idl-lower/tests/reported_idl.rs::a_fully_qualified_scoped_name_resolves,
crates/idl-lower/tests/lowering.rs::a_qualified_constant_still_resolves_through_its_module,
crates/idl-parse/tests/parse.rs::a_leading_double_colon_is_the_global_scope,
crates/idl-lower/tests/dialects.rs::the_root_anchored_spelling_names_the_same_module,
crates/ast/tests/node_space.rs::nested_modules_are_addressable_by_path —
node_space.rs:43: ast.module_by_path(&scoped(&["Robot", "Sensors"])),.
Status: done
§7.5.1 Global Names
Spec: §7.5.1, p. 103 — “Every IDL definition in a file has a global
name within that file”; the global name is the concatenation of the current
root, the current scope, "::" and the identifier.
Repo: crates/idl-lower/src/scope.rs::ScopeStack (qualify and
qualify_segments), crates/idl-lower/tests/interface_as_type.rs.
Tests: crates/idl-lower/tests/interface_as_type.rs::the_key_is_the_declaration_s_own_scoped_name_and_not_the_written_segment,
crates/ast/tests/node_space.rs::nested_modules_are_addressable_by_path,
crates/idl-lower/tests/dialects.rs::a_typeprefix_may_name_the_module_it_is_written_in,
crates/idl-lower/tests/dialects.rs::a_sibling_declaration_wins_over_one_further_out —
dialects.rs:1307: "IDL:inner.example/outer/m/S:1.0".
Status: done
§7.5.1 Ambiguity
Spec: §7.5.1, p. 103–104 — “Ambiguous declarations shall be treated as
errors”; the clause names the example of two inherited string_t.
Repo: crates/idl-lower/src/scope.rs::ScopeStack::lookup_candidates.
Tests: crates/ast/tests/resolve_profile_query.rs::an_ambiguous_name_reports_every_candidate,
crates/ast/tests/resolve_profile_query.rs::a_duplicate_scoped_name_is_reported_as_ambiguous_with_both_nodes.
Status: partial — the ambiguity report on the model level is covered
and names every candidate. The spec example (§7.5.1: interface C: A, B with an attribute whose type is bound differently in both bases) is
driven by no test.
§7.5.1 Visibility through Inheritance and Multiple Global Names
Spec: §7.5.1, p. 103 — “Inheritance causes all identifiers defined in
base interfaces, both direct and indirect, to be visible in derived
interfaces”; “Multiple paths to the same original identifier … do not
conflict with each other”; “Inheritance introduces multiple global IDL
names for the inherited identifiers … the exception is known by the global
names ::A::E and ::B::E”.
Repo: —
Tests: —
Status: open — there is no test that checks that an identifier
inherited from a base is resolvable under two global names and that two
paths to the same declaration are not a conflict. The flattening in
crates/lang-rules is a language column, not a statement about the names.
§7.5.2 Scope Kinds and their Beginning and End
Spec: §7.5.2, p. 104 — “The following kinds of definitions form scopes:
modules, structures, unions, maps, interfaces, value types, operations,
exceptions, event types, components, homes.”; “The scope of an operation
begins immediately following its opening ( and ends immediately preceding
its closing ).”
Repo: crates/idl-lower/src/scope.rs::ScopeStack::push_container and
pop.
Tests: crates/idl-lower/tests/validation.rs::the_same_name_in_two_scopes_does_not_collide,
crates/idl-lower/tests/lowering.rs::a_constant_resolves_by_its_simple_name_in_its_own_scope,
crates/ast/tests/node_space.rs::nested_modules_are_addressable_by_path —
validation.rs:51: "module A { struct S { long x; }; };",.
Status: done
§7.5.2 One Identifier once per Scope
Spec: §7.5.2, p. 104 — “An identifier can only be defined once in a scope. However, identifiers can be redefined in nested scopes.”
Repo: crates/idl-lower/src/scope.rs::ScopeStack::bind.
Tests: crates/idl-lower/tests/validation.rs::the_same_name_in_two_scopes_does_not_collide,
crates/idl-lower/tests/lowering.rs::a_name_declared_in_two_openings_of_one_module_collides,
crates/idl-lower/tests/validation.rs::two_members_of_one_aggregate_differing_only_by_case_collide —
validation.rs:116: "struct S { long tail; short Tail; };",.
Status: done
§7.5.2 Reopening a Module
Spec: §7.5.2, p. 104 — “An identifier declaring a module is considered to be defined by its first occurrence in a scope. Subsequent occurrences of a module declaration with the same identifier within the same scope reopens the module and hence its scope.”
Repo: crates/idl-lower/src/scope.rs::ScopeStack::push.
Tests: crates/idl-lower/tests/lowering.rs::a_module_reopened_across_two_files_converges_on_one_node,
crates/idl-lower/tests/lowering.rs::a_reopened_module_still_sees_what_the_first_opening_declared,
crates/ast/tests/node_space.rs::reopening_a_module_merges_into_the_same_node —
node_space.rs:58: assert_eq!(first, second);.
Status: done
§7.5.2 No Self-renaming of the Scope Name
Spec: §7.5.2, p. 104 — “The name of a module, structure, union, map, interface, value type, event type, exception or home may not be redefined within the immediate scope of the module, structure, union, map, interface, value type, event type, exception or home.”
Repo: crates/idl-lower/src/lower.rs::check_redefines_enclosing_scope.
Tests: crates/idl-lower/tests/validation.rs::a_declaration_may_not_reuse_the_name_of_its_own_scope,
crates/idl-lower/tests/validation.rs::only_the_immediate_scope_is_compared —
validation.rs:1016: assert_clean("module Ma { module Mb { typedef short Ma; }; };");.
Status: done — the clause does not list operations, and the check reaches exactly that far; see the item on §7.5.2 Identifier Introduction for the second, open rule of this clause.
§7.5.2 Introduction of an Identifier by Use
Spec: §7.5.2, p. 104–105 — “An identifier from a surrounding scope is introduced into a scope if it is used in that scope. An identifier is not introduced into a scope by merely being visible in that scope.”
Repo: —
Tests: —
Status: open — there is no use support and no counter-check that
transfers the name into the introducing scope. The survey under
tools/idl-4.2-gap-scan/ lists the probe scope-7.5.2-introduced-ident
with expect=reject, but measures ok; the two counter-probes
scope-7.5.2-not-introduced-ok and scope-7.5.2-rooted-no-introduce pass
today, rightly, but for the wrong reason, because the rule does not exist
at all.
§7.5.2 Only the First Link of a Qualified Name is Introduced
Spec: §7.5.2, p. 105 — “Only the first identifier in a qualified name is introduced into the current scope. This is illustrated by Inner1::S1 in the example above, which introduces Inner1 into the scope of Inner2 but does not introduce S1. A qualified name of the form ::X::Y::Z does not cause X to be introduced, but a qualified name of the form X::Y::Z does.”
Repo: —
Tests: —
Status: open — the same missing rule as in the item above. The probe
scope-7.5.2-rooted-no-introduce passes, but measures nothing: without
introduction tracking it cannot fail.
§7.5.2 Enum Value Names in the Enclosing Scope
Spec: §7.5.2, p. 105 — “Enumeration value names are introduced into the
enclosing scope and then are treated like any other declaration in that
scope.”; the example enum BadE { E3, E4, E5 }; is marked // Error
because E3 already comes from E.
Repo: crates/idl-lower/src/scope.rs::ScopeStack::bind,
crates/idl-lower/src/lower.rs::enumeration.
Tests: crates/idl-lower/tests/lowering.rs::an_enumerator_is_named_from_the_scope_around_its_enumeration,
crates/idl-lower/tests/lowering.rs::one_literal_name_in_two_enumerations_collides,
crates/idl-lower/tests/lowering.rs::a_union_over_an_enumeration_lowers_with_its_labels_evaluated,
crates/idl-lower/tests/lowering.rs::a_case_label_may_name_its_enumerator_by_a_qualified_name —
lowering.rs:217: assert_eq!(ast.eval_integral(expr), Ok(1));.
Status: done
§7.5.2 Resolution of an Unqualified Name
Spec: §7.5.2, p. 105–106 — “A name can be used in an unqualified form within a particular scope; it will be resolved by successively searching farther out in enclosing scopes, while taking into consideration inheritance relationships among interfaces.”
Repo: crates/idl-lower/src/expr.rs::lookup_name,
crates/idl-lower/src/scope.rs::ScopeStack::lookup_candidates.
Tests: crates/idl-lower/tests/lowering.rs::a_constant_resolves_by_its_simple_name_in_its_own_scope,
crates/idl-lower/tests/lowering.rs::a_qualified_constant_still_resolves_through_its_module,
crates/idl-lower/tests/dialects.rs::a_sibling_declaration_wins_over_one_further_out —
lowering.rs:1597: assert_eq!(ast.eval_integral(bound).expect("evaluates"), 8);.
Status: done
§7.5.3 Special Scoping Rules for Type Names
Spec: §7.5.3, p. 106 — “Once a type has been defined anywhere within the scope of a module, interface or value type, it may not be redefined except within the scope of a nested module, interface or value type, or within the scope of a derived interface or value type.”
Repo: crates/idl-lower/src/scope.rs::ScopeStack::bind.
Tests: crates/idl-lower/tests/lowering.rs::a_name_declared_in_two_openings_of_one_module_collides,
crates/idl-lower/tests/keys_and_inheritance.rs::a_member_name_of_the_base_chain_cannot_be_declared_again.
Status: partial — the bar holds for two openings of the same module
and for the structure inheritance. The exception named in the clause, the
reuse in a derived interface, is not tested as a positive case; the clause
demands it.
§7.5.3 Potential Scope
Spec: §7.5.3, p. 107 — “if a type name is introduced into a scope that is nested in a non-module scope definition its potential scope extends over all its enclosing scopes out to the enclosing non-module scope”; “A type may not be redefined within its scope or potential scope”; further the note that a redefinition after the use in a module is admissible.
Repo: —
Tests: —
Status: open — the notion potential scope has no counterpart in the
tree. crates/idl-lower/src/scope.rs keeps a scope stack without a use
count, hence without the bookkeeping from which the rule would follow. The
positive note of the clause (redefinition after use in a module) has no
test either.
§8 Standardized Annotations
§8.1 Overview
Spec: §8.1, p. 109 — “The syntax to define annotations is given in the clause 7.4.15, Building Block Annotations. Any profile that embeds that building block will support annotations.”; “this clause defines some standardized annotations and groups them in Groups of Annotations”.
Repo: crates/ast/src/node/annotation.rs::BUILTIN_ANNOTATIONS (31
names), crates/idl-lower/src/annotation.rs::apply_one.
Tests: crates/ast/tests/node_space.rs::every_builtin_annotation_of_the_spec_list_is_present,
crates/ast/tests/node_space.rs::builtin_identities_come_from_the_builtin_space,
crates/ast/tests/node_space.rs::builtin_identities_do_not_collide_with_parsed_content,
crates/idl-lower/tests/annotations.rs::a_user_declared_annotation_is_kept_whole —
node_space.rs:848: assert_eq!(BUILTIN_ANNOTATIONS.len(), 31);.
Status: done — the table carries the 24 annotations of this clause plus
seven from DDS-XTypes 1.3 §7.4.4 (non_serialized, try_construct,
topic, hashid, data_representation, ignore_literal_names,
default_nested); the test checks the length of the table, not the
assignment to a group.
§8.2.1 Rules for Defining Standardized Annotations
Spec: §8.2.1, p. 109 — “The annotations that are standardized here have been selected for their general purpose nature, meaning that their application can be considered in various contexts.”
Repo: crates/ast/src/model.rs::Ast::populate_builtins.
Tests: —
Status: n/a (informative) — the paragraph motivates the selection;
each annotation is audited separately in §8.3.x.
§8.2.2 Rules for Using Standardized Annotations
Spec: §8.2.2, p. 109–110 — four requirements on a specification that uses a standardized annotation: respect the syntax of the spec, pin down the meaning, restrict the admissible elements and document the default behaviour.
Repo: crates/idl-lower/src/annotation.rs::apply_one.
Tests: tools/idlc/tests/annotation_arguments.rs::an_unknown_annotation_is_ignored_whatever_it_is_given,
tools/idlc/tests/strict.rs::strict_does_not_refuse_an_unknown_annotation,
tools/idlc/tests/strict.rs::every_subcommand_refuses_every_vendor_extension_under_strict,
crates/idl-lower/tests/annotations.rs::every_spelling_of_one_builtin_says_the_same_thing —
annotations.rs:1001: assert!(xtypes_of_member(&ast, "S", 0).is_key, "{source:?}");.
Status: partial — no test checks the paragraph’s four requirements
on a specification that uses a standardized annotation; the cited tests
only check that unknown annotations are ignored and that the spelling
counts.
§8.3.1.1 @id Annotation
Spec: §8.3.1.1, p. 110 — “@annotation id { unsigned long value; };”;
the value is a 32-bit integer.
Repo: crates/idl-lower/src/annotation.rs::apply_one (the id branch),
crates/idl-lower/src/complete.rs::derive_repository_ids.
Tests: crates/idl-lower/tests/annotations.rs::a_declared_id_records_that_it_was_declared,
crates/idl-lower/tests/annotations.rs::an_id_that_is_not_an_integer_is_reported_rather_than_ignored,
crates/idl-lower/tests/annotations.rs::an_id_and_a_hashid_on_one_member_are_rejected,
crates/idl-lower/tests/completion.rs::a_declared_id_wins_over_the_aggregates_autoid —
completion.rs:146: assert_eq!(member_id(&ast, "S", 0), (4, MemberIdOrigin::Declared));.
Status: done
§8.3.1.2 @autoid Annotation
Spec: §8.3.1.2, p. 110 — “@annotation autoid { enum AutoidKind { SEQUENTIAL, HASH }; AutoidKind value default HASH; };”.
Repo: crates/idl-lower/src/annotation.rs::apply_one (the autoid
branch), crates/idl-lower/src/complete.rs::member_ids.
Tests: crates/idl-lower/tests/annotations.rs::both_autoid_policies_are_distinguished,
crates/idl-lower/tests/completion.rs::autoid_sequential_and_autoid_hash_differ,
crates/idl-lower/tests/completion.rs::an_autoid_hash_member_is_skipped_the_same_way —
annotations.rs:457: assert_eq!(xtypes_of_type(&ast, "S").autoid, Some(expected), "{source}");.
Status: done
§8.3.1.3 @optional Annotation
Spec: §8.3.1.3, p. 111 — “@annotation optional { boolean value default TRUE; };”; an optional member may not be a key.
Repo: crates/idl-lower/src/annotation.rs::apply_one (the optional
branch), crates/idl-lower/src/validate.rs::validate_type.
Tests: crates/idl-lower/tests/annotations.rs::the_member_flags_each_reach_their_own_field,
crates/idl-lower/tests/annotations.rs::several_annotations_on_one_member_all_apply,
crates/idl-lower/tests/validation.rs::a_key_member_must_not_be_optional —
annotations.rs:286: assert!(xtypes_of_member(&ast, "S", 1).is_optional);.
Status: done
§8.3.1.4 @position Annotation
Spec: §8.3.1.4, p. 111 — “@annotation position { unsigned short value; };”; the value range is 0..65535, and the position must lie within
the bitmask size (§7.4.13.4.3.3).
Repo: crates/idl-lower/src/annotation.rs::apply_one (the position
branch), crates/idl-lower/src/complete.rs::check_bitmask_bounds.
Tests: crates/idl-lower/tests/annotations.rs::an_explicit_bit_position_reaches_the_bit,
crates/idl-lower/tests/completion.rs::bit_positions_run_from_zero_and_an_explicit_one_shifts_the_rest,
crates/idl-lower/tests/validation.rs::a_bit_position_outside_the_bitmasks_size_is_refused,
crates/ast/tests/node_space.rs::a_positional_bit_and_an_explicit_position_are_distinguishable —
annotations.rs:744: assert_eq!(ast.bit_value(bits[0]).expect("A").position, Some(5));.
Status: done
§8.3.1.5 @value Annotation
Spec: §8.3.1.5, p. 111 — “@annotation value { any value; };”; the
value of an enumerator is pinned down.
Repo: crates/idl-lower/src/annotation.rs::apply_one (the value
branch), crates/ast/src/query.rs::effective_enumerator_value.
Tests: crates/idl-lower/tests/annotations.rs::an_explicit_enumerator_value_keeps_the_expression_it_was_written_as,
crates/idl-lower/tests/completion.rs::enumerators_without_values_run_from_zero_upwards,
crates/idl-lower/tests/completion.rs::an_explicit_enumerator_value_shifts_the_ones_after_it,
crates/ast/tests/node_space.rs::a_positional_enumerator_and_an_explicit_value_are_distinguishable —
completion.rs:271: assert_eq!(ast.effective_enumerator_value(enumerators[2]), Some(11));.
Status: done
§8.3.1.6 @extensibility Annotation
Spec: §8.3.1.6, p. 111–112 — “@annotation extensibility { enum ExtensibilityKind { FINAL, APPENDABLE, MUTABLE }; ExtensibilityKind value; };”.
Repo: crates/idl-lower/src/annotation.rs::apply_one (the
extensibility branch).
Tests: crates/idl-lower/tests/annotations.rs::each_extensibility_keyword_reaches_the_facet,
crates/idl-lower/tests/annotations.rs::an_extensibility_argument_that_is_not_one_of_the_three_is_reported,
crates/idl-lower/tests/completion.rs::a_written_extensibility_is_what_the_rule_reports —
annotations.rs:229: ("@mutable struct S { long x; };", Extensibility::Mutable),.
Status: done
§8.3.1.7 @final, §8.3.1.8 @appendable, §8.3.1.9 @mutable
Spec: §8.3.1.7–§8.3.1.9, p. 112 — the three short forms are “Shortcut for @extensibility(FINAL)” and correspondingly for APPENDABLE and MUTABLE.
Repo: crates/idl-lower/src/annotation.rs::apply_one (the final,
appendable, mutable branches).
Tests: crates/idl-lower/tests/annotations.rs::each_extensibility_keyword_reaches_the_facet,
crates/idl-lower/tests/reported_idl.rs::an_unannotated_struct_is_appendable,
crates/idl-lower/tests/keys_and_inheritance.rs::a_derived_structure_that_repeats_its_bases_extensibility_is_accepted —
keys_and_inheritance.rs:90: assert!(found.is_empty(), "{found:?}");.
Status: done
§8.3.2.1 @key Annotation
Spec: §8.3.2.1, p. 112–113 — “@annotation key { boolean value default TRUE; };”; only the discriminator of a union may be a key.
Repo: crates/idl-lower/src/annotation.rs::apply_one (the key
branch), crates/idl-lower/src/validate.rs::is_legal_discriminator.
Tests: crates/idl-lower/tests/annotations.rs::the_member_flags_each_reach_their_own_field,
crates/idl-lower/tests/validation.rs::key_on_its_own_is_accepted,
crates/idl-lower/tests/validation.rs::only_a_unions_discriminator_may_be_a_key,
crates/idl-lower/tests/validation.rs::a_map_cannot_be_part_of_a_key,
crates/idl-lower/tests/keys_and_inheritance.rs::a_key_written_in_a_derived_structure_is_refused,
crates/idl-lower/tests/annotations.rs::a_suffix_annotation_carries_its_arguments —
annotations.rs:285: assert!(xtypes_of_member(&ast, "S", 0).is_key);.
Status: done
§8.3.2.2 @must_understand Annotation
Spec: §8.3.2.2, p. 113 — “@annotation must_understand { boolean value default TRUE; };”.
Repo: crates/idl-lower/src/annotation.rs::apply_one (the
must_understand branch).
Tests: crates/idl-lower/tests/annotations.rs::the_member_flags_each_reach_their_own_field.
Status: partial — the flag reaches the member facet; the meaning of
the flag (a middleware receiver that does not understand the extension must
reject the message) is an XTypes requirement and is checked here only as a
flag. That is the scope of clause 8.
§8.3.2.3 @default_literal Annotation
Spec: §8.3.2.3, p. 113 — “@annotation default_literal { };”; it marks
the enumerator, not the enum.
Repo: crates/idl-lower/src/annotation.rs::apply_one (the
default_literal branch).
Tests: crates/idl-lower/tests/annotations.rs::a_default_literal_marks_the_enumerator_and_not_the_enum —
annotations.rs:772: assert!(marked(1));.
Status: done
§8.3.3.1 @default Annotation
Spec: §8.3.3.1, p. 113–114 — “@annotation default { any value; };”.
Repo: —
Tests: —
Status: open — code exists: the annotation is in the builtin table, and the branch default in crates/idl-lower/src/annotation.rs::apply_one sets XTypesFacet::default_value. No test checks this field; crates/idl-lower/tests/annotations.rs has no case for it, the survey lists the probe ann-8.3.3.1-default as ok.
§8.3.3.2 @range Annotation
Spec: §8.3.3.2, p. 114 — “@annotation range { any min; any max; };”
with the condition max >= min.
Repo: crates/idl-lower/src/annotation.rs::apply_one (the range
branch), crates/ast/src/facet/xtypes.rs::XTypesFacet.
Tests: crates/idl-lower/tests/annotations.rs::a_unit_and_a_range_reach_their_fields.
Status: partial — min/max are read and written into the facet;
the condition max >= min is not checked and has no test. @range(5, 1)
is accepted.
§8.3.3.3 @min and §8.3.3.4 @max
Spec: §8.3.3.3 / §8.3.3.4, p. 114 — “@annotation min { any value; };” and “@annotation max { any value; };”; written separately they yield
the same range as @range.
Repo: crates/idl-lower/src/annotation.rs::apply_one (the min and
max branches).
Tests: crates/idl-lower/tests/annotations.rs::min_and_max_written_separately_combine_into_one_range —
annotations.rs:712: assert!(range.max.is_some(), "the max was lost");.
Status: done
§8.3.3.5 @unit Annotation
Spec: §8.3.3.5, p. 114 — “@annotation unit { string value; };” plus
the reference to the BIPM abbreviations.
Repo: crates/idl-lower/src/annotation.rs::apply_one (the unit
branch).
Tests: crates/idl-lower/tests/annotations.rs::a_unit_and_a_range_reach_their_fields —
annotations.rs:702: assert_eq!(x.unit.as_deref(), Some("m/s"));.
Status: done
§8.3.4.1 @bit_bound Annotation
Spec: §8.3.4.1, p. 115 — “@annotation bit_bound { unsigned short value; };”; the value may be at most 64 (§7.4.13.4.3.3), and without the
annotation it is 32.
Repo: crates/idl-lower/src/annotation.rs::apply_one (the bit_bound
branch), crates/idl-lower/src/complete.rs::check_bit_bounds.
Tests: crates/idl-lower/tests/annotations.rs::a_bit_bound_reaches_the_type,
crates/idl-lower/tests/completion.rs::an_enum_without_a_bit_bound_is_thirty_two_bits,
crates/idl-lower/tests/completion.rs::a_written_bit_bound_is_what_the_rule_reports,
crates/idl-lower/tests/validation.rs::a_bit_bound_over_sixty_four_is_refused —
annotations.rs:752: assert_eq!(xtypes_of_type(&ast, "E").bit_bound, Some(16));.
Status: done
§8.3.4.2 @external Annotation
Spec: §8.3.4.2, p. 115 — “@annotation external { boolean value default TRUE; };”. XTypes 1.3 §7.3.1.2.1.4 lets it apply also to an element of
a collection, a map key and a map value; the front end carries it there.
Repo: crates/idl-lower/src/annotation.rs::apply_one (the external
branch).
Tests: crates/idl-lower/tests/annotations.rs::the_member_flags_each_reach_their_own_field,
crates/idl-lower/tests/annotations.rs::external_on_an_element_a_map_key_or_a_map_value_is_carried,
crates/idl-lower/tests/validation.rs::external_on_a_type_declaration_is_refused_by_name,
crates/idl-lower/tests/validation.rs::external_on_a_member_and_on_a_branch_is_accepted —
validation.rs:426: assert_trips(source, DiagnosticCode::InvalidAnnotation);.
Status: done
§8.3.4.3 @nested Annotation
Spec: §8.3.4.3, p. 115 — “@annotation nested { boolean value default TRUE; };”; it acts transitively on the types declared in a module.
Repo: crates/idl-lower/src/annotation.rs::apply_one (the nested
branch).
Tests: crates/idl-lower/tests/annotations.rs::a_nested_annotation_reaches_the_type,
crates/idl-lower/tests/annotations.rs::default_nested_on_a_module_reaches_the_types_in_it —
annotations.rs:214: assert!(ast.effective_nested(by_name("Inner")));.
Status: done
§8.3.5.1 @verbatim Annotation
Spec: §8.3.5.1, p. 116 — “@annotation verbatim { enumeration PlacementKind { BEGIN_FILE, BEFORE_DECLARATION, BEGIN_DECLARATION, END_DECLARATION, AFTER_DECLARATION, END_FILE }; string language default "\*"; PlacementKind placement default BEFORE_DECLARATION; string text; };”;
the language values are "c", "c++", "java", "idl" and "*".
Repo: crates/idl-lower/src/annotation.rs::verbatim_placement (the six
placements), crates/idl-lower/src/annotation.rs::apply_one (the verbatim
branch).
Tests: crates/idl-lower/tests/annotations.rs::a_verbatim_directive_keeps_its_language_placement_and_text,
crates/idl-lower/tests/annotations.rs::a_verbatim_directive_defaults_language_and_placement,
crates/idl-lower/tests/annotations.rs::repeated_verbatim_directives_accumulate_in_declaration_order,
crates/idl-lower/tests/annotations.rs::a_verbatim_directive_for_an_unknown_language_is_kept_as_written,
crates/idl-lower/tests/annotations.rs::an_unknown_verbatim_placement_is_reported,
tools/idlc/tests/annotation_arguments.rs::a_verbatim_directive_still_reaches_the_model_whole —
annotation_arguments.rs:175: assert_eq!(verbatim.len(), 1, "{verbatim:?}");.
Status: done
§8.3.6.1 @service Annotation
Spec: §8.3.6.1, p. 117 — “@annotation service { string platform default "\*"; };”; the platform values are "CORBA", "DDS" and "*".
Repo: crates/idl-lower/src/annotation.rs::apply_one (the service
branch).
Tests: crates/idl-lower/tests/annotations.rs::service_and_ami_reach_the_corba_facet —
annotations.rs:904: assert!(corba.is_service);.
Status: done
§8.3.6.2 @oneway Annotation
Spec: §8.3.6.2, p. 117 — “@annotation oneway { boolean value default TRUE; };”; “This annotation may only concern operations without
any return value (void return type) and without any out or
inout parameters.”
Repo: crates/idl-lower/src/annotation.rs::apply_one (the oneway
branch), crates/idl-lower/src/annotation.rs::enumerated_parameter.
Tests: tools/idlc/tests/annotation_arguments.rs::a_builtin_with_an_enumerated_parameter_reads_it_without_resolving_it.
Status: partial — @oneway is in the builtin table, the survey lists
the probe ann-8.3.6.2-oneway with ok. No Rust test writes @oneway
into an .idl line and checks the facet
(crates/ast/tests/node_space.rs::a_oneway_operation_is_flagged_and_a_normal_one_is_not
checks the keyword form, not the annotation form). The secondary
constraint of the clause — void return type and no out/inout parameters
— is checked nowhere.
§8.3.6.3 @ami Annotation
Spec: §8.3.6.3, p. 117 — “@annotation ami { boolean value default TRUE; };”.
Repo: crates/idl-lower/src/annotation.rs::apply_one (the ami
branch).
Tests: crates/idl-lower/tests/annotations.rs::service_and_ami_reach_the_corba_facet —
annotations.rs:905: assert!(corba.is_ami);.
Status: done
§9 Profiles
§9.1 Overview
Spec: §9.1, p. 119 — “This clause defines some relevant combinations of building blocks, called profiles. Profiles are just sets of building blocks, possibly complemented with groups of annotations.”; “These profiles are not normative for the related middleware solutions.”
Repo: crates/ast/src/profile/mod.rs::Profile,
crates/ast/src/profile/verdict.rs::ALL_PROFILES.
Tests: crates/ast/tests/profile_table.rs::the_construct_table_is_total_over_profiles_and_constructs,
crates/ast/tests/profile_table.rs::the_facet_table_is_total_over_profiles_and_properties,
crates/ast/tests/resolve_profile_query.rs::every_profile_accepts_a_model_of_plain_primitives,
crates/ast/tests/resolve_profile_query.rs::a_map_is_valid_under_xtypes_and_invalid_under_corba_33.
Status: partial — the profile machinery exists and is checked totally
by table, but it describes other specifications (XTypes13, Corba33,
Ros2, DdsXml, FlatData, Vendor). The seven profiles of this clause
are none of them.
§9.2.1 Plain CORBA Profile
Spec: §9.2.1, p. 119 — the profile consists of Core Data Types, Any, Interfaces – Basic, Interfaces – Full, Value Types, CORBA-Specific – Interfaces and CORBA-Specific – Value Types.
Repo: —
Tests: —
Status: open — there is no mapping of this profile in the tree.
Neither Profile nor IdlFeatures (formerly
crates/idl/src/features/mod.rs, removed today) knows such a building
block combination; the only place the name of the profile occurs is the
prose in docs/idl-building-blocks.md.
§9.2.2 Minimum CORBA Profile
Spec: §9.2.2, p. 119–120 — “As opposed to Plain CORBA Profile, it does not embed Any nor Valuetypes.”
Repo: —
Tests: —
Status: open — as §9.2.1; no symbol, no test.
§9.2.3 CCM Profile
Spec: §9.2.3, p. 120 — the profile complements Components – Basic and CCM-Specific with the seven CORBA building blocks.
Repo: crates/idl-parse/src/dialect.rs,
crates/idl-lower/src/lower.rs::interface_bases (the supports and
component branches).
Tests: crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/idl-lower/tests/dialects.rs::each_port_form_reaches_its_own_component_role,
crates/idl-lower/tests/dialects.rs::a_home_records_what_it_manages_and_the_key_it_does_so_by.
Status: partial — the building blocks of the profile are recognised
and tested individually. The profile itself — a named, switchable
combination — does not exist; there is no mechanism that switches the
building blocks on and off together.
§9.2.4 CCM with Generic Interaction Support Profile
Spec: §9.2.4, p. 120 — this profile complements Components – Ports and Connectors and Template Modules with the CCM profile.
Repo: crates/idl-lower/src/lower.rs::port,
crates/idl-lower/src/lower.rs::template_module_inst.
Tests: crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/idl-lower/tests/dialects.rs::a_template_modules_parameters_reach_its_facet.
Status: partial — both additional building blocks are implemented and
tested; the words GIS and Generic Interaction Support do not occur in
the front end. As with §9.2.3 there is no profile switch.
§9.3.1 Plain DDS Profile
Spec: §9.3.1, p. 121 — “It is made of: Building Block Core Data Types; Building Block Anonymous Types.”
Repo: —
Tests: —
Status: open — no profile with this composition (crates/idl-parse/src/dialect.rs). The anonymous types are not tested (§7.4.14.3), and there is no check that separates the two building blocks together from a CORBA front end.
§9.3.2 Extensible DDS Profile
Spec: §9.3.2, p. 121 — this profile complements Extended Data-Types, Anonymous Types, Annotations and the four annotation groups.
Repo: crates/ast/src/profile/mod.rs::Profile,
crates/idl-lower/src/annotation.rs::apply_one.
Tests: crates/ast/tests/resolve_profile_query.rs::a_map_is_valid_under_xtypes_and_invalid_under_corba_33,
crates/idl-lower/tests/conformance.rs::the_xtypes_specifications_own_idl_lowers_completely.
Status: partial — the XTypes part of the profile is modelled as
Profile::XTypes13 and checked by table; the four annotation groups of
this clause (General Purpose, Data Modeling, Data Implementation, Code
Generation) do not exist as such, the annotations are a flat builtin table
(§8.1).
§9.3.3 RPC over DDS Profile
Spec: §9.3.3, p. 121 — the profile complements Interfaces – Basic and the group of Interfaces annotations.
Repo: crates/lang-rules/src/adapter/interface.rs::Service::is_remote,
crates/lang-rules/src/generate.rs::COMPLETE_DECLARATIONS_LANGUAGES.
Tests: crates/lang-rules/tests/interface_bindings.rs::the_seam_reads_every_part_of_an_interface,
crates/lang-rules/tests/inherited_operations.rs::every_incomplete_language_refuses_rather_than_flattens_or_drops,
crates/lang-rules/tests/inherited_operations.rs::c_python_and_node_now_refuse_instead_of_silently_answering_empty.
Status: partial — the binding rule for interfaces is implemented and
tested, including the list of languages that cannot render it completely.
The profile as a switchable set of building blocks does not exist.
Annex A: Consolidated IDL Grammar
Annex A Consolidated Grammar (227 productions)
Spec: Annex A, p. 123–132 — “This annex gathers all the rules from all the building blocks”; the productions (1)–(227) are numbered.
Repo: crates/idl-parse/src/decl.rs, crates/idl-parse/src/type_spec.rs,
crates/idl-parse/src/parser.rs, tools/idl-4.2-gap-scan/cases.tsv.
Tests: crates/idl-lower/tests/idl_4_2_grammar.rs::adjacent_string_literals_are_one_literal,
crates/idl-lower/tests/idl_4_2_grammar.rs::a_struct_defined_inside_a_typedef_is_declared_and_aliased,
crates/idl-lower/tests/idl_4_2_grammar.rs::every_constructed_form_can_be_defined_inside_a_typedef,
crates/idl-lower/tests/idl_4_2_grammar.rs::typeprefix_and_import_inside_an_interface_body_parse,
crates/idl-lower/tests/conformance.rs::every_fixture_round_trips_byte_for_byte,
crates/idl-lower/tests/conformance.rs::every_fixture_survives_a_snapshot_round_trip,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends.
Status: partial — Annex A is enumerated in
tools/idl-4.2-gap-scan/cases.tsv and the setpoints are pinned down in
expected.tsv, not in a Rust test: 161 of the 227 productions carry a
probe, 66 none. The measurement of these lines stands in
idl-4.2.gaps.en.md; the tool run is
tools/idl-4.2-gap-scan/scan.sh.
Audit Status
130 done / 35 partial / 17 open / 1 blocked / 7 n/a (informative).
Open items: idl-4.2.open.en.md.
OMG IDL 4.2 — Spec-Coverage
Spec: OMG Interface Definition Language 4.2 — formal/18-01-05 (March 2018, 132 Seiten) →
Item-für-Item-Audit gegen die Spec; jede Anforderung mit Spec-Zitat,
Repo-Pfad, Test-Pfad und Status (done / partial / open / n/a).
Kontext: Das IDL-Frontend ist über sechs Crates verteilt:
crates/idl-cst/· docs.rs — Lexer und CST: Tokens, Trivia, Spans, Baum.crates/idl-parse/· docs.rs — Präprozessor nach ISO/IEC 14882:2003, Parser, Deklarationen, Typ-Specs, Vendor-Dialekte.crates/ast/· docs.rs — das Modell: Knoten, Facetten, Builtin-Annotationen, Profile, Resolve.crates/idl-lower/· docs.rs — Lowering, Annotationen, Scope, Validierung, Repository-Ids.crates/idl-compose/· docs.rs — die Stufe, die Frontend und Modell zusammensetzt und den unzulässigen Zyklus erkennt.crates/ccm/· docs.rs — die IDL→IDL-Umschreibung der CCM-Konstrukte;crates/corba-codegen/— Repository-Ids, Stubs, Skeletons, Annex-A1-Traits.
tools/idlc/ ist der Compiler-Treiber. Die vollständige Negativliste zur
Grammatik (357 Proben, neun Spalten je Unterbefehl) steht in
idl-4.2.gaps.md; diese Seite ist die Positivliste.
Offene Punkte: siehe idl-4.2.open.md.
§7.1 Overview
§7.1 Overview
Spec: §7.1, S. 13–14 — die Klausel führt die Bestandteile einer IDL-Spezifikation ein und legt fest, dass die Regeln in atomare building blocks gruppiert sind, die erst in einem Profil verwendet werden.
Repo: crates/idl-parse/src/, crates/idl-lower/src/,
crates/idl-cst/src/.
Tests: —
Status: n/a (informative) — §7.1 gliedert die Specification und
stellt keine Anforderung an eine Implementierung. Die Bausteine werden je
in §7.4.x auditiert.
§7.2 Lexical Conventions
§7.2.1 Tokens
Spec: §7.2.1, S. 17 — “There are five kinds of tokens: identifiers, keywords, literals, operators, and other separators”; “the next token is taken to be the longest string of characters that could possibly constitute a token”.
Repo: crates/idl-cst/src/token.rs::TokenKind,
crates/idl-cst/src/lex.rs::next_token.
Tests: crates/idl-cst/tests/lexer.rs::an_empty_file_yields_one_eof_token,
crates/idl-cst/tests/lexer.rs::every_byte_is_reachable_for_a_realistic_file,
crates/idl-cst/tests/lexer.rs::spans_never_run_past_the_input,
crates/idl-cst/tests/lexer.rs::a_span_covers_what_it_claims,
crates/idl-cst/tests/tree.rs::a_flat_tree_reproduces_its_source_byte_for_byte —
lexer.rs:390: assert_eq!(Span::new(0, 6).slice(source), Some("module"));.
Status: done
§7.2.2 Comments
Spec: §7.2.2, S. 17 — “The characters /* start a comment, which terminates with the characters */. These comments do not nest.”; “The characters // start a comment, which terminates at the end of the line on which they occur.”
Repo: crates/idl-cst/src/lex.rs::scan_trivia; die Trivia wandert an
das nächste Token, der Baum führt sie mit.
Tests: crates/idl-cst/tests/lexer.rs::a_comment_before_a_token_is_that_tokens_leading_trivia,
crates/idl-cst/tests/lexer.rs::the_eof_token_carries_the_files_trailing_trivia,
crates/idl-cst/tests/lexer.rs::a_block_comment_is_one_piece_of_trivia_even_across_lines,
crates/idl-cst/tests/lexer.rs::an_unterminated_block_comment_runs_to_end_of_file_rather_than_failing,
crates/idl-cst/tests/tree.rs::a_tree_over_comments_and_spacing_reproduces_them_too,
crates/idl-cst/tests/tree.rs::a_leading_comment_is_not_part_of_it_either —
lexer.rs:274: assert_eq!(comments.len(), 1);.
Status: done
§7.2.3 Identifiers
Spec: §7.2.3, S. 18 — “An identifier is an arbitrarily long sequence of ASCII alphabetic, digit and underscore (_) characters. The first character must be an ASCII alphabetic character.”; “IDL identifiers are case insensitive.”
Repo: crates/idl-cst/src/lex.rs::lex_word,
crates/idl-cst/src/token.rs::identifier_name.
Tests: crates/idl-cst/tests/lexer.rs::an_ordinary_identifier_is_not_marked_escaped,
crates/idl-cst/tests/lexer.rs::an_identifier_that_differs_from_a_keyword_only_in_case_is_named_with_it —
lexer.rs:87: assert_eq!(zerodds_idl_cst::keyword_collision("CUSTOM"), Some("custom"));.
Status: done
§7.2.3.1 Collision Rules
Spec: §7.2.3.1, S. 18 — “Upper- and lower-case letters are treated as the same letter”; “There is only one namespace for IDL identifiers in each scope. Using the same identifier for a constant and an interface, for example, produces a compilation error.”
Repo: crates/idl-cst/src/token.rs::keyword_collision,
crates/idl-lower/src/lower.rs::identifiers_do_not_collide_with_keywords,
crates/idl-lower/src/scope.rs::ScopeStack.
Tests: crates/idl-lower/tests/validation.rs::two_names_differing_only_by_case_collide,
crates/idl-lower/tests/validation.rs::the_same_name_in_two_scopes_does_not_collide,
crates/idl-lower/tests/validation.rs::two_members_of_one_aggregate_differing_only_by_case_collide,
crates/idl-lower/tests/validation.rs::an_identifier_differing_from_a_keyword_only_in_case_is_refused,
crates/idl-lower/tests/validation.rs::a_name_that_collides_with_no_keyword_is_left_alone,
crates/idl-lower/tests/lowering.rs::a_name_declared_in_two_openings_of_one_module_collides —
lowering.rs:122: .any(|d| d.code == DiagnosticCode::DuplicateName),.
Status: done
§7.2.3.2 Escaped Identifiers
Spec: §7.2.3.2, S. 18 — “users may lexically”escape” identifiers by prepending an underscore (_) to an identifier. This is a purely lexical convention that ONLY turns off keyword checking.”
Repo: crates/idl-cst/src/token.rs::identifier_name (der führende
_ gehört nicht zum Namen), crates/idl-lower/src/lower.rs::identifiers_do_not_collide_with_keywords.
Tests: crates/idl-cst/tests/lexer.rs::an_escaped_identifier_is_the_name_without_the_underscore,
crates/idl-cst/tests/lexer.rs::an_underscore_prefixed_non_keyword_is_still_an_escaped_identifier,
crates/idl-lower/tests/validation.rs::the_underscore_escape_turns_the_keyword_check_off,
crates/idl-parse/tests/parse.rs::a_name_colliding_with_a_keyword_parses_as_a_name_and_is_refused_a_layer_up —
validation.rs:643: assert_clean("enum Ee { AA, _custom, BB };");.
Status: done
§7.2.4 Keywords (Table 7-6)
Spec: §7.2.4, S. 19 — “The identifiers listed in Table 7-6 are reserved
for use as keywords and may not be used for another purpose, unless escaped
with a leading underscore.”; Tabelle 7-6 nennt 84 Keywords einschliesslich
der vier grossgeschriebenen TRUE, FALSE, Object, ValueBase.
Repo: crates/idl-cst/src/token.rs::KEYWORDS (die Tabelle selbst),
crates/idl-cst/src/token.rs::keyword_collision.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier,
crates/idl-cst/tests/lexer.rs::a_keyword_is_recognised_only_in_the_spelling_table_7_6_gives,
crates/idl-cst/tests/lexer.rs::the_four_keywords_table_7_6_capitalises_are_spelled_as_it_spells_them,
crates/idl-lower/tests/validation.rs::the_diagnostic_names_the_keyword_and_the_clause —
lexer.rs:30: for (text, expected) in KEYWORDS {.
Status: done — der Test iteriert über alle Einträge der Tabelle, nicht über eine Stichprobe.
§7.2.5 Other Characters Recognized by IDL (Punctuation)
Spec: §7.2.5, S. 20 — Tabelle 7-7 (Punctuation) und Tabelle 7-8 (die
Präprozessor-Token #, ##, !, ||, &&).
Repo: crates/idl-cst/src/lex.rs::lex_punct,
crates/idl-parse/src/preprocess/pptoken.rs::PUNCTUATORS.
Tests: crates/idl-cst/tests/lexer.rs::a_hash_that_is_not_at_the_start_of_a_line_is_punctuation,
crates/idl-cst/tests/lexer.rs::an_illegal_byte_run_produces_one_error_token_not_one_per_byte,
crates/idl-parse/tests/parse.rs::every_operator_of_the_ladder_parses,
crates/idl-parse/tests/parse.rs::a_leading_double_colon_is_the_global_scope.
Status: partial — die Operatorleiter und # sind einzeln belegt; ein
Test über alle 28 Zeichen aus Tabelle 7-7 und alle fünf aus Tabelle 7-8
existiert nicht. Auch die iso-8859-1-Buchstaben aus Tabelle 7-2 sind
nicht einzeln probiert.
§7.2.6 Literals
Spec: §7.2.6, S. 20 — die Klausel benennt Integer-, Character-, Floating-Point-, String- und Fixed-Point-Literale.
Repo: crates/idl-cst/src/lex.rs::lex_number (Integer, Gleitkomma,
Fixed), crates/idl-cst/src/lex.rs::lex_char, crates/idl-cst/src/lex.rs::lex_string.
Tests: crates/idl-cst/tests/lexer.rs::a_literal_value_is_recovered_from_the_token_text_alone,
crates/idl-cst/tests/lexer.rs::text_that_is_not_one_whole_token_of_that_kind_has_no_value,
crates/idl-cst/tests/lexer.rs::a_literal_too_large_for_i128_is_an_error_not_a_wrapped_value —
lexer.rs:165: assert_eq!(kinds(&huge)[0], TokenKind::Error);.
Status: done
§7.2.6.1 Integer Literals
Spec: §7.2.6.1, S. 20–21 — Dezimal-, Oktal- (0 vorangestellt) und
Hexadezimal- (0x/0X) Form; die Schreibweise bleibt erhalten.
Repo: crates/idl-cst/src/lex.rs::lex_number, crates/idl-cst/src/token.rs::IntLiteral.
Tests: crates/idl-cst/tests/lexer.rs::every_radix_reaches_the_same_value_and_keeps_how_it_was_written,
crates/idl-cst/tests/lexer.rs::a_leading_zero_before_a_point_is_a_decimal_number_and_not_an_octal_one,
crates/idl-cst/tests/lexer.rs::a_literal_too_large_for_i128_is_an_error_not_a_wrapped_value —
lexer.rs:132: assert_eq!(tokens[0].kind, TokenKind::IntLiteral, "{text}");.
Status: done
§7.2.6.2 Character Literals
Spec: §7.2.6.2, S. 21–22 — ein Zeichenliteral ist ein einfaches Anführungszeichen, genau ein Zeichen, ein einfaches Anführungszeichen.
Repo: crates/idl-cst/src/lex.rs::lex_char.
Tests: crates/idl-cst/tests/lexer.rs::character_and_string_literals_resolve_their_escapes,
crates/idl-cst/tests/lexer.rs::a_raw_non_ascii_char_literal_is_its_code_point_and_not_its_last_octet,
crates/idl-cst/tests/lexer.rs::a_char_literal_the_type_cannot_hold_is_an_error_token —
lexer.rs:495: assert_eq!(lex("'ab'")[0].kind, TokenKind::Error);.
Status: done
§7.2.6.2.1 Wide and Non-wide Characters
Spec: §7.2.6.2.1, S. 21 — das L-Präfix (L'x') bezeichnet ein Wide
Character; der Wertebereich ist ISO 10646.
Repo: crates/idl-cst/src/lex.rs::next_token (TokenKind::WCharLiteral).
Tests: crates/idl-cst/tests/lexer.rs::wide_literals_are_their_own_kinds,
crates/idl-cst/tests/lexer.rs::a_char_literal_the_type_cannot_hold_is_an_error_token,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends —
lexer.rs:203: assert_eq!(kinds("L'x'")[0], TokenKind::WCharLiteral);.
Status: done
§7.2.6.2.2 Escape Sequences
Spec: §7.2.6.2.2, S. 21–22 — die Escape-Sequenzen des Spec-Absatzes zu
character literals: dezimale, oktale und hexadezimale Form sowie die
\u-/\U-Form für Wide Characters.
Repo: crates/idl-cst/src/lex.rs::scan_escape.
Tests: crates/idl-cst/tests/lexer.rs::character_and_string_literals_resolve_their_escapes,
crates/idl-cst/tests/lexer.rs::a_string_literal_value_has_its_escapes_resolved,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(lex-7.2.6.2-char-escape-octal, lex-7.2.6.2-char-escape-hex,
lex-7.2.6.2-wchar-escape-unicode).
Status: partial — die dezimalen und hexadezimalen Formen sind im
Lexer-Test belegt, die \u-/\U-Form nur als .idl-Fixture unter
tools/idlc/tests/idl-4.2-gaps/, nicht als Rust-Test.
§7.2.6.3 String Literals und Adjacent Concatenation
Spec: §7.2.6.3, S. 22 — “Adjacent string literals are concatenated. Characters in concatenated strings are kept distinct.”; “Attempts to assign a wide string literal to a non-wide string constant or to assign a non-wide string literal to a wide string constant result in a compile-time diagnostic.”
Repo: crates/idl-parse/src/parser.rs::eat_adjacent_string_literals,
crates/idl-cst/src/lex.rs::lex_string.
Tests: crates/idl-lower/tests/idl_4_2_grammar.rs::adjacent_string_literals_are_one_literal,
crates/idl-lower/tests/idl_4_2_grammar.rs::the_characters_of_concatenated_strings_are_kept_distinct,
crates/idl-lower/tests/idl_4_2_grammar.rs::adjacent_wide_string_literals_are_one_literal,
crates/idl-lower/tests/idl_4_2_grammar.rs::a_narrow_and_a_wide_literal_are_not_concatenated,
crates/idl-lower/tests/idl_4_2_grammar.rs::an_annotation_argument_takes_the_whole_concatenated_literal,
crates/idl-lower/tests/idl_4_2_grammar.rs::a_typeid_takes_the_whole_concatenated_literal,
crates/idl-lower/tests/validation.rs::the_wide_and_narrow_string_pair_is_the_case_the_clause_names —
idl_4_2_grammar.rs:54: assert_eq!(constant(&ast, "K"), ConstValue::String("abcd".to_string()));.
Status: done
§7.2.6.4 Floating-point Literals
Spec: §7.2.6.4, S. 22–23 — die Gleitkomma-Literale mit und ohne Exponent und mit führendem oder nachgestelltem Punkt.
Repo: crates/idl-cst/src/lex.rs::lex_number,
crates/idl-lower/src/expr.rs.
Tests: crates/idl-cst/tests/lexer.rs::float_forms_stay_distinguishable_from_one_another,
crates/idl-cst/tests/lexer.rs::a_leading_zero_before_a_point_is_a_decimal_number_and_not_an_octal_one,
crates/idl-lower/tests/floating_constant_arithmetic.rs::a_difference_of_two_literals_evaluates,
crates/idl-lower/tests/floating_constant_arithmetic.rs::the_arithmetic_is_double,
crates/idl-lower/tests/floating_constant_arithmetic.rs::a_large_value_keeps_its_exponent,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(lex-7.2.6.4-float-leading-dot, lex-7.2.6.4-float-trailing-dot) —
lexer.rs:144: assert_eq!(kinds(text)[0], TokenKind::FloatLiteral, "{text}");.
Status: done
§7.2.6.5 Fixed-point Literals
Spec: §7.2.6.5, S. 23 — die d/D-Suffixform ist das
Fixed-Point-Literal; f/F ist die Gleitkommaform.
Repo: crates/idl-cst/src/lex.rs::lex_number (der d-Zweig),
crates/idl-lower/src/expr.rs (Auswertung als fixed<digits, scale>).
Tests: crates/idl-cst/tests/lexer.rs::a_d_suffix_makes_a_fixed_point_literal,
crates/idl-lower/tests/lowering.rs::a_fixed_constant_takes_its_type_from_its_literal,
crates/idl-lower/tests/completion.rs::a_fixed_type_carries_its_digits_and_scale,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(lex-7.2.6.5-fixed-literal) —
lexer.rs:157: assert_eq!(kinds(text)[0], TokenKind::FixedLiteral, "{text}");.
Status: done
§7.3 Preprocessing
§7.3 Preprocessing (ISO/IEC 14882:2003)
Spec: §7.3, S. 23 — “IDL shall be preprocessed according to the specification of the preprocessor in ISO/IEC 14882:2003.”
Repo: crates/idl-parse/src/preprocess/mod.rs (Direktivenlauf),
crates/idl-parse/src/preprocess/condition.rs (#if-Auswertung),
crates/idl-parse/src/preprocess/macro_.rs (Makrotabelle),
crates/idl-parse/src/preprocess/pptoken.rs (Präprozessor-Token).
Tests: crates/idl-parse/tests/preprocess.rs::a_macro_is_expanded_before_the_parser_sees_it,
crates/idl-parse/tests/preprocess.rs::the_expanded_text_is_itself_lexable,
crates/idl-parse/tests/preprocess.rs::the_expanded_stream_carries_no_directive_tokens,
crates/idl-parse/tests/preprocessor_iso_14882.rs::the_diagnostic_code_is_stable —
preprocess.rs:493: assert!(text.contains('8'), "the macro was not expanded: {text}");.
Status: done
§7.3 Zeilenfortsetzung mit Backslash
Spec: §7.3, S. 23 — “A preprocessing directive (or any line) may be continued on the next line in a source file by placing a backslash character (), immediately before the newline at the end of the line to be continued.”
Repo: crates/idl-parse/src/preprocess/mod.rs::splice (am Anfang von
directive), crates/idl-cst/src/lex.rs::scan_trivia auf der
Präprozessor-Ebene.
Tests: crates/idl-parse/tests/preprocessor_iso_14882.rs::a_backslash_continues_a_directive,
crates/idl-cst/tests/lexer.rs::a_preprocessor_line_is_trivia_including_its_continuations —
lexer.rs:296: assert_eq!(reconstruct(source), source);.
Status: done
§7.3 Makro-Expansion und Rescan mit Hide-Set
Spec: §7.3, S. 23 (Übernahme aus ISO/IEC 14882:2003 §16.3) — ein Makro, das sich selbst expandiert, expandiert sich nicht erneut; der Rescan greift auf die Tokens nach dem Aufruf zu.
Repo: crates/idl-parse/src/preprocess/mod.rs::run und
substitute, crates/idl-parse/src/preprocess/macro_.rs::MacroTable.
Tests: crates/idl-parse/tests/preprocess.rs::a_defined_name_is_replaced_by_its_body,
crates/idl-parse/tests/preprocess.rs::a_macro_expanding_to_another_macro_is_rescanned,
crates/idl-parse/tests/preprocessor_iso_14882.rs::a_macro_does_not_expand_inside_its_own_expansion,
crates/idl-parse/tests/preprocessor_iso_14882.rs::the_rescan_reaches_the_tokens_after_the_invocation,
crates/idl-parse/tests/preprocessor_iso_14882.rs::an_argument_is_expanded_before_it_is_substituted,
crates/idl-parse/tests/preprocessor_iso_14882.rs::an_expansion_that_is_not_an_idl_token_is_reported —
preprocess.rs:67: assert!(result.text.contains("= 1"), "{}", result.text);.
Status: done
§7.3 Funktionsartige Makros, Stringize #, Token-Paste ##
Spec: §7.3 in Verbindung mit ISO/IEC 14882:2003 §16.3.1 und §16.3.2 —
objektartige und funktionsartige Makros, # als Stringize-Operator,
## als Token-Paste.
Repo: crates/idl-parse/src/preprocess/mod.rs::substitute und
arguments, crates/idl-parse/src/preprocess/pptoken.rs (Punktuatoren).
Tests: crates/idl-parse/tests/preprocessor_iso_14882.rs::a_function_like_macro_substitutes_its_arguments,
crates/idl-parse/tests/preprocessor_iso_14882.rs::stringize_spells_the_argument,
crates/idl-parse/tests/preprocessor_iso_14882.rs::token_paste_joins_two_tokens,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(lex-7.3-define-function, lex-7.3-token-paste) —
preprocessor_iso_14882.rs:137: "struct Sa { long m ; } ;".
Status: done
§7.3 #include
Spec: §7.3, S. 23 — “Text in files included with a #include directive is treated as if it appeared in the including file.”
Repo: crates/idl-parse/src/preprocess/mod.rs::include mit der
Schranke MAX_INCLUDE_DEPTH.
Tests: crates/idl-parse/tests/preprocess.rs::an_included_file_contributes_its_declarations,
crates/idl-parse/tests/preprocess.rs::both_include_spellings_resolve,
crates/idl-parse/tests/preprocess.rs::an_include_cycle_is_diagnosed_and_not_followed,
crates/idl-parse/tests/preprocess.rs::an_include_chain_past_the_nesting_bound_is_refused,
crates/idl-parse/tests/source_map.rs::a_token_from_an_include_names_that_file,
crates/idl-lower/tests/conformance.rs::a_fixture_with_an_include_gains_the_declarations_it_includes —
preprocess.rs:206: assert!(result.text.contains("Common"));.
Status: done
§7.3 #define und #undef
Spec: §7.3, S. 23 — #define und #undef mit objektartigem Namen;
die reservierten Namen der ISO-Norm dürfen nicht neu definiert werden.
Repo: crates/idl-parse/src/preprocess/mod.rs::directive,
crates/idl-parse/src/preprocess/macro_.rs::MacroTable::define und
undefine.
Tests: crates/idl-parse/tests/preprocess.rs::a_redefinition_replaces_the_earlier_one,
crates/idl-parse/tests/preprocess.rs::a_define_without_a_name_is_diagnosed,
crates/idl-parse/tests/preprocess.rs::an_undefined_name_is_left_alone,
crates/idl-parse/tests/preprocessor_iso_14882.rs::the_predefined_names_cannot_be_defined,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(lex-7.3-undef) —
preprocess.rs:41: assert!(expanded.contains("MAX"), "{expanded}");.
Status: done
§7.3 Konditionalen #if / #ifdef / #ifndef / #else / #elif / #endif
Spec: §7.3 in Verbindung mit ISO/IEC 14882:2003 §16.1 — die
Kondition wird über einen konstanten Ausdruck ausgewertet, defined(X)
fragt die Definition ab.
Repo: crates/idl-parse/src/preprocess/mod.rs::directive und
evaluate_condition, crates/idl-parse/src/preprocess/condition.rs::evaluate.
Tests: crates/idl-parse/tests/preprocess.rs::ifdef_keeps_only_the_taken_branch,
crates/idl-parse/tests/preprocess.rs::ifndef_is_the_other_way_round,
crates/idl-parse/tests/preprocess.rs::elif_takes_the_first_true_branch_and_no_later_one,
crates/idl-parse/tests/preprocess.rs::else_is_taken_only_when_nothing_before_it_was,
crates/idl-parse/tests/preprocess.rs::conditionals_nest,
crates/idl-parse/tests/preprocess.rs::a_define_inside_a_dropped_branch_does_not_take_effect,
crates/idl-parse/tests/preprocess.rs::an_if_with_a_literal_works_and_an_unevaluable_one_is_reported,
crates/idl-parse/tests/preprocessor_iso_14882.rs::if_evaluates_an_arithmetic_expression,
crates/idl-parse/tests/preprocessor_iso_14882.rs::a_division_by_zero_in_a_live_condition_is_an_error —
preprocess.rs:76: assert!(expanded.contains("Kept"), "{expanded}");.
Status: done
§7.3 #line
Spec: §7.3 in Verbindung mit ISO/IEC 14882:2003 §16.4 — #line setzt
Zeilennummer und Dateiname für die folgenden Tokens.
Repo: crates/idl-parse/src/preprocess/mod.rs::line_control.
Tests: crates/idl-parse/tests/preprocessor_iso_14882.rs::hash_line_renumbers_and_renames,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(lex-7.3-line-directive) —
preprocessor_iso_14882.rs:259: "const long K = 100 ; const string F = \"robot.idl\" ;".
Status: done
§7.3 #pragma und #pragma once
Spec: §7.3, S. 23 — “The textual location of IDL-specific pragmas may be semantically constrained.”
Repo: crates/idl-parse/src/preprocess/mod.rs::directive und
flush_trailing_pragmas; interpretiert wird eine #pragma-Zeile in
crates/idl-lower/src/complete.rs.
Tests: crates/idl-parse/tests/preprocess.rs::a_pragma_is_not_the_preprocessors_business,
crates/idl-parse/tests/preprocess.rs::a_pragma_the_preprocessor_does_not_own_still_reaches_the_stream,
crates/idl-parse/tests/preprocess.rs::pragma_once_holds_the_way_an_ifndef_guard_does,
crates/idl-parse/tests/preprocess.rs::a_pragma_once_in_a_branch_that_is_cut_out_does_not_guard,
crates/idl-lower/tests/dialects.rs::a_pragma_id_sets_the_repository_id_like_typeid_does,
crates/idl-lower/tests/dialects.rs::a_cyclone_pragma_keylist_reaches_the_same_field_as_rtis_keylist,
crates/idl-lower/tests/dialects.rs::the_opendds_pragmas_reach_the_opendds_facet —
preprocess.rs:332: assert_eq!(kept, 1, "the keylist pragma did not survive");.
Status: done
§7.3 #error
Spec: §7.3 in Verbindung mit ISO/IEC 14882:2003 §16.5 — “#error causes the implementation to produce a diagnostic message that includes the specified sequence of preprocessing tokens.”
Repo: crates/idl-parse/src/preprocess/mod.rs::directive, Arm error
(DiagnosticCode::ErrorDirective).
Tests: crates/idl-parse/tests/preprocess.rs::an_error_directive_is_a_diagnostic_and_carries_its_text,
crates/idl-parse/tests/preprocess.rs::an_error_directive_in_a_branch_that_is_cut_out_says_nothing,
crates/idl-parse/tests/preprocess.rs::a_bare_error_directive_is_still_a_diagnostic —
preprocess.rs:732: out.diagnostics.iter().any(|d| d.code.as_str() == "IDL0020"),.
Status: done
§7.3 LINE und FILE
Spec: §7.3 in Verbindung mit ISO/IEC 14882:2003 §16.10 — die
vordefinierten Namen __LINE__ und __FILE__.
Repo: crates/idl-parse/src/preprocess/mod.rs::predefined.
Tests: crates/idl-parse/tests/preprocessor_iso_14882.rs::line_and_file_name_where_they_stand,
crates/idl-parse/tests/preprocessor_iso_14882.rs::line_inside_a_macro_is_the_line_of_the_invocation,
crates/idl-parse/tests/preprocessor_iso_14882.rs::the_predefined_names_cannot_be_defined —
preprocessor_iso_14882.rs:239: "const long K = 3 ;".
Status: done
§7.4 IDL Grammar
§7.4 Grammatikrahmen und vorbestehende Nichtterminale
Spec: §7.4, S. 24 — “The grammar for a well-formed IDL specification is
described by rules expressed in Extended Backus Naur Form (EBNF) completed
to support rule extensions as explained in clause 7.1”; Tabelle 7-10 führt
<identifier>, <integer_literal>, <string_literal>,
<wide_string_literal>, <character_literal>, <wide_character_literal>,
<fixed_pt_literal>, <floating_pt_literal> als vorbestehende
Nichtterminale.
Repo: crates/idl-parse/src/parser.rs,
crates/idl-parse/src/type_spec.rs::is_primitive_keyword,
crates/idl-parse/src/decl.rs::parse_definition.
Tests: crates/idl-parse/tests/parse.rs::a_file_using_most_of_the_grammar_parses_cleanly_and_round_trips,
crates/idl-parse/tests/parse.rs::the_multi_word_primitive_types_parse_as_one_type_each,
crates/idl-lower/tests/validation.rs::a_file_using_the_whole_language_reports_nothing —
parse.rs:449: assert_eq!(result.text(), source);.
Status: done
§7.4.1 Building Block Core Data Types
§7.4.1.1 Purpose
Spec: §7.4.1.1, S. 24 — “The Core Data Types are the data types that must be supported by every profile.”
Repo: crates/idl-lower/src/lower.rs::lower,
crates/ast/src/model.rs::Ast.
Tests: —
Status: n/a (informative) — die Klausel begründet den Baustein und
verlangt nichts über die Form; die einzelnen Typen sind in §7.4.1.4.4.2
auditiert.
§7.4.1.3 Syntax (Produktionen 1–68)
Spec: §7.4.1.3, S. 24–30 — die Produktionen der EBNF-Tabelle:
specification, definition, module_dcl, const_dcl, const_type,
const_expr, type_dcl, typedef_dcl, type_declarator, constr_type_dcl,
struct_dcl, member, union_dcl, switch_type, case, case_label,
enum_dcl, enumerator, array_declarator, simple_type_spec,
native_type, forward_dcl.
Repo: crates/idl-parse/src/decl.rs::parse_definition und die
Produktionsfunktionen daneben (parse_module, parse_const,
parse_typedef, parse_struct_def, parse_union_case, parse_enum_def,
parse_native), crates/idl-parse/src/type_spec.rs::parse_type_spec.
Tests: crates/idl-parse/tests/parse.rs::each_declaration_form_is_recognised,
crates/idl-parse/tests/parse.rs::several_declarators_share_one_type,
crates/idl-parse/tests/parse.rs::a_forward_declaration_is_its_own_form,
crates/idl-parse/tests/parse.rs::an_array_declarator_is_only_known_at_the_bracket,
crates/idl-lower/tests/validation.rs::an_enumeration_with_no_enumerator_is_refused,
crates/idl-lower/tests/validation.rs::a_bitmask_with_no_bit_value_is_refused,
crates/idl-lower/tests/validation.rs::a_union_with_no_case_is_refused,
crates/idl-lower/tests/validation.rs::the_two_bodies_the_grammar_does_let_be_empty_stay_empty,
crates/idl-lower/tests/idl_4_2_grammar.rs::every_constructed_form_can_be_defined_inside_a_typedef.
Status: partial — die Produktionen sind erkannt, aber Produktion 62
erlaubt native_type auch als Member-Typ-Spec
(<type_spec> ::+ <native_type> | …); struct S { native H; }; ist nicht
abgedeckt, parse_type_spec hat keinen Native-Zweig. Die Lücke ist in
idl-4.2.gaps.md §A gemessen.
§7.4.1.4.1 IDL Specification
Spec: §7.4.1.4.1, S. 30 — eine IDL-Spezifikation besteht aus Deklarationen; die Included-Dateien zählen dazu.
Repo: crates/idl-lower/src/lower.rs::lower.
Tests: crates/idl-lower/tests/conformance.rs::every_fixture_parses_with_no_diagnostics_beyond_the_extensions_it_declares,
crates/idl-lower/tests/conformance.rs::every_fixture_produces_a_model_with_declarations_in_it,
crates/idl-lower/tests/conformance.rs::every_node_of_every_fixture_names_the_file_it_came_from,
crates/idl-lower/tests/conformance.rs::a_fixture_with_an_include_gains_the_declarations_it_includes —
conformance.rs:202: ast.types().count() > 0 || ast.interfaces().count() > 0,.
Status: done
§7.4.1.4.2 Modules
Spec: §7.4.1.4.2, S. 30–31 — ein module eröffnet einen Scope, der
bis zur schliessenden } reicht.
Repo: crates/idl-lower/src/lower.rs::module,
crates/idl-lower/src/scope.rs::ScopeStack::push_container.
Tests: crates/idl-lower/tests/lowering.rs::a_module_becomes_a_module_node,
crates/idl-lower/tests/lowering.rs::nested_modules_nest_in_the_model_too,
crates/idl-lower/tests/conformance.rs::a_conditional_in_a_fixture_keeps_the_branch_out_of_the_model,
crates/ast/tests/node_space.rs::nested_modules_are_addressable_by_path,
crates/ast/tests/node_space.rs::a_fresh_model_has_an_anonymous_root_module —
lowering.rs:51: assert!(ast.module_by_path(&scoped(&["Robot"])).is_some());.
Status: done
§7.4.1.4.3 Constants
Spec: §7.4.1.4.3, S. 37 — eine Konstantendeklaration besteht unter
anderem aus “a value expression (<const_expr>), which shall be consistent
with the type declared for the constant”.
Repo: crates/idl-lower/src/lower.rs::value_disagrees_with und
check_const_value_form, crates/idl-lower/src/expr.rs (Auswertung).
Tests: crates/idl-lower/tests/validation.rs::a_constant_whose_value_is_not_of_its_declared_type_is_refused,
crates/idl-lower/tests/validation.rs::every_form_the_specification_admits_still_gets_through,
crates/idl-lower/tests/completion.rs::a_constant_takes_its_declared_type_not_the_expressions,
crates/idl-lower/tests/lowering.rs::a_string_constant_evaluates_even_though_no_integer_holds_it,
crates/idl-lower/tests/lowering.rs::eval_const_follows_a_reference_and_keeps_arithmetic_integral,
crates/ast/tests/node_space.rs::every_operator_of_idl_4_2_is_representable,
crates/ast/tests/node_space.rs::division_by_zero_is_an_error_not_a_panic —
validation.rs:701: assert_trips("const long K = \"x\";", DiagnosticCode::TypeMismatch);.
Status: done
§7.4.1.4.4 Data Types (Rahmen)
Spec: §7.4.1.4.4, S. 38 — die Klausel gliedert die Daten-Typen in
referencing, basic, template und constructed.
Repo: crates/idl-lower/src/validate.rs::validate_type.
Tests: crates/idl-lower/tests/validation.rs::a_file_using_the_whole_language_reports_nothing,
crates/idl-lower/tests/lowering.rs::each_primitive_keyword_reaches_its_model_kind —
lowering.rs:347: TypeKind::Primitive(expected),.
Status: done
§7.4.1.4.4.1 Referencing Types
Spec: §7.4.1.4.4.1, S. 38 — ein Referenz-Typ ist ein qualifizierter Name; er darf auf eine später deklarierte Definition zeigen.
Repo: crates/idl-lower/src/lower.rs::named_type_ref,
crates/idl-lower/src/scope.rs::ScopeStack::lookup_candidates.
Tests: crates/idl-lower/tests/lowering.rs::a_reference_to_a_type_declared_later_is_pending_not_an_error,
crates/idl-lower/tests/lowering.rs::a_reference_to_a_type_declared_earlier_resolves_immediately,
crates/idl-lower/tests/lowering.rs::a_pending_reference_resolves_once_the_name_arrives,
crates/idl-lower/tests/lowering.rs::a_name_that_never_arrives_ends_up_broken_rather_than_pending,
crates/idl-lower/tests/reported_idl.rs::a_fully_qualified_scoped_name_resolves,
crates/ast/tests/node_space.rs::an_unknown_path_resolves_to_nothing —
lowering.rs:381: assert!(report.resolved >= 1, "nothing resolved: {report:?}");.
Status: done
§7.4.1.4.4.2 Basic Types
Spec: §7.4.1.4.4.2, S. 38–39 — die Basis-Typen der Produktionen 30–37.
Repo: crates/idl-lower/src/lower.rs::primitive_of,
crates/ast/src/node/type_.rs::PrimitiveKind.
Tests: crates/idl-lower/tests/lowering.rs::each_primitive_keyword_reaches_its_model_kind,
crates/ast/tests/node_space.rs::every_primitive_of_the_spec_table_is_representable —
node_space.rs:86: assert_eq!(PrimitiveKind::ALL.len(), 15);.
Status: done
§7.4.1.4.4.2.1 Integer Types
Spec: §7.4.1.4.4.2.1, S. 38–39 — short, long, long long,
unsigned short, unsigned long, unsigned long long.
Repo: crates/idl-lower/src/lower.rs::primitive_of,
crates/idl-parse/src/type_spec.rs::is_primitive_keyword.
Tests: crates/idl-lower/tests/lowering.rs::each_primitive_keyword_reaches_its_model_kind,
crates/idl-parse/tests/parse.rs::the_multi_word_primitive_types_parse_as_one_type_each,
crates/idl-lower/tests/validation.rs::every_form_the_specification_admits_still_gets_through —
lowering.rs:327: ("unsigned long long", PrimitiveKind::UInt64),.
Status: done
§7.4.1.4.4.2.2 Floating-Point Types
Spec: §7.4.1.4.4.2.2, S. 34 — “IDL floating-point types are float, double, and long double. The float type represents IEEE single-precision floating point numbers; the double type represents IEEE double-precision floating point numbers. The long double data type represents an IEEE double-extended floating-point number”.
Repo: crates/idl-lower/src/lower.rs::primitive_of (Arme Float32,
Float64, Float128), crates/float128/src/lib.rs::Float128.
Tests: crates/idl-lower/tests/lowering.rs::each_primitive_keyword_reaches_its_model_kind,
crates/idl-lower/tests/floating_constant_arithmetic.rs::long_double_arithmetic_is_refused_and_a_long_double_literal_is_not.
Status: partial — float und double sind modelliert und getestet. long double ist als Float128 modelliert; die Arithmetik eines long double-Ausdrucks wird abgewiesen (EvalError::LongDouble), eigenes Item.
§7.4.1.4.4.2.2 long double als IEEE double-extended
Spec: §7.4.1.4.4.2.2, S. 34 — “The long double data type represents an IEEE double-extended floating-point number, which has an exponent of at least 15 bits in length and a signed fraction of at least 64 bits”.
Repo: crates/float128/src/lib.rs (Float128), crates/idl-lower/src/lower.rs (primitive_of, Arm Float128)
Tests: crates/idl-lower/tests/floating_constant_arithmetic.rs::long_double_arithmetic_is_refused_and_a_long_double_literal_is_not
Status: blocked — Rust stable hat keinen Typ f128 (rust-lang/rust#116909); aufgehoben, sobald f128 in Rust stable verfügbar ist. Bis dahin weist die Konstantenauswertung long double-Arithmetik mit EvalError::LongDouble ab.
§7.4.1.4.4.2.3 char Type
Spec: §7.4.1.4.4.2.3, S. 39 — der Typ char, ISO Latin-1, ein Byte.
Repo: crates/idl-lower/src/lower.rs::value_disagrees_with (Arm
PrimitiveKind::Char), crates/idl-cst/src/lex.rs::lex_char.
Tests: crates/idl-lower/tests/validation.rs::a_constant_whose_value_is_not_of_its_declared_type_is_refused,
crates/idl-lower/tests/validation.rs::every_form_the_specification_admits_still_gets_through,
crates/idl-cst/tests/lexer.rs::a_raw_non_ascii_char_literal_is_its_code_point_and_not_its_last_octet —
lexer.rs:473: assert_eq!(tokens[0].value, TokenValue::Char { value: 0x00E4 });.
Status: done
§7.4.1.4.4.2.4 Wide Char Type
Spec: §7.4.1.4.4.2.4, S. 39 — der Typ wchar, ISO 10646.
Repo: crates/idl-lower/src/lower.rs::value_disagrees_with (Arm
PrimitiveKind::WChar), crates/idl-cst/src/lex.rs::next_token.
Tests: crates/idl-lower/tests/validation.rs::a_constant_whose_value_is_not_of_its_declared_type_is_refused,
crates/idl-lower/tests/validation.rs::the_wide_and_narrow_string_pair_is_the_case_the_clause_names,
crates/idl-cst/tests/lexer.rs::wide_literals_are_their_own_kinds —
lexer.rs:203: assert_eq!(kinds("L'x'")[0], TokenKind::WCharLiteral);.
Status: done
§7.4.1.4.4.2.5 Boolean Type
Spec: §7.4.1.4.4.2.5, S. 39 — der Typ boolean, Wertebereich 0/1,
konstante Werte TRUE/FALSE.
Repo: crates/idl-lower/src/validate.rs::primitive_range (Arm
PrimitiveKind::Boolean).
Tests: crates/idl-lower/tests/validation.rs::every_form_the_specification_admits_still_gets_through,
crates/idl-lower/tests/validation.rs::a_constant_whose_value_is_not_of_its_declared_type_is_refused,
crates/idl-lower/tests/validation.rs::a_boolean_discriminator_admits_only_zero_and_one —
validation.rs:281: "union U switch (boolean) { case 0: long a; case 1: long b; };",.
Status: done
§7.4.1.4.4.2.6 Octet Type
Spec: §7.4.1.4.4.2.6, S. 39 — der Typ octet, ein vorzeichenloses
Byte.
Repo: crates/idl-lower/src/validate.rs::primitive_range (Arm
Octet | UInt8).
Tests: crates/idl-lower/tests/lowering.rs::each_primitive_keyword_reaches_its_model_kind,
crates/idl-lower/tests/completion.rs::a_constant_takes_its_declared_type_not_the_expressions,
crates/idl-lower/tests/validation.rs::every_form_the_specification_admits_still_gets_through —
completion.rs:320: TypeKind::Primitive(zerodds_ast::PrimitiveKind::Octet).
Status: done
§7.4.1.4.4.3 Template Types
Spec: §7.4.1.4.4.3, S. 39–41 — Sequences, Strings, Wstrings und Fixed als Schablonen-Typen mit optionaler Schranke.
Repo: crates/idl-parse/src/type_spec.rs (parse_sequence_type,
parse_string_type), crates/idl-lower/src/validate.rs::validate_type.
Tests: crates/idl-lower/tests/lowering.rs::a_sequence_member_carries_its_element_type,
crates/idl-lower/tests/completion.rs::a_bounded_string_and_sequence_carry_their_bound_expressions,
crates/idl-lower/tests/completion.rs::an_unbounded_collection_says_so_rather_than_carrying_a_zero —
completion.rs:418: assert!(!bound.is_bounded(), "{name} gained a bound");.
Status: done
§7.4.1.4.4.3.1 Sequences
Spec: §7.4.1.4.4.3.1, S. 39–40 — sequence < <positive_int_const> > < type_spec >; die Schranke muss positiv sein.
Repo: crates/idl-parse/src/type_spec.rs::parse_sequence_type,
crates/idl-lower/src/validate.rs::validate_type.
Tests: crates/idl-lower/tests/validation.rs::a_negative_sequence_bound_is_rejected,
crates/idl-lower/tests/validation.rs::a_positive_bound_is_accepted,
crates/idl-lower/tests/lowering.rs::a_sequence_member_carries_its_element_type —
validation.rs:481: "struct S { sequence<long, -1> a; };",.
Status: done
§7.4.1.4.4.3.2 Strings
Spec: §7.4.1.4.4.3.2, S. 40 — string < <positive_int_const> >.
Repo: crates/idl-parse/src/type_spec.rs::parse_string_type.
Tests: crates/idl-lower/tests/validation.rs::a_zero_string_bound_is_rejected,
crates/idl-lower/tests/completion.rs::a_bounded_string_and_sequence_carry_their_bound_expressions,
crates/ast/tests/node_space.rs::narrow_and_wide_strings_are_distinct_kinds —
validation.rs:475: assert_trips("struct S { string<0> a; };", DiagnosticCode::InvalidBound);.
Status: done
§7.4.1.4.4.3.3 Wstrings
Spec: §7.4.1.4.4.3.3, S. 40 — wstring < <positive_int_const> >,
ISO 10646.
Repo: crates/idl-parse/src/type_spec.rs::parse_string_type
(Zweig TokenKind::Wstring).
Tests: crates/idl-lower/tests/validation.rs::a_zero_string_bound_is_rejected,
crates/idl-lower/tests/idl_4_2_grammar.rs::adjacent_wide_string_literals_are_one_literal,
crates/ast/tests/node_space.rs::narrow_and_wide_strings_are_distinct_kinds,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(bb1-006-const-wstring) —
idl_4_2_grammar.rs:74: ConstValue::WString("abcd".chars().map(u32::from).collect()).
Status: done
§7.4.1.4.4.3.4 Fixed Type
Spec: §7.4.1.4.4.3.4, S. 40–41 — fixed < <positive_int_const> , <positive_int_const> > mit höchstens 31 Stellen; die Skala darf die
Stellenzahl nicht übersteigen.
Repo: crates/idl-lower/src/validate.rs::fixed_rules mit
MAX_FIXED_DIGITS, crates/idl-lower/src/expr.rs (Fixed-Arithmetik).
Tests: crates/idl-lower/tests/validation.rs::a_fixed_with_more_than_thirty_one_digits_is_rejected,
crates/idl-lower/tests/validation.rs::a_fixed_whose_scale_exceeds_its_digits_is_rejected,
crates/idl-lower/tests/validation.rs::a_fixed_within_its_ranges_is_accepted,
crates/idl-lower/tests/fixed_constant_arithmetic.rs::a_sum_lines_the_points_up_and_drops_the_insignificant_zero,
crates/idl-lower/tests/fixed_constant_arithmetic.rs::a_product_carries_both_scales,
crates/idl-lower/tests/fixed_constant_arithmetic.rs::a_quotient_is_exact_or_cut_without_rounding,
crates/idl-lower/tests/lowering.rs::table_7_11_decides_the_type_of_a_fixed_expression,
crates/ast/tests/node_space.rs::fixed_retains_digits_and_scale —
validation.rs:503: assert_trips("struct S { fixed<32,2> a; };", DiagnosticCode::InvalidBound);.
Status: done
§7.4.1.4.4.4 Constructed Types
Spec: §7.4.1.4.4.4, S. 41–43 — Structures, Unions, Enumerations, Forward Declarations und Native als konstruierte Typen.
Repo: crates/idl-lower/src/lower.rs (structure, union,
enumeration, native), crates/idl-lower/src/validate.rs::union_rules.
Tests: crates/idl-lower/tests/lowering.rs::a_struct_carries_its_members_in_order,
crates/idl-lower/tests/lowering.rs::an_enum_carries_its_enumerators_in_order,
crates/ast/tests/node_space.rs::struct_members_land_in_declaration_order_with_the_right_parent,
crates/idl-lower/tests/spans.rs::a_struct_member_names_its_declarator_and_not_the_space_before_it —
lowering.rs:492: assert_eq!(names, vec!["IDLE", "ACTIVE", "FAULT"]);.
Status: done
§7.4.1.4.4.4.1 Structures
Spec: §7.4.1.4.4.4.1, S. 41–42 — struct <identifier> { <member> * },
eine Liste von <member>, jede mit eigenem Declarator.
Repo: crates/idl-lower/src/lower.rs::structure.
Tests: crates/idl-lower/tests/lowering.rs::a_struct_carries_its_members_in_order,
crates/idl-lower/tests/lowering.rs::several_declarators_share_the_type_and_become_separate_members,
crates/idl-lower/tests/lowering.rs::an_exception_carries_its_members,
crates/idl-lower/tests/spans.rs::the_second_declarator_of_a_list_names_its_own_line —
lowering.rs:304: assert_eq!(names, vec!["x", "y", "z"]);.
Status: done
§7.4.1.4.4.4.2 Unions und die Regeln zu Case-Labels
Spec: §7.4.1.4.4.4.2, S. 42 — “If the discriminator value was
explicitly listed in a case statement, the value of the element associated
with the case label is the discriminator”; ferner: kein Label darf zweimal
vorkommen, und es darf höchstens ein default geben.
Repo: crates/idl-lower/src/validate.rs::union_rules,
crates/idl-lower/src/lower.rs::union.
Tests: crates/idl-lower/tests/lowering.rs::a_union_over_an_enumeration_lowers_with_its_labels_evaluated,
crates/idl-lower/tests/lowering.rs::a_case_label_may_name_its_enumerator_by_a_qualified_name,
crates/idl-lower/tests/validation.rs::a_repeated_case_label_is_rejected,
crates/idl-lower/tests/validation.rs::distinct_case_labels_are_accepted,
crates/idl-lower/tests/validation.rs::two_default_cases_are_rejected,
crates/idl-lower/tests/spans.rs::a_repeated_case_label_is_reported_on_the_branch_that_repeats_it,
crates/ast/tests/node_space.rs::a_default_case_is_recorded_on_the_union_as_well_as_in_the_case_list,
crates/ast/tests/node_space.rs::a_case_may_carry_several_labels —
lowering.rs:193: assert_eq!(labels, [0, 1, 2]);.
Status: done
§7.4.1.4.4.4.3 Enumerations
Spec: §7.4.1.4.4.4.3, S. 42 — enum <identifier> { <enumerator> { "," <enumerator> } * }; ein Enumerator kann einen expliziten Wert
tragen, die folgenden laufen von da an weiter.
Repo: crates/ast/src/query.rs::effective_enumerator_value,
crates/idl-lower/src/lower.rs::enumeration.
Tests: crates/idl-lower/tests/lowering.rs::an_enum_carries_its_enumerators_in_order,
crates/idl-lower/tests/lowering.rs::an_enumerator_evaluates_inside_a_larger_expression,
crates/idl-lower/tests/completion.rs::enumerators_without_values_run_from_zero_upwards,
crates/idl-lower/tests/completion.rs::an_explicit_enumerator_value_shifts_the_ones_after_it,
crates/ast/tests/node_space.rs::a_positional_enumerator_and_an_explicit_value_are_distinguishable —
completion.rs:271: assert_eq!(ast.effective_enumerator_value(enumerators[2]), Some(11));.
Status: done
§7.4.1.4.4.4.4 Constructed Recursive Types und Forward Declarations
Spec: §7.4.1.4.4.4.4, S. 42–43 — eine Struktur darf sich nur über ein
Element enthalten, das einen Wert terminiert; die Forward Declaration
struct <identifier> ; wird von der Definition vervollständigt.
Repo: crates/idl-lower/src/validate.rs::forward_declarations_are_defined,
crates/ast-layout/src/xcdr.rs::types_that_close_an_inadmissible_cycle,
crates/idl-compose/src/lib.rs::compose_source_with.
Tests: crates/idl-compose/tests/recursion.rs::a_cycle_with_no_terminator_on_it_is_refused,
crates/idl-compose/tests/recursion.rs::a_cycle_with_a_terminator_on_it_is_admitted,
crates/idl-compose/tests/recursion.rs::the_diagnostic_names_the_type_and_the_clause,
crates/idl-compose/tests/recursion.rs::the_interop_corpus_case_for_this_is_refused_and_its_neighbours_are_not,
crates/idl-compose/tests/recursion.rs::a_forward_declared_cycle_is_reported_once,
crates/idl-lower/tests/lowering.rs::a_forward_declaration_on_its_own_is_forward,
crates/idl-lower/tests/lowering.rs::the_definition_completes_the_forward_node_rather_than_adding_a_second,
crates/idl-lower/tests/validation.rs::a_forward_declaration_never_defined_is_rejected,
crates/idl-lower/tests/validation.rs::a_forward_declaration_that_is_defined_is_accepted —
recursion.rs:104: assert!(message.contains("Ma::Sa"), "{message}");.
Status: done
§7.4.1.4.4.6 Native Types
Spec: §7.4.1.4.4.6, S. 43 — native <identifier> ; deklariert einen
nativen Typ; die Verwendung als Member-Typ-Spec steht in Produktion 62.
Repo: crates/idl-lower/src/lower.rs::native,
crates/idl-parse/src/decl.rs::parse_native.
Tests: crates/idl-lower/tests/lowering.rs::a_native_declaration_becomes_a_native_type,
crates/idl-parse/tests/parse.rs::each_declaration_form_is_recognised.
Status: partial — die Deklaration ist belegt, die Verwendung als
Member-Typ (struct S { native H; };) nicht; siehe das Item zu §7.4.1.3.
§7.4.1.4.4.7 Naming Data Types (Produktion 64)
Spec: §7.4.1.4.4.7, S. 43 — (64) <type_declarator> ::= { <simple_type_spec> | <template_type_spec> | <constr_type_dcl> } <any_declarators>; die dritte Alternative erlaubt die Konstruktion im
typedef selbst.
Repo: crates/idl-parse/src/decl.rs::parse_typedef,
crates/idl-lower/src/lower.rs::typedef.
Tests: crates/idl-lower/tests/idl_4_2_grammar.rs::a_struct_defined_inside_a_typedef_is_declared_and_aliased,
crates/idl-lower/tests/idl_4_2_grammar.rs::every_constructed_form_can_be_defined_inside_a_typedef,
crates/idl-lower/tests/lowering.rs::a_typedef_becomes_an_alias_to_its_target,
crates/idl-lower/tests/lowering.rs::one_typedef_may_declare_several_names,
crates/idl-lower/tests/lowering.rs::a_typedef_declarator_keeps_its_array_dimensions,
crates/idl-lower/tests/lowering.rs::dimensions_belong_to_the_declarator_and_not_to_the_typedef —
idl_4_2_grammar.rs:153: TypeKind::Alias { aliased } => assert_eq!(aliased.resolved(), Some(inline)),.
Status: done
§7.4.1.5 Specific Keywords
Spec: §7.4.1.5, S. 43–44 — Tabelle 7-27: die Keywords dieses Bausteins.
Repo: crates/idl-cst/src/token.rs::KEYWORDS,
crates/idl-lower/src/lower.rs::identifiers_do_not_collide_with_keywords.
Tests: crates/idl-lower/tests/validation.rs::an_identifier_differing_from_a_keyword_only_in_case_is_refused,
crates/idl-lower/tests/validation.rs::the_diagnostic_names_the_keyword_and_the_clause,
crates/idl-lower/tests/validation.rs::the_underscore_escape_turns_the_keyword_check_off —
validation.rs:619: DiagnosticCode::KeywordCollision,.
Status: done
§7.4.2 Building Block Any
§7.4.2.1 Purpose und §7.4.2.2 Dependencies
Spec: §7.4.2.1 / §7.4.2.2, S. 43–44 — der Baustein führt any ein
und stützt sich auf den Building Block Core Data Types.
Repo: crates/idl-parse/src/type_spec.rs,
crates/ast/src/node/type_.rs::TypeKind.
Tests: —
Status: n/a (informative) — die beiden Klauseln begründen und
benennen die Abhängigkeit; der Typ selbst steht in §7.4.2.3.
§7.4.2.3 Syntax — der Typ any
Spec: §7.4.2.3, S. 44 — (69) <type_spec> ::+ <any_type>,
(70) <type_declarator> ::= <simple_type_spec> <any_declarators>;
any steht an jeder Stelle, an der <type_spec> steht.
Repo: crates/ast/src/node/type_.rs::TypeKind::Any,
crates/idl-lower/src/lower.rs::primitive_of.
Tests: crates/idl-lower/tests/lowering.rs::an_any_member_reaches_the_model_as_a_type_rather_than_a_broken_reference,
crates/idl-lower/tests/lowering.rs::every_any_in_a_file_shares_one_built_in_node,
crates/idl-lower/tests/lowering.rs::any_is_reachable_in_every_position_the_grammar_gives_it —
lowering.rs:702: assert_eq!(lowered.ast.type_(type_).expect("any").kind, TypeKind::Any);.
Status: done — das Modell trägt any; kein Sprachbackend emittiert
eine Sprachform dafür (NoLanguageForm { construct: "any" }, siehe
idl-4.2.gaps.md §C).
§7.4.2.5 Specific Keywords — any, Object, ValueBase
Spec: §7.4.2.5, S. 44 — die Keywords des Bausteins sind any,
Object, ValueBase; alle drei sind eingebaute Typnamen.
Repo: crates/idl-cst/src/token.rs::TokenKind,
crates/ast/src/node/type_.rs::TypeKind.
Tests: crates/idl-lower/tests/lowering.rs::none_of_the_three_built_in_type_names_leaves_a_broken_reference,
crates/idl-lower/tests/lowering.rs::an_object_parameter_reaches_the_model_as_an_object_reference,
crates/idl-lower/tests/lowering.rs::object_is_reachable_in_every_position_rule_118_gives_it,
crates/idl-lower/tests/lowering.rs::a_valuebase_parameter_reaches_the_model_as_valuebase,
crates/idl-lower/tests/lowering.rs::valuebase_is_reachable_in_every_position_rule_132_gives_it —
lowering.rs:768: TypeKind::ObjectRef { interface: None }.
Status: done
§7.4.3 Building Block Interfaces – Basic
§7.4.3.3 Syntax — interface, exception, forward
Spec: §7.4.3.3, S. 45–47 — (73)–(85): interface_dcl,
interface_header, interface_body, export, interface_forward_dcl,
exception_dcl.
Repo: crates/idl-parse/src/decl.rs::parse_interface,
crates/idl-lower/src/lower.rs::interface.
Tests: crates/idl-parse/tests/parse.rs::each_declaration_form_is_recognised,
crates/idl-parse/tests/parse.rs::an_interface_with_operations_and_attributes_parses,
crates/idl-lower/tests/lowering.rs::an_exception_carries_its_members,
crates/idl-lower/tests/conformance.rs::every_fixture_parses_with_no_diagnostics_beyond_the_extensions_it_declares —
parse.rs:156: assert!(found.contains(&CstKind::Operation));.
Status: done
§7.4.3.4.2 Exceptions
Spec: §7.4.3.4.2, S. 48–49 — eine Exception ist ein Aggregat mit Mitgliedern; ihr Name wird in den umgebenden Scope eingeführt.
Repo: crates/idl-lower/src/lower.rs::structure (Zweig Exception),
crates/idl-lower/src/scope.rs::ScopeStack.
Tests: crates/idl-lower/tests/lowering.rs::an_exception_carries_its_members,
crates/idl-parse/tests/parse.rs::each_declaration_form_is_recognised —
lowering.rs:571: assert_eq!(any.kind(), zerodds_ast::NodeKind::Exception);.
Status: done
§7.4.3.4.3.1 Interface Header
Spec: §7.4.3.4.3.1, S. 49 — interface <identifier> [ : <interface_name> { "," <interface_name> } * ].
Repo: crates/idl-lower/src/lower.rs::interface_bases.
Tests: crates/idl-lower/tests/lowering.rs::a_component_keeps_its_supports_clause_apart_from_its_base,
crates/idl-lower/tests/conformance.rs::every_fixture_produces_a_model_with_declarations_in_it —
lowering.rs:1392: assert_eq!(component.bases.len(), 1, "the base list took the supports");.
Status: done
§7.4.3.4.3.2 Interface Inheritance
Spec: §7.4.3.4.3.2, S. 49 — Basis-Interfaces werden im Header genannt; jedes geerbte Element ist im abgeleiteten Interface sichtbar.
Repo: crates/idl-lower/src/lower.rs::interface_bases,
crates/ast/src/node/interface.rs::InterfaceNode.
Tests: crates/lang-rules/tests/inherited_operations.rs::the_cpp_class_reaches_the_bases_operation_through_its_base_clause,
crates/lang-rules/tests/inherited_operations.rs::the_java_interface_reaches_the_bases_operation_through_extends,
crates/lang-rules/tests/inherited_operations.rs::the_rust_trait_reaches_the_bases_operation_through_a_supertrait,
crates/lang-rules/tests/inherited_operations.rs::every_incomplete_language_refuses_rather_than_flattens_or_drops —
inherited_operations.rs:102: assert!(out.contains("class Derived : public Base {"), "{out}");.
Status: done
§7.4.3.4.3.2.1 Inheritance Rules
Spec: §7.4.3.4.3.2.1, S. 49–50 — die Liste der Basis-Interfaces darf
keinen Namen zweimal nennen; die Vererbung ist transitiv; virtual und
nicht-virtual werden unterschieden.
Repo: —
Tests: —
Status: open — es gibt weder eine Diagnose für ein doppelt genanntes
Basis-Interface noch einen transitiven Gang im Frontend; der Abgleich
inheritance_rules in crates/idl-lower/src/validate.rs gilt nur für
TypeKind::Structure. Das Schlüsselwort virtual kommt im heutigen Baum
nirgends vor. Die Abflachung in crates/lang-rules geschieht je Spalte,
nicht im Frontend.
§7.4.3.4.3.3.1 Operations
Spec: §7.4.3.4.3.3.1, S. 50–51 — <parameter_dcl> mit in, out,
inout; oneway; raises ( <exception_identifier> { "," … } * );
context ( "<string_literal>" { "," … } * ).
Repo: crates/idl-lower/src/lower.rs::operation,
crates/ast/src/model.rs::add_context,
crates/ast/src/node/interface.rs::OperationNode.
Tests: crates/idl-lower/tests/conformance.rs::every_fixture_lowers_to_exactly_the_diagnostics_it_should,
crates/idl-lower/tests/conformance.rs::the_expected_diagnostics_are_the_ones_the_fixtures_actually_earn,
crates/corba-codegen/tests/model_connection.rs::oneway_survives_lowering,
crates/corba-codegen/tests/model_connection.rs::a_raises_clause_reaches_the_stub,
crates/ast/tests/node_space.rs::a_oneway_operation_is_flagged_and_a_normal_one_is_not.
Status: partial — oneway und raises sind getestet. Für die
Richtungen in/out/inout und für die context (…)-Klausel gibt es
keinen Test, der über das Frontend geht: die context-Klausel wird
geparst und gelowert (OperationNode::contexts), aber keine committete
.idl-Datei des Baums enthält eine, und ParamDirection wird nur in
handgebauten Modell-Tests geprüft.
§7.4.3.4.3.3.2 Attributes
Spec: §7.4.3.4.3.3.2, S. 51–52 — attribute <parameter_mode> <type_spec> <identifier> ; mit readonly, sowie getraises/setraises
als eigene Attributformen.
Repo: crates/idl-lower/src/lower.rs::attribute,
crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-parse/tests/parse.rs::an_interface_with_operations_and_attributes_parses,
crates/idl-lower/tests/validation.rs::an_attribute_named_like_its_type_collides,
crates/lang-rules/tests/interface_bindings.rs::an_attribute_implies_the_operations_of_seven_five_one_one_three,
crates/idl-lower/tests/conformance.rs::every_fixture_parses_with_no_diagnostics_beyond_the_extensions_it_declares.
Status: partial — readonly attribute und die Ableitung der
Operationen sind belegt; getraises und setraises werden geparst und
gelowert (add_attribute_raises), aber kein Test behauptet etwas über
sie. Nur die Fixture
crates/idl-parse/tests/fixtures/spec_features/attr_raises.idl führt sie
durch die Pipeline, ohne Aussage über ihr Ergebnis.
§7.4.3.4.3.4 Forward Declaration
Spec: §7.4.3.4.3.4, S. 52 — interface <identifier> ; ist die
Forward Declaration; die spätere Definition ergänzt denselben Knoten.
Repo: crates/idl-lower/src/lower.rs::forward_interface_kind,
crates/ast/src/model.rs::add_forward_interface.
Tests: crates/idl-lower/tests/lowering.rs::a_forward_declared_interface_is_completed_by_its_definition,
crates/idl-lower/tests/lowering.rs::a_forward_interface_keeps_the_form_its_header_wrote,
crates/idl-lower/tests/lowering.rs::an_interface_forward_that_is_never_defined_is_still_reported,
crates/idl-lower/tests/lowering.rs::a_reference_taken_against_a_forward_interface_survives_the_definition,
crates/idl-lower/tests/lowering.rs::a_second_full_interface_definition_is_a_duplicate_not_a_completion,
crates/idl-lower/tests/spans.rs::an_unfinished_forward_interface_points_at_the_declaration_too,
crates/lang-rules/tests/interface_bindings.rs::a_forward_declaration_without_a_definition_is_e002 —
lowering.rs:1070: assert_eq!(lowered.ast.operations_of(id).len(), 1);.
Status: done
§7.4.3.5 Specific Keywords
Spec: §7.4.3.5, S. 52–53 — die Keywords des Bausteins.
Repo: crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier,
crates/idl-cst/tests/lexer.rs::a_keyword_is_recognised_only_in_the_spelling_table_7_6_gives —
lexer.rs:59: assert_eq!(kinds("custom")[0], TokenKind::Custom);.
Status: done
§7.4.4 Building Block Interfaces – Full
§7.4.4.4 Ein Interface als Typ
Spec: §7.4.4.4, S. 53 — ein Interface-Name darf an jeder Stelle
stehen, an der <type_spec> steht, und löst zu einer Objektreferenz auf.
Repo: crates/idl-lower/src/lower.rs::type_ref_from_scoped_name,
crates/idl-lower/tests/interface_as_type.rs.
Tests: crates/idl-lower/tests/interface_as_type.rs::an_interface_used_as_a_type_resolves_in_every_spelling,
crates/idl-lower/tests/interface_as_type.rs::what_it_resolves_to_is_an_object_reference_and_not_the_interface,
crates/idl-lower/tests/interface_as_type.rs::the_key_is_the_declaration_s_own_scoped_name_and_not_the_written_segment,
crates/idl-lower/tests/interface_as_type.rs::a_name_that_is_not_declared_still_breaks —
interface_as_type.rs:109: assert_eq!(ast.interface(interface).expect("I").name, "I");.
Status: done
§7.4.4.4 Mehrfachvererbung und Mehrdeutigkeit
Spec: §7.4.4.4, S. 53 — ein Element, das über zwei Wege geerbt wird, gilt nicht als mehrdeutig; zwei verschiedene Deklarationen desselben Namens in der Sichtbarkeit dagegen schon.
Repo: crates/lang-rules/src/adapter/interface.rs::Service::is_remote,
crates/idl-lower/src/scope.rs::ScopeStack::lookup_candidates.
Tests: crates/lang-rules/tests/interface_bindings.rs::all_operations_flattened_keeps_a_non_readonly_attributes_setter,
crates/ast/tests/resolve_profile_query.rs::an_ambiguous_name_reports_every_candidate,
crates/ast/tests/resolve_profile_query.rs::a_duplicate_scoped_name_is_reported_as_ambiguous_with_both_nodes.
Status: partial — die Abflachung über einen Diamanten und die
Mehrdeutigkeitsmeldung auf Modellebene sind belegt. Eine Diagnose im
Frontend für die Ambiguität aus zwei vererbten, verschieden deklarierten
Elementen gibt es nicht: inheritance_rules in
crates/idl-lower/src/validate.rs kennt nur TypeKind::Structure als
Vererbungsträger.
§7.4.4.4 Attribut und Operation mit demselben Namen
Spec: §7.4.4.4, S. 53 — Attribut- und Operationsnamen teilen sich einen Namespace innerhalb des Interface-Rumpfs.
Repo: —
Tests: —
Status: open — Code vorhanden: one_namespace_per_scope (crates/idl-lower/src/lower.rs) sammelt Attribut- und Operationsnamen in eine Namensliste; kein Test lässt ein Attribut und eine Operation desselben Namens in einem Interface entstehen.
§7.4.4.5 Specific Keywords
Spec: §7.4.4.5, S. 53 — “There are no additional keywords with this building block.”
Repo: crates/idl-cst/src/token.rs::KEYWORDS.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier.
Status: n/a (informative) — die Klausel sagt selbst, dass es keine
zusätzlichen Keywords gibt; es gibt nichts zu prüfen.
§7.4.5 Building Block Value Types
§7.4.5.3 Syntax
Spec: §7.4.5.3, S. 54 — (125)–(131): valuetype_dcl,
valuetype_header, valuetype_body, state_member, init_dcl.
Repo: crates/idl-lower/src/lower.rs::valuetype,
crates/idl-lower/src/lower.rs::valuetype_kind.
Tests: crates/idl-lower/tests/dialects.rs::a_valuetype_keeps_its_modifier_bases_and_supported_interfaces,
crates/idl-parse/tests/parse.rs::each_declaration_form_is_recognised,
crates/idl-lower/tests/conformance.rs::every_fixture_lowers_to_exactly_the_diagnostics_it_should —
dialects.rs:550: assert_eq!(state.len(), 2, "a state member was lost");.
Status: done
§7.4.5.4.1 Concrete (Stateful) Value Types
Spec: §7.4.5.4.1, S. 55 — ein konkreter Value Type trägt
State-Members und Modifikatoren (custom, abstract, truncatable).
Repo: crates/idl-lower/src/lower.rs::valuetype,
crates/ast/src/node/type_.rs::ValuetypeKind.
Tests: crates/idl-lower/tests/dialects.rs::a_valuetype_keeps_its_modifier_bases_and_supported_interfaces,
crates/idl-lower/tests/lowering.rs::an_abstract_valuetype_parses_as_a_valuetype,
crates/ccm/tests/equivalent_idl.rs::a_plain_valuetype_is_not_an_event_type —
lowering.rs:1316: assert_eq!(kind, zerodds_ast::ValuetypeKind::Abstract);.
Status: done
§7.4.5.4.1.2 Value Inheritance Specification
Spec: §7.4.5.4.1.2, S. 55 — der Header erlaubt eine Basis
(: supports
Repo: crates/idl-lower/src/lower.rs::interface_bases (die
supports-Alternative).
Tests: crates/idl-lower/tests/dialects.rs::a_valuetype_keeps_its_modifier_bases_and_supported_interfaces,
crates/idl-lower/tests/lowering.rs::a_component_keeps_its_supports_clause_apart_from_its_base —
lowering.rs:1398: assert_eq!(supports, 2, "the supports clause was dropped");.
Status: done
§7.4.5.4.1.3.1 State Members
Spec: §7.4.5.4.1.3.1, S. 55 — public <member_type_spec> <simple_declarator> und private …; die Sichtbarkeit gehört zum Value
Type, nicht zum Struct-Member.
Repo: crates/idl-lower/src/lower.rs::valuetype (Zweig State-Member),
crates/ast/src/facet/corba.rs::state_visibility.
Tests: crates/idl-lower/tests/lowering.rs::a_state_member_keeps_the_keyword_it_was_written_with,
crates/idl-lower/tests/lowering.rs::a_struct_member_has_no_state_visibility —
lowering.rs:1414: Some(zerodds_ast::StateVisibility::Public),.
Status: done
§7.4.5.4.1.3.2 Initializers
Spec: §7.4.5.4.1.3.2, S. 55–56 — factory <identifier> ( … ) ; wird zu
einer Operation des Value Type.
Repo: crates/idl-lower/src/lower.rs::template_formals (Initialiser
im valuetype-Zweig), crates/idl-parse/src/decl.rs::parse_factory.
Tests: crates/idl-lower/tests/dialects.rs::a_valuetype_initialiser_becomes_an_operation_of_it,
crates/ccm/tests/equivalent_idl.rs::a_factory_is_emitted_with_create_failure_first_in_its_raises —
dialects.rs:569: assert_eq!(state.len(), 1, "the operation was counted as state");.
Status: partial — kein Test prüft, dass die factory-Deklaration
als Operation des Value Type erscheint; der zitierte Test prüft nur, dass
sie nicht als State-Member gezählt wird.
§7.4.5.4.2 Forward Declarations
Spec: §7.4.5.4.2, S. 56 — valuetype <identifier> ; wird von der
Definition vervollständigt.
Repo: crates/idl-lower/src/lower.rs::valuetype_kind,
crates/ast/src/model.rs::add_forward_interface.
Tests: crates/idl-lower/tests/lowering.rs::a_forward_declared_valuetype_is_completed_by_its_definition,
crates/idl-lower/tests/lowering.rs::a_valuetype_forward_that_is_never_defined_is_still_reported,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(bb5-110-value-forward) —
lowering.rs:1361: assert_eq!(declared.len(), 1, "{source:?}: two nodes for one name");.
Status: done
§7.4.5.5 Specific Keywords
Spec: §7.4.5.5, S. 56 — die Keywords des Bausteins.
Repo: crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier —
lexer.rs:73: assert_eq!(kinds("TRUE")[0], TokenKind::True);.
Status: done
§7.4.6 Building Block CORBA-Specific – Interfaces
§7.4.6.3 Syntax — repository directives, local, native
Spec: §7.4.6.3, S. 58–59 — (112)–(124): type_id_dcl,
type_prefix_dcl, import_dcl, local, native, context_dcl,
context_spec, op_oneway_dcl.
Repo: crates/idl-lower/src/complete.rs::apply_repository_directives,
crates/idl-parse/src/decl.rs (Zweige typeid, typeprefix, import).
Tests: crates/idl-lower/tests/idl_4_2_grammar.rs::typeprefix_and_import_inside_an_interface_body_parse,
crates/idl-lower/tests/lowering.rs::a_native_declaration_becomes_a_native_type,
crates/idl-parse/tests/parse.rs::each_declaration_form_is_recognised —
lowering.rs:578: assert_eq!(ast.type_(handle).expect("Handle").kind, TypeKind::Native);.
Status: done
§7.4.6.4.1.1 Repository Identity Declaration (typeid)
Spec: §7.4.6.4.1.1, S. 59 — typeid <identifier> <string_literal> ;
setzt die Repository-Id unmittelbar.
Repo: crates/idl-lower/src/complete.rs::derive_repository_ids,
crates/corba-codegen/src/repository_id.rs.
Tests: crates/idl-lower/tests/dialects.rs::a_typeid_directive_sets_the_id_outright,
crates/idl-lower/tests/idl_4_2_grammar.rs::a_typeid_inside_an_interface_body_sets_the_id,
crates/idl-lower/tests/dialects.rs::a_pragma_id_sets_the_repository_id_like_typeid_does,
crates/corba-codegen/tests/model_connection.rs::an_interfaces_repository_id_comes_from_the_model —
idl_4_2_grammar.rs:188: Some("IDL:Ia:2.0").
Status: done
§7.4.6.4.1.2 Repository Identifier Prefix Declaration (typeprefix)
Spec: §7.4.6.4.1.2, S. 59–60 — typeprefix <scoped_name> <string_literal> ; prägt alle darunter abgeleiteten Ids.
Repo: crates/idl-lower/src/complete.rs::apply_repository_directives
und derived_repository_id, crates/corba-codegen/src/repository_id.rs.
Tests: crates/idl-lower/tests/dialects.rs::a_typeprefix_directive_prefixes_the_ids_derived_below_it,
crates/idl-lower/tests/dialects.rs::a_typeprefix_may_name_the_module_it_is_written_in,
crates/idl-lower/tests/dialects.rs::the_root_anchored_spelling_names_the_same_module,
crates/idl-lower/tests/dialects.rs::a_sibling_declaration_wins_over_one_further_out,
crates/idl-lower/tests/dialects.rs::a_directive_naming_nothing_is_still_reported,
crates/idl-lower/tests/dialects.rs::a_pragma_prefix_prefixes_the_ids_of_its_module,
crates/corba-codegen/tests/model_connection.rs::a_prefix_reaches_an_interface_and_an_exception —
model_connection.rs:447: assert_eq!(resolved.id, "IDL:omg.org/CosNaming/NamingContext:1.0");.
Status: done
§7.4.6.4.1.3 Repository Id Conflict
Spec: §7.4.6.4.1.3, S. 60 — zwei Deklarationen, die dieselbe Repository-Id ergeben, sind ein Konflikt.
Repo: crates/idl-lower/src/complete.rs::derived_repository_id,
crates/corba-codegen/src/repository_id.rs.
Tests: crates/idl-lower/tests/dialects.rs::a_directive_naming_nothing_is_still_reported,
crates/corba-codegen/tests/model_connection.rs::a_types_repository_id_is_the_models_and_not_a_second_derivation.
Status: partial — die Herleitung ist eindeutig (ein Präfix, ein
typeid); ein eigener Konflikt-Test für zwei Deklarationen mit derselben
abgeleiteten Id existiert nicht. Der vorhandene Test prüft die negative
Seite (ein Verweis auf nichts wird gemeldet).
§7.4.6.4.1.4 Imports
Spec: §7.4.6.4.1.4, S. 60–61 — import <scoped_name> ; bleibt wie
geschrieben im Modell.
Repo: crates/idl-lower/src/lower.rs::interface (Zweig Import),
crates/idl-parse/src/decl.rs.
Tests: crates/idl-lower/tests/dialects.rs::an_import_is_kept_as_written,
crates/idl-lower/tests/dialects.rs::a_declaration_in_an_interface_is_named_through_it,
crates/idl-lower/tests/idl_4_2_grammar.rs::typeprefix_and_import_inside_an_interface_body_parse —
dialects.rs:349: assert_eq!(imports, vec!["IDL:Other:1.0".to_string()]);.
Status: done
§7.4.6.4.3 Local Interfaces
Spec: §7.4.6.4.3, S. 62 — local interface <identifier> … ist ein
Interface ohne Endpunkte.
Repo: crates/idl-lower/src/lower.rs::interface_bases (Setzen von
InterfaceKind::Local), crates/lang-rules/src/adapter/interface.rs::Service::is_remote.
Tests: crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/idl-lower/tests/lowering.rs::a_forward_interface_keeps_the_form_its_header_wrote,
crates/corba-codegen/tests/annex_a1_traits.rs::table_a2_reads_local_and_abstract_off_the_interface_declaration,
crates/lang-rules/tests/interface_bindings.rs::a_local_interface_is_refused_by_the_seam —
interface_bindings.rs:742: assert!(interface_cpp::cpp_interface_items(&ast).is_err());.
Status: done — ein local interface hat keine Endpunkte: die Dienst-Bindung weist ihn ab (DDS-RPC 1.0 §7.3.1.1 Produktion 7) und keine Sprache schreibt eine Klasse dafür.
§7.4.6.4.4 Use of Native Types
Spec: §7.4.6.4.4, S. 62–63 — ein nativer Typ darf an jeder Stelle stehen, an der ein Typ verlangt wird.
Repo: crates/idl-parse/src/decl.rs::parse_native,
crates/idl-lower/src/lower.rs::native.
Tests: crates/idl-lower/tests/lowering.rs::a_native_declaration_becomes_a_native_type,
crates/idl-lower/tests/conformance.rs::the_xtypes_specifications_own_idl_lowers_completely.
Status: partial — die Deklaration ist belegt, die Verwendung als
Member-Typ-Spec (Produktion 62) nicht; siehe das Item zu §7.4.1.3.
§7.4.6.4.6 Context Expressions
Spec: §7.4.6.4.6, S. 63 — context ( "<string>" { "," <string> } * )
an einer Operation; die Zeichenketten sind Ausdrücke.
Repo: —
Tests: —
Status: open — Code vorhanden: geparst und gelowert (crates/idl-lower/src/lower.rs::operation, OperationNode::contexts); kein Test, keine committete .idl-Datei schreibt ein context, die Probe bb6-123-op-with-context in tools/idl-4.2-gap-scan/ hat fixtures = 0.
§7.4.6.4.7 CORBA Module
Spec: §7.4.6.4.7, S. 63–64 — das Modul CORBA ist vordefiniert; es
trägt Object, ValueBase und die Standardausnahmen.
Repo: —
Tests: —
Status: open — es gibt kein module CORBA in irgendeiner
committeten .idl-Datei des Baums, kein Symbol in
crates/idl-parse/src oder crates/idl-lower/src und keine Probe.
Object und ValueBase sind als eingebaute Typnamen erreichbar
(§7.4.2.5), aber nicht über ein Modul, dessen Inhalt man auflösen könnte.
§7.4.6.5 Specific Keywords
Spec: §7.4.6.5, S. 64 — die Keywords des Bausteins.
Repo: crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier —
lexer.rs:73: assert_eq!(kinds("TRUE")[0], TokenKind::True);.
Status: done
§7.4.7 Building Block CORBA-Specific – Value Types
§7.4.7.3 Syntax
Spec: §7.4.7.3, S. 64–65 — die Werttyp-Produktionen mit custom,
abstract, truncatable, dem Value-Box und dem ValueBase.
Repo: crates/idl-lower/src/lower.rs::valuetype_kind,
crates/idl-lower/src/lower.rs::value_box.
Tests: crates/idl-lower/tests/lowering.rs::a_value_box_reaches_the_model_as_one,
crates/idl-lower/tests/lowering.rs::a_value_box_may_box_any_type_spec,
crates/idl-lower/tests/lowering.rs::the_other_valuetype_forms_are_unaffected_by_the_box,
crates/idl-lower/tests/lowering.rs::an_abstract_valuetype_parses_as_a_valuetype —
lowering.rs:1224: TypeKind::Primitive(PrimitiveKind::Int32).
Status: done
§7.4.7.4.1 Boxed Value Types
Spec: §7.4.7.4.1, S. 65–66 — der Value-Box ist ein Zustand ohne
public-/private-Kennzeichnung und mit einer Boxvariable.
Repo: crates/idl-lower/src/lower.rs::value_box,
crates/corba-codegen/src/traits.rs.
Tests: crates/idl-lower/tests/lowering.rs::a_value_box_reaches_the_model_as_one,
crates/idl-lower/tests/lowering.rs::a_value_box_may_box_any_type_spec,
crates/idl-lower/tests/lowering.rs::a_value_box_round_trips_byte_for_byte,
crates/corba-codegen/tests/annex_a1_traits.rs::table_a9_gives_a_valuebox_its_boxed_trait —
annex_a1_traits.rs:281: Some(TraitDefinition::TraitsOf("long".to_string())).
Status: done
§7.4.7.4.2 Abstract Value Types und Abstract Interfaces
Spec: §7.4.7.4.2, S. 66–67 — abstract valuetype und abstract interface.
Repo: crates/idl-lower/src/lower.rs::valuetype_kind,
crates/ast/src/node/type_.rs::ValuetypeKind.
Tests: crates/idl-lower/tests/lowering.rs::an_abstract_valuetype_parses_as_a_valuetype,
crates/idl-lower/tests/lowering.rs::abstract_still_reaches_the_interface_header_it_also_belongs_to,
crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/corba-codegen/tests/annex_a1_traits.rs::table_a8_reads_abstract_and_truncatable_off_the_declaration —
annex_a1_traits.rs:269: Some(TraitDefinition::Flag(true)).
Status: done
§7.4.7.4.3 Value Inheritance Rules
Spec: §7.4.7.4.3, S. 67–68 — die Regeln, welche Kombinationen aus
abstract, custom, truncatable, Basis und supports zulässig sind.
Repo: —
Tests: —
Status: open — es gibt keine Prüfung dieser Kombinationen. Der
einzige Abgleich von Vererbung im Frontend, inheritance_rules in
crates/idl-lower/src/validate.rs, gilt ausschließlich für
TypeKind::Structure { base }; ein Valuetype trägt dort keine Basis.
§7.4.7.4.4 Custom Marshaling
Spec: §7.4.7.4.4, S. 68–69 — custom valuetype; die
Marshaling-Operationen sind Teil der Definition.
Repo: crates/idl-lower/src/lower.rs::valuetype_kind (setzt
ValuetypeKind::Custom), crates/corba-codegen/src/skeleton.rs.
Tests: crates/idl-lower/tests/dialects.rs::a_valuetype_keeps_its_modifier_bases_and_supported_interfaces,
crates/idl-lower/tests/lowering.rs::the_other_valuetype_forms_are_unaffected_by_the_box.
Status: partial — das Schlüsselwort custom wird erkannt und im
Modell als ValuetypeKind::Custom geführt. Die Marshal-/Unmarshal-
Operationen werden nicht als solche erkannt und nicht auf
Skelett-Operationen abgebildet; der Test prüft die Variante, nicht die
Regel.
§7.4.7.4.5 Truncatable
Spec: §7.4.7.4.5, S. 69 — truncatable erlaubt das Abschneiden einer
unbekannten Erweiterung beim Marshalisieren.
Repo: crates/idl-lower/src/lower.rs::valuetype_kind,
crates/corba-codegen/src/traits.rs.
Tests: crates/idl-lower/tests/dialects.rs::a_valuetype_keeps_its_modifier_bases_and_supported_interfaces,
crates/corba-codegen/tests/annex_a1_traits.rs::table_a8_reads_abstract_and_truncatable_off_the_declaration.
Status: partial — truncatable wird als Modifikator erfasst und in
Tabelle A.8 ausgewertet. Das Abschneiden selbst wird in
crates/corba-codegen/src/skeleton.rs nicht als solches geführt und hat
keinen Test.
§7.4.7.4.6 Value Base
Spec: §7.4.7.4.6, S. 69–70 — ValueBase ist der eingebaute
Basistyp eines custom valuetype.
Repo: crates/ast/src/node/type_.rs::TypeKind::ValueBase,
crates/corba-codegen/tests/orb_agreement.rs.
Tests: crates/idl-lower/tests/lowering.rs::a_valuebase_parameter_reaches_the_model_as_valuebase,
crates/idl-lower/tests/lowering.rs::valuebase_is_reachable_in_every_position_rule_132_gives_it,
crates/idl-lower/tests/lowering.rs::none_of_the_three_built_in_type_names_leaves_a_broken_reference.
Status: partial — im Modell ist ValueBase vorhanden und an jeder
Position erreichbar; kein Sprachbackend emittiert eine Form dafür. Die
Probe bb7-132-valuebase steht in expected.tsv für Rust und C auf
err (NoLanguageForm { construct: "ValueBase" }).
§7.4.8 Building Block Components – Basic
§7.4.8.3 Syntax
Spec: §7.4.8.3, S. 70–71 — (135)–(144): component_dcl,
component_header, component_body, export, provides_dcl,
uses_dcl, port_dcl.
Repo: crates/idl-parse/src/decl.rs::parse_port und
parse_component, crates/idl-lower/src/lower.rs::interface und port.
Tests: crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/idl-lower/tests/dialects.rs::each_port_form_reaches_its_own_component_role,
crates/idl-lower/tests/conformance.rs::every_fixture_parses_with_no_diagnostics_beyond_the_extensions_it_declares,
tools/idlc/tests/idl_4_2_gaps.rs::the_fixture_directory_holds_exactly_the_named_fixtures —
dialects.rs:103: ComponentRole::Receptacle { multiple, .. } => assert!(!multiple),.
Status: done
§7.4.8.4.1 Component Header
Spec: §7.4.8.4.1, S. 71 — component <identifier> [ : <component_name> { "," … } * ] [ supports <interface_identifier> { "," … } * ].
Repo: crates/idl-lower/src/lower.rs::interface_bases.
Tests: crates/idl-lower/tests/lowering.rs::a_component_keeps_its_supports_clause_apart_from_its_base,
crates/ccm/tests/equivalent_idl.rs::a_component_with_supports_inherits_ccmobject_and_the_supported_ones,
crates/ccm/tests/equivalent_idl.rs::a_derived_component_with_supports_lists_the_base_first_and_then_the_supported —
equivalent_idl.rs:169: assert_eq!(base_names(&ast, component), ["B", "I1", "I2"]);.
Status: done
§7.4.8.4.2.1 Facets und §7.4.8.4.2.2 Receptacles
Spec: §7.4.8.4.2.1 / §7.4.8.4.2.2, S. 71–72 — provides ergibt ein
Facet, uses einen Receptacle; beide nennen das Interface, das sie
tragen.
Repo: crates/idl-lower/src/lower.rs::port,
crates/ast/src/facet/corba.rs::ComponentRole::{Facet, Receptacle},
crates/ccm/src/transform.rs::transform_component.
Tests: crates/idl-lower/tests/dialects.rs::each_port_form_reaches_its_own_component_role,
crates/idl-lower/tests/lowering.rs::a_ports_role_resolves_the_interface_or_event_behind_it,
crates/ccm/tests/equivalent_idl.rs::provides_yields_a_provide_operation_returning_the_facet,
crates/ccm/tests/equivalent_idl.rs::uses_simplex_yields_connect_disconnect_and_get_connection,
crates/ccm/tests/equivalent_idl.rs::uses_multiple_returns_a_cookie_and_the_plural_getter.
Status: partial — im Modell und in der CCM-Umschreibung getestet. Beide
Backends lehnen das Konstrukt ab, weil der von einem Port getragene
Object-Typ keine Sprachform hat (NoLanguageForm { construct: "Object", language: "Rust" }, dieselbe Meldung für C); das ist in
idl-4.2.gaps.md §C.2 festgehalten.
§7.4.8.4.2.3 Component Attributes
Spec: §7.4.8.4.2.3, S. 72 — attribute <param_mode> <type_spec> <identifier> ; im Komponentenrumpf.
Repo: crates/idl-lower/src/lower.rs::attribute.
Tests: crates/ccm/tests/equivalent_idl.rs::a_basic_component_carries_its_attributes_and_no_port_operation,
crates/ccm/tests/equivalent_idl.rs::a_component_attribute_is_left_alone —
equivalent_idl.rs:324: assert_eq!(ast.attribute(attributes[0]).expect("rate").name, "rate");.
Status: done
§7.4.8.4.3 Forward Declaration
Spec: §7.4.8.4.3, S. 73 — component <identifier> ;.
Repo: crates/idl-lower/src/lower.rs::forward_interface_kind,
crates/ast/src/model.rs::add_forward_interface.
Tests: crates/idl-lower/tests/lowering.rs::a_forward_declared_component_is_completed_by_its_definition,
crates/idl-lower/tests/lowering.rs::a_component_forward_that_is_never_defined_is_still_reported,
crates/idl-lower/tests/lowering.rs::every_component_model_forward_keeps_its_own_form —
lowering.rs:1195: assert_eq!(node.kind, expected, "{source:?}");.
Status: done
§7.4.8.5 Specific Keywords
Spec: §7.4.8.5, S. 73 — die Keywords des Bausteins.
Repo: crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier —
lexer.rs:73: assert_eq!(kinds("TRUE")[0], TokenKind::True);.
Status: done
§7.4.9 Building Block Components – Homes
§7.4.9.3 Syntax
Spec: §7.4.9.3, S. 74–75 — (145)–(154): home_dcl, home_header,
home_body, manages_dcl, primarykey_dcl, factory_dcl,
finder_dcl.
Repo: crates/idl-parse/src/decl.rs::parse_factory,
crates/idl-lower/src/lower.rs::manages_clause.
Tests: crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/idl-lower/tests/dialects.rs::a_home_records_what_it_manages_and_the_key_it_does_so_by,
crates/idl-lower/tests/conformance.rs::every_fixture_parses_with_no_diagnostics_beyond_the_extensions_it_declares —
dialects.rs:146: assert!(manages.component.is_resolved(), "the component was lost");.
Status: done
§7.4.9.4.1 Home Header
Spec: §7.4.9.4.1, S. 75 — abstract home <identifier> …,
home <identifier> …, home <identifier> for <scoped_name> … und die
Klausel manages <component> ;.
Repo: crates/idl-lower/src/lower.rs::manages_clause
(zerodds_ast::HomeManages).
Tests: crates/idl-lower/tests/lowering.rs::a_home_resolves_what_it_manages_and_the_key_it_manages_by,
crates/idl-lower/tests/dialects.rs::a_home_records_what_it_manages_and_the_key_it_does_so_by,
crates/ccm/tests/equivalent_idl.rs::a_keyless_home_yields_an_implicit_inheriting_keylesscmhome,
crates/ccm/tests/equivalent_idl.rs::a_keyed_home_yields_the_four_operations_and_inherits_nothing.
Status: partial — home mit manages und die Vererbung sind
abgedeckt. abstract home und home <identifier> for <scoped_name> sind
es nicht: das Keyword abstract erreicht in
crates/idl-parse/src/decl.rs::parse_interface eine
expect(TokenKind::Interface)-Stelle, und die Zeichenkette home for
kommt im Baum nicht vor.
§7.4.9.4.2 Home Body — factory, finder, primarykey
Spec: §7.4.9.4.2, S. 75–76 — factory und finder werden zu
Operationen des Homes; primary key nennt den Schlüsseltyp.
Repo: crates/idl-lower/src/lower.rs::manages_clause,
crates/ccm/src/transform.rs::transform_home,
crates/ccm/src/validate.rs::validate_primary_key.
Tests: crates/ccm/tests/equivalent_idl.rs::a_factory_is_emitted_with_create_failure_first_in_its_raises,
crates/ccm/tests/equivalent_idl.rs::a_finder_is_emitted_with_finder_failure_and_the_callers_own_raises,
crates/ccm/tests/equivalent_idl.rs::a_primary_key_with_a_public_scalar_member_is_accepted,
crates/ccm/tests/equivalent_idl.rs::a_primary_key_without_the_base_is_rejected,
crates/ccm/tests/equivalent_idl.rs::a_primary_key_with_a_private_member_is_rejected,
crates/ccm/tests/equivalent_idl.rs::a_primary_key_holding_an_object_reference_is_rejected,
crates/ccm/tests/equivalent_idl.rs::a_primary_key_holding_a_nested_struct_is_accepted —
equivalent_idl.rs:691: assert_eq!(raises.len(), 2, "FinderFailure plus the caller's own");.
Status: done
§7.4.9.5 Specific Keywords
Spec: §7.4.9.5, S. 76 — die Keywords des Bausteins.
Repo: crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier —
lexer.rs:73: assert_eq!(kinds("TRUE")[0], TokenKind::True);.
Status: done
§7.4.10 Building Block CCM-Specific
§7.4.10.3 Syntax — eventtype und Event-Ports
Spec: §7.4.10.3, S. 77–78 — (166)–(172): eventtype_dcl,
eventtype_header, eventtype_body, eventtype_forward_dcl,
emits_dcl, publishes_dcl, consumes_dcl.
Repo: crates/idl-lower/src/lower.rs::valuetype und port,
crates/ccm/src/transform.rs::transform_event_type.
Tests: crates/idl-lower/tests/dialects.rs::each_port_form_reaches_its_own_component_role,
crates/idl-lower/tests/dialects.rs::each_template_parameter_kind_is_distinguished,
crates/ccm/tests/equivalent_idl.rs::the_first_event_type_of_a_chain_inherits_event_base,
crates/ccm/tests/equivalent_idl.rs::one_event_type_yields_one_consumer_interface_however_many_ports_name_it,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends —
equivalent_idl.rs:492: assert_eq!(bases.len(), 1, "EventBase was not added");.
Status: done
§7.4.10.4.1.2 Event Ports
Spec: §7.4.10.4.1.2, S. 78–79 — emits, publishes und consumes
unterscheiden sich darin, ob ein Cookie zurückkommt.
Repo: crates/idl-lower/src/lower.rs::port
(ComponentRole::EventSource mit publisher),
crates/ccm/src/transform.rs::transform_component.
Tests: crates/idl-lower/tests/dialects.rs::each_port_form_reaches_its_own_component_role,
crates/ccm/tests/equivalent_idl.rs::emits_yields_connect_and_disconnect_and_the_consumer_interface,
crates/ccm/tests/equivalent_idl.rs::publishes_yields_subscribe_returning_a_cookie,
crates/ccm/tests/equivalent_idl.rs::consumes_yields_a_get_consumer_operation —
equivalent_idl.rs:283: assert!(names.contains(&"unsubscribe_ticker".to_string()));.
Status: done
§7.4.10.4.2.1 Supported Interfaces
Spec: §7.4.10.4.2.1, S. 79 — supports im Komponenten- und im
Home-Header.
Repo: crates/idl-lower/src/lower.rs::interface_bases,
crates/ccm/src/transform.rs.
Tests: crates/idl-lower/tests/lowering.rs::a_component_keeps_its_supports_clause_apart_from_its_base,
crates/ccm/tests/equivalent_idl.rs::a_component_with_supports_inherits_ccmobject_and_the_supported_ones,
crates/ccm/tests/equivalent_idl.rs::a_home_with_supports_puts_the_supported_interfaces_on_its_explicit,
crates/ccm/tests/equivalent_idl.rs::a_derived_home_with_supports_extends_the_base_explicit —
equivalent_idl.rs:476: ["CManagerBaseExplicit", "IExtra"].
Status: done
§7.4.10.4.3 Multiple Uses
Spec: §7.4.10.4.3, S. 80 — uses <type> <name> for <multiport_type> ; erlaubt mehrere Ports unter einem Namen.
Repo: crates/idl-lower/src/lower.rs::port
(ComponentRole::Receptacle { multiple }),
crates/ccm/src/transform.rs::transform_component.
Tests: crates/idl-lower/tests/dialects.rs::each_port_form_reaches_its_own_component_role,
crates/ccm/tests/equivalent_idl.rs::uses_multiple_returns_a_cookie_and_the_plural_getter —
equivalent_idl.rs:250: assert!(names.contains(&"get_connections_managers".to_string()));.
Status: done
§7.4.10.4.4.2 Object Root
Spec: §7.4.10.4.4.2, S. 80 — eine Komponente darf Object als
Object-Root tragen.
Repo: —
Tests: —
Status: open — Code vorhanden: die Form wird geparst und gelowert (crates/idl-parse/src/decl.rs::parse_port, ComponentRole::Facet mit Ref::Broken); kein Test, die Fixture crates/idl-parse/tests/fixtures/spec_features/ccm_components.idl wird nur auf Parse-Diagnosen geprüft. Beide Backends lehnen die Probe bb8-141-provides ab, weil Object keine Sprachform hat.
§7.4.10.5 Specific Keywords
Spec: §7.4.10.5, S. 80 — die Keywords des Bausteins.
Repo: crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier —
lexer.rs:73: assert_eq!(kinds("TRUE")[0], TokenKind::True);.
Status: done
§7.4.11 Building Block Components – Ports and Connectors
§7.4.11.3 Syntax
Spec: §7.4.11.3, S. 83–84 — (173)–(183): porttype_dcl,
porttype_header, porttype_body, connector_dcl, connector_header,
connector_body, bridge_dcl, provides_dcl, uses_dcl.
Repo: crates/idl-parse/src/decl.rs, crates/idl-lower/src/lower.rs::port.
Tests: crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/idl-lower/tests/lowering.rs::every_component_model_forward_keeps_its_own_form —
dialects.rs:67: ("connector K { };", "K", InterfaceKind::Connector),.
Status: done
§7.4.11.4.1.1 Port Type Declaration
Spec: §7.4.11.4.1.1, S. 83 — porttype <identifier> [ : <porttype_name> … ] { <porttype_export> * }.
Repo: crates/idl-lower/src/lower.rs::interface (InterfaceKind::PortType),
crates/lang-rules/src/adapter/interface.rs::Service::is_remote.
Tests: crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/idl-lower/tests/lowering.rs::every_component_model_forward_keeps_its_own_form.
Status: partial — im Modell vorhanden und als InterfaceKind::PortType
getestet; Service::is_remote schliesst PortType von jeder
DDS-RPC-Bindung aus. Kein Sprachbackend emittiert eine
Porttyp-Bindung (die Proben bb11-173 und bb11-174 stehen auf err),
und es gibt keinen Test, der behauptet, dass ComponentRole::PortTypeRole
das Modell erreicht.
§7.4.11.4.3 Connectors
Spec: §7.4.11.4.3, S. 84 — connector <identifier> … beschreibt eine
Brücke; <provides>/<uses> mit port/mirrorport bilden sie.
Repo: crates/idl-lower/src/lower.rs::port
(ComponentRole::ConnectorRole), crates/ccm/src/transform.rs::transform_component.
Tests: crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/idl-lower/tests/lowering.rs::every_component_model_forward_keeps_its_own_form,
tools/idlc/tests/idl_4_2_gaps.rs::the_fixture_directory_holds_exactly_the_named_fixtures.
Status: partial — connector ist im Modell als
InterfaceKind::Connector vorhanden; die port/mirrorport-Mitglieder
werden geparst und gelowert, aber die CCM-Umschreibung verwirft sie
bewusst (crates/ccm/src/transform.rs, Zeile 255 ff., mit dem Kommentar,
die Zuordnung über den Porttyp sei nicht §6 dieser Specification). Kein
Test behauptet etwas über ComponentRole::ConnectorRole.
§7.4.11.5 Specific Keywords
Spec: §7.4.11.5, S. 84 — die Keywords des Bausteins.
Repo: crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier —
lexer.rs:73: assert_eq!(kinds("TRUE")[0], TokenKind::True);.
Status: done
§7.4.12 Building Block Template Modules
§7.4.12.3 Syntax
Spec: §7.4.12.3, S. 86–87 — (186)–(194): template_dcl,
formal_parameters, formal_parameter, actual_parameters,
actual_parameter, template_module_instantiation,
template_module_ref.
Repo: crates/idl-lower/src/lower.rs::template_module_inst,
crates/idl-lower/src/lower.rs::template_formals,
crates/idl-parse/src/decl.rs::at_template_module_inst.
Tests: crates/idl-lower/tests/dialects.rs::a_template_modules_parameters_reach_its_facet,
crates/idl-lower/tests/dialects.rs::each_template_parameter_kind_is_distinguished,
crates/idl-lower/tests/conformance.rs::every_fixture_parses_with_no_diagnostics_beyond_the_extensions_it_declares,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(bb12-185-template-module) —
dialects.rs:170: assert_eq!(params.len(), 2);.
Status: done
§7.4.12.4.1 Template Module Declaration
Spec: §7.4.12.4.1, S. 87–88 — module <identifier> < formal_parameters > { … }; die formalen Typen sind typename,
struct, union, enum, exception, interface, valuetype,
eventtype und sequence.
Repo: crates/idl-lower/src/lower.rs::template_formals,
crates/ast/src/facet/corba.rs::TemplateParamKind.
Tests: crates/idl-lower/tests/dialects.rs::each_template_parameter_kind_is_distinguished,
crates/idl-lower/tests/dialects.rs::a_sequence_type_formal_parameter_parses_and_carries_its_element,
crates/idl-lower/tests/dialects.rs::the_bare_sequence_classifier_still_parses_as_itself,
crates/idl-lower/tests/dialects.rs::a_bounded_sequence_parameter_keeps_its_bound,
crates/idl-lower/tests/dialects.rs::a_template_module_declares_no_types_of_its_own —
dialects.rs:205: assert_eq!(params.first().map(|p| p.kind), Some(expected), "{written}");.
Status: done
§7.4.12.4.2 Template Module Instantiation
Spec: §7.4.12.4.2, S. 88–89 — module <identifier> < actual_parameters > <identifier> ;; alias übergibt einen formalen Typ
weiter.
Repo: crates/idl-lower/src/lower.rs::template_module_inst,
crates/idl-lower/src/lower.rs::template_body.
Tests: crates/idl-lower/tests/dialects.rs::an_instantiation_lowers_the_body_with_the_actual_substituted,
crates/idl-lower/tests/dialects.rs::two_instantiations_of_one_template_are_two_independent_modules,
crates/idl-lower/tests/dialects.rs::a_const_actual_parameter_becomes_a_constant_of_the_instance,
crates/idl-lower/tests/dialects.rs::an_alias_hands_the_enclosing_templates_parameter_on,
crates/idl-lower/tests/dialects.rs::an_instantiation_of_a_template_nobody_declared_is_reported_by_name,
crates/idl-lower/tests/dialects.rs::an_instantiation_with_the_wrong_number_of_actuals_is_reported,
crates/idl-lower/tests/dialects.rs::a_plain_module_is_untouched_by_the_instantiation_lookahead —
dialects.rs:1462: zerodds_ast::TypeKind::Primitive(zerodds_ast::PrimitiveKind::Int32).
Status: done
§7.4.12.5 Specific Keywords
Spec: §7.4.12.5, S. 89 — das einzige zusätzliche Keyword des
Bausteins ist alias.
Repo: crates/idl-cst/src/token.rs::TokenKind.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier,
crates/idl-lower/tests/dialects.rs::an_alias_hands_the_enclosing_templates_parameter_on —
dialects.rs:1516: assert!(names.contains(&"Concrete::S".to_string()), "{names:?}");.
Status: done
§7.4.13 Building Block Extended Data Types
§7.4.13.4.1 Structures with Single Inheritance
Spec: §7.4.13.4.1, S. 89 — eine Struktur kann von höchstens einer
anderen erben; die Erweiterbarkeit der Basis gilt fort, ein in der
abgeleiteten Struktur neu vergebener @id ist zu Recht.
Repo: crates/ast/src/node/type_.rs::TypeKind::Structure { base },
crates/idl-lower/src/validate.rs::inheritance_rules.
Tests: crates/idl-lower/tests/lowering.rs::a_struct_with_a_base_records_it,
crates/idl-parse/tests/parse.rs::a_struct_with_a_base_records_its_inheritance,
crates/idl-lower/tests/keys_and_inheritance.rs::a_derived_structure_with_another_extensibility_than_its_base_is_refused,
crates/idl-lower/tests/keys_and_inheritance.rs::a_member_name_of_the_base_chain_cannot_be_declared_again,
crates/idl-lower/tests/keys_and_inheritance.rs::a_member_id_of_the_base_chain_cannot_be_given_again,
crates/idl-lower/tests/completion.rs::a_derived_structure_that_said_nothing_has_its_bases_extensibility,
crates/idl-lower/tests/completion.rs::the_callers_default_extensibility_does_not_override_a_bases —
keys_and_inheritance.rs:95: assert_eq!(out.ast.effective_extensibility(id), Extensibility::Mutable);.
Status: done
§7.4.13.4.1 Void Content
Spec: §7.4.13.4.1, S. 89 — eine Struktur ohne Member (struct S { };)
ist in diesem Baustein zulässig.
Repo: crates/ast/src/node/type_.rs::TypeKind::Structure,
crates/idl-lower/src/validate.rs::validate_type.
Tests: crates/idl-lower/tests/validation.rs::the_two_bodies_the_grammar_does_let_be_empty_stay_empty,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends.
Status: partial — der leere Struct wird akzeptiert und das Modell
trägt ihn; das C-Backend weist ihn ab (NoLanguageForm, C23 §6.7.2.1p8
lässt eine Struktur ohne benanntes Mitglied undefiniert). Rust emittiert
ihn.
§7.4.13.4.2 Union Discriminators
Spec: §7.4.13.4.2, S. 89–90 — zulässig sind die Integer-Typen,
boolean, char, octet und eine Enumeration; ein Case-Label muss im
Wertebereich des Diskriminators liegen.
Repo: crates/idl-lower/src/validate.rs::is_legal_discriminator,
crates/idl-lower/src/validate.rs::label_is_in_range.
Tests: crates/idl-lower/tests/validation.rs::each_legal_discriminator_type_is_accepted,
crates/idl-lower/tests/validation.rs::an_enum_discriminator_is_accepted,
crates/idl-lower/tests/validation.rs::a_typedef_to_a_legal_discriminator_is_accepted,
crates/idl-lower/tests/validation.rs::a_float_discriminator_is_rejected,
crates/idl-lower/tests/validation.rs::a_string_discriminator_is_rejected,
crates/idl-lower/tests/validation.rs::a_struct_discriminator_is_rejected,
crates/idl-lower/tests/validation.rs::a_case_label_outside_the_discriminators_range_is_rejected,
crates/idl-lower/tests/validation.rs::a_case_label_inside_the_range_is_accepted,
crates/idl-lower/tests/validation.rs::a_boolean_discriminator_admits_only_zero_and_one,
crates/idl-lower/tests/validation.rs::only_a_unions_discriminator_may_be_a_key,
crates/idl-lower/tests/validation.rs::no_union_member_is_optional,
crates/idl-lower/tests/annotations.rs::a_key_on_a_union_discriminator_is_refused_with_the_clause_that_permits_it —
validation.rs:184: assert!(!trips(&source, DiagnosticCode::InvalidDiscriminator),.
Status: done
§7.4.13.4.3.1 Maps
Spec: §7.4.13.4.3.1, S. 90 — map < key_type , value_type > < bound >; eine Map darf kein Teil eines Schlüssels sein.
Repo: crates/idl-parse/src/type_spec.rs::parse_map_type,
crates/idl-lower/src/validate.rs::validate_type.
Tests: crates/idl-lower/tests/validation.rs::a_map_cannot_be_part_of_a_key,
crates/idl-lower/tests/annotations.rs::a_map_key_may_only_be_discard,
crates/idl-lower/tests/annotations.rs::external_on_an_element_a_map_key_or_a_map_value_is_carried,
crates/idl-lower/tests/annotations.rs::only_try_construct_is_accepted_on_a_collection_element,
crates/idl-lower/tests/conformance.rs::the_xtypes_specifications_own_idl_lowers_completely —
validation.rs:340: assert_trips(source, DiagnosticCode::InvalidAnnotation);.
Status: done
§7.4.13.4.3.2 Bit Sets (einschliesslich Bit Fields)
Spec: §7.4.13.4.3.2, S. 90–91 — bitfield < width > [ , type_spec ];
“The maximum value is 64”; “When the destination type is given, the
number of stored bits cannot exceed its size (i.e., 1 for boolean, 8 for
octet, …)”.
Repo: crates/idl-lower/src/complete.rs::check_bitset_bounds und
holder_width, crates/idl-lower/src/complete.rs::MAX_BITFIELD_BITS.
Tests: crates/idl-lower/tests/validation.rs::a_bitfield_wider_than_sixty_four_bits_is_refused,
crates/idl-lower/tests/validation.rs::a_bitfield_wider_than_its_destination_type_is_refused,
crates/idl-lower/tests/validation.rs::the_bit_forms_the_specification_admits_still_get_through,
crates/idl-lower/tests/conformance.rs::the_xtypes_specifications_own_idl_lowers_completely,
crates/ast/tests/node_space.rs::an_anonymous_bitfield_carries_no_name —
validation.rs:785: assert_clean("bitset Ba { bitfield<64> f1; };");.
Status: done
§7.4.13.4.3.3 Bit Masks und ihre Annotation-Constraints
Spec: §7.4.13.4.3.3, S. 91–94 — “By default, the size of a bit mask is
32”; “A bit mask must contain at least one value and no more than its size
expressed in bits”; @bit_bound “must be lower than or equal to 64”;
@position “Possible positions range from 0 … up to (size – 1)”.
Repo: crates/idl-lower/src/complete.rs::check_bitmask_bounds und
check_bit_bounds, crates/idl-lower/src/complete.rs::MAX_BIT_BOUND.
Tests: crates/idl-lower/tests/validation.rs::a_bit_bound_over_sixty_four_is_refused,
crates/idl-lower/tests/validation.rs::a_bitmask_with_more_values_than_its_size_is_refused,
crates/idl-lower/tests/validation.rs::a_bitmask_with_no_bit_value_is_refused,
crates/idl-lower/tests/validation.rs::a_bit_position_outside_the_bitmasks_size_is_refused,
crates/idl-lower/tests/completion.rs::bit_positions_run_from_zero_and_an_explicit_one_shifts_the_rest,
crates/idl-lower/tests/completion.rs::a_written_bit_bound_is_what_the_rule_reports,
crates/idl-lower/tests/annotations.rs::an_explicit_bit_position_reaches_the_bit —
validation.rs:813: assert_clean("@bit_bound(64) bitmask Ba { F1 };");.
Status: done
§7.4.13.4.3.3 Doppelte @position
Spec: §7.4.13.4.3.3, S. 92 — die Notizen der Klausel halten fest, dass annotierte Bit-Werte ungeordnet sein dürfen, aber keine Dubletten.
Repo: —
Tests: —
Status: open — check_bitmask_bounds (crates/idl-lower/src/complete.rs) prüft @bit_bound, die Anzahl der Werte und den Bereich von @position, aber nicht, dass zwei @position-Werte gleich sind. bitmask B { @position(1) A, @position(1) C }; wird akzeptiert; der spätere Wert überschreibt den früheren im Modell.
§7.4.13.4.4 Integers restricted to holding 8-bits of information
Spec: §7.4.13.4.4, S. 94 — (212) führt int8 und uint8 als eigene
Typen mit dem Wertebereich ±2^7 bzw. 0..2^8−1.
Repo: crates/idl-lower/src/lower.rs::primitive_of,
crates/idl-parse/src/type_spec.rs::is_primitive_keyword.
Tests: crates/idl-lower/tests/lowering.rs::each_primitive_keyword_reaches_its_model_kind,
crates/ast/tests/node_space.rs::every_primitive_of_the_spec_table_is_representable,
crates/idl-lower/tests/validation.rs::every_form_the_specification_admits_still_gets_through —
validation.rs:732: "const int8 K = 1;",.
Status: done
§7.4.13.4.5 Explicitly-named Integer Types
Spec: §7.4.13.4.5, S. 94 — (213)–(215) führen int16/int32/int64
und uint16/uint32/uint64 als Aliase der klassischen Schreibweisen mit
gleichem Wertebereich.
Repo: crates/idl-parse/src/type_spec.rs::is_primitive_keyword,
crates/idl-lower/src/lower.rs::primitive_of.
Tests: crates/idl-lower/tests/lowering.rs::each_primitive_keyword_reaches_its_model_kind,
crates/ast/tests/node_space.rs::every_primitive_of_the_spec_table_is_representable,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends
(bb13-212-int64) —
lowering.rs:333: ("int64", PrimitiveKind::Int64),.
Status: done
§7.4.13.4.6 Ranges for all Integer Types (Table 7-26)
Spec: §7.4.13.4.6, S. 94–95 — Tabelle 7-26 nennt für jeden Integer-Typ
den Wertebereich und den gleichwertigen Core-Typ; int8/uint8 haben
kein Core-Gegenstück (Spalte “N/A”).
Repo: crates/idl-lower/src/validate.rs::primitive_range.
Tests: crates/idl-lower/tests/validation.rs::a_case_label_outside_the_discriminators_range_is_rejected,
crates/idl-lower/tests/validation.rs::a_case_label_inside_the_range_is_accepted,
crates/idl-lower/tests/floating_constant_arithmetic.rs::a_value_beyond_the_declared_range_is_refused.
Status: partial — die Tabelle primitive_range bildet genau die
Spalten aus Tabelle 7-26 ab, wird aber nur für Case-Labels eines
Diskriminators gelesen. Der Wertebereich einer Konstante wird nicht
geprüft: value_disagrees_with vergleicht nur die Form des Literalwerts,
nicht seinen Zahlwert; const octet K = 300; und const int8 K = 200;
gehen durch.
§7.4.13.5 Specific Keywords
Spec: §7.4.13.5, S. 95–96 — Tabelle 7-27 nennt bitfield, bitmask,
bitset, map, int8, uint8, int16, int32, int64, uint16,
uint32, uint64.
Repo: crates/idl-cst/src/token.rs::KEYWORDS,
crates/idl-parse/src/type_spec.rs::is_primitive_keyword.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier,
crates/idl-lower/tests/lowering.rs::each_primitive_keyword_reaches_its_model_kind,
crates/idl-parse/tests/parse.rs::each_declaration_form_is_recognised —
lowering.rs:331: ("int8", PrimitiveKind::Int8),.
Status: done
§7.4.14 Building Block Anonymous Types
§7.4.14.3 Rule (216) — template_type_spec als type_spec
Spec: §7.4.14.3, S. 97 — (216) <type_spec> ::+ <template_type_spec>
erlaubt sequence<…> und string<…> dort, wo ein Typ verlangt wird.
Repo: —
Tests: —
Status: open — die Klausel ist nicht als eigene Form geprüft. Der Pfad, den sie öffnet (struct S { sequence<long> m; };), ist im Parser (crates/idl-parse/src/type_spec.rs::parse_type_spec, crates/idl-parse/src/decl.rs::parse_member_list) nicht erreichbar: parse_member verlangt einen Declarator, und sequence<long> m; wird als Deklarator gelesen. Die Tests zu Sequenz-Parametern und a_sequence_member_carries_its_element_type prüfen die Template-Modul-Form, nicht die anonyme.
§7.4.14.3 Rule (217) — array_declarator als declarator
Spec: §7.4.14.3, S. 97 — (217) <declarator> ::= <complex_declarator> | <array_declarator>, sodass long a[3][4]; ohne
typedef entsteht.
Repo: crates/idl-parse/src/decl.rs::parse_member_list,
crates/idl-parse/src/parser.rs (Array-Declarator-Erkennung an der
eckigen Klammer).
Tests: crates/idl-parse/tests/parse.rs::an_array_declarator_is_only_known_at_the_bracket,
crates/idl-lower/tests/lowering.rs::a_typedef_declarator_keeps_its_array_dimensions,
crates/idl-lower/tests/lowering.rs::dimensions_belong_to_the_declarator_and_not_to_the_typedef.
Status: partial — die Array-Dimensionen werden am Deklarator
erkannt und dem Deklarator zugeordnet; getestet ist das über den
typedef-Weg. Die anonyme Form struct S { long arr[3]; }; hat keinen
eigenen Test.
§7.4.14.4 Verschachtelte Templates und >>
Spec: §7.4.14.4, S. 97 — “For those nested template declarations,
white space must be used to separate the two > tokens ending the
declaration so they are not parsed as a single >> token.”
Repo: crates/idl-parse/src/parser.rs::split_shift_right,
crates/idl-parse/src/type_spec.rs::close_type_arguments.
Tests: crates/idl-parse/tests/parse.rs::a_nested_sequence_splits_the_shift_token_and_still_round_trips,
crates/idl-parse/tests/parse.rs::three_deep_nesting_splits_as_far_as_it_needs_to,
crates/idl-parse/tests/parse.rs::shift_right_in_an_expression_is_not_split.
Status: partial — die Verschachtelung funktioniert auch ohne
Whitespace (sequence<sequence<long>>), was die Klausel nicht fordert. Der
umgekehrte Fall, die vom Spec verlangte Schreibweise mit Whitespace
(sequence<sequence<long> >), wird von keinem Test berührt: der
Split-Zweig wird nur für das einzelne >>-Token ausgelöst.
§7.4.14.5 Specific keywords
Spec: §7.4.14.5, S. 97 — “There are no additional keywords with this building block.”
Repo: crates/idl-cst/src/token.rs::KEYWORDS.
Tests: —
Status: n/a (informative) — die Klausel sagt selbst, dass es keine
zusätzlichen Keywords gibt; es gibt nichts zu prüfen.
§7.4.15 Building Block Annotations
§7.4.15.1 Purpose
Spec: §7.4.15.1, S. 97 — “This building block defines a framework to add meta-data to IDL constructs, by means of annotations.”
Repo: crates/idl-parse/src/decl.rs::parse_annotation_decl,
crates/idl-lower/src/annotation.rs::apply_one.
Tests: —
Status: n/a (informative) — die Klausel begründet den Baustein; die
Produktionen stehen in §7.4.15.3.
§7.4.15.2 Dependencies
Spec: §7.4.15.2, S. 97 — “This building block only relies on Building Block Core Data Types. It is actually orthogonal to all others.”
Repo: crates/idl-lower/src/annotation.rs::enumerated_parameter.
Tests: tools/idlc/tests/annotation_arguments.rs::a_builtin_with_an_enumerated_parameter_reads_it_without_resolving_it,
tools/idlc/tests/annotation_arguments.rs::a_verbatim_directive_still_reaches_the_model_whole,
tools/idlc/tests/annotation_arguments.rs::the_rti_fixture_that_carried_both_defects_now_passes —
annotation_arguments.rs:145: assert!(found.is_empty(), "{source:?} was refused: {found:?}");.
Status: done
§7.4.15.3 Rules (218)–(227)
Spec: §7.4.15.3, S. 98 — (218) <definition> ::+ <annotation_dcl> ";";
(219) <annotation_dcl>; (220) <annotation_header>; (221)
<annotation_body> = { <annotation_member> | <enum_dcl> ";" | <const_dcl> ";" | <typedef_dcl> ";" }*; (222) <annotation_member>;
(223) <annotation_member_type>; (224) <any_const_type>; (225)
<annotation_appl>; (226) <annotation_appl_params>; (227)
<annotation_appl_param>.
Repo: crates/idl-parse/src/decl.rs::parse_annotation_decl und
parse_annotation_tail, crates/idl-lower/src/annotation.rs::apply_one.
Tests: crates/idl-parse/tests/parse.rs::an_annotation_body_admits_only_what_rule_221_lists,
crates/idl-parse/tests/parse.rs::the_declarations_rule_221_does_list_are_still_taken,
crates/idl-parse/tests/parse.rs::annotations_bind_to_the_declaration_that_follows,
crates/idl-parse/tests/parse.rs::an_annotation_takes_arguments_in_both_forms,
crates/idl-lower/tests/annotations.rs::a_root_anchored_annotation_name_reaches_the_builtin_it_names,
crates/idl-lower/tests/annotations.rs::a_qualified_annotation_name_reaches_its_declaration,
crates/idl-lower/tests/annotations.rs::every_spelling_of_one_builtin_says_the_same_thing,
crates/idl-lower/tests/annotations.rs::an_annotation_name_that_is_a_keyword_still_works_qualified,
crates/idl-lower/tests/annotations.rs::an_annotation_with_no_name_at_all_is_still_refused —
parse.rs:481: DiagnosticCode::UnexpectedToken,.
Status: done
§7.4.15.4.1 Defining Annotations
Spec: §7.4.15.4.1, S. 99 — der Rumpf einer Annotation ist ein eigener Scope; an der Anwendungsstelle gilt “Members with no default value must be given a value”.
Repo: crates/idl-parse/src/decl.rs::parse_annotation_decl (die vier
zugelassenen Deklarationsformen), crates/idl-lower/src/scope.rs::ScopeStack::push_container,
crates/idl-lower/src/annotation.rs::check_annotation_application.
Tests: tools/idlc/tests/annotation_arguments.rs::an_annotation_body_may_declare_the_types_its_members_use,
tools/idlc/tests/annotation_arguments.rs::the_user_annotation_fixture_passes,
crates/idl-lower/tests/validation.rs::an_annotation_member_with_no_default_takes_the_default_of_its_type,
crates/idl-lower/tests/validation.rs::an_annotations_declared_members_reach_the_model,
crates/idl-parse/tests/parse.rs::the_declarations_rule_221_does_list_are_still_taken,
crates/idl-parse/tests/parse.rs::an_annotation_body_admits_only_what_rule_221_lists —
validation.rs:883: "@annotation Aa { long v; };\n@Aa struct Sa { long m; };",.
Status: partial — das Front-End gibt einem Annotationsmember ohne Default und ohne
Wert den Default seines Typs (XTypes 1.3 §7.3.1.2.5); IDL 4.2 verlangt hier einen
Wert. Die beiden Specs widersprechen sich; ein Issue-Entwurf dazu fehlt noch.
§7.4.15.4.2 Applying Annotations
Spec: §7.4.15.4.2, S. 100–101 — “in case an unknown annotation is encountered, it should be ignored by the IDL-processing tools”; “A constant expression, whose type must be compatible with the member’s declaration”; “In case there is only one member, the annotation application may be shortened to the name of the annotation prefixed with @ and followed with the constant value of that unique member”; “malformed definitions shall be treated as an error”.
Repo: crates/idl-lower/src/annotation.rs::check_annotation_application
und apply_one (nur für aufgelöste Deklarationen aufgerufen).
Tests: crates/idl-lower/tests/validation.rs::an_annotation_argument_has_to_have_the_members_type,
crates/idl-lower/tests/validation.rs::an_argument_naming_no_member_is_refused,
crates/idl-lower/tests/validation.rs::the_short_form_is_only_for_an_annotation_with_one_member,
crates/idl-lower/tests/validation.rs::none_of_the_four_rules_reaches_an_unknown_annotation,
tools/idlc/tests/annotation_arguments.rs::an_unknown_annotation_is_ignored_whatever_it_is_given,
tools/idlc/tests/annotation_arguments.rs::a_name_outside_an_unknown_annotation_still_has_to_resolve,
tools/idlc/tests/annotation_arguments.rs::a_literal_argument_of_an_unknown_annotation_still_reaches_the_model,
tools/idlc/tests/strict.rs::strict_does_not_refuse_an_unknown_annotation,
crates/idl-lower/tests/dialects.rs::strict_does_not_refuse_an_unknown_annotation,
crates/ast/tests/node_space.rs::the_value_member_shorthand_is_recorded —
validation.rs:915: "@annotation Aa { long v default 0; };\n@Aa(nosuch = 1) struct Sa { long m; };",.
Status: done
§7.4.15.5 Specific Keywords
Spec: §7.4.15.5, S. 102 — die Syntax nutzt @ als Punctuator;
@annotation ist die Kopfmarke, kein Keyword.
Repo: crates/idl-cst/src/token.rs::TokenKind::Annotation,
crates/idl-cst/src/tree.rs::CstKind::AnnotationDecl.
Tests: crates/idl-cst/tests/lexer.rs::every_keyword_lexes_as_its_own_kind_and_not_as_an_identifier,
crates/idl-parse/tests/parse.rs::each_declaration_form_is_recognised —
parse.rs:88: assert!(parses_cleanly(source), "{source:?} produced diagnostics");.
Status: done
§7.4.16 Relationships between the Building Blocks
§7.4.16 Abhängigkeitsgitter (Figure 7-2)
Spec: §7.4.16, S. 102 — “Even if the building blocks have been designed as independent as possible, they are linked by some dependencies. The following figure represents the graph of their relationships (actually a lattice).”
Repo: —
Tests: —
Status: open — es gibt im heutigen Baum keine Abbildung dieses
Gitters. crates/ast/src/profile/mod.rs::Profile ist eine flache
Enumeration anderer Specificationen (Idl42Core, XTypes13, Corba33,
Ros2, DdsXml, FlatData, Vendor), und zwischen den Profilen gibt es
keine Kante. Der einzige Ort, an dem die Namen der Bausteine vorkommen,
ist die Prosa in docs/idl-building-blocks.md.
§7.5 Names and Scoping
§7.5 Sichtbarkeitsregeln über alle Building Blocks
Spec: §7.5, S. 102 — “This clause defines the visibility rules that apply to names. Those rules are considering the whole IDL grammar (i.e., the union of all building blocks).”
Repo: crates/idl-lower/src/scope.rs::ScopeStack,
crates/ast/src/resolve.rs.
Tests: crates/idl-lower/tests/lowering.rs::a_constant_resolves_by_its_simple_name_in_its_own_scope,
crates/ast/tests/resolve_profile_query.rs::every_profile_accepts_a_model_of_plain_primitives,
crates/ast/tests/profile_table.rs::the_construct_table_is_total_over_profiles_and_constructs,
crates/ast/tests/profile_table.rs::the_facet_table_is_total_over_profiles_and_properties —
lowering.rs:1568: ast.eval_integral(bound).expect("the bound evaluates"),.
Status: done
§7.5.1 Qualified Names
Spec: §7.5.1, S. 102–103 — “A qualified name (one of the form
<scoped_name>::<identifier>) is resolved by first resolving the qualifier
<scoped_name> to a scope S, and then locating the definition of
<identifier> within S. The <identifier> is not searched for in enclosing
scopes.”; “When a qualified name begins with '::', the resolution process
starts with the file scope”.
Repo: crates/idl-lower/src/scope.rs::ScopeStack::lookup_candidates,
crates/idl-lower/src/expr.rs::lookup_name.
Tests: crates/idl-lower/tests/reported_idl.rs::a_fully_qualified_scoped_name_resolves,
crates/idl-lower/tests/lowering.rs::a_qualified_constant_still_resolves_through_its_module,
crates/idl-parse/tests/parse.rs::a_leading_double_colon_is_the_global_scope,
crates/idl-lower/tests/dialects.rs::the_root_anchored_spelling_names_the_same_module,
crates/ast/tests/node_space.rs::nested_modules_are_addressable_by_path —
node_space.rs:43: ast.module_by_path(&scoped(&["Robot", "Sensors"])),.
Status: done
§7.5.1 Global Names
Spec: §7.5.1, S. 103 — “Every IDL definition in a file has a global
name within that file”; der globale Name ist die Verkettung aus aktuellem
Root, aktuellem Scope, "::" und dem Bezeichner.
Repo: crates/idl-lower/src/scope.rs::ScopeStack (qualify und
qualify_segments), crates/idl-lower/tests/interface_as_type.rs.
Tests: crates/idl-lower/tests/interface_as_type.rs::the_key_is_the_declaration_s_own_scoped_name_and_not_the_written_segment,
crates/ast/tests/node_space.rs::nested_modules_are_addressable_by_path,
crates/idl-lower/tests/dialects.rs::a_typeprefix_may_name_the_module_it_is_written_in,
crates/idl-lower/tests/dialects.rs::a_sibling_declaration_wins_over_one_further_out —
dialects.rs:1307: "IDL:inner.example/outer/m/S:1.0".
Status: done
§7.5.1 Mehrdeutigkeit
Spec: §7.5.1, S. 103–104 — “Ambiguous declarations shall be treated as
errors”; die Klausel nennt das Beispiel zweier geerbter string_t.
Repo: crates/idl-lower/src/scope.rs::ScopeStack::lookup_candidates.
Tests: crates/ast/tests/resolve_profile_query.rs::an_ambiguous_name_reports_every_candidate,
crates/ast/tests/resolve_profile_query.rs::a_duplicate_scoped_name_is_reported_as_ambiguous_with_both_nodes.
Status: partial — die Mehrdeutigkeitsmeldung auf Modellebene ist
belegt und nennt alle Kandidaten. Das Spec-Beispiel (§7.5.1: interface C: A, B mit einem Attribut, dessen Typ in beiden Basen unterschiedlich
belegt ist) wird von keinem Test getrieben.
§7.5.1 Sichtbarkeit durch Inheritance und mehrere globale Namen
Spec: §7.5.1, S. 103 — “Inheritance causes all identifiers defined in
base interfaces, both direct and indirect, to be visible in derived
interfaces”; “Multiple paths to the same original identifier … do not
conflict with each other”; “Inheritance introduces multiple global IDL
names for the inherited identifiers … the exception is known by the global
names ::A::E and ::B::E”.
Repo: —
Tests: —
Status: open — es gibt keinen Test, der prüft, dass ein aus einer
Basis geerbter Bezeichner unter zwei globalen Namen auflösbar ist und
dass zwei Wege zu derselben Deklaration kein Konflikt sind. Die
Abflachung in crates/lang-rules ist eine Sprachspalte, keine Aussage
über die Namen.
§7.5.2 Scope-Arten und ihr Beginn und Ende
Spec: §7.5.2, S. 104 — “The following kinds of definitions form scopes:
modules, structures, unions, maps, interfaces, value types, operations,
exceptions, event types, components, homes.”; “The scope of an operation
begins immediately following its opening ( and ends immediately preceding
its closing ).”
Repo: crates/idl-lower/src/scope.rs::ScopeStack::push_container und
pop.
Tests: crates/idl-lower/tests/validation.rs::the_same_name_in_two_scopes_does_not_collide,
crates/idl-lower/tests/lowering.rs::a_constant_resolves_by_its_simple_name_in_its_own_scope,
crates/ast/tests/node_space.rs::nested_modules_are_addressable_by_path —
validation.rs:51: "module A { struct S { long x; }; };",.
Status: done
§7.5.2 Ein Bezeichner einmal pro Scope
Spec: §7.5.2, S. 104 — “An identifier can only be defined once in a scope. However, identifiers can be redefined in nested scopes.”
Repo: crates/idl-lower/src/scope.rs::ScopeStack::bind.
Tests: crates/idl-lower/tests/validation.rs::the_same_name_in_two_scopes_does_not_collide,
crates/idl-lower/tests/lowering.rs::a_name_declared_in_two_openings_of_one_module_collides,
crates/idl-lower/tests/validation.rs::two_members_of_one_aggregate_differing_only_by_case_collide —
validation.rs:116: "struct S { long tail; short Tail; };",.
Status: done
§7.5.2 Wiedereröffnung eines Moduls
Spec: §7.5.2, S. 104 — “An identifier declaring a module is considered to be defined by its first occurrence in a scope. Subsequent occurrences of a module declaration with the same identifier within the same scope reopens the module and hence its scope.”
Repo: crates/idl-lower/src/scope.rs::ScopeStack::push.
Tests: crates/idl-lower/tests/lowering.rs::a_module_reopened_across_two_files_converges_on_one_node,
crates/idl-lower/tests/lowering.rs::a_reopened_module_still_sees_what_the_first_opening_declared,
crates/ast/tests/node_space.rs::reopening_a_module_merges_into_the_same_node —
node_space.rs:58: assert_eq!(first, second);.
Status: done
§7.5.2 Keine Selbst-Umbenennung des Scope-Namens
Spec: §7.5.2, S. 104 — “The name of a module, structure, union, map, interface, value type, event type, exception or home may not be redefined within the immediate scope of the module, structure, union, map, interface, value type, event type, exception or home.”
Repo: crates/idl-lower/src/lower.rs::check_redefines_enclosing_scope.
Tests: crates/idl-lower/tests/validation.rs::a_declaration_may_not_reuse_the_name_of_its_own_scope,
crates/idl-lower/tests/validation.rs::only_the_immediate_scope_is_compared —
validation.rs:1016: assert_clean("module Ma { module Mb { typedef short Ma; }; };");.
Status: done — die Klausel zählt Operationen nicht auf, und genau so weit greift die Prüfung; siehe das Item zu §7.5.2 Identifier-Einführung für die zweite, offene Regel dieser Klausel.
§7.5.2 Einführung eines Bezeichners durch Benutzung
Spec: §7.5.2, S. 104–105 — “An identifier from a surrounding scope is introduced into a scope if it is used in that scope. An identifier is not introduced into a scope by merely being visible in that scope.”
Repo: —
Tests: —
Status: open — es gibt keine use-Unterstützung und keine
Gegenprüfung, die den Namen in den einführenden Scope überträgt. Die
Erhebung unter tools/idl-4.2-gap-scan/ führt die Probe
scope-7.5.2-introduced-ident mit expect=reject, gemessen wird aber
ok; die beiden Gegenproben scope-7.5.2-not-introduced-ok und
scope-7.5.2-rooted-no-introduce gehen heute durch, richtig, aber aus dem
falschen Grund, weil die Regel gar nicht existiert.
§7.5.2 Nur das erste Glied eines qualifizierten Namens wird eingeführt
Spec: §7.5.2, S. 105 — “Only the first identifier in a qualified name is introduced into the current scope. This is illustrated by Inner1::S1 in the example above, which introduces Inner1 into the scope of Inner2 but does not introduce S1. A qualified name of the form ::X::Y::Z does not cause X to be introduced, but a qualified name of the form X::Y::Z does.”
Repo: —
Tests: —
Status: open — dieselbe fehlende Regel wie im Item darüber. Die Probe
scope-7.5.2-rooted-no-introduce geht durch, misst aber nichts: ohne
Einführungs-Tracking kann sie nicht fehlschlagen.
§7.5.2 Enum-Wertnamen im umgebenden Scope
Spec: §7.5.2, S. 105 — “Enumeration value names are introduced into the
enclosing scope and then are treated like any other declaration in that
scope.”; das Beispiel enum BadE { E3, E4, E5 }; ist mit // Error
gekennzeichnet, weil E3 schon aus E stammt.
Repo: crates/idl-lower/src/scope.rs::ScopeStack::bind,
crates/idl-lower/src/lower.rs::enumeration.
Tests: crates/idl-lower/tests/lowering.rs::an_enumerator_is_named_from_the_scope_around_its_enumeration,
crates/idl-lower/tests/lowering.rs::one_literal_name_in_two_enumerations_collides,
crates/idl-lower/tests/lowering.rs::a_union_over_an_enumeration_lowers_with_its_labels_evaluated,
crates/idl-lower/tests/lowering.rs::a_case_label_may_name_its_enumerator_by_a_qualified_name —
lowering.rs:217: assert_eq!(ast.eval_integral(expr), Ok(1));.
Status: done
§7.5.2 Auflösung eines unqualifizierten Namens
Spec: §7.5.2, S. 105–106 — “A name can be used in an unqualified form within a particular scope; it will be resolved by successively searching farther out in enclosing scopes, while taking into consideration inheritance relationships among interfaces.”
Repo: crates/idl-lower/src/expr.rs::lookup_name,
crates/idl-lower/src/scope.rs::ScopeStack::lookup_candidates.
Tests: crates/idl-lower/tests/lowering.rs::a_constant_resolves_by_its_simple_name_in_its_own_scope,
crates/idl-lower/tests/lowering.rs::a_qualified_constant_still_resolves_through_its_module,
crates/idl-lower/tests/dialects.rs::a_sibling_declaration_wins_over_one_further_out —
lowering.rs:1597: assert_eq!(ast.eval_integral(bound).expect("evaluates"), 8);.
Status: done
§7.5.3 Special Scoping Rules for Type Names
Spec: §7.5.3, S. 106 — “Once a type has been defined anywhere within the scope of a module, interface or value type, it may not be redefined except within the scope of a nested module, interface or value type, or within the scope of a derived interface or value type.”
Repo: crates/idl-lower/src/scope.rs::ScopeStack::bind.
Tests: crates/idl-lower/tests/lowering.rs::a_name_declared_in_two_openings_of_one_module_collides,
crates/idl-lower/tests/keys_and_inheritance.rs::a_member_name_of_the_base_chain_cannot_be_declared_again.
Status: partial — die Sperre gilt für zwei Öffnungen desselben Moduls
und für die Strukturvererbung. Der in der Klausel genannte Ausnahmefall,
die Wiederverwendung in einem abgeleiteten Interface, ist nicht als
positiver Fall getestet; die Klausel fordert ihn.
§7.5.3 Potential Scope
Spec: §7.5.3, S. 107 — “if a type name is introduced into a scope that is nested in a non-module scope definition its potential scope extends over all its enclosing scopes out to the enclosing non-module scope”; “A type may not be redefined within its scope or potential scope”; ferner die Note, dass eine Redefinition nach der Benutzung in einem Modul zulässig ist.
Repo: —
Tests: —
Status: open — der Begriff Potential Scope hat im Baum keine Entsprechung.
crates/idl-lower/src/scope.rs führt einen Scope-Stack ohne
Verwendungszählung, also ohne die Buchführung, aus der die Regel
folgen würde. Auch die positive Note der Klausel (Redefinition nach
Benutzung in einem Modul) hat keinen Test.
§8 Standardized Annotations
§8.1 Overview
Spec: §8.1, S. 109 — “The syntax to define annotations is given in the clause 7.4.15, Building Block Annotations. Any profile that embeds that building block will support annotations.”; “this clause defines some standardized annotations and groups them in Groups of Annotations”.
Repo: crates/ast/src/node/annotation.rs::BUILTIN_ANNOTATIONS (31
Namen), crates/idl-lower/src/annotation.rs::apply_one.
Tests: crates/ast/tests/node_space.rs::every_builtin_annotation_of_the_spec_list_is_present,
crates/ast/tests/node_space.rs::builtin_identities_come_from_the_builtin_space,
crates/ast/tests/node_space.rs::builtin_identities_do_not_collide_with_parsed_content,
crates/idl-lower/tests/annotations.rs::a_user_declared_annotation_is_kept_whole —
node_space.rs:848: assert_eq!(BUILTIN_ANNOTATIONS.len(), 31);.
Status: done — die Tabelle trägt die 24 Annotationen dieser Klausel
sowie sieben aus DDS-XTypes 1.3 §7.4.4 (non_serialized, try_construct,
topic, hashid, data_representation, ignore_literal_names,
default_nested); der Test prüft die Länge der Tabelle, nicht die
Zuordnung zu einer Gruppe.
§8.2.1 Rules for Defining Standardized Annotations
Spec: §8.2.1, S. 109 — “The annotations that are standardized here have been selected for their general purpose nature, meaning that their application can be considered in various contexts.”
Repo: crates/ast/src/model.rs::Ast::populate_builtins.
Tests: —
Status: n/a (informative) — der Absatz begründet die Auswahl; jede
Annotation wird in §8.3.x einzeln auditiert.
§8.2.2 Rules for Using Standardized Annotations
Spec: §8.2.2, S. 109–110 — vier Anforderungen an eine Spezifikation, die eine standardisierte Annotation verwendet: die Syntax der Spec respektieren, die Bedeutung präzisieren, die gültigen Elemente einschränken und das Default-Verhalten dokumentieren.
Repo: crates/idl-lower/src/annotation.rs::apply_one.
Tests: tools/idlc/tests/annotation_arguments.rs::an_unknown_annotation_is_ignored_whatever_it_is_given,
tools/idlc/tests/strict.rs::strict_does_not_refuse_an_unknown_annotation,
tools/idlc/tests/strict.rs::every_subcommand_refuses_every_vendor_extension_under_strict,
crates/idl-lower/tests/annotations.rs::every_spelling_of_one_builtin_says_the_same_thing —
annotations.rs:1001: assert!(xtypes_of_member(&ast, "S", 0).is_key, "{source:?}");.
Status: partial — kein Test prüft die vier Anforderungen des
Absatzes an eine Spezifikation, die eine standardisierte Annotation
verwendet; die zitierten Tests prüfen nur, dass unbekannte Annotationen
ignoriert werden und dass die Schreibweise zählt.
§8.3.1.1 @id Annotation
Spec: §8.3.1.1, S. 110 — “@annotation id { unsigned long value; };”;
der Wert ist ein 32-Bit-Integer.
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweig id),
crates/idl-lower/src/complete.rs::derive_repository_ids.
Tests: crates/idl-lower/tests/annotations.rs::a_declared_id_records_that_it_was_declared,
crates/idl-lower/tests/annotations.rs::an_id_that_is_not_an_integer_is_reported_rather_than_ignored,
crates/idl-lower/tests/annotations.rs::an_id_and_a_hashid_on_one_member_are_rejected,
crates/idl-lower/tests/completion.rs::a_declared_id_wins_over_the_aggregates_autoid —
completion.rs:146: assert_eq!(member_id(&ast, "S", 0), (4, MemberIdOrigin::Declared));.
Status: done
§8.3.1.2 @autoid Annotation
Spec: §8.3.1.2, S. 110 — “@annotation autoid { enum AutoidKind { SEQUENTIAL, HASH }; AutoidKind value default HASH; };”.
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweig autoid),
crates/idl-lower/src/complete.rs::member_ids.
Tests: crates/idl-lower/tests/annotations.rs::both_autoid_policies_are_distinguished,
crates/idl-lower/tests/completion.rs::autoid_sequential_and_autoid_hash_differ,
crates/idl-lower/tests/completion.rs::an_autoid_hash_member_is_skipped_the_same_way —
annotations.rs:457: assert_eq!(xtypes_of_type(&ast, "S").autoid, Some(expected), "{source}");.
Status: done
§8.3.1.3 @optional Annotation
Spec: §8.3.1.3, S. 111 — “@annotation optional { boolean value default TRUE; };”; ein optionales Member darf kein Key sein.
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweig
optional), crates/idl-lower/src/validate.rs::validate_type.
Tests: crates/idl-lower/tests/annotations.rs::the_member_flags_each_reach_their_own_field,
crates/idl-lower/tests/annotations.rs::several_annotations_on_one_member_all_apply,
crates/idl-lower/tests/validation.rs::a_key_member_must_not_be_optional —
annotations.rs:286: assert!(xtypes_of_member(&ast, "S", 1).is_optional);.
Status: done
§8.3.1.4 @position Annotation
Spec: §8.3.1.4, S. 111 — “@annotation position { unsigned short value; };”; der Wertebereich ist 0..65535, und die Position muss innerhalb
der Bitmask-Grösse liegen (§7.4.13.4.3.3).
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweig
position), crates/idl-lower/src/complete.rs::check_bitmask_bounds.
Tests: crates/idl-lower/tests/annotations.rs::an_explicit_bit_position_reaches_the_bit,
crates/idl-lower/tests/completion.rs::bit_positions_run_from_zero_and_an_explicit_one_shifts_the_rest,
crates/idl-lower/tests/validation.rs::a_bit_position_outside_the_bitmasks_size_is_refused,
crates/ast/tests/node_space.rs::a_positional_bit_and_an_explicit_position_are_distinguishable —
annotations.rs:744: assert_eq!(ast.bit_value(bits[0]).expect("A").position, Some(5));.
Status: done
§8.3.1.5 @value Annotation
Spec: §8.3.1.5, S. 111 — “@annotation value { any value; };”; der Wert
eines Enumerators wird festgeschrieben.
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweig value),
crates/ast/src/query.rs::effective_enumerator_value.
Tests: crates/idl-lower/tests/annotations.rs::an_explicit_enumerator_value_keeps_the_expression_it_was_written_as,
crates/idl-lower/tests/completion.rs::enumerators_without_values_run_from_zero_upwards,
crates/idl-lower/tests/completion.rs::an_explicit_enumerator_value_shifts_the_ones_after_it,
crates/ast/tests/node_space.rs::a_positional_enumerator_and_an_explicit_value_are_distinguishable —
completion.rs:271: assert_eq!(ast.effective_enumerator_value(enumerators[2]), Some(11));.
Status: done
§8.3.1.6 @extensibility Annotation
Spec: §8.3.1.6, S. 111–112 — “@annotation extensibility { enum ExtensibilityKind { FINAL, APPENDABLE, MUTABLE }; ExtensibilityKind value; };”.
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweig
extensibility).
Tests: crates/idl-lower/tests/annotations.rs::each_extensibility_keyword_reaches_the_facet,
crates/idl-lower/tests/annotations.rs::an_extensibility_argument_that_is_not_one_of_the_three_is_reported,
crates/idl-lower/tests/completion.rs::a_written_extensibility_is_what_the_rule_reports —
annotations.rs:229: ("@mutable struct S { long x; };", Extensibility::Mutable),.
Status: done
§8.3.1.7 @final, §8.3.1.8 @appendable, §8.3.1.9 @mutable
Spec: §8.3.1.7–§8.3.1.9, S. 112 — die drei Kurzformen sind “Shortcut for @extensibility(FINAL)” und entsprechend für APPENDABLE und MUTABLE.
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweige final,
appendable, mutable).
Tests: crates/idl-lower/tests/annotations.rs::each_extensibility_keyword_reaches_the_facet,
crates/idl-lower/tests/reported_idl.rs::an_unannotated_struct_is_appendable,
crates/idl-lower/tests/keys_and_inheritance.rs::a_derived_structure_that_repeats_its_bases_extensibility_is_accepted —
keys_and_inheritance.rs:90: assert!(found.is_empty(), "{found:?}");.
Status: done
§8.3.2.1 @key Annotation
Spec: §8.3.2.1, S. 112–113 — “@annotation key { boolean value default TRUE; };”; nur der Diskriminator einer Union darf ein Key sein.
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweig key),
crates/idl-lower/src/validate.rs::is_legal_discriminator.
Tests: crates/idl-lower/tests/annotations.rs::the_member_flags_each_reach_their_own_field,
crates/idl-lower/tests/validation.rs::key_on_its_own_is_accepted,
crates/idl-lower/tests/validation.rs::only_a_unions_discriminator_may_be_a_key,
crates/idl-lower/tests/validation.rs::a_map_cannot_be_part_of_a_key,
crates/idl-lower/tests/keys_and_inheritance.rs::a_key_written_in_a_derived_structure_is_refused,
crates/idl-lower/tests/annotations.rs::a_suffix_annotation_carries_its_arguments —
annotations.rs:285: assert!(xtypes_of_member(&ast, "S", 0).is_key);.
Status: done
§8.3.2.2 @must_understand Annotation
Spec: §8.3.2.2, S. 113 — “@annotation must_understand { boolean value default TRUE; };”.
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweig
must_understand).
Tests: crates/idl-lower/tests/annotations.rs::the_member_flags_each_reach_their_own_field.
Status: partial — das Flag erreicht das Member-Facet; die Bedeutung des
Flags (ein Middleware-Empfänger, der die Erweiterung nicht versteht, muss
die Nachricht zurückweisen) ist eine XTypes-Anforderung und wird hier nur
als Flag geprüft. Das ist der Umfang der Klausel 8.
§8.3.2.3 @default_literal Annotation
Spec: §8.3.2.3, S. 113 — “@annotation default_literal { };”; sie
markiert den Enumerator, nicht das enum.
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweig
default_literal).
Tests: crates/idl-lower/tests/annotations.rs::a_default_literal_marks_the_enumerator_and_not_the_enum —
annotations.rs:772: assert!(marked(1));.
Status: done
§8.3.3.1 @default Annotation
Spec: §8.3.3.1, S. 113–114 — “@annotation default { any value; };”.
Repo: —
Tests: —
Status: open — Code vorhanden: die Annotation steht in der Builtin-Tabelle, und der Zweig default in crates/idl-lower/src/annotation.rs::apply_one setzt XTypesFacet::default_value. Kein Test prüft dieses Feld; crates/idl-lower/tests/annotations.rs hat keinen Fall dafür, die Erhebung führt die Probe ann-8.3.3.1-default mit ok.
§8.3.3.2 @range Annotation
Spec: §8.3.3.2, S. 114 — “@annotation range { any min; any max; };”
mit der Bedingung max >= min.
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweig range),
crates/ast/src/facet/xtypes.rs::XTypesFacet.
Tests: crates/idl-lower/tests/annotations.rs::a_unit_and_a_range_reach_their_fields.
Status: partial — min/max werden gelesen und ins Facet geschrieben;
die Bedingung max >= min wird nicht geprüft und hat keinen Test.
@range(5, 1) wird akzeptiert.
§8.3.3.3 @min und §8.3.3.4 @max
Spec: §8.3.3.3 / §8.3.3.4, S. 114 — “@annotation min { any value; };” und “@annotation max { any value; };”; getrennt geschrieben
ergeben sie dieselbe Range wie @range.
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweige min
und max).
Tests: crates/idl-lower/tests/annotations.rs::min_and_max_written_separately_combine_into_one_range —
annotations.rs:712: assert!(range.max.is_some(), "the max was lost");.
Status: done
§8.3.3.5 @unit Annotation
Spec: §8.3.3.5, S. 114 — “@annotation unit { string value; };” plus
der Hinweis auf die BIPM-Abkürzungen.
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweig unit).
Tests: crates/idl-lower/tests/annotations.rs::a_unit_and_a_range_reach_their_fields —
annotations.rs:702: assert_eq!(x.unit.as_deref(), Some("m/s"));.
Status: done
§8.3.4.1 @bit_bound Annotation
Spec: §8.3.4.1, S. 115 — “@annotation bit_bound { unsigned short value; };”; der Wert darf höchstens 64 sein (§7.4.13.4.3.3), und ohne
Annotation sind es 32.
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweig
bit_bound), crates/idl-lower/src/complete.rs::check_bit_bounds.
Tests: crates/idl-lower/tests/annotations.rs::a_bit_bound_reaches_the_type,
crates/idl-lower/tests/completion.rs::an_enum_without_a_bit_bound_is_thirty_two_bits,
crates/idl-lower/tests/completion.rs::a_written_bit_bound_is_what_the_rule_reports,
crates/idl-lower/tests/validation.rs::a_bit_bound_over_sixty_four_is_refused —
annotations.rs:752: assert_eq!(xtypes_of_type(&ast, "E").bit_bound, Some(16));.
Status: done
§8.3.4.2 @external Annotation
Spec: §8.3.4.2, S. 115 — “@annotation external { boolean value default TRUE; };”. XTypes 1.3 §7.3.1.2.1.4 lässt sie auch auf einem Element
einer Collection, einem Map-Schlüssel und einem Map-Wert zu; das Front-End trägt
sie dort.
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweig
external).
Tests: crates/idl-lower/tests/annotations.rs::the_member_flags_each_reach_their_own_field,
crates/idl-lower/tests/annotations.rs::external_on_an_element_a_map_key_or_a_map_value_is_carried,
crates/idl-lower/tests/validation.rs::external_on_a_type_declaration_is_refused_by_name,
crates/idl-lower/tests/validation.rs::external_on_a_member_and_on_a_branch_is_accepted —
validation.rs:426: assert_trips(source, DiagnosticCode::InvalidAnnotation);.
Status: done
§8.3.4.3 @nested Annotation
Spec: §8.3.4.3, S. 115 — “@annotation nested { boolean value default TRUE; };”; sie wirkt transitiv auf die in einem Modul deklarierten
Typen.
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweig nested).
Tests: crates/idl-lower/tests/annotations.rs::a_nested_annotation_reaches_the_type,
crates/idl-lower/tests/annotations.rs::default_nested_on_a_module_reaches_the_types_in_it —
annotations.rs:214: assert!(ast.effective_nested(by_name("Inner")));.
Status: done
§8.3.5.1 @verbatim Annotation
Spec: §8.3.5.1, S. 116 — “@annotation verbatim { enumeration PlacementKind { BEGIN_FILE, BEFORE_DECLARATION, BEGIN_DECLARATION, END_DECLARATION, AFTER_DECLARATION, END_FILE }; string language default "\*"; PlacementKind placement default BEFORE_DECLARATION; string text; };”;
die language-Werte sind "c", "c++", "java", "idl" und "*".
Repo: crates/idl-lower/src/annotation.rs::verbatim_placement (die
sechs Placements), crates/idl-lower/src/annotation.rs::apply_one (Zweig
verbatim).
Tests: crates/idl-lower/tests/annotations.rs::a_verbatim_directive_keeps_its_language_placement_and_text,
crates/idl-lower/tests/annotations.rs::a_verbatim_directive_defaults_language_and_placement,
crates/idl-lower/tests/annotations.rs::repeated_verbatim_directives_accumulate_in_declaration_order,
crates/idl-lower/tests/annotations.rs::a_verbatim_directive_for_an_unknown_language_is_kept_as_written,
crates/idl-lower/tests/annotations.rs::an_unknown_verbatim_placement_is_reported,
tools/idlc/tests/annotation_arguments.rs::a_verbatim_directive_still_reaches_the_model_whole —
annotation_arguments.rs:175: assert_eq!(verbatim.len(), 1, "{verbatim:?}");.
Status: done
§8.3.6.1 @service Annotation
Spec: §8.3.6.1, S. 117 — “@annotation service { string platform default "\*"; };”; die Platform-Werte sind "CORBA", "DDS" und "*".
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweig
service).
Tests: crates/idl-lower/tests/annotations.rs::service_and_ami_reach_the_corba_facet —
annotations.rs:904: assert!(corba.is_service);.
Status: done
§8.3.6.2 @oneway Annotation
Spec: §8.3.6.2, S. 117 — “@annotation oneway { boolean value default TRUE; };”; “This annotation may only concern operations without
any return value (void return type) and without any out or
inout parameters.”
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweig
oneway), crates/idl-lower/src/annotation.rs::enumerated_parameter.
Tests: tools/idlc/tests/annotation_arguments.rs::a_builtin_with_an_enumerated_parameter_reads_it_without_resolving_it.
Status: partial — @oneway ist in der Builtin-Tabelle, die Erhebung
führt die Probe ann-8.3.6.2-oneway mit ok. Kein Rust-Test schreibt
@oneway in eine .idl-Zeile und prüft das Facet
(crates/ast/tests/node_space.rs::a_oneway_operation_is_flagged_and_a_normal_one_is_not
prüft die Schlüsselwort-Form, nicht die Annotation-Form). Die
Nebenspannung der Klausel — void-Rückgabetyp und keine out/inout-Parameter
— wird nirgends geprüft.
§8.3.6.3 @ami Annotation
Spec: §8.3.6.3, S. 117 — “@annotation ami { boolean value default TRUE; };”.
Repo: crates/idl-lower/src/annotation.rs::apply_one (Zweig ami).
Tests: crates/idl-lower/tests/annotations.rs::service_and_ami_reach_the_corba_facet —
annotations.rs:905: assert!(corba.is_ami);.
Status: done
§9 Profiles
§9.1 Overview
Spec: §9.1, S. 119 — “This clause defines some relevant combinations of building blocks, called profiles. Profiles are just sets of building blocks, possibly complemented with groups of annotations.”; “These profiles are not normative for the related middleware solutions.”
Repo: crates/ast/src/profile/mod.rs::Profile,
crates/ast/src/profile/verdict.rs::ALL_PROFILES.
Tests: crates/ast/tests/profile_table.rs::the_construct_table_is_total_over_profiles_and_constructs,
crates/ast/tests/profile_table.rs::the_facet_table_is_total_over_profiles_and_properties,
crates/ast/tests/resolve_profile_query.rs::every_profile_accepts_a_model_of_plain_primitives,
crates/ast/tests/resolve_profile_query.rs::a_map_is_valid_under_xtypes_and_invalid_under_corba_33.
Status: partial — die Profilmechanik existiert und ist tabellarisch
total geprüft, aber sie beschreibt andere Specificationen (XTypes13,
Corba33, Ros2, DdsXml, FlatData, Vendor). Die sieben Profile
dieser Klausel sind keine davon.
§9.2.1 Plain CORBA Profile
Spec: §9.2.1, S. 119 — das Profil besteht aus Core Data Types, Any, Interfaces – Basic, Interfaces – Full, Value Types, CORBA-Specific – Interfaces und CORBA-Specific – Value Types.
Repo: —
Tests: —
Status: open — es gibt keine Abbildung dieses Profils im Baum. Weder
Profile noch IdlFeatures (früher crates/idl/src/features/mod.rs,
heute entfernt) kennen eine solche Building-Block-Kombination; der
einzige Ort, an dem der Name des Profils vorkommt, ist die Prosa in
docs/idl-building-blocks.md.
§9.2.2 Minimum CORBA Profile
Spec: §9.2.2, S. 119–120 — “As opposed to Plain CORBA Profile, it does not embed Any nor Valuetypes.”
Repo: —
Tests: —
Status: open — wie §9.2.1; kein Symbol, kein Test.
§9.2.3 CCM Profile
Spec: §9.2.3, S. 120 — das Profil ergänzt Components – Basic und CCM-Specific um die sieben CORBA-Bausteine.
Repo: crates/idl-parse/src/dialect.rs,
crates/idl-lower/src/lower.rs::interface_bases (die supports- und
Komponenten-Zweige).
Tests: crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/idl-lower/tests/dialects.rs::each_port_form_reaches_its_own_component_role,
crates/idl-lower/tests/dialects.rs::a_home_records_what_it_manages_and_the_key_it_does_so_by.
Status: partial — die Bausteine des Profils sind einzeln erkannt und
getestet. Das Profil selbst — eine benannte, schaltbare Kombination — gibt
es nicht; es gibt keinen Mechanismus, der die Bausteine gemeinsam an- und
abschaltet.
§9.2.4 CCM with Generic Interaction Support Profile
Spec: §9.2.4, S. 120 — dieses Profil ergänzt Components – Ports and Connectors und Template Modules um das CCM-Profil.
Repo: crates/idl-lower/src/lower.rs::port,
crates/idl-lower/src/lower.rs::template_module_inst.
Tests: crates/idl-lower/tests/dialects.rs::each_component_form_reaches_its_own_interface_kind,
crates/idl-lower/tests/dialects.rs::a_template_modules_parameters_reach_its_facet.
Status: partial — beide zusätzlichen Bausteine sind implementiert und
getestet; die words GIS und Generic Interaction Support kommen im
Frontend nicht vor. Wie bei §9.2.3 gibt es keinen Profilschalter.
§9.3.1 Plain DDS Profile
Spec: §9.3.1, S. 121 — “It is made of: Building Block Core Data Types; Building Block Anonymous Types.”
Repo: —
Tests: —
Status: open — kein Profil mit dieser Zusammensetzung (crates/idl-parse/src/dialect.rs). Die Anonymous Types sind nicht getestet (§7.4.14.3), und es gibt keine Prüfung, die die beiden Bausteine zusammen von einem CORBA-Frontend unterscheidet.
§9.3.2 Extensible DDS Profile
Spec: §9.3.2, S. 121 — dieses Profil ergänzt Extended Data-Types, Anonymous Types, Annotations und die vier Annotations-Gruppen.
Repo: crates/ast/src/profile/mod.rs::Profile,
crates/idl-lower/src/annotation.rs::apply_one.
Tests: crates/ast/tests/resolve_profile_query.rs::a_map_is_valid_under_xtypes_and_invalid_under_corba_33,
crates/idl-lower/tests/conformance.rs::the_xtypes_specifications_own_idl_lowers_completely.
Status: partial — der XTypes-Anteil des Profils ist als
Profile::XTypes13 modelliert und tabellarisch geprüft; die vier
Annotations-Gruppen dieser Klausel (General Purpose, Data Modeling, Data
Implementation, Code Generation) existieren als solche nicht, die
Annotationen sind eine flache Builtin-Tabelle (§8.1).
§9.3.3 RPC over DDS Profile
Spec: §9.3.3, S. 121 — das Profil ergänzt Interfaces – Basic und die Gruppe der Interfaces-Annotationen.
Repo: crates/lang-rules/src/adapter/interface.rs::Service::is_remote,
crates/lang-rules/src/generate.rs::COMPLETE_DECLARATIONS_LANGUAGES.
Tests: crates/lang-rules/tests/interface_bindings.rs::the_seam_reads_every_part_of_an_interface,
crates/lang-rules/tests/inherited_operations.rs::every_incomplete_language_refuses_rather_than_flattens_or_drops,
crates/lang-rules/tests/inherited_operations.rs::c_python_and_node_now_refuse_instead_of_silently_answering_empty.
Status: partial — die Binding-Regel für Interfaces ist implementiert
und getestet, einschliesslich der Liste der Sprachen, die sie nicht
vollständig abbilden können. Das Profil als schaltbare Bausteinmenge gibt
es nicht.
Annex A: Consolidated IDL Grammar
Annex A Konsolidierte Grammatik (227 Produktionen)
Spec: Annex A, S. 123–132 — “This annex gathers all the rules from all the building blocks”; die Produktionen (1)–(227) sind durchnummeriert.
Repo: crates/idl-parse/src/decl.rs, crates/idl-parse/src/type_spec.rs,
crates/idl-parse/src/parser.rs, tools/idl-4.2-gap-scan/cases.tsv.
Tests: crates/idl-lower/tests/idl_4_2_grammar.rs::adjacent_string_literals_are_one_literal,
crates/idl-lower/tests/idl_4_2_grammar.rs::a_struct_defined_inside_a_typedef_is_declared_and_aliased,
crates/idl-lower/tests/idl_4_2_grammar.rs::every_constructed_form_can_be_defined_inside_a_typedef,
crates/idl-lower/tests/idl_4_2_grammar.rs::typeprefix_and_import_inside_an_interface_body_parse,
crates/idl-lower/tests/conformance.rs::every_fixture_round_trips_byte_for_byte,
crates/idl-lower/tests/conformance.rs::every_fixture_survives_a_snapshot_round_trip,
tools/idlc/tests/idl_4_2_gaps.rs::every_idl_4_2_section_d_fixture_passes_check_and_both_backends.
Status: partial — Annex A ist in tools/idl-4.2-gap-scan/cases.tsv
enumerate und die Sollwerte in expected.tsv festgeschrieben, nicht in
einem Rust-Test: 161 der 227 Produktionen tragen eine Probe, 66 keine.
Die Messung dieser Zeilen steht in idl-4.2.gaps.md;
der Werkzeuglauf ist tools/idl-4.2-gap-scan/scan.sh.
Audit-Status
130 done / 35 partial / 17 open / 1 blocked / 7 n/a (informative).
Offene Punkte: idl-4.2.open.md.