Skip to content

Commit

Permalink
Scaffolding: Annotate NRTs
Browse files Browse the repository at this point in the history
Part of #19007
  • Loading branch information
bricelam committed Mar 2, 2021
1 parent 2eabf1f commit 2de4fe1
Show file tree
Hide file tree
Showing 43 changed files with 190 additions and 90 deletions.
35 changes: 19 additions & 16 deletions src/EFCore.Relational/Design/AnnotationCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Utilities;
using NotNullWhenAttribute = System.Diagnostics.CodeAnalysis.NotNullWhenAttribute;

#nullable enable
#pragma warning disable EF1001 // Accessing annotation names (internal)

namespace Microsoft.EntityFrameworkCore.Design
Expand Down Expand Up @@ -144,21 +146,21 @@ public virtual IReadOnlyList<MethodCallCodeFragment> GenerateFluentApiCalls(
annotations,
RelationalAnnotationNames.ColumnName, nameof(RelationalPropertyBuilderExtensions.HasColumnName), methodCallCodeFragments);

if (TryGetAndRemove(annotations, RelationalAnnotationNames.DefaultValueSql, out string defaultValueSql))
if (TryGetAndRemove(annotations, RelationalAnnotationNames.DefaultValueSql, out string? defaultValueSql))
{
methodCallCodeFragments.Add(
defaultValueSql?.Length == 0
defaultValueSql.Length == 0
? new MethodCallCodeFragment(
nameof(RelationalPropertyBuilderExtensions.HasDefaultValueSql))
: new MethodCallCodeFragment(
nameof(RelationalPropertyBuilderExtensions.HasDefaultValueSql),
defaultValueSql));
}

