Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable Base term for IEdmTerm #1962

Draft
wants to merge 2 commits into
base: release-7.x
Choose a base branch
from
Draft

Enable Base term for IEdmTerm #1962

wants to merge 2 commits into from

Conversation

xuzhg
Copy link
Member

@xuzhg xuzhg commented Dec 17, 2020

Issues

This pull request fixes issue #1955. & #1816

Description

*14.1.1 Specialized Term

A term MAY specialize another term in scope by specifying it as its base type.

When applying a term with a base term, the base term MUST also be applied with the same qualifier, and so on until a term without a base term is reached.

Attribute BaseTerm

The value of BaseTerm is the qualified name of the base term.

This PR is to enable the base term.

Checklist (Uncheck if it is not completed)

  • Test cases added
  • Build and test with one-click build and test script passed

Additional work necessary

If documentation update is needed, please add "Docs Needed" label to the issue and provide details about the required document change in the issue.

[Fact]
public void ParseCsdlTermWithMembersWorksAsExpected()
public void ParseCsdlTermWithBaseTermAndMembersWorksAsExpected()
Copy link
Member

@mikepizzo mikepizzo Dec 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ParseCsdlTermWithBaseTermAndMembersWorksAsExpected [](start = 20, length = 50)

Can you also add some XML test variants of reading/writing terms with base values? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no related test cases to test part of an XML Element.

I added a whole write test cases to cover it.


In reply to: 545398235 [](ancestors = 545398235)

@@ -815,6 +815,34 @@ public void VerifyTermWrittenCorrectly()
}");
}

[Fact]
public void VerifyTermWithBaseTermWrittenCorrectly()
Copy link
Member

@mikepizzo mikepizzo Dec 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VerifyTermWithBaseTermWrittenCorrectly [](start = 20, length = 38)

Please add XML Variation as well. #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Do you mean "Line 827 - 828"


In reply to: 545398455 [](ancestors = 545398455)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes; missed that -- thanks.


In reply to: 545399808 [](ancestors = 545399808,545398455)

/// <summary>
/// Gets the base term of this term.
/// </summary>
IEdmTerm BaseTerm { get; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is my only real concern with the PR. We need to convince ourselves that we are the only ones implementing this interface, as anyone else providign a custom implementation will break when they update to the new library and have to modify their code to implement this property.

The fallback would be to define an IEdmTermWithBase : IEdmTerm, but that would require logic each place we consume IEdmTerm that we care about base to handle base as well, if the instance of IEdmTerm can be cast to IEdmTermWithBase. We could add IEdmTermWithBase in 7.9 and clean it up in 8.0, or we can convince ourselves that there aren't any custom implementations of IEdmTerm that we would break.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's also my concern. However, i have the following two reasons:

  1. To add new into a public interface is less "harmful" than to remove or to change element in the public interface.
  2. I can't find any reason why there's a customer who need to implement this interface.

In reply to: 545401071 [](ancestors = 545401071)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'm understand the high-level concern but missing the specifics for our case. Could we not have this property be of type BaseTerm : IEdmTerm that has an internal constructor so we have full control over the behavior?

@mikepizzo
Copy link
Member

What are the ramifications of introducing a base Term? Do consumers of the API need to do anything different?

i.e., for structured types, a base type implies that all of the properties of the base type are available on the derived type. a client that looks only at the declared properties of the derived type will miss the properties inherited from the base type.

Are there similar ramifications for consumers of a derived term?

@mikepizzo
Copy link
Member

public interface IEdmTerm : IEdmSchemaElement

Need to update public api


Refers to: src/Microsoft.OData.Edm/Vocabularies/Annotations/IEdmTerm.cs:12 in 22945d8. [](commit_id = 22945d8, deletion_comment = False)

@xuzhg
Copy link
Member Author

xuzhg commented Dec 17, 2020

Quick answer is that" It's the same usage of "Base type" and "Base Term".

When we create the annotation, we can create the PropertyValue for the "Property" defined in the base term.
However, OData.Edm lib doesn't have the process to verify that "PropertyName" of the Record is defined or not.
Let me add a test case to cover it.


In reply to: 747701313 [](ancestors = 747701313)

@@ -1383,6 +1383,11 @@ public enum EdmErrorCode
/// </summary>
AnnotationApplyToNotAllowedAnnotatable = 400,

/// <summary>
/// This ter, type is part of a cycle.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix docstring

{
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Add newline

@@ -7742,21 +7756,6 @@ public abstract class Microsoft.OData.Client.OperationResponse {
int StatusCode { public get; }
}

[
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is from a merged PR. Have you rebased your branch?

@@ -7774,21 +7788,6 @@ public abstract class Microsoft.OData.Client.OperationResponse {
int StatusCode { public get; }
}

[
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is from a merged PR. Have you rebased your branch?

@@ -3080,6 +3080,7 @@ public enum Microsoft.OData.Edm.Validation.EdmErrorCode : int {
BadCyclicComplex = 227
BadCyclicEntity = 229
BadCyclicEntityContainer = 228
BadCyclicTerm = 401
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assigning value of 401 seems to have affected other enum values. Is that okay?

// Evaluate the inductive step to detect cycles.
// Overriding BaseTerm getter from concrete type implementing IEdmTerm will be invoked to
// detect cycles. The object assignment is required by compiler only.
IEdmTerm baseTerm2 = baseTerm.BaseTerm;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar, but does this mean that we expect baseTerm.BaseTerm to throw or something if there is a cycle?

protected string GetCyclicBaseTermName(string baseTermName)
{
IEdmTerm schemaBaseTerm = this.Context.FindTerm(baseTermName);
return (schemaBaseTerm != null) ? schemaBaseTerm.FullName() : baseTermName;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super nit: I prefer the null propagation syntax here: return schemaBaseTerm?.FullName() ?? baseTermName

@xuzhg xuzhg marked this pull request as draft January 4, 2022 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants