Skip to content

Commit

Permalink
Incremental compilesIncremental re-write part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
ladeak committed Oct 9, 2024
1 parent 9ef122f commit eccb116
Show file tree
Hide file tree
Showing 59 changed files with 1,151 additions and 1,463 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<ImplicitUsings>true</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
Expand Down
4 changes: 1 addition & 3 deletions sample/AspNetCoreMinimal.Entities/Entities.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
using LaDeak.JsonMergePatch.Abstractions;

namespace AspNetCoreMinimal.Entities;
Expand Down
1 change: 1 addition & 0 deletions sample/AspNetCoreMinimal/AspNetCoreMinimal.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<ImplicitUsings>true</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
Expand Down
6 changes: 1 addition & 5 deletions sample/AspNetCoreMinimal/Controllers/SampleController.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
using System.Text.Json;
using AspNetCoreMinimal.Entities;
using LaDeak.JsonMergePatch.Abstractions;
using LaDeak.JsonMergePatch.Http;
Expand Down
12 changes: 1 addition & 11 deletions sample/AspNetCoreMinimal/Program.cs
Original file line number Diff line number Diff line change
@@ -1,32 +1,22 @@
using System.Text.Json.Serialization;
using LaDeak.JsonMergePatch.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var builder = WebApplication.CreateBuilder(args);

var mvcBuilder = builder.Services.AddControllers().AddMvcOptions(options =>
{
LaDeak.JsonMergePatch.Abstractions.JsonMergePatchOptions.Repository = LaDeak.JsonMergePatch.Generated.SafeAspNetCoreMinimal.Entities.TypeRepository.Instance;
var jsonOptions = new Microsoft.AspNetCore.Http.Json.JsonOptions();
jsonOptions.SerializerOptions.AddContext<SampleJsonContext>();
jsonOptions.SerializerOptions.TypeInfoResolver = SampleJsonContext.Default;
options.InputFormatters.Insert(0, new JsonMergePatchInputReader(jsonOptions));
});
builder.Services.AddHttpClient();


var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();


[JsonSerializable(typeof(LaDeak.JsonMergePatch.Generated.SafeAspNetCoreMinimal.Entities.WeatherForecastWrapped))]
[JsonSerializable(typeof(LaDeak.JsonMergePatch.Generated.SafeAspNetCoreMinimal.Entities.CitiesDataWrapped))]
public partial class SampleJsonContext : JsonSerializerContext
Expand Down
1 change: 1 addition & 0 deletions sample/ConsoleApp/ConsoleApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>
<ImplicitUsings>true</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
Expand Down
53 changes: 25 additions & 28 deletions sample/ConsoleApp/Program.cs
Original file line number Diff line number Diff line change
@@ -1,38 +1,35 @@
using System;
using System.Net.Http;
using System.Threading.Tasks;
using ConsoleAppLibrary;
using ConsoleAppLibrary;
using LaDeak.JsonMergePatch.Abstractions;
using LaDeak.JsonMergePatch.Http;

namespace ReadJsonPatchAsync
namespace ReadJsonPatchAsync;

