3
3
4
4
using System . Buffers ;
5
5
using System . Collections . Immutable ;
6
+ using Microsoft . Build . Graph ;
6
7
using Microsoft . CodeAnalysis . ExternalAccess . Watch . Api ;
7
8
using Microsoft . DotNet . HotReload ;
8
9
9
10
namespace Microsoft . DotNet . Watch
10
11
{
11
- internal sealed class BlazorWebAssemblyDeltaApplier ( IReporter reporter , BrowserRefreshServer browserRefreshServer , Version ? targetFrameworkVersion ) : SingleProcessDeltaApplier ( reporter )
12
+ internal sealed class BlazorWebAssemblyDeltaApplier ( IReporter reporter , BrowserRefreshServer browserRefreshServer , ProjectGraphNode project ) : SingleProcessDeltaApplier ( reporter )
12
13
{
13
- private const string DefaultCapabilities60 = "Baseline" ;
14
- private const string DefaultCapabilities70 = "Baseline AddMethodToExistingType AddStaticFieldToExistingType NewTypeDefinition ChangeCustomAttributes" ;
15
- private const string DefaultCapabilities80 = "Baseline AddMethodToExistingType AddStaticFieldToExistingType NewTypeDefinition ChangeCustomAttributes AddInstanceFieldToExistingType GenericAddMethodToExistingType GenericUpdateMethod UpdateParameters GenericAddFieldToExistingType" ;
14
+ private static readonly ImmutableArray < string > s_defaultCapabilities60 =
15
+ [ "Baseline" ] ;
16
+
17
+ private static readonly ImmutableArray < string > s_defaultCapabilities70 =
18
+ [ "Baseline" , "AddMethodToExistingType" , "AddStaticFieldToExistingType" , "NewTypeDefinition" , "ChangeCustomAttributes" ] ;
19
+
20
+ private static readonly ImmutableArray < string > s_defaultCapabilities80 =
21
+ [ "Baseline" , "AddMethodToExistingType" , "AddStaticFieldToExistingType" , "NewTypeDefinition" , "ChangeCustomAttributes" ,
22
+ "AddInstanceFieldToExistingType" , "GenericAddMethodToExistingType" , "GenericUpdateMethod" , "UpdateParameters" , "GenericAddFieldToExistingType" ] ;
23
+
24
+ private static readonly ImmutableArray < string > s_defaultCapabilities90 =
25
+ s_defaultCapabilities80 ;
16
26
17
- private ImmutableArray < string > _cachedCapabilities ;
18
- private readonly SemaphoreSlim _capabilityRetrievalSemaphore = new ( initialCount : 1 ) ;
19
27
private int _updateId ;
20
28
21
29
public override void Dispose ( )
@@ -32,109 +40,31 @@ public override async Task WaitForProcessRunningAsync(CancellationToken cancella
32
40
// Alternatively, we could inject agent into blazor-devserver.dll and establish a connection on the named pipe.
33
41
=> await browserRefreshServer . WaitForClientConnectionAsync ( cancellationToken ) ;
34
42
35
- public override async Task < ImmutableArray < string > > GetApplyUpdateCapabilitiesAsync ( CancellationToken cancellationToken )
43
+ public override Task < ImmutableArray < string > > GetApplyUpdateCapabilitiesAsync ( CancellationToken cancellationToken )
36
44
{
37
- var cachedCapabilities = _cachedCapabilities ;
38
- if ( ! cachedCapabilities . IsDefault )
39
- {
40
- return cachedCapabilities ;
41
- }
45
+ var capabilities = project . GetWebAssemblyCapabilities ( ) ;
42
46
43
- await _capabilityRetrievalSemaphore . WaitAsync ( cancellationToken ) ;
44
- try
45
- {
46
- if ( _cachedCapabilities . IsDefault )
47
- {
48
- _cachedCapabilities = await RetrieveAsync ( cancellationToken ) ;
49
- }
50
- }
51
- finally
47
+ if ( capabilities . IsEmpty )
52
48
{
53
- _capabilityRetrievalSemaphore . Release ( ) ;
54
- }
49
+ var targetFramework = project . GetTargetFrameworkVersion ( ) ;
55
50
56
- return _cachedCapabilities ;
57
-
58
- async Task < ImmutableArray < string > > RetrieveAsync ( CancellationToken cancellationToken )
59
- {
60
- var buffer = ArrayPool < byte > . Shared . Rent ( 32 * 1024 ) ;
51
+ Reporter . Verbose ( $ "Using capabilities based on target framework: '{ targetFramework } '.") ;
61
52
62
- try
53
+ capabilities = targetFramework ? . Major switch
63
54
{
64
- Reporter . Verbose ( "Connecting to the browser." ) ;
65
-
66
- await browserRefreshServer . WaitForClientConnectionAsync ( cancellationToken ) ;
67
-
68
- string capabilities ;
69
- if ( browserRefreshServer . Options . TestFlags . HasFlag ( TestFlags . MockBrowser ) )
70
- {
71
- // When testing return default capabilities without connecting to an actual browser.
72
- capabilities = GetDefaultCapabilities ( targetFrameworkVersion ) ;
73
- }
74
- else
75
- {
76
- string ? capabilityString = null ;
77
-
78
- await browserRefreshServer . SendAndReceiveAsync (
79
- request : _ => default ( JsonGetApplyUpdateCapabilitiesRequest ) ,
80
- response : ( value , reporter ) =>
81
- {
82
- var str = Encoding . UTF8 . GetString ( value ) ;
83
- if ( str . StartsWith ( '!' ) )
84
- {
85
- reporter . Verbose ( $ "Exception while reading WASM runtime capabilities: { str [ 1 ..] } ") ;
86
- }
87
- else if ( str . Length == 0 )
88
- {
89
- reporter . Verbose ( $ "Unable to read WASM runtime capabilities") ;
90
- }
91
- else if ( capabilityString == null )
92
- {
93
- capabilityString = str ;
94
- }
95
- else if ( capabilityString != str )
96
- {
97
- reporter . Verbose ( $ "Received different capabilities from different browsers:{ Environment . NewLine } '{ str } '{ Environment . NewLine } '{ capabilityString } '") ;
98
- }
99
- } ,
100
- cancellationToken ) ;
101
-
102
- if ( capabilityString != null )
103
- {
104
- capabilities = capabilityString ;
105
- }
106
- else
107
- {
108
- capabilities = GetDefaultCapabilities ( targetFrameworkVersion ) ;
109
- Reporter . Verbose ( $ "Falling back to default WASM capabilities: '{ capabilities } '") ;
110
- }
111
- }
112
-
113
- // Capabilities are expressed a space-separated string.
114
- // e.g. https://github.com/dotnet/runtime/blob/14343bdc281102bf6fffa1ecdd920221d46761bc/src/coreclr/System.Private.CoreLib/src/System/Reflection/Metadata/AssemblyExtensions.cs#L87
115
- return capabilities . Split ( ' ' ) . ToImmutableArray ( ) ;
116
- }
117
- catch ( Exception e ) when ( ! cancellationToken . IsCancellationRequested )
118
- {
119
- Reporter . Error ( $ "Failed to read capabilities: { e . Message } ") ;
120
-
121
- // Do not attempt to retrieve capabilities again if it fails once, unless the operation is canceled.
122
- return [ ] ;
123
- }
124
- finally
125
- {
126
- ArrayPool < byte > . Shared . Return ( buffer ) ;
127
- }
55
+ 9 => s_defaultCapabilities90 ,
56
+ 8 => s_defaultCapabilities80 ,
57
+ 7 => s_defaultCapabilities70 ,
58
+ 6 => s_defaultCapabilities60 ,
59
+ _ => [ ] ,
60
+ } ;
61
+ }
62
+ else
63
+ {
64
+ Reporter . Verbose ( $ "Project specifies capabilities.") ;
128
65
}
129
66
130
- static string GetDefaultCapabilities ( Version ? targetFrameworkVersion )
131
- => targetFrameworkVersion ? . Major switch
132
- {
133
- >= 8 => DefaultCapabilities80 ,
134
- >= 7 => DefaultCapabilities70 ,
135
- >= 6 => DefaultCapabilities60 ,
136
- _ => string . Empty ,
137
- } ;
67
+ return Task . FromResult ( capabilities ) ;
138
68
}
139
69
140
70
public override async Task < ApplyStatus > Apply ( ImmutableArray < WatchHotReloadService . Update > updates , CancellationToken cancellationToken )
0 commit comments