Skip to content

Fix aot mac #1609

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

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
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
10 changes: 10 additions & 0 deletions backend/FwLite/FwLiteShared/FwLiteSharedKernel.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Net;
using System.Text.Json.Serialization.Metadata;
using FwLiteShared.Auth;
using FwLiteShared.Events;
using FwLiteShared.Json;
using FwLiteShared.Projects;
using FwLiteShared.Services;
using FwLiteShared.Sync;
Expand All @@ -9,6 +11,7 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Microsoft.JSInterop;
using MiniLcm;
using Polly;
using Polly.Simmy;
using SIL.Harmony;
Expand Down Expand Up @@ -115,4 +118,11 @@ private static void DecorateConstructor<TService>(this IServiceCollection servic
}, descriptor.Lifetime);
}
}

public static IJsonTypeInfoResolver MakeLcmCrdtExternalJsonTypeResolver(this CrdtConfig config)
{
var resolver = JsonTypeInfoResolver.Combine(config.JsonSerializerOptions.TypeInfoResolver, SharedSourceGenerationContext.Default);
resolver = resolver.AddExternalMiniLcmModifiers();
return resolver;
}
}
31 changes: 31 additions & 0 deletions backend/FwLite/FwLiteShared/Json/SharedSourceGenerationContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Text.Json.Serialization;
using FwLiteShared.Auth;
using FwLiteShared.Events;
using FwLiteShared.Projects;
using FwLiteShared.Services;
using LcmCrdt;
using MiniLcm.Models;
using SIL.Harmony.Db;

namespace FwLiteShared.Json;

[JsonSourceGenerationOptions]
[JsonSerializable(typeof(IAsyncEnumerable<HistoryLineItem>))]
[JsonSerializable(typeof(IAsyncEnumerable<ProjectActivity>))]
[JsonSerializable(typeof(IAsyncEnumerable<Entry>))]
[JsonSerializable(typeof(IProjectIdentifier))]
[JsonSerializable(typeof(ServerStatus[]))]
[JsonSerializable(typeof(LexboxServer))]
[JsonSerializable(typeof(CrdtProject))]
[JsonSerializable(typeof(ProjectData))]
[JsonSerializable(typeof(FwLiteConfig))]
[JsonSerializable(typeof(ObjectSnapshot))]

Check warning on line 22 in backend/FwLite/FwLiteShared/Json/SharedSourceGenerationContext.cs

View workflow job for this annotation

GitHub Actions / Build FW Lite and run tests

