Skip to content

Conversation

@seidewitz
Copy link
Member

This PR fixes a bug that could case inconsistent name resolution for a qualified name used as the target of a nested redefinition. It also revises the name resolution cases affected by the bug fix, so that the resolution that resulted from the bug actually becomes the expected resolution.

(This PR is an alternative to PR #714. The "Background" and "Cause" sections below are the same as in the other PR.)

Background

Consider the following SysML model:

item def A {
    item x { 
        attribute y;
    }
}

item def B :> A {
	item x :>> x {
		attribute :>> x::y;
	}
}

When a file with this model is initially opened in the Eclipse Xtext editor, and the attribute usage nested in B::x (commented) is viewed in the outline, the target x::y of the redefinition is shown as resolving to the attribute usage itself (that is B::x::y). Previously, however, if a space was typed so that the model was re-parsed and validated, the outline then showed that the target of the redefinition had resolved instead to the attribute usage A::x::y. On the other hand, if the model is entered in Jupyter, the attribute usage in question generates the error “Featuring types of redefining feature and redefined feature cannot be the same”, indicating that x::y has resolved to B::x::y, making the redefinition invalid.

Cause

  • When the model is opened in the Xtext editor, no validation is done initially. To be viewed in the outline, however, the qualified name x::y has to be resolved as the target of a redefinition.
    • The name resolution algorithm initially resolves x::y to A::x::y, which determines that the effective name of the redefining attribute is y.
    • But this means that, in the scope of B (the parent of B::x), x::y then resolves to B::x::y, and the resolution is updated to this element (i.e., the redefining attribute usage itself).
    • This is also what happens in the Jupyter deployment, but, in the environment, validation is also carried out, resulting in the error message.
  • In the Xtext editor (but not in Jupyter), after a change to the model text, the text is re-parsed, and then Xtext performs reconcilation and resolves all cross-reference proxies.
    • In the case of a Redefinition relationship, it checks the general Relationship::target value before the Redefinition::redefinedFeature value.
    • The source and target for any kind of Specialization are lists containing the single values of the specific and general properties of the Specialization, respectively. The getSource and getTarget methods in SpecializationImpl implement this by creating a list and then inserting the specific or general values into the list.
    • In the generated code for these methods, the getSpecific and getGeneral methods are used, which will resolve proxies if necessary, so the returned lists never contain (resolvable) proxies. However, Previously, these calls had been replaced by calls to basicGetSpecific and basicGetGeneral, which do not do proxy resolution.
    • So, when the target of the Redefinition was found to be a proxy, Xtext resolved the proxy and then updated the target list with the resolved element. However, since the list was created in the getTarget method, this did not result in the redefinedFeature property value actually being updated for the Redefinition, so the value was left as the earlier resolution to A::x::y.

Changes

  1. SpecializationImpl.java – Replaced the non-generated versions of getSource and getTarget with the generated versions. (A comment in the code indicated that the changes had been made to these methods to prevent circular name resolution. However, testing indicated that the generated version without the changes no longer caused circular resolution errors.)
    • This change alone resolves the bug, so, in the example model above, x::y would always resolve to B::x::y. However, this resolution is not particularly useful, since it always results in an error, requiring additional qualification to resolve to A::x::y. It would be more intuitive for the name resolution of x::y in the example be consistently to A::x::y rather than B::x::y. The changes below achieve this.
  2. KerMLScope.xtend – Updated the owned method so that an owned membership of a namespace is skipped if the owned member element is the owning feature of a redefinition relationship that is being skipped.
    • In the above example, this means that the usage attribute :>> x::y; is skipped when considering the resolution of x::y. So, y is not considered to be redefined during this resolution process, and the segment y of the qualified name resolves to the feature y inherited from A::x. As a result, x::y resolves to A::x::y, as desired.
  3. KerMLScopeProvider.xtend – Updated so that the first feature name in a feature chain that is a target of a redefinition is resolved in the same way as regular feature name that is the target of a redefinition.
  4. TypeUtil.java – Updated method getFeaturesRedefinedBy so that it is passed an owned feature to skip when collecting redefined features from the owned features of a given type.
  5. FeatureUtil.java, FeatureAdapter.java – Updated the methods FeatureUtil::getRedefinedFeaturesWithComputedOf and FeaturAdapter::getRedefinedFeaturesWithComputed so that they are no longer passed a skip argument.
  6. ConstructorExpressionAdapter.java – Revised the adding of the implied result type to the result parameter of a constructor expression so that it is added immediately when the result parameter is added.
  7. Redefinition_Scoping.kerml.xt – Added a KerML Xpect test using a KerML version of the above example model, to check that the nested redefinition is parsed and validates without error.

- Nested redefinition case is expected to succeed.
Skip the redefining feature entirely when resolving its redefined
feature name.
Use owningRelationship of featureChained, rather than FeatureChaining.
Updated checkConstructorExpressionResultSpecialization in
ConstructorExpressionAdapter.
@seidewitz seidewitz added this to the 2025-11 milestone Nov 19, 2025
@seidewitz seidewitz self-assigned this Nov 19, 2025
@seidewitz seidewitz added the bug Something isn't working label Nov 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants