Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ protected override FormattableString BuildDescription()
private List<PropertyProvider>? _additionalPropertyProperties;
private ModelProvider? _baseModelProvider;
private ConstructorProvider? _fullConstructor;
private (string Name, string Namespace)? _fullConstructorIdentity;
internal PropertyProvider? DiscriminatorProperty { get; private set; }

private readonly bool _isDiscriminatedBaseType;
Expand Down Expand Up @@ -189,11 +188,15 @@ public override void Reset()
_rawDataField = null;
_additionalPropertyFields = null;
_additionalPropertyProperties = null;
_fullConstructor = null;
_fullConstructorIdentity = null;
_isMultiLevelDiscriminator = null;
}

private protected override void ResetConstructors()
{
base.ResetConstructors();
_fullConstructor = null;
}
Comment thread
JoshLove-msft marked this conversation as resolved.

protected FieldProvider? RawDataField
{
get
Expand Down Expand Up @@ -235,26 +238,7 @@ protected FieldProvider? RawDataField
/// <summary>
/// The constructor that takes every serializable property.
/// </summary>
/// <remarks>
/// This instance is also returned as part of <see cref="TypeProvider.Constructors"/>, and callers are free to
/// mutate the constructors they receive. An identity change invalidates the constructor list, so the cached
/// instance is rebuilt alongside it; otherwise a rebuild would reuse the same instance and re-apply any
/// mutation, producing duplicated members.
/// </remarks>
public ConstructorProvider FullConstructor
{
get
{
var identity = (Type.Name, Type.Namespace);
if (_fullConstructor is null || _fullConstructorIdentity != identity)
{
_fullConstructor = BuildFullConstructor();
_fullConstructorIdentity = identity;
}

return _fullConstructor;
}
}
public ConstructorProvider FullConstructor => _fullConstructor ??= BuildFullConstructor();

protected override string BuildNamespace() => string.IsNullOrEmpty(_inputModel.Namespace) ?
// TODO remove null check once https://github.com/Azure/typespec-azure/issues/2209 is fixed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ public virtual void Reset()
_methods = null;
_properties = null;
_fields = null;
_constructors = null;
ResetConstructors();
_implements = null;
_serializationProviders = null;
_nestedTypes = null;
Expand All @@ -712,6 +712,11 @@ public virtual void Reset()
_arguments = null;
}

private protected virtual void ResetConstructors()
{
_constructors = null;
}
Comment thread
JoshLove-msft marked this conversation as resolved.

/// <summary>
/// Updates the type provider with new values for its properties, methods, constructors, etc.
/// </summary>
Expand Down Expand Up @@ -830,7 +835,7 @@ private void ResetMembersBasedOnIdentityChange(string? name = null, string? @nam
// recalculate declaration modifiers and constructors
_declarationModifiers = null;
// constructors might change based on declaration modifier changes
_constructors = null;
ResetConstructors();
// serialization providers need to reflect the new type name/namespace
_serializationProviders = null;
Type.Update(name: name, @namespace: @namespace);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2385,6 +2385,13 @@ public void TestUpdate_ResetsFullConstructor()
var newerFullConstructor = modelProvider.FullConstructor;
Assert.AreNotSame(newFullConstructor, newerFullConstructor);
Assert.IsTrue(modelProvider.Constructors.Contains(newerFullConstructor));

// Re-applying the current identity also invalidates the constructor list because
// customization metadata and declaration modifiers may have changed.
modelProvider.Update(name: modelProvider.Name);
var sameIdentityFullConstructor = modelProvider.FullConstructor;
Assert.AreNotSame(newerFullConstructor, sameIdentityFullConstructor);
Assert.IsTrue(modelProvider.Constructors.Contains(sameIdentityFullConstructor));
}

// Regression coverage for the duplication that the stale FullConstructor caused: a generator that
Expand All @@ -2404,6 +2411,11 @@ public void TestUpdate_DoesNotReapplyConstructorMutationsAfterIdentityChange()
_ = modelProvider.Constructors;

Assert.AreEqual(1, modelProvider.FullConstructor.Suppressions.Count);

modelProvider.Update(name: modelProvider.Name);
_ = modelProvider.Constructors;

Assert.AreEqual(1, modelProvider.FullConstructor.Suppressions.Count);
}

// Mimics how ScmModelProvider post-processes the constructors returned from the base implementation.
Expand Down
Loading