The constructor on type 'SIL.Harmony.Db.ObjectSnapshot' has been annotated with JsonConstructorAttribute but is not accessible by the source generator. (https://learn.microsoft.com/dotnet/fundamentals/syslib-diagnostics/syslib1222)

Check warning on line 22 in backend/FwLite/FwLiteShared/Json/SharedSourceGenerationContext.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Android

The constructor on type 'SIL.Harmony.Db.ObjectSnapshot' has been annotated with JsonConstructorAttribute but is not accessible by the source generator. (https://learn.microsoft.com/dotnet/fundamentals/syslib-diagnostics/syslib1222)
[JsonSerializable(typeof(ProjectScope))]
[JsonSerializable(typeof(IFwEvent))]
[JsonSerializable(typeof(Dictionary<string, ProjectModel[]>))]
[JsonSerializable(typeof(IReadOnlyCollection<ProjectModel>))]
public partial class SharedSourceGenerationContext : JsonSerializerContext

Check warning on line 27 in backend/FwLite/FwLiteShared/Json/SharedSourceGenerationContext.cs

View workflow job for this annotation

GitHub Actions / Build FW Lite and run tests

The constructor on type 'SIL.Harmony.Commit' has been annotated with JsonConstructorAttribute but is not accessible by the source generator. (https://learn.microsoft.com/dotnet/fundamentals/syslib-diagnostics/syslib1222)

Check warning on line 27 in backend/FwLite/FwLiteShared/Json/SharedSourceGenerationContext.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Android

The constructor on type 'SIL.Harmony.Commit' has been annotated with JsonConstructorAttribute but is not accessible by the source generator. (https://learn.microsoft.com/dotnet/fundamentals/syslib-diagnostics/syslib1222)
{

}

4 changes: 1 addition & 3 deletions backend/FwLite/FwLiteShared/Services/FwLiteJson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ public static void ConfigureJsonSerializerOptions(this IJSRuntime jsRuntime, Crd
throw new InvalidOperationException("Unable to find JsonSerializerOptions property");
var options = (JsonSerializerOptions?)_jsRuntimeJsonOptionsProperty.GetValue(jsRuntime, null);
if (options is null) throw new InvalidOperationException("JSRuntime.JsonSerializerOptions returned null");
options.TypeInfoResolver = (options.TypeInfoResolver ?? new DefaultJsonTypeInfoResolver())
.WithAddedModifier(crdtConfig.MakeJsonTypeModifier())
.AddExternalMiniLcmModifiers();
options.TypeInfoResolver = JsonTypeInfoResolver.Combine(options.TypeInfoResolver, crdtConfig.MakeLcmCrdtExternalJsonTypeResolver());
}
}
33 changes: 30 additions & 3 deletions backend/FwLite/FwLiteWeb/FwLiteWebKernel.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
using FwDataMiniLcmBridge;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization.Metadata;
using FwDataMiniLcmBridge;
using FwLiteProjectSync;
using SIL.Harmony;
using FwLiteShared;
using FwLiteShared.Auth;
using FwLiteWeb.Routes;
using LcmCrdt;
using FwLiteWeb.Services;
using FwLiteWeb.Utils;
using Microsoft.AspNetCore.Http.Json;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Options;
Expand All @@ -32,14 +36,37 @@ public static IServiceCollection AddFwLiteWebServices(this IServiceCollection se

services.AddOptions<JsonOptions>().PostConfigure<IOptions<CrdtConfig>>((jsonOptions, crdtConfig) =>
{
jsonOptions.SerializerOptions.TypeInfoResolver = crdtConfig.Value.MakeLcmCrdtExternalJsonTypeResolver();
jsonOptions.SerializerOptions.TypeInfoResolver = jsonOptions.SerializerOptions.TypeInfoResolver.WithWebTypeInfo(crdtConfig.Value);
});

services.AddOptions<JsonHubProtocolOptions>().PostConfigure<IOptions<CrdtConfig>>(
(jsonOptions, crdtConfig) =>
{
jsonOptions.PayloadSerializerOptions.TypeInfoResolver = crdtConfig.Value.MakeLcmCrdtExternalJsonTypeResolver();
jsonOptions.PayloadSerializerOptions.TypeInfoResolver = jsonOptions.PayloadSerializerOptions.TypeInfoResolver.WithWebTypeInfo(crdtConfig.Value);
});
services.PostConfigure<CrdtConfig>(config =>
{
var type = typeof(RazorComponentsServiceCollectionExtensions).Assembly.GetType(
"Microsoft.AspNetCore.Components.ServerComponentSerializationSettings");
if (type is null)
throw new InvalidOperationException(
"Microsoft.AspNetCore.Components.ServerComponentSerializationSettings not found");
var property = type.GetField("JsonSerializationOptions", BindingFlags.Static | BindingFlags.Public);
if (property is null)
throw new InvalidOperationException(
"ServerComponentSerializationSettings.JsonSerializationOptions property not found");
var jsonSerializerOptions = (JsonSerializerOptions?)property.GetValue(null);
if (jsonSerializerOptions is null)
throw new InvalidOperationException(
"ServerComponentSerializationSettings.JsonSerializationOptions is null");
jsonSerializerOptions.TypeInfoResolver = jsonSerializerOptions.TypeInfoResolver.WithWebTypeInfo(config);

});
return services;
}

private static IJsonTypeInfoResolver WithWebTypeInfo(this IJsonTypeInfoResolver? resolver, CrdtConfig config)
{
return JsonTypeInfoResolver.Combine(resolver, config.MakeLcmCrdtExternalJsonTypeResolver());
}
}
5 changes: 4 additions & 1 deletion backend/FwLite/FwLiteWeb/Routes/AuthRoutes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ public static class AuthRoutes
{
public const string CallbackRoute = "AuthRoutes_Callback";
public record ServerStatus(string DisplayName, bool LoggedIn, string? LoggedInAs, string? Authority);

public record AuthRecord(string? Name);

public static IEndpointConventionBuilder MapAuthRoutes(this WebApplication app)
{
var group = app.MapGroup("/api/auth").WithOpenApi();
Expand Down Expand Up @@ -40,7 +43,7 @@ public static IEndpointConventionBuilder MapAuthRoutes(this WebApplication app)
group.MapGet("/me/{authority}",
async (AuthService authService, string authority, IOptions<AuthConfig> options) =>
{
return new { name = await authService.GetLoggedInName(options.Value.GetServerByAuthority(authority)) };
return new AuthRecord(await authService.GetLoggedInName(options.Value.GetServerByAuthority(authority)));
});
group.MapGet("/logout/{authority}",
async (AuthService authService, string authority, IOptions<AuthConfig> options) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ public class ChangeSerializationTests
{
private static readonly Lazy<JsonSerializerOptions> LazyOptions = new(() =>
{
var config = new CrdtConfig();
LcmCrdtKernel.ConfigureCrdt(config);
var config = LcmCrdtKernel.MakeConfig();
config.JsonSerializerOptions.ReadCommentHandling = JsonCommentHandling.Skip;
return config.JsonSerializerOptions;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ public class SnapshotDeserializationTests

private static readonly Lazy<JsonSerializerOptions> LazyOptions = new(() =>
{
var config = new CrdtConfig();
LcmCrdtKernel.ConfigureCrdt(config);
var config = LcmCrdtKernel.MakeConfig();
config.JsonSerializerOptions.ReadCommentHandling = JsonCommentHandling.Skip;
return config.JsonSerializerOptions;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,7 @@
ComponentSenseId
SnapshotId Unique
ComplexFormEntryId, ComponentEntryId Unique
Annotations:
Relational:Filter: ComponentSenseId IS NULL
ComplexFormEntryId, ComponentEntryId, ComponentSenseId Unique
Annotations:
Relational:Filter: ComponentSenseId IS NOT NULL
Annotations:
DiscriminatorProperty:
Relational:FunctionName:
Expand Down Expand Up @@ -270,7 +266,7 @@
Order (double) Required
SnapshotId (no field, Guid?) Shadow FK Index
Type (WritingSystemType) Required Index
WsId (WritingSystemId) Required Index
WsId (WritingSystemId) Required Index Sentinel:default
Keys:
Id PK
Foreign keys:
Expand Down Expand Up @@ -308,6 +304,13 @@
DateTime (DateTimeOffset) Required
Annotations:
Relational:ColumnName: DateTime
Annotations:
Relational:FunctionName:
Relational:Schema:
Relational:SqlQuery:
Relational:TableName: Commits
Relational:ViewName:
Relational:ViewSchema:
Keys:
Id PK
Annotations:
Expand Down
2 changes: 1 addition & 1 deletion backend/FwLite/LcmCrdt/Changes/CreateEntryChange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public CreateEntryChange(Entry entry) : base(entry.Id == Guid.Empty ? Guid.NewGu
}

[JsonConstructor]
private CreateEntryChange(Guid entityId) : base(entityId)
internal CreateEntryChange(Guid entityId) : base(entityId)
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public CreateExampleSentenceChange(ExampleSentence exampleSentence, Guid senseId
}

[JsonConstructor]
private CreateExampleSentenceChange(Guid entityId, Guid senseId) : base(entityId)
internal CreateExampleSentenceChange(Guid entityId, Guid senseId) : base(entityId)
{
SenseId = senseId;
}
Expand Down
2 changes: 1 addition & 1 deletion backend/FwLite/LcmCrdt/Changes/CreateSenseChange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public CreateSenseChange(Sense sense, Guid entryId) : base(sense.Id == Guid.Empt
}

[JsonConstructor]
private CreateSenseChange(Guid entityId, Guid entryId) : base(entityId)
internal CreateSenseChange(Guid entityId, Guid entryId) : base(entityId)
{
EntryId = entryId;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public CreateWritingSystemChange(WritingSystem writingSystem, WritingSystemType
}

[JsonConstructor]
private CreateWritingSystemChange(Guid entityId) : base(entityId)
internal CreateWritingSystemChange(Guid entityId) : base(entityId)
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace LcmCrdt.Changes.Entries;
public class SetComplexFormComponentChange : EditChange<ComplexFormComponent>, ISelfNamedType<SetComplexFormComponentChange>
{
[JsonConstructor]
protected SetComplexFormComponentChange(Guid entityId, Guid? complexFormEntryId, Guid? componentEntryId, Guid? componentSenseId) : base(entityId)
internal SetComplexFormComponentChange(Guid entityId, Guid? complexFormEntryId, Guid? componentEntryId, Guid? componentSenseId) : base(entityId)
{
ComplexFormEntryId = complexFormEntryId;
ComponentEntryId = componentEntryId;
Expand Down
140 changes: 140 additions & 0 deletions backend/FwLite/LcmCrdt/CompiledModels/ChangeEntityEntityType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// <auto-generated />
using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.Json;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using SIL.Harmony.Changes;
using SIL.Harmony.Core;
using SIL.Harmony.Db.EntityConfig;

#pragma warning disable 219, 612, 618
#nullable disable

namespace LcmCrdt.CompiledModels
{
internal partial class ChangeEntityEntityType
{
public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null)
{
var runtimeEntityType = model.AddEntityType(
"SIL.Harmony.Core.ChangeEntity<SIL.Harmony.Changes.IChange>",
typeof(ChangeEntity<IChange>),
baseEntityType);

var commitId = runtimeEntityType.AddProperty(
"CommitId",
typeof(Guid),
propertyInfo: typeof(ChangeEntity<IChange>).GetProperty("CommitId", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly),
fieldInfo: typeof(ChangeEntity<IChange>).GetField("<CommitId>k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly),
afterSaveBehavior: PropertySaveBehavior.Throw,
sentinel: new Guid("00000000-0000-0000-0000-000000000000"));
commitId.TypeMapping = SqliteGuidTypeMapping.Default;

var index = runtimeEntityType.AddProperty(
"Index",
typeof(int),
propertyInfo: typeof(ChangeEntity<IChange>).GetProperty("Index", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly),
fieldInfo: typeof(ChangeEntity<IChange>).GetField("<Index>k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly),
afterSaveBehavior: PropertySaveBehavior.Throw,
sentinel: 0);
index.TypeMapping = IntTypeMapping.Default.Clone(
comparer: new ValueComparer<int>(
(int v1, int v2) => v1 == v2,
(int v) => v,
(int v) => v),
keyComparer: new ValueComparer<int>(
(int v1, int v2) => v1 == v2,
(int v) => v,
(int v) => v),
providerValueComparer: new ValueComparer<int>(
(int v1, int v2) => v1 == v2,
(int v) => v,
(int v) => v),
mappingInfo: new RelationalTypeMappingInfo(
storeTypeName: "INTEGER"));

var change = runtimeEntityType.AddProperty(
"Change",
typeof(IChange),
propertyInfo: typeof(ChangeEntity<IChange>).GetProperty("Change", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly),
fieldInfo: typeof(ChangeEntity<IChange>).GetField("<Change>k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly),
nullable: true);
change.TypeMapping = SqliteStringTypeMapping.Default.Clone(
comparer: new ValueComparer<IChange>(
(IChange v1, IChange v2) => object.Equals(v1, v2),
(IChange v) => v.GetHashCode(),
(IChange v) => v),
keyComparer: new ValueComparer<IChange>(
(IChange v1, IChange v2) => object.Equals(v1, v2),
(IChange v) => v.GetHashCode(),
(IChange v) => v),
providerValueComparer: new ValueComparer<string>(
(string v1, string v2) => v1 == v2,
(string v) => v.GetHashCode(),
(string v) => v),
mappingInfo: new RelationalTypeMappingInfo(
storeTypeName: "jsonb"),
converter: new ValueConverter<IChange, string>(
(IChange change) => ChangeEntityConfig.SerializeChange(change, null),
(string json) => ChangeEntityConfig.DeserializeChange(json, null)),
jsonValueReaderWriter: new JsonConvertedValueReaderWriter<IChange, string>(
JsonStringReaderWriter.Instance,
new ValueConverter<IChange, string>(
(IChange change) => ChangeEntityConfig.SerializeChange(change, null),
(string json) => ChangeEntityConfig.DeserializeChange(json, null))));
change.AddAnnotation("Relational:ColumnType", "jsonb");

var entityId = runtimeEntityType.AddProperty(
"EntityId",
typeof(Guid),
propertyInfo: typeof(ChangeEntity<IChange>).GetProperty("EntityId", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly),
fieldInfo: typeof(ChangeEntity<IChange>).GetField("<EntityId>k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly),
sentinel: new Guid("00000000-0000-0000-0000-000000000000"));
entityId.TypeMapping = SqliteGuidTypeMapping.Default;

var key = runtimeEntityType.AddKey(
new[] { commitId, index });
runtimeEntityType.SetPrimaryKey(key);

return runtimeEntityType;
}

public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType)
{
var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("CommitId") },
principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id") }),
principalEntityType,
deleteBehavior: DeleteBehavior.Cascade,
required: true);

var changeEntities = principalEntityType.AddNavigation("ChangeEntities",
runtimeForeignKey,
onDependent: false,
typeof(List<ChangeEntity<IChange>>),
propertyInfo: typeof(CommitBase<IChange>).GetProperty("ChangeEntities", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly),
fieldInfo: typeof(CommitBase<IChange>).GetField("<ChangeEntities>k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly));

return runtimeForeignKey;
}

public static void CreateAnnotations(RuntimeEntityType runtimeEntityType)
{
runtimeEntityType.AddAnnotation("Relational:FunctionName", null);
runtimeEntityType.AddAnnotation("Relational:Schema", null);
runtimeEntityType.AddAnnotation("Relational:SqlQuery", null);
runtimeEntityType.AddAnnotation("Relational:TableName", "ChangeEntities");
runtimeEntityType.AddAnnotation("Relational:ViewName", null);
runtimeEntityType.AddAnnotation("Relational:ViewSchema", null);

Customize(runtimeEntityType);
}

static partial void Customize(RuntimeEntityType runtimeEntityType);
}
}
Loading
Loading