Skip to content

Commit 717d810

Browse files
committed
generated ysls now also records if the methods have errors.
Intention is that then the editor can know that a command/function exists but is currently in a state that isn't safe to be called. The location values generated should still be valid allowing jumping to the right file and position to fix it.
1 parent 007bd39 commit 717d810

File tree

5 files changed

+82
-22
lines changed

5 files changed

+82
-22
lines changed

Editor/Analysis/Action.cs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ public Action(string name, ActionType type, IMethodSymbol methodSymbol)
229229
public string? ReturnDescription;
230230
public string YarnReturnTypeString => this.MethodSymbol.ReturnType.GetYarnTypeString();
231231

232+
public bool ContainsErrors = false;
233+
232234
public string ToJSON()
233235
{
234236
var result = new Dictionary<string, object?>();
@@ -243,6 +245,8 @@ public string ToJSON()
243245
result["language"] = "csharp";
244246
result["async"] = this.AsyncType != AsyncType.Sync;
245247

248+
result["containsErrors"] = this.ContainsErrors;
249+
246250
if (this.Declaration != null)
247251
{
248252
var location = this.Declaration.GetLocation().GetLineSpan();
@@ -487,6 +491,8 @@ private IEnumerable<Diagnostic> ValidateFunction(Compilation compilation, ILogge
487491
yield return Diagnostic.Create(Diagnostics.YS1006YarnFunctionsMustBeStatic, identifierLocation);
488492
}
489493

494+
logger?.Inc();
495+
logger?.WriteLine($"Validating {identifier} as a function");
490496
var paramDiags = ValidateParameters(compilation, logger);
491497
foreach (var p in paramDiags)
492498
{
@@ -496,6 +502,7 @@ private IEnumerable<Diagnostic> ValidateFunction(Compilation compilation, ILogge
496502
// Functions must return a number, string, or bool
497503
var returnTypeSymbol = this.MethodSymbol.ReturnType;
498504

505+
logger?.Dec();
499506
switch (returnTypeSymbol.SpecialType)
500507
{
501508
case SpecialType.System_Boolean:
@@ -522,33 +529,32 @@ private IEnumerable<Diagnostic> ValidateFunction(Compilation compilation, ILogge
522529
// validates the parameters are correct
523530
private List<Diagnostic> ValidateParameters(Compilation compilation, ILogger? logger)
524531
{
532+
logger?.Inc();
525533
List<Diagnostic> diagnostics = new List<Diagnostic>();
526534
ParameterListSyntax? parameterList = null;
527-
Location? actionLocation = null;
528535
string? identifier = null;
529536

530537
if (this.MethodDeclarationSyntax is MethodDeclarationSyntax methodDeclaration)
531538
{
532539
identifier = methodDeclaration.Identifier.ToString();
533-
logger?.WriteLine($"Validating {identifier} as a method");
540+
logger?.WriteLine($"identified {identifier} as a method");
534541
parameterList = methodDeclaration.ParameterList;
535-
actionLocation = methodDeclaration.GetLocation();
536542
}
537543
else if (this.MethodDeclarationSyntax is LocalFunctionStatementSyntax localFunctionStatement)
538544
{
539545
identifier = localFunctionStatement.Identifier.ToString();
540-
logger?.WriteLine($"Validating {identifier} as a local function");
546+
logger?.WriteLine($"identified {identifier} as a local function");
541547
parameterList = localFunctionStatement.ParameterList;
542-
actionLocation = localFunctionStatement.GetLocation();
543548
}
544549
else if(this.MethodDeclarationSyntax is LambdaExpressionSyntax lambdaExpression)
545550
{
546-
logger?.WriteLine("The action is a lambda.");
547-
actionLocation = lambdaExpression.GetLocation();
551+
logger?.WriteLine("identifed the action as a lambda.");
552+
var actionLocation = lambdaExpression.GetLocation();
548553

549554
if (lambdaExpression is SimpleLambdaExpressionSyntax)
550555
{
551556
logger?.WriteLine("The action is a simple lambda, validations do not apply here, skipping this action.");
557+
logger?.Dec();
552558
diagnostics.Add(Diagnostic.Create(Diagnostics.YS1012ActionIsALambda, actionLocation));
553559
return diagnostics;
554560
}
@@ -567,15 +573,18 @@ private List<Diagnostic> ValidateParameters(Compilation compilation, ILogger? lo
567573
if (parameterList == null || parameterList.Parameters.Count() == 0)
568574
{
569575
logger?.WriteLine($"{identifier} has no parameters, ignoring");
576+
logger?.Dec();
570577
return diagnostics;
571578
}
572579

573580
logger?.WriteLine($"Will be checking {parameterList.Parameters.Count()} parameters");
574581
foreach (var parameter in parameterList.Parameters)
575582
{
583+
logger?.Inc();
576584
if (parameter.Type == null)
577585
{
578586
logger?.WriteLine($"{parameter.ToFullString()} has no type, ignoring validation?");
587+
logger?.Dec();
579588
continue;
580589
}
581590

@@ -588,13 +597,15 @@ private List<Diagnostic> ValidateParameters(Compilation compilation, ILogger? lo
588597
if (typeInfo == null)
589598
{
590599
logger?.WriteLine($"Unable to determine typeinfo of {parameterName} ignoring validation?");
600+
logger?.Dec();
591601
continue;
592602
}
593603

594604
var symbol = model.GetDeclaredSymbol(parameter);
595605
if (symbol == null)
596606
{
597607
logger?.WriteLine($"Unable to determine the declared symbol for {parameterName}, skipping validation");
608+
logger?.Dec();
598609
continue;
599610
}
600611

@@ -603,7 +614,6 @@ private List<Diagnostic> ValidateParameters(Compilation compilation, ILogger? lo
603614
if (symbol.Type is IArrayTypeSymbol arrayTypeSymbol)
604615
{
605616
var subtype = arrayTypeSymbol.ElementType;
606-
logger?.WriteLine($"{parameterName} is a params array made up of {subtype}:_{subtype.Name}_:-{subtype.GetYarnTypeString()}-");
607617
if (subtype.GetYarnTypeString() == "any")
608618
{
609619
logger?.WriteLine($"{parameterName} is a parameter array of non Yarn compatible types!");
@@ -621,7 +631,6 @@ private List<Diagnostic> ValidateParameters(Compilation compilation, ILogger? lo
621631
}
622632
}
623633

624-
625634
foreach (var attribute in symbol.GetAttributes())
626635
{
627636
// this attribute is an enum parameter
@@ -642,15 +651,19 @@ private List<Diagnostic> ValidateParameters(Compilation compilation, ILogger? lo
642651
}
643652
}
644653
}
654+
logger?.Dec();
645655
}
646656

657+
logger?.Dec();
647658
return diagnostics;
648659
}
649660

650661
private IEnumerable<Diagnostic> ValidateCommand(Compilation compilation, ILogger? logger)
651662
{
663+
logger?.Inc();
652664
if (MethodSymbol == null)
653665
{
666+
logger?.Dec();
654667
throw new NullReferenceException("Method symbol is null");
655668
}
656669

@@ -705,9 +718,12 @@ private IEnumerable<Diagnostic> ValidateCommand(Compilation compilation, ILogger
705718
}
706719
else
707720
{
721+
logger?.Dec();
708722
throw new InvalidOperationException($"Expected decl for {this.Name} ({this.SourceFileName}) was of unexpected type {this.MethodDeclarationSyntax?.GetType().Name ?? "null"}");
709723
}
710724

725+
logger?.WriteLine($"Validating {identifier} as a command");
726+
711727
var paramDiags = ValidateParameters(compilation, logger);
712728
foreach (var p in paramDiags)
713729
{
@@ -719,6 +735,7 @@ private IEnumerable<Diagnostic> ValidateCommand(Compilation compilation, ILogger
719735
var typeIsKnownInvalid = knownInvalidCommandReturnTypes.Contains(returnTypeSymbol);
720736

721737
var returnTypeIsValid = typeIsKnownValid && !typeIsKnownInvalid;
738+
logger?.Dec();
722739

723740
if (returnTypeIsValid == false)
724741
{

Editor/Analysis/ActionsRegistrationGenerator~/ActionsGenerator.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,6 @@ public void Execute(GeneratorExecutionContext context)
210210
return;
211211
}
212212

213-
HashSet<string> removals = new HashSet<string>();
214213
// validating and logging all the actions
215214
foreach (var action in actions)
216215
{
@@ -224,7 +223,11 @@ public void Execute(GeneratorExecutionContext context)
224223
foreach (var diagnostic in diagnostics)
225224
{
226225
context.ReportDiagnostic(diagnostic);
227-
output.WriteLine($"Skipping '{action.Name}' ({action.MethodName}): {diagnostic}");
226+
if (diagnostic.Severity == DiagnosticSeverity.Warning || diagnostic.Severity == DiagnosticSeverity.Error)
227+
{
228+
output.WriteLine($"Flagging '{action.Name}' ({action.MethodName}): {diagnostic}");
229+
action.ContainsErrors = true;
230+
}
228231
}
229232

230233
if (diagnostics.Count > 0)
@@ -250,17 +253,14 @@ public void Execute(GeneratorExecutionContext context)
250253
action.Declaration?.GetLocation(),
251254
action.Name
252255
));
253-
output.WriteLine($"Action {action.MethodIdentifierName} will be skipped due to it's name {action.Name}");
254-
removals.Add(action.Name);
256+
action.ContainsErrors = true;
257+
output.WriteLine($"Action {action.MethodIdentifierName} will be flagged due to it's name {action.Name}");
255258
continue;
256259
}
257260

258261
output.WriteLine($"Action {action.Name}: {action.SourceFileName}:{action.Declaration?.GetLocation()?.GetLineSpan().StartLinePosition.Line} ({action.Type})");
259262
}
260263

261-
// removing any actions that failed validation
262-
actions = actions.Where(x => !removals.Contains(x.Name)).ToList();
263-
264264
output.Write($"Generating source code...");
265265

266266
var source = Analyser.GenerateRegistrationFileSource(actions);

Editor/Analysis/Analyser.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,10 @@ static string GetLocationOfAssemblyWithType(string typeName)
121121

122122
foreach (var action in output)
123123
{
124-
action.Validate(compilation, logger);
124+
if (action.Validate(compilation, logger).Any(d => d.Severity == DiagnosticSeverity.Warning || d.Severity == DiagnosticSeverity.Error))
125+
{
126+
action.ContainsErrors = true;
127+
}
125128
}
126129

127130
return output;

Editor/Analysis/ILogger.cs

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,16 @@ public interface ILogger : IDisposable
1616
void Write(object obj);
1717
void WriteLine(object obj);
1818
void WriteException(System.Exception ex, string? message = null);
19+
20+
void Inc();
21+
void Dec();
22+
void SetDepth(int depth);
1923
}
2024

2125
public class FileLogger : ILogger
2226
{
2327
System.IO.TextWriter writer;
28+
private int depth = 0;
2429

2530
public FileLogger(System.IO.TextWriter writer)
2631
{
@@ -35,24 +40,40 @@ public void Dispose()
3540

3641
public void Write(object text)
3742
{
38-
writer.Write(text);
43+
var tabs = new String('\t', depth);
44+
writer.Write(tabs + text);
3945
}
4046

4147
public void WriteLine(object text)
4248
{
43-
writer.WriteLine(text);
49+
var tabs = new String('\t', depth);
50+
writer.WriteLine(tabs + text);
4451
}
4552
public void WriteException(System.Exception ex, string? message)
4653
{
54+
var tabs = new String('\t', depth);
4755
if (message == null)
4856
{
49-
writer.WriteLine($"Exception: {ex.Message}");
57+
writer.WriteLine($"{tabs}Exception: {ex.Message}");
5058
}
5159
else
5260
{
53-
writer.WriteLine($"{message}: {ex.Message}");
61+
writer.WriteLine($"{tabs}{message}: {ex.Message}");
5462
}
5563
}
64+
65+
public void Inc()
66+
{
67+
depth +=1 ;
68+
}
69+
public void Dec()
70+
{
71+
depth = Math.Max(depth - 1, 0);
72+
}
73+
public void SetDepth(int depth)
74+
{
75+
this.depth = Math.Max(depth, 0);
76+
}
5677
}
5778

5879
public class UnityLogger : ILogger
@@ -66,8 +87,9 @@ public void Write(object text)
6687

6788
public void WriteLine(object text)
6889
{
90+
var tabs = new String('\t', depth);
6991
#if UNITY_EDITOR
70-
Debug.LogWarning(text.ToString());
92+
Debug.LogWarning(tabs + text.ToString());
7193
#endif
7294
}
7395

@@ -77,6 +99,20 @@ public void WriteException(System.Exception ex, string? message = null)
7799
Debug.LogException(ex);
78100
#endif
79101
}
102+
103+
private int depth = 0;
104+
public void Inc()
105+
{
106+
depth +=1 ;
107+
}
108+
public void Dec()
109+
{
110+
depth = Math.Max(depth - 1, 0);
111+
}
112+
public void SetDepth(int depth)
113+
{
114+
this.depth = Math.Max(depth, 0);
115+
}
80116
}
81117

82118
public class NullLogger : ILogger
@@ -88,5 +124,9 @@ public void Write(object text) { }
88124
public void WriteLine(object text) { }
89125

90126
public void WriteException(System.Exception ex, string? message = null) { }
127+
128+
public void Inc(){}
129+
public void Dec(){}
130+
public void SetDepth(int depth) {}
91131
}
92132
}
1 KB
Binary file not shown.

0 commit comments

Comments
 (0)