com.wallstop-studios.dxmessaging 3.0.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +211 -2
- package/Editor/Analyzers/DxMessagingConsoleHarvester.cs +69 -62
- package/Editor/Analyzers/Microsoft.CodeAnalysis.CSharp.dll.meta +3 -3
- package/Editor/Analyzers/Microsoft.CodeAnalysis.dll.meta +3 -3
- package/Editor/Analyzers/System.Collections.Immutable.dll.meta +3 -3
- package/Editor/Analyzers/System.Reflection.Metadata.dll.meta +3 -3
- package/Editor/Analyzers/System.Runtime.CompilerServices.Unsafe.dll.meta +3 -3
- package/Editor/Analyzers/WallstopStudios.DxMessaging.Analyzer.dll +0 -0
- package/Editor/Analyzers/WallstopStudios.DxMessaging.Analyzer.dll.meta +15 -2
- package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll +0 -0
- package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll.meta +2 -2
- package/Editor/AssemblyInfo.cs.meta +9 -1
- package/Editor/CustomEditors/MessageAwareComponentInspectorOverlay.cs +24 -15
- package/Editor/CustomEditors/MessagingComponentEditor.cs.meta +9 -1
- package/Editor/DxMessagingEditorIdle.cs +62 -0
- package/{Runtime/Core/Internal/TypedDispatchLinkIndex.cs.meta → Editor/DxMessagingEditorIdle.cs.meta} +1 -1
- package/Editor/DxMessagingEditorInitializer.cs +112 -15
- package/Editor/DxMessagingEditorInitializer.cs.meta +9 -1
- package/Editor/DxMessagingEditorLog.cs +32 -0
- package/Editor/DxMessagingEditorLog.cs.meta +11 -0
- package/Editor/Settings/DxMessagingBaseCallIgnoreSync.cs +135 -12
- package/Editor/Settings/DxMessagingSettings.cs +92 -31
- package/Editor/Settings/DxMessagingSettings.cs.meta +9 -1
- package/Editor/Settings/DxMessagingSettingsProvider.cs.meta +9 -1
- package/Editor/SetupCscRsp.cs +339 -173
- package/Editor/SetupCscRsp.cs.meta +9 -1
- package/Editor/Testing/MessagingComponentEditorHarness.cs +1 -1
- package/Editor/Testing/MessagingComponentEditorHarness.cs.meta +9 -1
- package/README.md +17 -18
- package/Runtime/AssemblyInfo.cs.meta +9 -1
- package/Runtime/Core/Attributes/DxAutoConstructorAttribute.cs.meta +9 -1
- package/Runtime/Core/Attributes/DxBroadcastMessageAttribute.cs.meta +9 -1
- package/Runtime/Core/Attributes/DxOptionalParameterAttribute.cs +2 -4
- package/Runtime/Core/Attributes/DxOptionalParameterAttribute.cs.meta +9 -1
- package/Runtime/Core/Attributes/DxTargetedMessageAttribute.cs.meta +9 -1
- package/Runtime/Core/Attributes/DxUntargetedMessageAttribute.cs.meta +9 -1
- package/Runtime/Core/Attributes/Il2CppSetOptionAttribute.cs +56 -0
- package/Runtime/Core/Attributes/Il2CppSetOptionAttribute.cs.meta +11 -0
- package/Runtime/Core/DataStructure/CyclicBuffer.cs +44 -26
- package/Runtime/Core/DataStructure/CyclicBuffer.cs.meta +9 -1
- package/Runtime/Core/Diagnostics/MessageEmissionData.cs.meta +9 -1
- package/Runtime/Core/Diagnostics/MessageRegistrationData.cs.meta +9 -1
- package/Runtime/Core/Diagnostics/MessageRegistrationType.cs.meta +9 -1
- package/Runtime/Core/Extensions/EnumExtensions.cs +6 -5
- package/Runtime/Core/Extensions/EnumExtensions.cs.meta +9 -1
- package/Runtime/Core/Extensions/IListExtensions.cs.meta +9 -1
- package/Runtime/Core/Extensions/MessageExtensions.cs +0 -60
- package/Runtime/Core/Helper/MessageCache.cs.meta +9 -1
- package/Runtime/Core/Helper/MessageHelperIndexer.cs.meta +9 -1
- package/Runtime/Core/InstanceId.cs +25 -1
- package/Runtime/Core/Internal/DxUnsafe.cs +60 -0
- package/Runtime/Core/Internal/DxUnsafe.cs.meta +11 -0
- package/Runtime/Core/Internal/FlatDispatch.cs +198 -0
- package/Runtime/Core/Internal/FlatDispatch.cs.meta +11 -0
- package/Runtime/Core/Internal/TypedSlots.cs +5 -21
- package/Runtime/Core/MessageBus/IMessageBus.cs +12 -12
- package/Runtime/Core/MessageBus/IMessageRegistrationBuilder.cs +1 -0
- package/Runtime/Core/MessageBus/Internal/BusSlots.cs +7 -6
- package/Runtime/Core/MessageBus/MessageBus.cs +2313 -2936
- package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs +187 -14
- package/Runtime/Core/MessageHandler.cs +1023 -1143
- package/Runtime/Core/MessageRegistrationToken.cs +425 -47
- package/Runtime/Core/Messages/GlobalStringMessage.cs.meta +9 -1
- package/Runtime/Core/Messages/ReflexiveMessage.cs.meta +9 -1
- package/Runtime/Core/Messages/StringMessage.cs.meta +9 -1
- package/Runtime/Unity/Integrations/Reflex/AssemblyInfo.cs.meta +9 -1
- package/Runtime/Unity/Integrations/VContainer/AssemblyInfo.cs.meta +9 -1
- package/Runtime/Unity/Integrations/Zenject/AssemblyInfo.cs.meta +9 -1
- package/Runtime/Unity/MessageAwareComponent.cs +46 -1
- package/Runtime/Unity/MessagingComponent.cs +43 -10
- package/Runtime/WallstopStudios.DxMessaging.asmdef +1 -1
- package/Samples~/DI/README.md +7 -7
- package/SourceGenerators/Directory.Build.props +50 -3
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoConstructorGenerator.cs +96 -63
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs +745 -87
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs.meta +9 -1
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.csproj +39 -46
- package/SourceGenerators/global.json +7 -0
- package/SourceGenerators/global.json.meta +7 -0
- package/package.json +27 -40
- package/Runtime/Core/Internal/TypedDispatchLinkIndex.cs +0 -51
package/Editor/SetupCscRsp.cs
CHANGED
|
@@ -31,10 +31,9 @@ namespace DxMessaging.Editor
|
|
|
31
31
|
private static readonly string SourceGeneratorDllName =
|
|
32
32
|
"WallstopStudios.DxMessaging.SourceGenerators.dll";
|
|
33
33
|
|
|
34
|
-
// The analyzer DLL is a SEPARATE assembly
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
// Both DLLs ship side-by-side and both need the RoslynAnalyzer label.
|
|
34
|
+
// The analyzer DLL is a SEPARATE assembly, but both compiler-host DLLs are pinned to
|
|
35
|
+
// Unity 2021-compatible Roslyn 3.8.0. They ship side-by-side and both need the
|
|
36
|
+
// RoslynAnalyzer label.
|
|
38
37
|
private static readonly string AnalyzerDllName = "WallstopStudios.DxMessaging.Analyzer.dll";
|
|
39
38
|
|
|
40
39
|
// The analyzer DLLs and shared Roslyn surface ship unconditionally; they're light enough
|
|
@@ -73,9 +72,36 @@ namespace DxMessaging.Editor
|
|
|
73
72
|
|
|
74
73
|
static SetupCscRsp()
|
|
75
74
|
{
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
ScheduleSetupStep(EnsureDLLsExistInAssets, "copy analyzer DLLs into Assets");
|
|
76
|
+
ScheduleSetupStep(EnsureCscRsp, "clean csc.rsp analyzer entries");
|
|
77
|
+
ScheduleAdditionalFileForIgnoreListSync();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
internal static void ScheduleAdditionalFileForIgnoreListSync()
|
|
81
|
+
{
|
|
82
|
+
ScheduleSetupStep(
|
|
83
|
+
EnsureAdditionalFileForIgnoreList,
|
|
84
|
+
"sync csc.rsp base-call ignore additionalfile entry"
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private static void ScheduleSetupStep(Action work, string description)
|
|
89
|
+
{
|
|
90
|
+
DxMessagingEditorIdle.ScheduleAssetDatabaseMutation(() =>
|
|
91
|
+
RunSetupStep(work, description)
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private static void RunSetupStep(Action work, string description)
|
|
96
|
+
{
|
|
97
|
+
try
|
|
98
|
+
{
|
|
99
|
+
work();
|
|
100
|
+
}
|
|
101
|
+
catch (Exception ex)
|
|
102
|
+
{
|
|
103
|
+
DxMessagingEditorLog.LogError($"SetupCscRsp failed to {description}.", ex);
|
|
104
|
+
}
|
|
79
105
|
}
|
|
80
106
|
|
|
81
107
|
private static void EnsureDLLsExistInAssets()
|
|
@@ -149,21 +175,28 @@ namespace DxMessaging.Editor
|
|
|
149
175
|
{
|
|
150
176
|
bool importerDirty = false;
|
|
151
177
|
|
|
178
|
+
// A RoslynAnalyzer-labeled DLL must be EXCLUDED from every
|
|
179
|
+
// build platform, including the Editor, so Unity treats it as a
|
|
180
|
+
// C# compiler analyzer rather than a managed precompiled
|
|
181
|
+
// assembly. The same-named DLL is importable from two locations
|
|
182
|
+
// (the package's own Editor/Analyzers copy and this Assets
|
|
183
|
+
// copy); if either is an Editor-enabled precompiled assembly,
|
|
184
|
+
// Unity 2021 aborts with "Multiple precompiled assemblies with
|
|
185
|
+
// the same name". The Roslyn runtime dependencies in the same
|
|
186
|
+
// folder already ship Editor-disabled and never collide -- this
|
|
187
|
+
// converges the analyzer DLLs onto that proven-safe shape.
|
|
188
|
+
// NOTE: SetExcludeFromAnyPlatform is a no-op once
|
|
189
|
+
// CompatibleWithAnyPlatform is false, so the Editor platform is
|
|
190
|
+
// disabled through the effective SetCompatibleWithEditor API.
|
|
152
191
|
if (importer.GetCompatibleWithAnyPlatform())
|
|
153
192
|
{
|
|
154
193
|
importer.SetCompatibleWithAnyPlatform(false);
|
|
155
194
|
importerDirty = true;
|
|
156
195
|
}
|
|
157
196
|
|
|
158
|
-
if (importer.
|
|
159
|
-
{
|
|
160
|
-
importer.SetExcludeFromAnyPlatform("Editor", false);
|
|
161
|
-
importerDirty = true;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if (!importer.GetExcludeFromAnyPlatform("Standalone"))
|
|
197
|
+
if (importer.GetCompatibleWithEditor())
|
|
165
198
|
{
|
|
166
|
-
importer.
|
|
199
|
+
importer.SetCompatibleWithEditor(false);
|
|
167
200
|
importerDirty = true;
|
|
168
201
|
}
|
|
169
202
|
|
|
@@ -176,10 +209,11 @@ namespace DxMessaging.Editor
|
|
|
176
209
|
DllNames.Add(requiredDllName);
|
|
177
210
|
break;
|
|
178
211
|
}
|
|
179
|
-
catch (Exception
|
|
212
|
+
catch (Exception ex)
|
|
180
213
|
{
|
|
181
|
-
|
|
182
|
-
$"Failed to copy {requiredDllName} to Assets
|
|
214
|
+
DxMessagingEditorLog.LogError(
|
|
215
|
+
$"Failed to copy {requiredDllName} to Assets.",
|
|
216
|
+
ex
|
|
183
217
|
);
|
|
184
218
|
}
|
|
185
219
|
}
|
|
@@ -214,9 +248,14 @@ namespace DxMessaging.Editor
|
|
|
214
248
|
}
|
|
215
249
|
|
|
216
250
|
/// <summary>
|
|
217
|
-
///
|
|
218
|
-
/// on-disk DLL roster.
|
|
251
|
+
/// Removes stale DxMessaging analyzer <c>-a:</c> entries from <c>csc.rsp</c>.
|
|
219
252
|
/// </summary>
|
|
253
|
+
/// <remarks>
|
|
254
|
+
/// DxMessaging analyzers are activated solely through the RoslynAnalyzer-labeled
|
|
255
|
+
/// <c>Assets/Plugins/Editor/WallstopStudios.DxMessaging</c> copy. A second
|
|
256
|
+
/// <c>-a:</c> registration here double-loads the analyzer/source-generator, and
|
|
257
|
+
/// registering dependency DLLs as analyzers makes Unity's compiler path fragile.
|
|
258
|
+
/// </remarks>
|
|
220
259
|
private static void EnsureCscRsp()
|
|
221
260
|
{
|
|
222
261
|
try
|
|
@@ -229,72 +268,12 @@ namespace DxMessaging.Editor
|
|
|
229
268
|
|
|
230
269
|
string rspContent = File.ReadAllText(RspFilePath);
|
|
231
270
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
StringComparer.OrdinalIgnoreCase
|
|
271
|
+
string[] newLines = CleanDxMessagingAnalyzerLines(
|
|
272
|
+
rspContent.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries),
|
|
273
|
+
out bool foundStaleEntries
|
|
236
274
|
);
|
|
237
275
|
|
|
238
|
-
|
|
239
|
-
List<string> newLines = new();
|
|
240
|
-
bool foundStaleEntries = false;
|
|
241
|
-
|
|
242
|
-
foreach (
|
|
243
|
-
string line in rspContent.Split(
|
|
244
|
-
new[] { '\r', '\n' },
|
|
245
|
-
StringSplitOptions.RemoveEmptyEntries
|
|
246
|
-
)
|
|
247
|
-
)
|
|
248
|
-
{
|
|
249
|
-
string trimmedLine = line.Trim();
|
|
250
|
-
|
|
251
|
-
// Check if this is a DxMessaging analyzer line
|
|
252
|
-
bool isDxMessagingAnalyzer =
|
|
253
|
-
trimmedLine.StartsWith("-a:", StringComparison.OrdinalIgnoreCase)
|
|
254
|
-
&& (
|
|
255
|
-
trimmedLine.Contains(
|
|
256
|
-
"com.wallstop-studios.dxmessaging",
|
|
257
|
-
StringComparison.OrdinalIgnoreCase
|
|
258
|
-
)
|
|
259
|
-
|| trimmedLine.Contains(
|
|
260
|
-
"WallstopStudios.DxMessaging",
|
|
261
|
-
StringComparison.OrdinalIgnoreCase
|
|
262
|
-
)
|
|
263
|
-
);
|
|
264
|
-
|
|
265
|
-
if (isDxMessagingAnalyzer)
|
|
266
|
-
{
|
|
267
|
-
// Only keep if it's in the current valid set
|
|
268
|
-
if (currentAnalyzerArgs.Contains(trimmedLine))
|
|
269
|
-
{
|
|
270
|
-
newLines.Add(trimmedLine);
|
|
271
|
-
}
|
|
272
|
-
else
|
|
273
|
-
{
|
|
274
|
-
foundStaleEntries = true;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
else
|
|
278
|
-
{
|
|
279
|
-
// Keep all non-DxMessaging lines as-is
|
|
280
|
-
newLines.Add(trimmedLine);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// Add any new analyzer arguments that aren't already present
|
|
285
|
-
bool foundNewEntries = false;
|
|
286
|
-
foreach (string analyzerArgument in currentAnalyzerArgs)
|
|
287
|
-
{
|
|
288
|
-
if (!newLines.Contains(analyzerArgument, StringComparer.OrdinalIgnoreCase))
|
|
289
|
-
{
|
|
290
|
-
newLines.Add(analyzerArgument);
|
|
291
|
-
foundNewEntries = true;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
bool modified = foundStaleEntries || foundNewEntries;
|
|
296
|
-
|
|
297
|
-
if (modified)
|
|
276
|
+
if (foundStaleEntries)
|
|
298
277
|
{
|
|
299
278
|
// Write the cleaned up content
|
|
300
279
|
string newContent = string.Join(Environment.NewLine, newLines);
|
|
@@ -309,18 +288,88 @@ namespace DxMessaging.Editor
|
|
|
309
288
|
}
|
|
310
289
|
catch (IOException ex)
|
|
311
290
|
{
|
|
312
|
-
|
|
291
|
+
DxMessagingEditorLog.LogError("Failed to modify csc.rsp.", ex);
|
|
313
292
|
}
|
|
314
293
|
}
|
|
315
294
|
|
|
295
|
+
internal static string[] CleanDxMessagingAnalyzerLines(
|
|
296
|
+
IEnumerable<string> lines,
|
|
297
|
+
out bool foundStaleEntries
|
|
298
|
+
)
|
|
299
|
+
{
|
|
300
|
+
List<string> newLines = new();
|
|
301
|
+
foundStaleEntries = false;
|
|
302
|
+
|
|
303
|
+
foreach (string line in lines ?? Array.Empty<string>())
|
|
304
|
+
{
|
|
305
|
+
string trimmedLine = line?.Trim();
|
|
306
|
+
if (string.IsNullOrEmpty(trimmedLine))
|
|
307
|
+
{
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (IsResponseFileComment(trimmedLine))
|
|
312
|
+
{
|
|
313
|
+
newLines.Add(trimmedLine);
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
List<string> retainedArguments = new();
|
|
318
|
+
bool removedFromLine = false;
|
|
319
|
+
foreach (string argument in SplitResponseFileArguments(trimmedLine))
|
|
320
|
+
{
|
|
321
|
+
if (IsDxMessagingAnalyzerArgument(argument))
|
|
322
|
+
{
|
|
323
|
+
foundStaleEntries = true;
|
|
324
|
+
removedFromLine = true;
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
retainedArguments.Add(argument);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (removedFromLine)
|
|
332
|
+
{
|
|
333
|
+
if (retainedArguments.Count > 0)
|
|
334
|
+
{
|
|
335
|
+
newLines.Add(string.Join(" ", retainedArguments));
|
|
336
|
+
}
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
newLines.Add(trimmedLine);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
return newLines.ToArray();
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
private static bool IsDxMessagingAnalyzerArgument(string trimmedLine)
|
|
347
|
+
{
|
|
348
|
+
return (
|
|
349
|
+
TryGetCompilerOptionValue(trimmedLine, "a", out string _)
|
|
350
|
+
|| TryGetCompilerOptionValue(trimmedLine, "analyzer", out string _)
|
|
351
|
+
)
|
|
352
|
+
&& (
|
|
353
|
+
trimmedLine.Contains(
|
|
354
|
+
"com.wallstop-studios.dxmessaging",
|
|
355
|
+
StringComparison.OrdinalIgnoreCase
|
|
356
|
+
)
|
|
357
|
+
|| trimmedLine.Contains(
|
|
358
|
+
"WallstopStudios.DxMessaging",
|
|
359
|
+
StringComparison.OrdinalIgnoreCase
|
|
360
|
+
)
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
|
|
316
364
|
/// <summary>
|
|
317
365
|
/// Ensures <c>csc.rsp</c> contains a single <c>-additionalfile:</c> line pointing at the
|
|
318
366
|
/// base-call ignore sidecar, when (and only when) that sidecar physically exists. Stale
|
|
319
367
|
/// entries pointing at moved or deleted sidecar paths are removed.
|
|
320
368
|
/// </summary>
|
|
321
369
|
/// <remarks>
|
|
322
|
-
/// The sidecar is generated by <see cref="DxMessagingBaseCallIgnoreSync"
|
|
323
|
-
///
|
|
370
|
+
/// The sidecar is generated by <see cref="DxMessagingBaseCallIgnoreSync"/>. csc happily
|
|
371
|
+
/// runs without it, so this method does NOT auto-create; sidecar writes schedule this sync
|
|
372
|
+
/// again after deferred regeneration completes.
|
|
324
373
|
/// </remarks>
|
|
325
374
|
private static void EnsureAdditionalFileForIgnoreList()
|
|
326
375
|
{
|
|
@@ -339,74 +388,12 @@ namespace DxMessaging.Editor
|
|
|
339
388
|
.Replace("\\", "/");
|
|
340
389
|
|
|
341
390
|
bool sidecarExists = File.Exists(sidecarAbsolutePath);
|
|
342
|
-
string
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
foreach (
|
|
350
|
-
string line in rspContent.Split(
|
|
351
|
-
new[] { '\r', '\n' },
|
|
352
|
-
StringSplitOptions.RemoveEmptyEntries
|
|
353
|
-
)
|
|
354
|
-
)
|
|
355
|
-
{
|
|
356
|
-
string trimmedLine = line.Trim();
|
|
357
|
-
|
|
358
|
-
bool isDxMessagingAdditionalFile =
|
|
359
|
-
trimmedLine.StartsWith(
|
|
360
|
-
"-additionalfile:",
|
|
361
|
-
StringComparison.OrdinalIgnoreCase
|
|
362
|
-
)
|
|
363
|
-
&& trimmedLine.Contains("DxMessaging.", StringComparison.OrdinalIgnoreCase)
|
|
364
|
-
&& trimmedLine.Contains(
|
|
365
|
-
"BaseCallIgnore",
|
|
366
|
-
StringComparison.OrdinalIgnoreCase
|
|
367
|
-
);
|
|
368
|
-
|
|
369
|
-
if (isDxMessagingAdditionalFile)
|
|
370
|
-
{
|
|
371
|
-
if (
|
|
372
|
-
sidecarExists
|
|
373
|
-
&& string.Equals(
|
|
374
|
-
trimmedLine,
|
|
375
|
-
desiredLine,
|
|
376
|
-
StringComparison.OrdinalIgnoreCase
|
|
377
|
-
)
|
|
378
|
-
)
|
|
379
|
-
{
|
|
380
|
-
if (!foundDesired)
|
|
381
|
-
{
|
|
382
|
-
newLines.Add(trimmedLine);
|
|
383
|
-
foundDesired = true;
|
|
384
|
-
}
|
|
385
|
-
else
|
|
386
|
-
{
|
|
387
|
-
// Drop duplicate.
|
|
388
|
-
foundStale = true;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
else
|
|
392
|
-
{
|
|
393
|
-
// Stale entry pointing at a moved/renamed/deleted sidecar; drop it.
|
|
394
|
-
foundStale = true;
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
else
|
|
398
|
-
{
|
|
399
|
-
newLines.Add(trimmedLine);
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
bool needsAppend = sidecarExists && !foundDesired;
|
|
404
|
-
if (needsAppend)
|
|
405
|
-
{
|
|
406
|
-
newLines.Add(desiredLine);
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
bool modified = foundStale || needsAppend;
|
|
391
|
+
string[] newLines = SynchronizeAdditionalFileForIgnoreListLines(
|
|
392
|
+
File.ReadAllLines(RspFilePath),
|
|
393
|
+
sidecarRelativePath,
|
|
394
|
+
sidecarExists,
|
|
395
|
+
out bool modified
|
|
396
|
+
);
|
|
410
397
|
|
|
411
398
|
if (modified)
|
|
412
399
|
{
|
|
@@ -422,46 +409,225 @@ namespace DxMessaging.Editor
|
|
|
422
409
|
}
|
|
423
410
|
catch (IOException ex)
|
|
424
411
|
{
|
|
425
|
-
|
|
412
|
+
DxMessagingEditorLog.LogError("Failed to update csc.rsp additionalfile entry.", ex);
|
|
426
413
|
}
|
|
427
414
|
}
|
|
428
415
|
|
|
429
|
-
|
|
416
|
+
internal static string[] SynchronizeAdditionalFileForIgnoreListLines(
|
|
417
|
+
IEnumerable<string> lines,
|
|
418
|
+
string sidecarRelativePath,
|
|
419
|
+
bool sidecarExists,
|
|
420
|
+
out bool modified
|
|
421
|
+
)
|
|
430
422
|
{
|
|
431
|
-
|
|
432
|
-
string
|
|
423
|
+
string desiredLine = FormatAdditionalFileArgument(sidecarRelativePath);
|
|
424
|
+
List<string> newLines = new();
|
|
425
|
+
bool foundDesired = false;
|
|
426
|
+
bool foundStale = false;
|
|
433
427
|
|
|
434
|
-
foreach (string
|
|
428
|
+
foreach (string line in lines ?? Array.Empty<string>())
|
|
435
429
|
{
|
|
436
|
-
|
|
430
|
+
string trimmedLine = line?.Trim();
|
|
431
|
+
if (string.IsNullOrEmpty(trimmedLine))
|
|
432
|
+
{
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (IsResponseFileComment(trimmedLine))
|
|
437
437
|
{
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
438
|
+
newLines.Add(trimmedLine);
|
|
439
|
+
continue;
|
|
440
|
+
}
|
|
441
441
|
|
|
442
|
-
|
|
443
|
-
|
|
442
|
+
List<string> retainedArguments = new();
|
|
443
|
+
bool removedFromLine = false;
|
|
444
|
+
foreach (string argument in SplitResponseFileArguments(trimmedLine))
|
|
445
|
+
{
|
|
446
|
+
if (!IsDxMessagingBaseCallIgnoreAdditionalFile(argument))
|
|
444
447
|
{
|
|
448
|
+
retainedArguments.Add(argument);
|
|
445
449
|
continue;
|
|
446
450
|
}
|
|
447
451
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
if (
|
|
452
|
+
bool isDesired =
|
|
453
|
+
sidecarExists
|
|
454
|
+
&& IsAdditionalFileArgumentForPath(argument, sidecarRelativePath);
|
|
455
|
+
if (!isDesired)
|
|
452
456
|
{
|
|
457
|
+
// Stale entry pointing at a moved/renamed/deleted sidecar; drop it.
|
|
458
|
+
foundStale = true;
|
|
459
|
+
removedFromLine = true;
|
|
453
460
|
continue;
|
|
454
461
|
}
|
|
455
462
|
|
|
456
|
-
|
|
457
|
-
if (!yielded.Add(normalizedRelativePath))
|
|
463
|
+
if (foundDesired)
|
|
458
464
|
{
|
|
465
|
+
// Drop duplicate.
|
|
466
|
+
foundStale = true;
|
|
467
|
+
removedFromLine = true;
|
|
459
468
|
continue;
|
|
460
469
|
}
|
|
461
470
|
|
|
462
|
-
|
|
471
|
+
retainedArguments.Add(desiredLine);
|
|
472
|
+
foundDesired = true;
|
|
473
|
+
if (!string.Equals(argument, desiredLine, StringComparison.Ordinal))
|
|
474
|
+
{
|
|
475
|
+
foundStale = true;
|
|
476
|
+
removedFromLine = true;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
if (retainedArguments.Count > 0)
|
|
481
|
+
{
|
|
482
|
+
newLines.Add(string.Join(" ", retainedArguments));
|
|
483
|
+
continue;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
if (!removedFromLine)
|
|
487
|
+
{
|
|
488
|
+
newLines.Add(trimmedLine);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
bool needsAppend = sidecarExists && !foundDesired;
|
|
493
|
+
if (needsAppend)
|
|
494
|
+
{
|
|
495
|
+
newLines.Add(desiredLine);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
modified = foundStale || needsAppend;
|
|
499
|
+
return newLines.ToArray();
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
private static string FormatAdditionalFileArgument(string sidecarRelativePath)
|
|
503
|
+
{
|
|
504
|
+
return $"-additionalfile:\"{sidecarRelativePath}\"";
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
private static bool IsResponseFileComment(string trimmedLine)
|
|
508
|
+
{
|
|
509
|
+
return trimmedLine.StartsWith("#", StringComparison.Ordinal);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
private static bool IsDxMessagingBaseCallIgnoreAdditionalFile(string trimmedLine)
|
|
513
|
+
{
|
|
514
|
+
return TryGetCompilerOptionValue(trimmedLine, "additionalfile", out string value)
|
|
515
|
+
&& value.Contains("DxMessaging.", StringComparison.OrdinalIgnoreCase)
|
|
516
|
+
&& value.Contains("BaseCallIgnore", StringComparison.OrdinalIgnoreCase);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
private static bool IsAdditionalFileArgumentForPath(
|
|
520
|
+
string argument,
|
|
521
|
+
string sidecarRelativePath
|
|
522
|
+
)
|
|
523
|
+
{
|
|
524
|
+
if (!TryGetCompilerOptionValue(argument, "additionalfile", out string value))
|
|
525
|
+
{
|
|
526
|
+
return false;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
string unquotedValue = UnquoteWholeArgument(value.Trim());
|
|
530
|
+
return string.Equals(
|
|
531
|
+
unquotedValue.Replace("\\", "/"),
|
|
532
|
+
sidecarRelativePath,
|
|
533
|
+
StringComparison.OrdinalIgnoreCase
|
|
534
|
+
);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
private static bool TryGetCompilerOptionValue(
|
|
538
|
+
string argument,
|
|
539
|
+
string optionName,
|
|
540
|
+
out string value
|
|
541
|
+
)
|
|
542
|
+
{
|
|
543
|
+
value = string.Empty;
|
|
544
|
+
if (string.IsNullOrEmpty(argument) || string.IsNullOrEmpty(optionName))
|
|
545
|
+
{
|
|
546
|
+
return false;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
string unquotedArgument = UnquoteWholeArgument(argument.Trim());
|
|
550
|
+
if (unquotedArgument.Length <= optionName.Length + 1)
|
|
551
|
+
{
|
|
552
|
+
return false;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
if (unquotedArgument[0] != '-' && unquotedArgument[0] != '/')
|
|
556
|
+
{
|
|
557
|
+
return false;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
if (unquotedArgument[optionName.Length + 1] != ':')
|
|
561
|
+
{
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
if (
|
|
566
|
+
string.Compare(
|
|
567
|
+
unquotedArgument,
|
|
568
|
+
1,
|
|
569
|
+
optionName,
|
|
570
|
+
0,
|
|
571
|
+
optionName.Length,
|
|
572
|
+
StringComparison.OrdinalIgnoreCase
|
|
573
|
+
) != 0
|
|
574
|
+
)
|
|
575
|
+
{
|
|
576
|
+
return false;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
value = unquotedArgument.Substring(optionName.Length + 2);
|
|
580
|
+
return true;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
private static string UnquoteWholeArgument(string argument)
|
|
584
|
+
{
|
|
585
|
+
if (argument.Length >= 2 && argument[0] == '"' && argument[argument.Length - 1] == '"')
|
|
586
|
+
{
|
|
587
|
+
return argument.Substring(1, argument.Length - 2).Replace("\"\"", "\"");
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
return argument;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
private static List<string> SplitResponseFileArguments(string line)
|
|
594
|
+
{
|
|
595
|
+
List<string> arguments = new();
|
|
596
|
+
if (string.IsNullOrWhiteSpace(line))
|
|
597
|
+
{
|
|
598
|
+
return arguments;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
System.Text.StringBuilder current = new();
|
|
602
|
+
bool inQuotes = false;
|
|
603
|
+
foreach (char character in line)
|
|
604
|
+
{
|
|
605
|
+
if (character == '"')
|
|
606
|
+
{
|
|
607
|
+
inQuotes = !inQuotes;
|
|
608
|
+
current.Append(character);
|
|
609
|
+
continue;
|
|
463
610
|
}
|
|
611
|
+
|
|
612
|
+
if (char.IsWhiteSpace(character) && !inQuotes)
|
|
613
|
+
{
|
|
614
|
+
if (current.Length > 0)
|
|
615
|
+
{
|
|
616
|
+
arguments.Add(current.ToString());
|
|
617
|
+
current.Clear();
|
|
618
|
+
}
|
|
619
|
+
continue;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
current.Append(character);
|
|
464
623
|
}
|
|
624
|
+
|
|
625
|
+
if (current.Length > 0)
|
|
626
|
+
{
|
|
627
|
+
arguments.Add(current.ToString());
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
return arguments;
|
|
465
631
|
}
|
|
466
632
|
}
|
|
467
633
|
}
|
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
fileFormatVersion: 2
|
|
2
2
|
guid: 54bd01ff5fd34bbc9950a1c7230a15d8
|
|
3
|
-
|
|
3
|
+
MonoImporter:
|
|
4
|
+
externalObjects: {}
|
|
5
|
+
serializedVersion: 2
|
|
6
|
+
defaultReferences: []
|
|
7
|
+
executionOrder: 0
|
|
8
|
+
icon: {instanceID: 0}
|
|
9
|
+
userData:
|
|
10
|
+
assetBundleName:
|
|
11
|
+
assetBundleVariant:
|
|
@@ -39,7 +39,7 @@ namespace DxMessaging.Editor.Testing
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
List<ListenerDiagnosticsView> listenerViews = component
|
|
42
|
-
._registeredListeners.OrderBy(pair => pair.Key
|
|
42
|
+
._registeredListeners.OrderBy(pair => InstanceId.StableId(pair.Key))
|
|
43
43
|
.Select(pair => CreateListenerView(pair.Key, pair.Value))
|
|
44
44
|
.ToList();
|
|
45
45
|
|
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
fileFormatVersion: 2
|
|
2
2
|
guid: 2624c9e8eb5243ebb71545774f411c2c
|
|
3
|
-
|
|
3
|
+
MonoImporter:
|
|
4
|
+
externalObjects: {}
|
|
5
|
+
serializedVersion: 2
|
|
6
|
+
defaultReferences: []
|
|
7
|
+
executionOrder: 0
|
|
8
|
+
icon: {instanceID: 0}
|
|
9
|
+
userData:
|
|
10
|
+
assetBundleName:
|
|
11
|
+
assetBundleVariant:
|