You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Data Model Annex declares an enumeration data type by giving a data classifier Data_Model::Data_Representation => Enum together with Data_Model::Enumerators => ("A", "B"). An enumerator is a StringLiteral inside that property association, not a declared EnumerationLiteral in any AADL namespace, so the Behavior Annex can only name it through the AS5506/3 Rev A D.7 property_reference alternative that writes a prefix before #. value_constant has no enumeration-literal alternative, so a bare enumerator name is not legal BA and is correctly rejected; the prefixed property reference is the only standard-legal form.
That form does not work, and it fails silently.
DeclarativeToStrictTranslator.toPropertyReference resolves the property definition with resolveQualified, then resolves each NamedPropertyField against that definition with resolvePropertyField. For Data_Model::Enumerators the definition is a Property whose type is list of aadlstring, so field resolution walks BasicProperty to the ListType and finds no named child. The prefix's own property association — the one that actually carries ("A", "B") — is never consulted, because that fallback only runs when resolveQualified fails to find the property definition. The field holder is therefore built with a null element.
Nothing reports that. AadlBaTypeChecker.checkResolvedModel only inspects ElementHolder, and PropertyElementHolder extends BehaviorElement, IndexableElement rather than ElementHolder, so the null element is invisible to the resolution check and checkResolvedTypes proceeds. AadlBaUtils.getDataRepresentation(PropertyReference) then dereferences the null element and throws:
java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "element" is null
at org.osate.ba.utils.AadlBaUtils.getDataRepresentation(AadlBaUtils.java:321)
at org.osate.ba.utils.AadlBaUtils.getDataRepresentation(AadlBaUtils.java:367)
at org.osate.ba.utils.AadlBaUtils.getDataRepresentation(AadlBaUtils.java:468)
at org.osate.ba.utils.AadlBaUtils.getTypeHolder(AadlBaUtils.java:922)
at org.osate.ba.utils.AadlBaUtils.getTypeHolder(AadlBaUtils.java:1036)
at org.osate.ba.analyzers.AadlBaTypeChecker.getType(AadlBaTypeChecker.java:536)
at org.osate.ba.analyzers.AadlBaTypeChecker.checkFactor(AadlBaTypeChecker.java:513)
...
at org.osate.ba.analyzers.AadlBaTypeChecker.checkResolvedTypes(AadlBaTypeChecker.java:143)
at org.osate.xtext.aadl2.ba.validation.BehaviorAnnexValidator.checkBehaviorAnnex(BehaviorAnnexValidator.java:204)
AadlBaTypeChecker.getType catches only DimensionException and UnsupportedOperationException, so the NullPointerException escapes checkResolvedTypes, aborting the remaining strict checkers for that annex. Xtext swallows it. The net effect is that a reference to an enumerator, a reference to an enumerator that does not exist, and every later diagnostic in the same annex are all reported as nothing at all.
Even if the field resolved, the type would be wrong. A StringLiteral is a PropertyExpression, so getDataRepresentation(PropertyReference) would classify the enumerator as STRING, which does not conform to the ENUM representation of the data classifier that declares it. AadlBaUtils.toDataModelEnumLiteral and DataModelEnumLiteral exist for exactly this pairing of classifier and string literal, and both currently have no callers.
Reproduction
The model has no unrelated AADL errors and no unresolved core references.
package EnumProbe
public
with Data_Model;
data direction_type
properties
Data_Model::Data_Representation => Enum;
Data_Model::Enumerators => ("Opening", "Closing");
end direction_type;
data int_type
properties
Data_Model::Data_Representation => Integer;
end int_type;
data bool_type
properties
Data_Model::Data_Representation => Boolean;
end bool_type;
abstract host
end host;
abstract implementation host.impl
subcomponents
state_value: data direction_type;
int_value: data int_type;
bool_value: data bool_type;
annex behavior_specification {**
states
start: initial state;
done: final state;
transitions
canary: start -[]-> done {
int_value := bool_value
};
enumerator: start -[]-> done {
state_value := direction_type#Data_Model::Enumerators.Opening
};
absent: start -[]-> done {
state_value := direction_type#Data_Model::Enumerators.NotAnEnumerator
};
numeric: start -[]-> done {
int_value := direction_type#Data_Model::Enumerators.Opening + 1
};
**};
end host.impl;
end EnumProbe;
Validating this reports exactly one diagnostic, on the canary transition:
ERROR | [bool_value] | type error for 'assignment', 'EnumProbe::int_type' expected, found 'EnumProbe::bool_type'.
The canary transition proves the type checker runs and works. The three transitions after it report nothing:
enumerator is the standard-legal form and should be accepted, but is accepted only because validation has already been aborted.
absent names an enumerator that is not in the Enumerators list and must be rejected.
numeric uses an enumeration value where the operator requires a numeric type and must be rejected.
Removing the canary transition leaves the annex with no diagnostics at all.
Expected behavior
direction_type#Data_Model::Enumerators.Opening resolves to the StringLiteral for "Opening" in the Enumerators association of direction_type, and types as the ENUM representation of direction_type, so assigning it to a direction_type value is accepted and assigning it to a value of a different enumeration data type is rejected.
direction_type#Data_Model::Enumerators.NotAnEnumerator is reported, because the name is not an element of the Enumerators list.
Using an enumeration value as an operand of an arithmetic operator is reported.
No NullPointerException escapes the strict checkers, and diagnostics that follow an unresolvable property field in the same annex are still reported. This applies to any unresolvable property field, not only an enumerator.
ba/org.osate.xtext.aadl2.ba/src/org/osate/xtext/aadl2/ba/translation/DeclarativeToStrictTranslator.java — toPropertyReference chooses primaryElement and walks fields; resolvePropertyField(Element, String) and resolvePropertyField(EObject, String) never see the prefix's property association when the property definition resolves.
ba/org.osate.ba/src/org/osate/ba/utils/AadlBaUtils.java — getDataRepresentation(PropertyReference) dereferences a null holder element and has no case for a Data Model Annex enumerator; getTypeHolder(Value, ComponentClassifier) sets no classifier for a ValueConstant; toDataModelEnumLiteral and DataModelEnumLiteral are unused.
ba/org.osate.ba/src/org/osate/ba/analyzers/AadlBaTypeChecker.java — checkResolvedModel inspects only ElementHolder, so a PropertyElementHolder with a null element does not stop checkResolvedTypes; getType does not catch NullPointerException.
ba/org.osate.ba/src/org/osate/ba/analyzers/AdaLikeDataTypeChecker.java — conformsTo relates neither ENUM to ENUM_LITERAL nor STRING to ENUM.
Summary
The Data Model Annex declares an enumeration data type by giving a data classifier
Data_Model::Data_Representation => Enumtogether withData_Model::Enumerators => ("A", "B"). An enumerator is aStringLiteralinside that property association, not a declaredEnumerationLiteralin any AADL namespace, so the Behavior Annex can only name it through the AS5506/3 Rev A D.7property_referencealternative that writes a prefix before#.value_constanthas no enumeration-literal alternative, so a bare enumerator name is not legal BA and is correctly rejected; the prefixed property reference is the only standard-legal form.That form does not work, and it fails silently.
DeclarativeToStrictTranslator.toPropertyReferenceresolves the property definition withresolveQualified, then resolves eachNamedPropertyFieldagainst that definition withresolvePropertyField. ForData_Model::Enumeratorsthe definition is aPropertywhose type islist of aadlstring, so field resolution walksBasicPropertyto theListTypeand finds no named child. The prefix's own property association — the one that actually carries("A", "B")— is never consulted, because that fallback only runs whenresolveQualifiedfails to find the property definition. The field holder is therefore built with anullelement.Nothing reports that.
AadlBaTypeChecker.checkResolvedModelonly inspectsElementHolder, andPropertyElementHolderextendsBehaviorElement, IndexableElementrather thanElementHolder, so the null element is invisible to the resolution check andcheckResolvedTypesproceeds.AadlBaUtils.getDataRepresentation(PropertyReference)then dereferences the null element and throws:AadlBaTypeChecker.getTypecatches onlyDimensionExceptionandUnsupportedOperationException, so theNullPointerExceptionescapescheckResolvedTypes, aborting the remaining strict checkers for that annex. Xtext swallows it. The net effect is that a reference to an enumerator, a reference to an enumerator that does not exist, and every later diagnostic in the same annex are all reported as nothing at all.Even if the field resolved, the type would be wrong. A
StringLiteralis aPropertyExpression, sogetDataRepresentation(PropertyReference)would classify the enumerator asSTRING, which does not conform to theENUMrepresentation of the data classifier that declares it.AadlBaUtils.toDataModelEnumLiteralandDataModelEnumLiteralexist for exactly this pairing of classifier and string literal, and both currently have no callers.Reproduction
The model has no unrelated AADL errors and no unresolved core references.
Validating this reports exactly one diagnostic, on the
canarytransition:The
canarytransition proves the type checker runs and works. The three transitions after it report nothing:enumeratoris the standard-legal form and should be accepted, but is accepted only because validation has already been aborted.absentnames an enumerator that is not in theEnumeratorslist and must be rejected.numericuses an enumeration value where the operator requires a numeric type and must be rejected.Removing the
canarytransition leaves the annex with no diagnostics at all.Expected behavior
direction_type#Data_Model::Enumerators.Openingresolves to theStringLiteralfor"Opening"in theEnumeratorsassociation ofdirection_type, and types as theENUMrepresentation ofdirection_type, so assigning it to adirection_typevalue is accepted and assigning it to a value of a different enumeration data type is rejected.direction_type#Data_Model::Enumerators.NotAnEnumeratoris reported, because the name is not an element of theEnumeratorslist.NullPointerExceptionescapes the strict checkers, and diagnostics that follow an unresolvable property field in the same annex are still reported. This applies to any unresolvable property field, not only an enumerator.Propertydefinition rather than a declaratively selectedPropertyAssociation, preserving Keep prefixed Behavior Annex property references symbolic for instance lookup 🤖 #3222.Relevant code
ba/org.osate.xtext.aadl2.ba/src/org/osate/xtext/aadl2/ba/translation/DeclarativeToStrictTranslator.java—toPropertyReferencechoosesprimaryElementand walksfields;resolvePropertyField(Element, String)andresolvePropertyField(EObject, String)never see the prefix's property association when the property definition resolves.ba/org.osate.ba/src/org/osate/ba/utils/AadlBaUtils.java—getDataRepresentation(PropertyReference)dereferences a null holder element and has no case for a Data Model Annex enumerator;getTypeHolder(Value, ComponentClassifier)sets no classifier for aValueConstant;toDataModelEnumLiteralandDataModelEnumLiteralare unused.ba/org.osate.ba/src/org/osate/ba/analyzers/AadlBaTypeChecker.java—checkResolvedModelinspects onlyElementHolder, so aPropertyElementHolderwith a null element does not stopcheckResolvedTypes;getTypedoes not catchNullPointerException.ba/org.osate.ba/src/org/osate/ba/analyzers/AdaLikeDataTypeChecker.java—conformsTorelates neitherENUMtoENUM_LITERALnorSTRINGtoENUM.