Skip to content

Commit 5fc3251

Browse files
authored
Simplify file-level directive diagnostics (#50636)
1 parent 73877a9 commit 5fc3251

17 files changed

+489
-416
lines changed

src/Cli/dotnet/Commands/CliCommandStrings.resx

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,12 +1098,12 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
10981098
<comment>{0}, {1} number of tests</comment>
10991099
</data>
11001100
<data name="InvalidProjectDirective" xml:space="preserve">
1101-
<value>The '#:project' directive at '{0}' is invalid: {1}</value>
1102-
<comment>{0} is the file path and line number. {1} is the inner error message.</comment>
1101+
<value>The '#:project' directive is invalid: {0}</value>
1102+
<comment>{0} is the inner error message.</comment>
11031103
</data>
11041104
<data name="MissingDirectiveName" xml:space="preserve">
1105-
<value>Missing name of '{0}' at {1}.</value>
1106-
<comment>{0} is the directive name like 'package' or 'sdk', {1} is the file path and line number.</comment>
1105+
<value>Missing name of '{0}'.</value>
1106+
<comment>{0} is the directive name like 'package' or 'sdk'.</comment>
11071107
</data>
11081108
<data name="MsBuildDefinition" xml:space="preserve">
11091109
<value>Run Microsoft Build Engine (MSBuild) commands.</value>
@@ -1592,28 +1592,32 @@ Tool '{1}' (version '{2}') was successfully installed. Entry is added to the man
15921592
<value>Project(s)</value>
15931593
</data>
15941594
<data name="PropertyDirectiveInvalidName" xml:space="preserve">
1595-
<value>Invalid property name at {0}. {1}</value>
1596-
<comment>{0} is the file path and line number. {1} is an inner exception message.</comment>
1595+
<value>Invalid property name: {0}</value>
1596+
<comment>{0} is an inner exception message.</comment>
15971597
</data>
15981598
<data name="PropertyDirectiveMissingParts" xml:space="preserve">
1599-
<value>The property directive needs to have two parts separated by '=' like '#:property PropertyName=PropertyValue': {0}</value>
1600-
<comment>{0} is the file path and line number.{Locked="#:property"}</comment>
1599+
<value>The property directive needs to have two parts separated by '=' like '#:property PropertyName=PropertyValue'.</value>
1600+
<comment>{Locked="#:property"}</comment>
16011601
</data>
16021602
<data name="StaticGraphRestoreNotSupported" xml:space="preserve">
1603-
<value>Static graph restore is not supported for file-based apps. Remove the '#:property' at {0}.</value>
1604-
<comment>{0} is the file path and line number.{Locked="#:property"}</comment>
1603+
<value>Static graph restore is not supported for file-based apps. Remove the '#:property'.</value>
1604+
<comment>{Locked="#:property"}</comment>
1605+
</data>
1606+
<data name="DirectiveError" xml:space="preserve">
1607+
<value>error</value>
1608+
<comment>Used when reporting directive errors like "file(location): error: message".</comment>
16051609
</data>
16061610
<data name="InvalidDirectiveName" xml:space="preserve">
1607-
<value>The directive at '{2}' should contain a name without special characters and an optional value separated by '{1}' like '#:{0} Name{1}Value'.</value>
1608-
<comment>{0} is the directive type like 'package' or 'sdk'. {1} is the expected separator like '@' or '='. {2} is the file path and line number.</comment>
1611+
<value>The directive should contain a name without special characters and an optional value separated by '{1}' like '#:{0} Name{1}Value'.</value>
1612+
<comment>{0} is the directive type like 'package' or 'sdk'. {1} is the expected separator like '@' or '='.</comment>
16091613
</data>
16101614
<data name="CannotConvertDirective" xml:space="preserve">
1611-
<value>Some directives cannot be converted: the first error is at {0}. Run the file to see all compilation errors. Specify '--force' to convert anyway.</value>
1612-
<comment>{Locked="--force"}. {0} is the file path and line number.</comment>
1615+
<value>Some directives cannot be converted. Run the file to see all compilation errors. Specify '--force' to convert anyway.</value>
1616+
<comment>{Locked="--force"}</comment>
16131617
</data>
16141618
<data name="DuplicateDirective" xml:space="preserve">
1615-
<value>Duplicate directives are not supported: {0} at {1}</value>
1616-
<comment>{0} is the directive type and name. {1} is the file path and line number.</comment>
1619+
<value>Duplicate directives are not supported: {0}</value>
1620+
<comment>{0} is the directive type and name.</comment>
16171621
</data>
16181622
<data name="InvalidOptionForStdin" xml:space="preserve">
16191623
<value>Cannot specify option '{0}' when also using '-' to read the file from standard input.</value>
@@ -2252,8 +2256,8 @@ and the corresponding package Ids for installed tools using the command
22522256
<value>Rows with Unlogged changes represent changes from actions other than .NET CLI workload commands. Usually this represents an update to the .NET SDK or to Visual Studio.</value>
22532257
</data>
22542258
<data name="UnrecognizedDirective" xml:space="preserve">
2255-
<value>Unrecognized directive '{0}' at {1}.</value>
2256-
<comment>{0} is the directive name like 'package' or 'sdk', {1} is the file path and line number.</comment>
2259+
<value>Unrecognized directive '{0}'.</value>
2260+
<comment>{0} is the directive name like 'package' or 'sdk'.</comment>
22572261
</data>
22582262
<data name="UpdateAllOptionDescription" xml:space="preserve">
22592263
<value>Update all tools.</value>

src/Cli/dotnet/Commands/Run/VirtualProjectBuildingCommand.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,7 +1488,7 @@ public static ImmutableArray<CSharpDirective> FindDirectives(SourceFile sourceFi
14881488
if (deduplicated.TryGetValue(directive, out var existingDirective))
14891489
{
14901490
var typeAndName = $"#:{existingDirective.GetType().Name.ToLowerInvariant()} {existingDirective.Name}";
1491-
diagnostics.AddError(sourceFile, directive.Info.Span, location => string.Format(CliCommandStrings.DuplicateDirective, typeAndName, location));
1491+
diagnostics.AddError(sourceFile, directive.Info.Span, string.Format(CliCommandStrings.DuplicateDirective, typeAndName));
14921492
}
14931493
else
14941494
{
@@ -1538,7 +1538,7 @@ void ReportErrorFor(SyntaxTrivia trivia)
15381538
{
15391539
if (trivia.ContainsDiagnostics && trivia.IsKind(SyntaxKind.IgnoredDirectiveTrivia))
15401540
{
1541-
diagnostics.AddError(sourceFile, trivia.Span, location => string.Format(CliCommandStrings.CannotConvertDirective, location));
1541+
diagnostics.AddError(sourceFile, trivia.Span, CliCommandStrings.CannotConvertDirective);
15421542
}
15431543
}
15441544

@@ -1660,7 +1660,7 @@ public FileLinePositionSpan GetFileLinePositionSpan(TextSpan span)
16601660
public string GetLocationString(TextSpan span)
16611661
{
16621662
var positionSpan = GetFileLinePositionSpan(span);
1663-
return $"{positionSpan.Path}:{positionSpan.StartLinePosition.Line + 1}";
1663+
return $"{positionSpan.Path}({positionSpan.StartLinePosition.Line + 1})";
16641664
}
16651665
}
16661666

@@ -1717,7 +1717,7 @@ public readonly struct ParseContext
17171717
"property" => Property.Parse(context),
17181718
"package" => Package.Parse(context),
17191719
"project" => Project.Parse(context),
1720-
var other => context.Diagnostics.AddError<Named>(context.SourceFile, context.Info.Span, location => string.Format(CliCommandStrings.UnrecognizedDirective, other, location)),
1720+
var other => context.Diagnostics.AddError<Named>(context.SourceFile, context.Info.Span, string.Format(CliCommandStrings.UnrecognizedDirective, other)),
17211721
};
17221722
}
17231723