public class Program
{
public class Program
[Patchable]
public class WeatherForecast
{
public class WeatherForecast
{
public DateTime Date { get; set; }
public int Temp { get; set; }
public string Summary { get; set; }
}
public DateTime Date { get; set; }
public int Temp { get; set; }
public string Summary { get; set; }
}

public static async Task Main(string[] args)
{
LaDeak.JsonMergePatch.Abstractions.JsonMergePatchOptions.Repository = LaDeak.JsonMergePatch.Generated.SafeConsoleApp.TypeRepository.Instance.Extend(LaDeak.JsonMergePatch.Generated.SafeConsoleAppLibrary.TypeRepository.Instance);
await ReadAsJsonMergePatchAsync();
}
public static async Task Main(string[] args)
{
LaDeak.JsonMergePatch.Abstractions.JsonMergePatchOptions.Repository = LaDeak.JsonMergePatch.Generated.SafeConsoleApp.TypeRepository.Instance.Extend(LaDeak.JsonMergePatch.Generated.SafeConsoleAppLibrary.TypeRepository.Instance);
await ReadAsJsonMergePatchAsync();
}

public static async Task ReadAsJsonMergePatchAsync()
{
var httpClient = new HttpClient();
var response = await httpClient.GetAsync("https://localhost:5001/Sample/Weather", HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
var responseData = await response.Content.ReadJsonPatchAsync<WeatherForecast>().ConfigureAwait(false);
var target = new WeatherForecast() { Date = DateTime.UtcNow, Summary = "Sample weather forecast", Temp = 24 };
var result = responseData.ApplyPatch(target);
Console.WriteLine($"Patched: Date={result.Date}, Summary={result.Summary}, Temp={result.Temp}");
public static async Task ReadAsJsonMergePatchAsync()
{
var httpClient = new HttpClient();
var response = await httpClient.GetAsync("https://localhost:5001/Sample/Weather", HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
var responseData = await response.Content.ReadJsonPatchAsync<WeatherForecast>().ConfigureAwait(false);
var target = new WeatherForecast() { Date = DateTime.UtcNow, Summary = "Sample weather forecast", Temp = 24 };
var result = responseData.ApplyPatch(target);
Console.WriteLine($"Patched: Date={result.Date}, Summary={result.Summary}, Temp={result.Temp}");

var client = new Client();
await client.ReadAsJsonMergePatchAsync();
}
var client = new Client();
await client.ReadAsJsonMergePatchAsync();
}
}
1 change: 1 addition & 0 deletions sample/ConsoleAppLibrary/ConsoleAppLibrary.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>
<ImplicitUsings>true</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
Expand Down
36 changes: 17 additions & 19 deletions sample/ConsoleAppLibrary/Sample.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
using System;
using System.Net.Http;
using System.Threading.Tasks;
using LaDeak.JsonMergePatch.Abstractions;
using LaDeak.JsonMergePatch.Http;

namespace ConsoleAppLibrary
namespace ConsoleAppLibrary;

[Patchable]
public class DeviceData
{
public class DeviceData
{
public double Watts { get; set; }
public string Name { get; set; }
}
public double Watts { get; set; }
public string Name { get; set; }
}

public class Client
public class Client
{
public async Task ReadAsJsonMergePatchAsync()
{
public async Task ReadAsJsonMergePatchAsync()
{
var httpClient = new HttpClient();
var response = await httpClient.GetAsync("https://localhost:5001/Sample/DeviceData", HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
var responseData = await response.Content.ReadJsonPatchAsync<DeviceData>().ConfigureAwait(false);
var target = new DeviceData() { Watts = 5, Name = "phone" };
var result = responseData.ApplyPatch(target);
Console.WriteLine($"Patched: Name={result.Name}, Watts={result.Watts}");
}
var httpClient = new HttpClient();
var response = await httpClient.GetAsync("https://localhost:5001/Sample/DeviceData", HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
var responseData = await response.Content.ReadJsonPatchAsync<DeviceData>().ConfigureAwait(false);
var target = new DeviceData() { Watts = 5, Name = "phone" };
var result = responseData.ApplyPatch(target);
Console.WriteLine($"Patched: Name={result.Name}, Watts={result.Watts}");
}
}
4 changes: 1 addition & 3 deletions src/JsonMergePatch.Abstractions/ITypeRepository.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.CodeAnalysis;

namespace LaDeak.JsonMergePatch.Abstractions;

Expand Down
6 changes: 1 addition & 5 deletions src/JsonMergePatch.Abstractions/ITypeRepositoryExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace LaDeak.JsonMergePatch.Abstractions;
namespace LaDeak.JsonMergePatch.Abstractions;

public static class ITypeRepositoryExtensions
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFramework>netstandard2.1</TargetFramework>
<RootNamespace>LaDeak.JsonMergePatch.Abstractions</RootNamespace>
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
</PropertyGroup>

</Project>
2 changes: 1 addition & 1 deletion src/JsonMergePatch.Abstractions/Patch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public abstract class Patch<T>
/// <summary>
/// List of properties used by the request.
/// </summary>
protected bool[] Properties;
protected bool[] Properties = [];

/// <summary>
/// Applies updates on input type using Json Merge Patch rules.
Expand Down
4 changes: 1 addition & 3 deletions src/JsonMergePatch.Abstractions/PatchableAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;

namespace LaDeak.JsonMergePatch.Abstractions;
namespace LaDeak.JsonMergePatch.Abstractions;

[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class)]
public class PatchableAttribute : Attribute
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>LaDeak.JsonMergePatch.AspNetCore</RootNamespace>
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
Expand Down
6 changes: 1 addition & 5 deletions src/JsonMergePatch.AspNetCore/JsonMergePatchInputReader.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using LaDeak.JsonMergePatch.Abstractions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Json;
Expand Down
15 changes: 4 additions & 11 deletions src/JsonMergePatch.Http/HttpContentExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
using System;
using System.Net.Http;
using System.Text;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using LaDeak.JsonMergePatch.Abstractions;

namespace LaDeak.JsonMergePatch.Http;
Expand All @@ -16,21 +12,18 @@ public static class HttpContentExtensions

public static async Task<Patch<TResult>?> ReadJsonPatchAsync<TResult>(this HttpContent content, ITypeRepository typeRepository, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default)
{
if (content == null)
throw new ArgumentNullException(nameof(content));
if (typeRepository == null)
throw new ArgumentNullException(nameof(typeRepository));
ArgumentNullException.ThrowIfNull(content);
ArgumentNullException.ThrowIfNull(typeRepository);
if (!typeRepository.TryGet(typeof(TResult), out var wrapperType))
throw new ArgumentException($"{typeof(TResult)} is missing generated wrapper type. Check if all members of the type definition is supported.");
if (content.Headers.ContentType?.MediaType != "application/merge-patch+json" && content.Headers.ContentType?.MediaType != "application/json" && !string.IsNullOrWhiteSpace(content.Headers.ContentType?.MediaType))
return null;

var contentStream = await content.ReadAsStreamAsync().ConfigureAwait(false);
#if NET5_0_OR_GREATER
Encoding? encoding = content.Headers.ContentType?.CharSet != null ? GetEncoding(content.Headers.ContentType.CharSet) : null;
if (encoding != null && encoding != Encoding.UTF8)
contentStream = Encoding.CreateTranscodingStream(contentStream, encoding, Encoding.UTF8);
#endif

await using (contentStream.ConfigureAwait(false))
{
var contentData = await JsonSerializer.DeserializeAsync(contentStream, wrapperType, options ?? _serializerOptions, cancellationToken).ConfigureAwait(false);
Expand Down
1 change: 1 addition & 0 deletions src/JsonMergePatch.Http/JsonMergePatch.Http.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>LaDeak.JsonMergePatch.Http</RootNamespace>
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
public abstract class ApplyPatchBuilder
{
/// <summary>
/// Generates logic to instantiate object for init property.
/// Generates logic to instantiate object with init property.
/// </summary>
/// <param name="state">The state representing the ApplyPatch method.</param>
/// <param name="i">The index of the property in the 'Properties' collection.</param>
/// <returns>Returns the new state.</returns>
public abstract BuilderState BuildInitOnly(BuilderState state, int i);

/// <summary>
/// Generates logic to instantiate object for non-init property.
/// Generates logic to instantiate object with non-init property.
/// </summary>
/// <param name="state">The state representing the ApplyPatch method.</param>
/// <param name="i">The index of the property in the 'Properties' collection.</param>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis;

namespace LaDeak.JsonMergePatch.SourceGenerator.ApplyPatchBuilders;

Expand All @@ -10,9 +8,9 @@ namespace LaDeak.JsonMergePatch.SourceGenerator.ApplyPatchBuilders;
public class GeneratableListBuilder : ApplyPatchBuilder
{
private readonly ITypeSymbol _firstGenericType;
private readonly IPropertySymbol _property;
private readonly string _propertyName;

public GeneratableListBuilder(INamedTypeSymbol namedType, IPropertySymbol property)
public GeneratableListBuilder(INamedTypeSymbol namedType, string propertyName)
{
if (!namedType.Name.Contains("List")
|| namedType.ContainingNamespace.ToDisplayString() != "System.Collections.Generic"
Expand All @@ -21,32 +19,31 @@ public GeneratableListBuilder(INamedTypeSymbol namedType, IPropertySymbol proper
throw new ArgumentException("Input argument type is not a generic list with generatable type.");
}
_firstGenericType = namedType.TypeArguments.First();
_property = property;
_propertyName = propertyName;
}

public override BuilderState BuildInitOnly(BuilderState state, int i)
{
state.AppendLine($"{_property.Name} = Properties[{i}] && input.{_property.Name} == null ? new() : input.{_property.Name},");
state.AppendLine($"{_propertyName} = Properties[{i}] && input.{_propertyName} == null ? new() : input.{_propertyName},");
return state;
}

public override BuilderState BuildInstantiation(BuilderState state, int i)
{
state.AppendLine($"if (Properties[{i}])");
state.IncrementIdentation().AppendLine($"input.{_property.Name} = new();");
state.IncrementIdentation().AppendLine($"input.{_propertyName} = new();");
return state;
}

public override BuilderState BuildPatch(BuilderState state)
{
if (_firstGenericType != null && GeneratedTypeFilter.IsGeneratableType(_firstGenericType))
PopulateGeneratableListProperties(state, _property);
PopulateGeneratableListProperties(state, _propertyName);
return state;
}

private void PopulateGeneratableListProperties(BuilderState state, IPropertySymbol property)
private void PopulateGeneratableListProperties(BuilderState state, string propertyName)
{
var propertyName = property.Name;
state.AppendLine($"if({propertyName} != null)");
state.AppendLine("{");
var ifBody = state.IncrementIdentation();
Expand Down
Loading

0 comments on commit eccb116

Please sign in to comment.