mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-28 14:20:47 +08:00
fix(AOT): restore sidecar delivery and narrow linked fallbacks
This commit is contained in:
@@ -21,6 +21,14 @@ public sealed class GenerateLinkedRegistrationSidecarTask : ITask
|
||||
|
||||
public string TargetFramework { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// When true, the Sidecar is extracted by a consumer from a normally-built referenced
|
||||
/// assembly. C# unit edges are only emitted by linked library builds, so each declared
|
||||
/// package gets an ExtractedManifest fallback marker: the plan widens to full fallback
|
||||
/// instead of trimming with incomplete evidence.
|
||||
/// </summary>
|
||||
public bool ExtractedFallback { get; set; }
|
||||
|
||||
[Output]
|
||||
public string SidecarPath { get; private set; } = string.Empty;
|
||||
|
||||
@@ -67,6 +75,19 @@ public sealed class GenerateLinkedRegistrationSidecarTask : ITask
|
||||
return LogError(error);
|
||||
}
|
||||
sidecar.Assembly.TargetFramework = TargetFramework.Trim();
|
||||
if (ExtractedFallback && sidecar.Packages.Length != 0)
|
||||
{
|
||||
sidecar.Fallbacks = sidecar.Fallbacks
|
||||
.Concat(sidecar.Packages.Select(static package => new LinkedSidecarFallback
|
||||
{
|
||||
PackageId = package.Id,
|
||||
Reason = LinkedRegistrationProtocol.FallbackReasonExtractedManifest,
|
||||
Source = "<extraction>",
|
||||
Line = 0,
|
||||
Column = 0
|
||||
}))
|
||||
.ToArray();
|
||||
}
|
||||
var bytes = LinkedRegistrationSidecarCodec.Write(sidecar);
|
||||
if (analysisBudgetExceeded ||
|
||||
bytes.Length > LinkedRegistrationAnalysisBudget.MaxSidecarBytes)
|
||||
|
||||
@@ -48,8 +48,11 @@ public static class AppBuilderExtensions
|
||||
/// </example>
|
||||
public static AppBuilder WithAtomUIDefaultOptions(this AppBuilder appBuilder)
|
||||
{
|
||||
return appBuilder
|
||||
.With(new AvaloniaNativePlatformOptions
|
||||
// 按目标平台分支设置平台选项。NativeAOT 在 RID 发布时会把 OperatingSystem.IsXxx()
|
||||
// 折叠为常量,非目标平台的分支及其引用的平台选项类型会被整体裁剪。
|
||||
if (OperatingSystem.IsMacOS())
|
||||
{
|
||||
appBuilder = appBuilder.With(new AvaloniaNativePlatformOptions
|
||||
{
|
||||
RenderingMode =
|
||||
[
|
||||
@@ -57,8 +60,11 @@ public static class AppBuilderExtensions
|
||||
AvaloniaNativeRenderingMode.Metal,
|
||||
AvaloniaNativeRenderingMode.Software
|
||||
]
|
||||
})
|
||||
.With(new Win32PlatformOptions
|
||||
});
|
||||
}
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
appBuilder = appBuilder.With(new Win32PlatformOptions
|
||||
{
|
||||
RenderingMode =
|
||||
[
|
||||
@@ -66,11 +72,16 @@ public static class AppBuilderExtensions
|
||||
Win32RenderingMode.Software
|
||||
],
|
||||
CompositionMode = [Win32CompositionMode.RedirectionSurface]
|
||||
})
|
||||
.With(new X11PlatformOptions
|
||||
});
|
||||
}
|
||||
if (OperatingSystem.IsLinux())
|
||||
{
|
||||
appBuilder = appBuilder.With(new X11PlatformOptions
|
||||
{
|
||||
EnableDrawnDecorations = true
|
||||
})
|
||||
});
|
||||
}
|
||||
return appBuilder
|
||||
.With(new FontManagerOptions
|
||||
{
|
||||
FontFallbacks = [new FontFallback
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>$(AtomUITargetFrameworks)</TargetFrameworks>
|
||||
<RootNamespace>AtomUI</RootNamespace>
|
||||
@@ -26,7 +26,6 @@
|
||||
<PackageReference Include="Avalonia.Native" />
|
||||
<PackageReference Include="Avalonia.Win32" />
|
||||
<PackageReference Include="Avalonia"/>
|
||||
<PackageReference Include="ReactiveUI.Avalonia"/>
|
||||
<PackageReference Include="System.Reactive"/>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ public sealed class LinkedRegistrationPackageManifestGenerator : IIncrementalGen
|
||||
{
|
||||
fallbacks.Add(new Fallback(
|
||||
packageId,
|
||||
"DynamicInvocation",
|
||||
LinkedRegistrationProtocol.FallbackReasonDynamicInvocation,
|
||||
NormalizeSourcePath(candidate.Source, projectDirectory),
|
||||
candidate.Line,
|
||||
candidate.Column,
|
||||
@@ -376,7 +376,12 @@ public sealed class LinkedRegistrationPackageManifestGenerator : IIncrementalGen
|
||||
AnalyzerConfigOptionsProvider optionsProvider,
|
||||
Fallback fallback)
|
||||
{
|
||||
var descriptor = AtomUIDiagnosticDescriptors.LinkedDynamicUsageWidened;
|
||||
var descriptor = string.Equals(
|
||||
fallback.Reason,
|
||||
LinkedRegistrationProtocol.FallbackReasonDynamicInvocation,
|
||||
StringComparison.Ordinal)
|
||||
? AtomUIDiagnosticDescriptors.LinkedDynamicUsageUncovered
|
||||
: AtomUIDiagnosticDescriptors.LinkedDynamicUsageWidened;
|
||||
if (LinkedRegistrationOptions.IsRegistrationStrict(optionsProvider))
|
||||
{
|
||||
descriptor = new DiagnosticDescriptor(
|
||||
|
||||
@@ -86,6 +86,15 @@ internal static class AtomUIDiagnosticDescriptors
|
||||
isEnabledByDefault: true,
|
||||
customTags: [WellKnownDiagnosticTags.Telemetry]);
|
||||
|
||||
public static readonly DiagnosticDescriptor LinkedDynamicUsageUncovered = new(
|
||||
AtomUIDiagnosticIds.LinkedDynamicUsageUncovered,
|
||||
"Dynamic AtomUI usage is not covered by the static registration plan",
|
||||
"AtomUI dynamic usage '{0}' cannot be resolved statically; controls of Package '{1}' created only through this site are not registered. Add an AtomUIRegistrationUnitRoot when the Unit is known, or an AtomUIPackageRoot for fully dynamic usage; no action is required when this site never creates AtomUI controls.",
|
||||
AtomUIDiagnosticCategories.LinkedRegistration,
|
||||
DiagnosticSeverity.Warning,
|
||||
isEnabledByDefault: true,
|
||||
customTags: [WellKnownDiagnosticTags.Telemetry]);
|
||||
|
||||
public static readonly DiagnosticDescriptor AotMissingGeneratedAccessor = new(
|
||||
AtomUIDiagnosticIds.AotMissingGeneratedAccessor,
|
||||
"AOT-sensitive data member path requires generated accessor",
|
||||
|
||||
@@ -40,4 +40,5 @@ internal static class AtomUIDiagnosticIds
|
||||
public const string LinkedLooseAxamlWidened = "ATOMUILINK007";
|
||||
public const string LinkedPackageEntryMissing = "ATOMUILINK008";
|
||||
public const string LinkedPackageEntryInvalid = "ATOMUILINK009";
|
||||
public const string LinkedDynamicUsageUncovered = "ATOMUILINK010";
|
||||
}
|
||||
|
||||
@@ -117,8 +117,16 @@ public sealed class ApplicationRegistrationPlanGenerator : IIncrementalGenerator
|
||||
usage.Kind == LinkedUsageKind.PackageRoot &&
|
||||
string.Equals(usage.Identity, packageId, StringComparison.Ordinal)) ||
|
||||
catalog.Fallbacks.Any(fallback =>
|
||||
fallback.PackageId.Length == 0 ||
|
||||
string.Equals(fallback.PackageId, packageId, StringComparison.Ordinal));
|
||||
// Unresolvable C# dynamic creation (DynamicInvocation) is reported as
|
||||
// guidance (ATOMUILINK010) but never widens the plan: application-declared
|
||||
// controls are already covered by base-type evidence, and purely
|
||||
// string-driven creation is covered by explicit Unit/Package roots.
|
||||
!string.Equals(
|
||||
fallback.Reason,
|
||||
LinkedRegistrationProtocol.FallbackReasonDynamicInvocation,
|
||||
StringComparison.Ordinal) &&
|
||||
(fallback.PackageId.Length == 0 ||
|
||||
string.Equals(fallback.PackageId, packageId, StringComparison.Ordinal)));
|
||||
if (isLegacy)
|
||||
{
|
||||
if (ValidateFragmentMethod(
|
||||
@@ -231,12 +239,29 @@ public sealed class ApplicationRegistrationPlanGenerator : IIncrementalGenerator
|
||||
.ThenBy(static item => item.Column)
|
||||
.ThenBy(static item => item.Reason, StringComparer.Ordinal))
|
||||
{
|
||||
// ExtractedManifest marks a consumer-extracted ProjectReference Sidecar: the plan
|
||||
// already widened to full fallback, and the delivery mode is not a code problem.
|
||||
if (string.Equals(
|
||||
fallback.Reason,
|
||||
LinkedRegistrationProtocol.FallbackReasonExtractedManifest,
|
||||
StringComparison.Ordinal))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (fallback.PackageId.Length != 0 && !invokedPackageSet.Contains(fallback.PackageId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var baseDescriptor = string.Equals(
|
||||
fallback.Reason,
|
||||
LinkedRegistrationProtocol.FallbackReasonDynamicInvocation,
|
||||
StringComparison.Ordinal)
|
||||
? AtomUIDiagnosticDescriptors.LinkedDynamicUsageUncovered
|
||||
: AtomUIDiagnosticDescriptors.LinkedDynamicUsageWidened;
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
GetFallbackDescriptor(LinkedRegistrationOptions.IsRegistrationStrict(optionsProvider)),
|
||||
GetFallbackDescriptor(
|
||||
LinkedRegistrationOptions.IsRegistrationStrict(optionsProvider),
|
||||
baseDescriptor),
|
||||
Location.None,
|
||||
fallback.Reason,
|
||||
fallback.PackageId.Length == 0 ? "<all invoked packages>" : fallback.PackageId));
|
||||
@@ -379,13 +404,12 @@ public sealed class ApplicationRegistrationPlanGenerator : IIncrementalGenerator
|
||||
descriptor.CustomTags.ToArray());
|
||||
}
|
||||
|
||||
private static DiagnosticDescriptor GetFallbackDescriptor(bool strict)
|
||||
private static DiagnosticDescriptor GetFallbackDescriptor(bool strict, DiagnosticDescriptor descriptor)
|
||||
{
|
||||
if (!strict)
|
||||
{
|
||||
return AtomUIDiagnosticDescriptors.LinkedDynamicUsageWidened;
|
||||
return descriptor;
|
||||
}
|
||||
var descriptor = AtomUIDiagnosticDescriptors.LinkedDynamicUsageWidened;
|
||||
return new DiagnosticDescriptor(
|
||||
descriptor.Id,
|
||||
descriptor.Title,
|
||||
|
||||
@@ -12,4 +12,13 @@ internal static class LinkedRegistrationProtocol
|
||||
internal const string UsageManifestKey = MetadataPrefix + "Usage.v1";
|
||||
internal const string FallbackManifestKey = MetadataPrefix + "Fallback.v1";
|
||||
internal const string PlanMarkerKey = MetadataPrefix + "Plan.v1";
|
||||
|
||||
internal const string FallbackReasonAnalysisBudgetExceeded = "AnalysisBudgetExceeded";
|
||||
internal const string FallbackReasonDynamicInvocation = "DynamicInvocation";
|
||||
internal const string FallbackReasonUnresolvedOwner = "UnresolvedOwner";
|
||||
// Sidecar extracted by the consumer from assembly metadata of a normally-built
|
||||
// ProjectReference: package/unit manifests are complete, but C# unit edges are only
|
||||
// computed by linked library builds. The plan must widen to full fallback for these
|
||||
// packages, and the reason is never surfaced as a diagnostic.
|
||||
internal const string FallbackReasonExtractedManifest = "ExtractedManifest";
|
||||
}
|
||||
|
||||
@@ -387,14 +387,15 @@ public sealed class LinkedRegistrationUsageGenerator : IIncrementalGenerator
|
||||
static packageId => packageId,
|
||||
StringComparer.Ordinal))
|
||||
{
|
||||
AddPackageFallback(
|
||||
packageId,
|
||||
dynamicUse.Source,
|
||||
dynamicUse.Line,
|
||||
dynamicUse.Column,
|
||||
// C# dynamic creation sites no longer widen the package: controls declared
|
||||
// in the application are already covered by base-type evidence, and purely
|
||||
// string-driven creation is covered by explicit Unit/Package roots. Report
|
||||
// guidance only.
|
||||
ReportFallback(
|
||||
AtomUIDiagnosticDescriptors.LinkedDynamicUsageUncovered,
|
||||
dynamicUse.Location,
|
||||
AtomUIDiagnosticDescriptors.LinkedDynamicUsageWidened,
|
||||
dynamicUse.Identity);
|
||||
dynamicUse.Identity,
|
||||
packageId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user