@@ -1729,13 +1729,13 @@ private static (string, string?)? ParseOptionalTwoParts(in ParseContext context,
17291729
string directiveKind = context.DirectiveKind;
17301730
if (firstPart.IsWhiteSpace())
17311731
{
1732-
return context.Diagnostics.AddError<(string, string?)?>(context.SourceFile, context.Info.Span, location => string.Format(CliCommandStrings.MissingDirectiveName, directiveKind, location));
1732+
return context.Diagnostics.AddError<(string, string?)?>(context.SourceFile, context.Info.Span, string.Format(CliCommandStrings.MissingDirectiveName, directiveKind));
17331733
}
17341734

17351735
// If the name contains characters that resemble separators, report an error to avoid any confusion.
17361736
if (Patterns.DisallowedNameCharacters.IsMatch(firstPart))
17371737
{
1738-
return context.Diagnostics.AddError<(string, string?)?>(context.SourceFile, context.Info.Span, location => string.Format(CliCommandStrings.InvalidDirectiveName, directiveKind, separator, location));
1738+
return context.Diagnostics.AddError<(string, string?)?>(context.SourceFile, context.Info.Span, string.Format(CliCommandStrings.InvalidDirectiveName, directiveKind, separator));
17391739
}
17401740

17411741
var secondPart = i < 0 ? [] : context.DirectiveText.AsSpan((i + 1)..).TrimStart();
@@ -1802,7 +1802,7 @@ public sealed class Property(in ParseInfo info) : Named(info)
18021802

18031803
if (propertyValue is null)
18041804
{
1805-
return context.Diagnostics.AddError<Property?>(context.SourceFile, context.Info.Span, static location => string.Format(CliCommandStrings.PropertyDirectiveMissingParts, location));
1805+
return context.Diagnostics.AddError<Property?>(context.SourceFile, context.Info.Span, CliCommandStrings.PropertyDirectiveMissingParts);
18061806
}
18071807

18081808
try
@@ -1811,13 +1811,13 @@ public sealed class Property(in ParseInfo info) : Named(info)
18111811
}
18121812
catch (XmlException ex)
18131813
{
1814-
return context.Diagnostics.AddError<Property?>(context.SourceFile, context.Info.Span, location => string.Format(CliCommandStrings.PropertyDirectiveInvalidName, location, ex.Message), ex);
1814+
return context.Diagnostics.AddError<Property?>(context.SourceFile, context.Info.Span, string.Format(CliCommandStrings.PropertyDirectiveInvalidName, ex.Message), ex);
18151815
}
18161816