if (TryGetAndRemove(annotations, RelationalAnnotationNames.ComputedColumnSql, out string computedColumnSql))
if (TryGetAndRemove(annotations, RelationalAnnotationNames.ComputedColumnSql, out string? computedColumnSql))
{
methodCallCodeFragments.Add(
computedColumnSql?.Length == 0
computedColumnSql.Length == 0
? new MethodCallCodeFragment(
nameof(RelationalPropertyBuilderExtensions.HasComputedColumnSql))
: TryGetAndRemove(annotations, RelationalAnnotationNames.IsStored, out bool isStored)
Expand Down Expand Up @@ -437,7 +439,7 @@ protected virtual bool IsHandledByConvention([NotNull] IIndex index, [NotNull] I
/// <param name="model"> The <see cref="IModel" />. </param>
/// <param name="annotation"> The <see cref="IAnnotation" />. </param>
/// <returns> <see langword="null" />. </returns>
protected virtual MethodCallCodeFragment GenerateFluentApi([NotNull] IModel model, [NotNull] IAnnotation annotation)
protected virtual MethodCallCodeFragment? GenerateFluentApi([NotNull] IModel model, [NotNull] IAnnotation annotation)
{
Check.NotNull(model, nameof(model));
Check.NotNull(annotation, nameof(annotation));
Expand All @@ -457,7 +459,7 @@ protected virtual MethodCallCodeFragment GenerateFluentApi([NotNull] IModel mode
/// <param name="entityType"> The <see cref="IEntityType" />. </param>
/// <param name="annotation"> The <see cref="IAnnotation" />. </param>
/// <returns> <see langword="null" />. </returns>
protected virtual MethodCallCodeFragment GenerateFluentApi([NotNull] IEntityType entityType, [NotNull] IAnnotation annotation)
protected virtual MethodCallCodeFragment? GenerateFluentApi([NotNull] IEntityType entityType, [NotNull] IAnnotation annotation)
{
Check.NotNull(entityType, nameof(entityType));
Check.NotNull(annotation, nameof(annotation));
Expand All @@ -477,7 +479,7 @@ protected virtual MethodCallCodeFragment GenerateFluentApi([NotNull] IEntityType
/// <param name="key"> The <see cref="IKey" />. </param>
/// <param name="annotation"> The <see cref="IAnnotation" />. </param>
/// <returns> <see langword="null" />. </returns>
protected virtual MethodCallCodeFragment GenerateFluentApi([NotNull] IKey key, [NotNull] IAnnotation annotation)
protected virtual MethodCallCodeFragment? GenerateFluentApi([NotNull] IKey key, [NotNull] IAnnotation annotation)
{
Check.NotNull(key, nameof(key));
Check.NotNull(annotation, nameof(annotation));
Expand All @@ -497,7 +499,7 @@ protected virtual MethodCallCodeFragment GenerateFluentApi([NotNull] IKey key, [
/// <param name="property"> The <see cref="IProperty" />. </param>
/// <param name="annotation"> The <see cref="IAnnotation" />. </param>
/// <returns> <see langword="null" />. </returns>
protected virtual MethodCallCodeFragment GenerateFluentApi([NotNull] IProperty property, [NotNull] IAnnotation annotation)
protected virtual MethodCallCodeFragment? GenerateFluentApi([NotNull] IProperty property, [NotNull] IAnnotation annotation)
{
Check.NotNull(property, nameof(property));
Check.NotNull(annotation, nameof(annotation));
Expand All @@ -517,7 +519,7 @@ protected virtual MethodCallCodeFragment GenerateFluentApi([NotNull] IProperty p
/// <param name="foreignKey"> The <see cref="IForeignKey" />. </param>
/// <param name="annotation"> The <see cref="IAnnotation" />. </param>
/// <returns> <see langword="null" />. </returns>
protected virtual MethodCallCodeFragment GenerateFluentApi([NotNull] IForeignKey foreignKey, [NotNull] IAnnotation annotation)
protected virtual MethodCallCodeFragment? GenerateFluentApi([NotNull] IForeignKey foreignKey, [NotNull] IAnnotation annotation)
{
Check.NotNull(foreignKey, nameof(foreignKey));
Check.NotNull(annotation, nameof(annotation));
Expand All @@ -537,7 +539,7 @@ protected virtual MethodCallCodeFragment GenerateFluentApi([NotNull] IForeignKey
/// <param name="navigation"> The <see cref="INavigation" />. </param>
/// <param name="annotation"> The <see cref="IAnnotation" />. </param>
/// <returns> <see langword="null" />. </returns>
protected virtual MethodCallCodeFragment GenerateFluentApi([NotNull] INavigation navigation, [NotNull] IAnnotation annotation)
protected virtual MethodCallCodeFragment? GenerateFluentApi([NotNull] INavigation navigation, [NotNull] IAnnotation annotation)
{
Check.NotNull(navigation, nameof(navigation));
Check.NotNull(annotation, nameof(annotation));
Expand All @@ -557,7 +559,7 @@ protected virtual MethodCallCodeFragment GenerateFluentApi([NotNull] INavigation
/// <param name="navigation"> The <see cref="ISkipNavigation" />. </param>
/// <param name="annotation"> The <see cref="IAnnotation" />. </param>
/// <returns> <see langword="null" />. </returns>
protected virtual MethodCallCodeFragment GenerateFluentApi([NotNull] ISkipNavigation navigation, [NotNull] IAnnotation annotation)
protected virtual MethodCallCodeFragment? GenerateFluentApi([NotNull] ISkipNavigation navigation, [NotNull] IAnnotation annotation)
{
Check.NotNull(navigation, nameof(navigation));
Check.NotNull(annotation, nameof(annotation));
Expand All @@ -577,7 +579,7 @@ protected virtual MethodCallCodeFragment GenerateFluentApi([NotNull] ISkipNaviga
/// <param name="index"> The <see cref="IIndex" />. </param>
/// <param name="annotation"> The <see cref="IAnnotation" />. </param>
/// <returns> <see langword="null" />. </returns>
protected virtual MethodCallCodeFragment GenerateFluentApi([NotNull] IIndex index, [NotNull] IAnnotation annotation)
protected virtual MethodCallCodeFragment? GenerateFluentApi([NotNull] IIndex index, [NotNull] IAnnotation annotation)
{
Check.NotNull(index, nameof(index));
Check.NotNull(annotation, nameof(annotation));
Expand All @@ -597,7 +599,7 @@ protected virtual MethodCallCodeFragment GenerateFluentApi([NotNull] IIndex inde
/// <param name="entityType"> The <see cref="IEntityType" />. </param>
/// <param name="annotation"> The <see cref="IAnnotation" />. </param>
/// <returns> <see langword="null" />. </returns>
protected virtual AttributeCodeFragment GenerateDataAnnotation([NotNull] IEntityType entityType, [NotNull] IAnnotation annotation)
protected virtual AttributeCodeFragment? GenerateDataAnnotation([NotNull] IEntityType entityType, [NotNull] IAnnotation annotation)
{
Check.NotNull(entityType, nameof(entityType));
Check.NotNull(annotation, nameof(annotation));
Expand All @@ -617,7 +619,7 @@ protected virtual AttributeCodeFragment GenerateDataAnnotation([NotNull] IEntity
/// <param name="property"> The <see cref="IProperty" />. </param>
/// <param name="annotation"> The <see cref="IAnnotation" />. </param>
/// <returns> <see langword="null" />. </returns>
protected virtual AttributeCodeFragment GenerateDataAnnotation([NotNull] IProperty property, [NotNull] IAnnotation annotation)
protected virtual AttributeCodeFragment? GenerateDataAnnotation([NotNull] IProperty property, [NotNull] IAnnotation annotation)
{
Check.NotNull(property, nameof(property));
Check.NotNull(annotation, nameof(annotation));
Expand All @@ -628,7 +630,8 @@ protected virtual AttributeCodeFragment GenerateDataAnnotation([NotNull] IProper
private IEnumerable<TCodeFragment> GenerateFluentApiCallsHelper<TAnnotatable, TCodeFragment>(
TAnnotatable annotatable,
IDictionary<string, IAnnotation> annotations,
Func<TAnnotatable, IAnnotation, TCodeFragment> generateCodeFragment)
Func<TAnnotatable, IAnnotation, TCodeFragment?> generateCodeFragment)
where TCodeFragment : notnull
{
foreach (var (name, annotation) in EnumerateForRemoval(annotations))
{
Expand All @@ -655,7 +658,7 @@ private void RemoveConventionalAnnotationsHelper<TAnnotatable>(
}
}

private static bool TryGetAndRemove<T>(IDictionary<string, IAnnotation> annotations, string annotationName, out T annotationValue)
private static bool TryGetAndRemove<T>(IDictionary<string, IAnnotation> annotations, string annotationName, [NotNullWhen(true)] out T? annotationValue)
{
if (annotations.TryGetValue(annotationName, out var annotation)
&& annotation.Value != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Utilities;

#nullable enable

namespace Microsoft.EntityFrameworkCore.Design
{
/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions src/EFCore.Relational/Design/AttributeCodeFragment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Utilities;

#nullable enable

namespace Microsoft.EntityFrameworkCore.Design
{
/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions src/EFCore.Relational/Design/IAnnotationCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;

#nullable enable

namespace Microsoft.EntityFrameworkCore.Design
{
/// <summary>
Expand Down
14 changes: 8 additions & 6 deletions src/EFCore.Relational/Design/MethodCallCodeFragment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,29 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Utilities;

#nullable enable

namespace Microsoft.EntityFrameworkCore.Design
{
/// <summary>
/// Represents a call to a method.
/// </summary>
public class MethodCallCodeFragment
{
private readonly List<object> _arguments;
private readonly List<object?> _arguments;

/// <summary>
/// Initializes a new instance of the <see cref="MethodCallCodeFragment" /> class.
/// </summary>
/// <param name="method"> The method's name. </param>
/// <param name="arguments"> The method call's arguments. Can be <see cref="NestedClosureCodeFragment" />. </param>
public MethodCallCodeFragment([NotNull] string method, [NotNull] params object[] arguments)
public MethodCallCodeFragment([NotNull] string method, [NotNull] params object?[] arguments)
{
Check.NotEmpty(method, nameof(method));
Check.NotNull(arguments, nameof(arguments));

Method = method;
_arguments = new List<object>(arguments);
_arguments = new List<object?>(arguments);
}

/// <summary>
Expand All @@ -36,7 +38,7 @@ public MethodCallCodeFragment([NotNull] string method, [NotNull] params object[]
/// <param name="chainedCall"> The next method call to chain after this. </param>
public MethodCallCodeFragment(
[NotNull] string method,
[NotNull] object[] arguments,
[NotNull] object?[] arguments,
[NotNull] MethodCallCodeFragment chainedCall)
: this(method, arguments)
{
Expand All @@ -55,14 +57,14 @@ public MethodCallCodeFragment(
/// Gets the method call's arguments.
/// </summary>
/// <value> The method call's arguments. </value>
public virtual IReadOnlyList<object> Arguments
public virtual IReadOnlyList<object?> Arguments
=> _arguments;

/// <summary>
/// Gets the next method call to chain after this.
/// </summary>
/// <value> The next method call. </value>
public virtual MethodCallCodeFragment ChainedCall { get; }
public virtual MethodCallCodeFragment? ChainedCall { get; }

/// <summary>
/// Creates a method chain from this method to another.
Expand Down
2 changes: 2 additions & 0 deletions src/EFCore.Relational/Design/NestedClosureCodeFragment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Utilities;

#nullable enable

namespace Microsoft.EntityFrameworkCore.Design
{
/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions src/EFCore.Relational/Scaffolding/DatabaseModelFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using System.Data.Common;
using Microsoft.EntityFrameworkCore.Scaffolding.Metadata;

#nullable enable

namespace Microsoft.EntityFrameworkCore.Scaffolding
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using System.Linq;
using JetBrains.Annotations;

#nullable enable

namespace Microsoft.EntityFrameworkCore.Scaffolding
{
/// <summary>
Expand All @@ -17,7 +19,7 @@ public class DatabaseModelFactoryOptions
/// </summary>
/// <param name="tables"> A list of tables to include. Empty to include all tables. </param>
/// <param name="schemas"> A list of schemas to include. Empty to include all schemas. </param>
public DatabaseModelFactoryOptions([CanBeNull] IEnumerable<string> tables = null, [CanBeNull] IEnumerable<string> schemas = null)
public DatabaseModelFactoryOptions([CanBeNull] IEnumerable<string>? tables = null, [CanBeNull] IEnumerable<string>? schemas = null)
{
Tables = tables ?? Enumerable.Empty<string>();
Schemas = schemas ?? Enumerable.Empty<string>();
Expand Down
2 changes: 2 additions & 0 deletions src/EFCore.Relational/Scaffolding/IDatabaseModelFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Scaffolding.Metadata;

#nullable enable

namespace Microsoft.EntityFrameworkCore.Scaffolding
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

using Microsoft.EntityFrameworkCore.Design;

#nullable enable

namespace Microsoft.EntityFrameworkCore.Scaffolding
{
/// <summary>
Expand All @@ -14,12 +16,12 @@ public interface IProviderCodeGeneratorPlugin
/// Generates a method chain used to configure provider-specific options.
/// </summary>
/// <returns> The method chain. May be null. </returns>
MethodCallCodeFragment GenerateProviderOptions();
MethodCallCodeFragment? GenerateProviderOptions();

/// <summary>
/// Generates a method chain to configure additional context options.
/// </summary>
/// <returns> The method chain. May be null. </returns>
MethodCallCodeFragment GenerateContextOptions();
MethodCallCodeFragment? GenerateContextOptions();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Design;

#nullable enable

namespace Microsoft.EntityFrameworkCore.Scaffolding
{
/// <summary>
Expand All @@ -16,7 +18,7 @@ public interface IProviderConfigurationCodeGenerator
/// Generates a method chain used to configure provider-specific options.
/// </summary>
/// <returns> The method chain. May be null. </returns>
MethodCallCodeFragment GenerateProviderOptions();
MethodCallCodeFragment? GenerateProviderOptions();

/// <summary>
/// Generates a code fragment like <c>.UseSqlServer("Database=Foo")</c> which can be used in
Expand All @@ -27,13 +29,13 @@ public interface IProviderConfigurationCodeGenerator
/// <returns> The code fragment. </returns>
MethodCallCodeFragment GenerateUseProvider(
[NotNull] string connectionString,
[CanBeNull] MethodCallCodeFragment providerOptions);
[CanBeNull] MethodCallCodeFragment? providerOptions);

/// <summary>
/// Generates a method chain to configure additional context options.
/// </summary>
/// <returns> The method chain. May be null. </returns>
MethodCallCodeFragment GenerateContextOptions();
MethodCallCodeFragment? GenerateContextOptions();

/// <summary>
/// Generates a code fragment like <c>.UseSqlServer("Database=Foo")</c> which can be used in
Expand Down
Loading

0 comments on commit 2de4fe1

Please sign in to comment.