-
Notifications
You must be signed in to change notification settings - Fork 351
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
base: release-7.x
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,9 @@ internal class CsdlSemanticsTerm : CsdlSemanticsElement, IEdmTerm, IEdmFullNamed | |
|
||
private readonly Cache<CsdlSemanticsTerm, IEdmTypeReference> typeCache = new Cache<CsdlSemanticsTerm, IEdmTypeReference>(); | ||
private static readonly Func<CsdlSemanticsTerm, IEdmTypeReference> ComputeTypeFunc = (me) => me.ComputeType(); | ||
private readonly Cache<CsdlSemanticsTerm, IEdmTerm> baseTermCache = new Cache<CsdlSemanticsTerm, IEdmTerm>(); | ||
private static readonly Func<CsdlSemanticsTerm, IEdmTerm> ComputeBaseTermFunc = (me) => me.ComputeBaseTerm(); | ||
private static readonly Func<CsdlSemanticsTerm, IEdmTerm> OnCycleBaseTermFunc = (me) => new CyclicTerm(me.GetCyclicBaseTermName(me.term.BaseTermName), me.Location); | ||
|
||
public CsdlSemanticsTerm(CsdlSemanticsSchema context, CsdlTerm valueTerm) | ||
: base(valueTerm) | ||
|
@@ -61,6 +64,11 @@ public IEdmTypeReference Type | |
get { return this.typeCache.GetValue(this, ComputeTypeFunc, null); } | ||
} | ||
|
||
public IEdmTerm BaseTerm | ||
{ | ||
get { return this.baseTermCache.GetValue(this, ComputeBaseTermFunc, OnCycleBaseTermFunc); } | ||
} | ||
|
||
public string AppliesTo | ||
{ | ||
get { return this.term.AppliesTo; } | ||
|
@@ -90,5 +98,31 @@ private IEdmTypeReference ComputeType() | |
{ | ||
return CsdlSemanticsModel.WrapTypeReference(this.Context, this.term.Type); | ||
} | ||
|
||
private IEdmTerm ComputeBaseTerm() | ||
{ | ||
if (this.term.BaseTermName != null) | ||
{ | ||
IEdmTerm baseTerm = this.Context.FindTerm(this.term.BaseTermName); | ||
if (baseTerm != null) | ||
{ | ||
// 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; | ||
} | ||
|
||
return baseTerm ?? new UnresolvedVocabularyTerm(this.term.BaseTermName); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
// Resolves the real name of the base term, in case it was using an alias before. | ||
protected string GetCyclicBaseTermName(string baseTermName) | ||
{ | ||
IEdmTerm schemaBaseTerm = this.Context.FindTerm(baseTermName); | ||
return (schemaBaseTerm != null) ? schemaBaseTerm.FullName() : baseTermName; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. super nit: I prefer the null propagation syntax here: |
||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
//--------------------------------------------------------------------- | ||
// <copyright file="CyclicTerm.cs" company="Microsoft"> | ||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. | ||
// </copyright> | ||
//--------------------------------------------------------------------- | ||
|
||
using Microsoft.OData.Edm.Validation; | ||
using Microsoft.OData.Edm.Vocabularies; | ||
|
||
namespace Microsoft.OData.Edm | ||
{ | ||
/// <summary> | ||
/// Represents an EDM term that cannot be determined due to a cyclic reference. | ||
/// </summary> | ||
internal class CyclicTerm : BadTerm | ||
{ | ||
public CyclicTerm(string qualifiedName, EdmLocation location) | ||
: base(qualifiedName, new EdmError[] { new EdmError(location, EdmErrorCode.BadCyclicTerm, Edm.Strings.Bad_CyclicTerm(qualifiedName)) }) | ||
{ | ||
} | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Add newline |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1383,6 +1383,11 @@ public enum EdmErrorCode | |
/// </summary> | ||
AnnotationApplyToNotAllowedAnnotatable = 400, | ||
|
||
/// <summary> | ||
/// This ter, type is part of a cycle. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix docstring |
||
/// </summary> | ||
BadCyclicTerm, | ||
|
||
/// <summary> | ||
/// Invalid $Key value. | ||
/// </summary> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar, but does this mean that we expect
baseTerm.BaseTerm
to throw or something if there is a cycle?