18171817
if (propertyName.Equals("RestoreUseStaticGraphEvaluation", StringComparison.OrdinalIgnoreCase) &&
18181818
MSBuildUtilities.ConvertStringToBool(propertyValue))
18191819
{
1820-
context.Diagnostics.AddError(context.SourceFile, context.Info.Span, static location => string.Format(CliCommandStrings.StaticGraphRestoreNotSupported, location));
1820+
context.Diagnostics.AddError(context.SourceFile, context.Info.Span, CliCommandStrings.StaticGraphRestoreNotSupported);
18211821
}
18221822

18231823
return new Property(context.Info)
@@ -1865,7 +1865,7 @@ public sealed class Project(in ParseInfo info) : Named(info)
18651865
if (directiveText.IsWhiteSpace())
18661866
{
18671867
string directiveKind = context.DirectiveKind;
1868-
return context.Diagnostics.AddError<Project?>(context.SourceFile, context.Info.Span, location => string.Format(CliCommandStrings.MissingDirectiveName, directiveKind, location));
1868+
return context.Diagnostics.AddError<Project?>(context.SourceFile, context.Info.Span, string.Format(CliCommandStrings.MissingDirectiveName, directiveKind));
18691869
}
18701870

18711871
try
@@ -1886,7 +1886,7 @@ public sealed class Project(in ParseInfo info) : Named(info)
18861886
}
18871887
catch (GracefulException e)
18881888
{
1889-
context.Diagnostics.AddError(context.SourceFile, context.Info.Span, location => string.Format(CliCommandStrings.InvalidProjectDirective, location, e.Message), e);
1889+
context.Diagnostics.AddError(context.SourceFile, context.Info.Span, string.Format(CliCommandStrings.InvalidProjectDirective, e.Message), e);
18901890
}
18911891

18921892
return new Project(context.Info)
@@ -1960,22 +1960,22 @@ internal readonly struct DiagnosticBag
19601960
public static DiagnosticBag Collect(out ImmutableArray<SimpleDiagnostic>.Builder builder) => new() { Builder = builder = ImmutableArray.CreateBuilder<SimpleDiagnostic>() };
19611961
public static DiagnosticBag Ignore() => new() { IgnoreDiagnostics = true, Builder = null };
19621962

1963-
public void AddError(SourceFile sourceFile, TextSpan span, Func<string, string> messageFactory, Exception? inner = null)
1963+
public void AddError(SourceFile sourceFile, TextSpan span, string message, Exception? inner = null)
19641964
{
19651965
if (Builder != null)
19661966
{
19671967
Debug.Assert(!IgnoreDiagnostics);
1968-
Builder.Add(new SimpleDiagnostic { Location = sourceFile.GetFileLinePositionSpan(span), Message = messageFactory(sourceFile.GetLocationString(span)) });
1968+
Builder.Add(new SimpleDiagnostic { Location = sourceFile.GetFileLinePositionSpan(span), Message = message });
19691969
}
19701970
else if (!IgnoreDiagnostics)
19711971
{
1972-
throw new GracefulException(messageFactory(sourceFile.GetLocationString(span)), inner);
1972+
throw new GracefulException($"{sourceFile.GetLocationString(span)}: {CliCommandStrings.DirectiveError}: {message}", inner);
19731973
}
19741974
}
19751975

1976-
public T? AddError<T>(SourceFile sourceFile, TextSpan span, Func<string, string> messageFactory, Exception? inner = null)
1976+
public T? AddError<T>(SourceFile sourceFile, TextSpan span, string message, Exception? inner = null)
19771977
{
1978-
AddError(sourceFile, span, messageFactory, inner);
1978+
AddError(sourceFile, span, message, inner);
19791979
return default;
19801980
}
19811981
}

0 commit comments

Comments
 (0)