Skip to content

Commit 058c8e6

Browse files
Improved diagnostics of error and warning locations
1 parent 9ceb31c commit 058c8e6

42 files changed

Lines changed: 189 additions & 119 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/Pure.DI.Core/Core/ApiInvocationProcessor.cs

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ sealed class ApiInvocationProcessor(
1818
ITypes types,
1919
IWildcardMatcher wildcardMatcher,
2020
Func<IFactoryApiWalker> factoryApiWalkerFactory,
21-
Func<ILocalVariableRenamingRewriter> localVariableRenamingRewriterFactory)
21+
Func<ILocalVariableRenamingRewriter> localVariableRenamingRewriterFactory,
22+
ILocationProvider locationProvider)
2223
: IApiInvocationProcessor
2324
{
2425
private static readonly char[] TypeNamePartsSeparators = ['.'];
@@ -96,12 +97,12 @@ MemberAccessExpressionSyntax memberAccess when memberAccess.Kind() == SyntaxKind
9697

9798
if (symbol.TypeArguments.Length == 2 && symbol.TypeArguments is [_, {} resultType])
9899
{
99-
VisitFactory(metadataVisitor, semanticModel, resultType, lambdaExpression);
100+
VisitFactory(name, metadataVisitor, semanticModel, resultType, lambdaExpression);
100101
break;
101102
}
102103
}
103104

104-
VisitFactory(metadataVisitor, semanticModel, type, lambdaExpression);
105+
VisitFactory(name, metadataVisitor, semanticModel, type, lambdaExpression);
105106
break;
106107

107108
case []:
@@ -207,7 +208,7 @@ MemberAccessExpressionSyntax memberAccess when memberAccess.Kind() == SyntaxKind
207208
case nameof(IConfiguration.RootBind):
208209
if (genericName.TypeArgumentList.Arguments is not [{} rootBindType])
209210
{
210-
throw new CompileErrorException(Strings.Error_InvalidRootType, name.GetLocation(), LogId.ErrorInvalidMetadata);
211+
throw new CompileErrorException(Strings.Error_InvalidRootType, locationProvider.GetLocation(name), LogId.ErrorInvalidMetadata);
211212
}
212213

213214
var tagArguments = invocation.ArgumentList.Arguments.SkipWhile((arg, i) => arg.NameColon?.Name.Identifier.Text != "tags" && i < 2);
@@ -253,20 +254,20 @@ MemberAccessExpressionSyntax memberAccess when memberAccess.Kind() == SyntaxKind
253254
{
254255
case [{ Expression: LambdaExpressionSyntax lambdaExpression }]:
255256
var factoryType = semantic.GetTypeSymbol<ITypeSymbol>(semanticModel, implementationTypeSyntax);
256-
VisitFactory(metadataVisitor, semanticModel, factoryType, lambdaExpression);
257+
VisitFactory(name, metadataVisitor, semanticModel, factoryType, lambdaExpression);
257258
break;
258259

259260
case [{ Expression: LiteralExpressionSyntax { Token.Value: string sourceCodeStatement } }]:
260261
var lambda = SyntaxFactory
261262
.SimpleLambdaExpression(SyntaxFactory.Parameter(SyntaxFactory.Identifier("_")))
262263
.WithExpressionBody(SyntaxFactory.IdentifierName(sourceCodeStatement));
263264
factoryType = semantic.GetTypeSymbol<ITypeSymbol>(semanticModel, implementationTypeSyntax);
264-
VisitFactory(metadataVisitor, semanticModel, factoryType, lambda);
265+
VisitFactory(name, metadataVisitor, semanticModel, factoryType, lambda);
265266
break;
266267

267268
case []:
268269
var implementationType = semantic.GetTypeSymbol<INamedTypeSymbol>(semanticModel, implementationTypeSyntax);
269-
metadataVisitor.VisitImplementation(new MdImplementation(semanticModel, implementationTypeSyntax, implementationType));
270+
metadataVisitor.VisitImplementation(new MdImplementation(semanticModel, name, implementationType));
270271
break;
271272

272273
default:
@@ -291,7 +292,7 @@ MemberAccessExpressionSyntax memberAccess when memberAccess.Kind() == SyntaxKind
291292
// ReSharper disable once MergeIntoNegatedPattern
292293
|| rootsType.SpecialType == Microsoft.CodeAnalysis.SpecialType.System_Object)
293294
{
294-
throw new CompileErrorException(Strings.Error_InvalidRootsRype, name.GetLocation(), LogId.ErrorInvalidMetadata);
295+
throw new CompileErrorException(Strings.Error_InvalidRootsRype, locationProvider.GetLocation(name), LogId.ErrorInvalidMetadata);
295296
}
296297

297298
var rootsArgs = arguments.GetArgs(invocation.ArgumentList, "name", "kind", "filter");
@@ -308,15 +309,15 @@ MemberAccessExpressionSyntax memberAccess when memberAccess.Kind() == SyntaxKind
308309

309310
if (!hasRootsType)
310311
{
311-
throw new CompileErrorException(string.Format(Strings.Error_Template_NoTypeForWildcard, symbolNames.GetName(rootsType), rootsWildcardFilter), name.GetLocation(), LogId.ErrorInvalidMetadata);
312+
throw new CompileErrorException(string.Format(Strings.Error_Template_NoTypeForWildcard, symbolNames.GetName(rootsType), rootsWildcardFilter), locationProvider.GetLocation(name), LogId.ErrorInvalidMetadata);
312313
}
313314

314315
break;
315316

316317
case nameof(IConfiguration.Root):
317318
if (genericName.TypeArgumentList.Arguments is not [{} rootTypeSyntax])
318319
{
319-
throw new CompileErrorException(Strings.Error_InvalidRootType, name.GetLocation(), LogId.ErrorInvalidMetadata);
320+
throw new CompileErrorException(Strings.Error_InvalidRootType, locationProvider.GetLocation(name), LogId.ErrorInvalidMetadata);
320321
}
321322

322323
var rootSymbol = semantic.GetTypeSymbol<INamedTypeSymbol>(semanticModel, rootTypeSyntax);
@@ -329,7 +330,7 @@ MemberAccessExpressionSyntax memberAccess when memberAccess.Kind() == SyntaxKind
329330
// ReSharper disable once MergeIntoNegatedPattern
330331
|| buildersRootType.SpecialType == Microsoft.CodeAnalysis.SpecialType.System_Object)
331332
{
332-
throw new CompileErrorException(Strings.Error_InvalidBuildersType, name.GetLocation(), LogId.ErrorInvalidMetadata);
333+
throw new CompileErrorException(Strings.Error_InvalidBuildersType, locationProvider.GetLocation(name), LogId.ErrorInvalidMetadata);
333334
}
334335

335336
var buildersArgs = arguments.GetArgs(invocation.ArgumentList, "name", "kind", "filter");
@@ -355,15 +356,15 @@ MemberAccessExpressionSyntax memberAccess when memberAccess.Kind() == SyntaxKind
355356

356357
if (!hasBuildersType)
357358
{
358-
throw new CompileErrorException(string.Format(Strings.Error_Template_NoTypeForWildcard, symbolNames.GetName(buildersRootType), buildersWildcardFilter), name.GetLocation(), LogId.ErrorInvalidMetadata);
359+
throw new CompileErrorException(string.Format(Strings.Error_Template_NoTypeForWildcard, symbolNames.GetName(buildersRootType), buildersWildcardFilter), locationProvider.GetLocation(name), LogId.ErrorInvalidMetadata);
359360
}
360361

361362
break;
362363

363364
case nameof(IConfiguration.Builder):
364365
if (genericName.TypeArgumentList.Arguments is not [{} builderRootTypeSyntax])
365366
{
366-
throw new CompileErrorException(Strings.Error_InvalidBuilderType, name.GetLocation(), LogId.ErrorInvalidMetadata);
367+
throw new CompileErrorException(Strings.Error_InvalidBuilderType, locationProvider.GetLocation(name), LogId.ErrorInvalidMetadata);
367368
}
368369

369370
var builderType = semantic.GetTypeSymbol<INamedTypeSymbol>(semanticModel, builderRootTypeSyntax);
@@ -529,7 +530,7 @@ private IEnumerable<INamedTypeSymbol> GetRelatedTypes(
529530
var marker = types.GetMarker(index, semanticModel.Compilation);
530531
if (marker is null)
531532
{
532-
throw new CompileErrorException(Strings.Error_TooManyTypeParameters, source.GetLocation(), LogId.ErrorInvalidMetadata);
533+
throw new CompileErrorException(Strings.Error_TooManyTypeParameters, locationProvider.GetLocation(source), LogId.ErrorInvalidMetadata);
533534
}
534535

535536
markers.Add(marker);
@@ -568,7 +569,7 @@ private void VisitBuilder(
568569
var builderLambdaExpression = (LambdaExpressionSyntax)SyntaxFactory.ParseExpression(factory.ToString());
569570

570571
metadataVisitor.VisitContract(new MdContract(semanticModel, source, builderType, ContractKind.Explicit, ImmutableArray.Create(builderTag)));
571-
VisitFactory(metadataVisitor, semanticModel, builderType, builderLambdaExpression);
572+
VisitFactory(source, metadataVisitor, semanticModel, builderType, builderLambdaExpression);
572573

573574
// Root
574575
metadataVisitor.VisitRoot(new MdRoot(source, semanticModel, builderType, builderName, builderTag, kind, invocationComments, true));
@@ -749,6 +750,7 @@ private void VisitArg(
749750
}
750751

751752
private void VisitFactory(
753+
SyntaxNode source,
752754
IMetadataVisitor metadataVisitor,
753755
SemanticModel semanticModel,
754756
ITypeSymbol resultType,
@@ -790,7 +792,7 @@ private void VisitFactory(
790792
metadataVisitor.VisitFactory(
791793
new MdFactory(
792794
semanticModel,
793-
lambdaExpression,
795+
source,
794796
resultType,
795797
localVariableRenamingRewriter,
796798
lambdaExpression,
@@ -1038,11 +1040,11 @@ tag is MemberAccessExpressionSyntax memberAccessExpression
10381040
return argType ?? defaultType;
10391041
}
10401042

1041-
private static void CheckNotAsync(LambdaExpressionSyntax lambdaExpression)
1043+
private void CheckNotAsync(LambdaExpressionSyntax lambdaExpression)
10421044
{
10431045
if (lambdaExpression.AsyncKeyword.IsKind(SyntaxKind.AsyncKeyword))
10441046
{
1045-
throw new CompileErrorException(Strings.Error_AsynchronousFactoryWithAsyncNotSupported, lambdaExpression.AsyncKeyword.GetLocation(), LogId.ErrorInvalidMetadata);
1047+
throw new CompileErrorException(Strings.Error_AsynchronousFactoryWithAsyncNotSupported, locationProvider.GetLocation(lambdaExpression.AsyncKeyword), LogId.ErrorInvalidMetadata);
10461048
}
10471049
}
10481050

@@ -1061,8 +1063,8 @@ private static void CheckNotAsync(LambdaExpressionSyntax lambdaExpression)
10611063
}*/
10621064

10631065
// ReSharper disable once SuggestBaseTypeForParameter
1064-
private static void NotSupported(SyntaxNode source) =>
1065-
throw new CompileErrorException(string.Format(Strings.Error_Template_NotSupported, source), source.GetLocation(), LogId.ErrorInvalidMetadata);
1066+
private void NotSupported(SyntaxNode source) =>
1067+
throw new CompileErrorException(string.Format(Strings.Error_Template_NotSupported, source), locationProvider.GetLocation(source), LogId.ErrorInvalidMetadata);
10661068

10671069
private IReadOnlyList<T> BuildConstantArgs<T>(
10681070
SemanticModel semanticModel,
@@ -1071,7 +1073,7 @@ private IReadOnlyList<T> BuildConstantArgs<T>(
10711073
.SelectMany(a => semantic.GetConstantValues<T>(semanticModel, a.Expression).Select(value => (value, a.Expression)))
10721074
.Select(a => a.value ?? throw new CompileErrorException(
10731075
string.Format(Strings.Error_Template_MustBeValueOfType, a.Expression, typeof(T)),
1074-
a.Expression.GetLocation(),
1076+
locationProvider.GetLocation(a.Expression),
10751077
LogId.ErrorInvalidMetadata))
10761078
.ToList();
10771079

@@ -1124,7 +1126,7 @@ private static CompositionName CreateCompositionName(
11241126
var name = nameFormatter.Format(nameTemplate!, type?.OriginalDefinition, tag);
11251127
if (!SyntaxFacts.IsValidIdentifier(name))
11261128
{
1127-
throw new CompileErrorException(string.Format(Strings.Error_Template_InvalidIdentifier, name), source.GetLocation(), LogId.ErrorInvalidMetadata);
1129+
throw new CompileErrorException(string.Format(Strings.Error_Template_InvalidIdentifier, name), locationProvider.GetLocation(source), LogId.ErrorInvalidMetadata);
11281130
}
11291131

11301132
return name;

src/Pure.DI.Core/Core/ArgDependencyNodeBuilder.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
namespace Pure.DI.Core;
44

5-
sealed class ArgDependencyNodeBuilder : IBuilder<DependencyNodeBuildContext, IEnumerable<DependencyNode>>
5+
sealed class ArgDependencyNodeBuilder(ILocationProvider locationProvider)
6+
: IBuilder<DependencyNodeBuildContext, IEnumerable<DependencyNode>>
67
{
78
public IEnumerable<DependencyNode> Build(DependencyNodeBuildContext ctx)
89
{
@@ -13,7 +14,7 @@ public IEnumerable<DependencyNode> Build(DependencyNodeBuildContext ctx)
1314
continue;
1415
}
1516

16-
yield return new DependencyNode(0, binding, ctx.TypeConstructor, Arg: new DpArg(arg, binding));
17+
yield return new DependencyNode(0, binding, ctx.TypeConstructor, Arg: new DpArg(arg, binding, locationProvider));
1718
}
1819
}
1920
}

src/Pure.DI.Core/Core/Attributes.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ namespace Pure.DI.Core;
55

66
sealed class Attributes(
77
ISemantic semantic,
8-
ISymbolNames symbolNames)
8+
ISymbolNames symbolNames,
9+
ILocationProvider locationProvider)
910
: IAttributes
1011
{
1112
public T GetAttribute<TMdAttribute, T>(
@@ -47,7 +48,7 @@ public T GetAttribute<TMdAttribute, T>(
4748

4849
throw new CompileErrorException(
4950
string.Format(Strings.Error_Template_InvalidAttributeArgumentPosition, attributeMetadata.ArgumentPosition, attributeMetadata.Source, args.Length),
50-
attributeMetadata.Source.GetLocation(),
51+
locationProvider.GetLocation(attributeMetadata.Source),
5152
LogId.ErrorInvalidMetadata);
5253
}
5354

@@ -62,7 +63,7 @@ public T GetAttribute<TMdAttribute, T>(
6263
case > 1:
6364
throw new CompileErrorException(
6465
string.Format(Strings.Error_Template_AttributeMemberCannotBeProcessed, member, member.ContainingType),
65-
attributeMetadata.Source.GetLocation(),
66+
locationProvider.GetLocation(attributeMetadata.Source),
6667
LogId.ErrorInvalidMetadata);
6768
}
6869
}
@@ -92,7 +93,7 @@ public T GetAttribute<TMdAttribute, T>(
9293
{
9394
throw new CompileErrorException(
9495
string.Format(Strings.Error_Template_InvalidAttributeArgumentPosition, attributeMetadata.ArgumentPosition, attributeMetadata.Source, args.Count),
95-
attributeMetadata.Source.GetLocation(),
96+
locationProvider.GetLocation(attributeMetadata.Source),
9697
LogId.ErrorInvalidMetadata);
9798
}
9899

src/Pure.DI.Core/Core/BindingBuilder.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ namespace Pure.DI.Core;
88
sealed class BindingBuilder(
99
[Tag(UniqueTag)] IIdGenerator idGenerator,
1010
IBaseSymbolsProvider baseSymbolsProvider,
11-
ITypes types)
11+
ITypes types,
12+
ILocationProvider locationProvider)
1213
: IBindingBuilder
1314
{
1415
private readonly List<MdContract> _contracts = [];
@@ -140,7 +141,7 @@ 1 when
140141
_arg);
141142
}
142143

143-
throw new CompileErrorException(Strings.Error_InvalidBinding, setup.Source.GetLocation(), LogId.ErrorInvalidMetadata);
144+
throw new CompileErrorException(Strings.Error_InvalidBinding, locationProvider.GetLocation(setup.Source), LogId.ErrorInvalidMetadata);
144145
}
145146
finally
146147
{

src/Pure.DI.Core/Core/BindingsValidator.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
#pragma warning disable CS9113 // Parameter is unread.
33
namespace Pure.DI.Core;
44

5-
sealed class BindingsValidator(ILogger logger, IRegistry<int> registry)
5+
sealed class BindingsValidator(
6+
ILogger logger,
7+
IRegistry<int> registry,
8+
ILocationProvider locationProvider)
69
: IValidator<DependencyGraph>
710
{
811
public bool Validate(DependencyGraph graph)
@@ -13,7 +16,7 @@ public bool Validate(DependencyGraph graph)
1316
{
1417
logger.CompileWarning(
1518
Strings.Warning_BindingIsNotUsed,
16-
binding.Source.GetLocation(),
19+
locationProvider.GetLocation(binding.Source),
1720
LogId.WarningMetadataDefect);
1821
}
1922
}

src/Pure.DI.Core/Core/Code/ClassDiagramBuilder.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ sealed class ClassDiagramBuilder(
1212
ITypeResolver typeResolver,
1313
IRootAccessModifierResolver rootAccessModifierResolver,
1414
ITypes types,
15+
ILocationProvider locationProvider,
1516
CancellationToken cancellationToken)
1617
: IBuilder<CompositionCode, LinesBuilder>
1718
{
@@ -101,7 +102,7 @@ public LinesBuilder Build(CompositionCode composition)
101102
lines.AppendLine($"{FormatType(setup, node.Type, DefaultFormatOptions)} --|> {FormatType(setup, contract.Type, DefaultFormatOptions)}{(string.IsNullOrWhiteSpace(tag) ? "" : $" : {tag}")}");
102103
}
103104

104-
var classDiagramWalker = new ClassDiagramWalker(setup, marker, this, classes, DefaultFormatOptions);
105+
var classDiagramWalker = new ClassDiagramWalker(setup, marker, this, classes, DefaultFormatOptions, locationProvider);
105106
classDiagramWalker.VisitDependencyNode(new LinesBuilder(), node);
106107
}
107108

@@ -354,8 +355,9 @@ private class ClassDiagramWalker(
354355
IMarker marker,
355356
ClassDiagramBuilder builder,
356357
IList<Class> classes,
357-
FormatOptions options)
358-
: DependenciesWalker<LinesBuilder>
358+
FormatOptions options,
359+
ILocationProvider locationProvider)
360+
: DependenciesWalker<LinesBuilder>(locationProvider)
359361
{
360362
public override void VisitDependencyNode(in LinesBuilder ctx, DependencyNode node)
361363
{

src/Pure.DI.Core/Core/Code/FactoryCodeBuilder.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ sealed class FactoryCodeBuilder(
1414
IVariableNameProvider variableNameProvider,
1515
Func<IFactoryValidator> factoryValidatorFactory,
1616
Func<IInitializersWalker> initializersWalkerFactory,
17-
IOverridesRegistry overridesRegistry)
17+
IOverridesRegistry overridesRegistry,
18+
ILocationProvider locationProvider)
1819
: ICodeBuilder<DpFactory>
1920
{
2021
public const string DefaultInstanceValueName = "instance_1182D127";
@@ -203,15 +204,15 @@ public void Build(BuildContext ctx, in DpFactory factory)
203204
{
204205
throw new CompileErrorException(
205206
string.Format(Strings.Error_Template_LifetimeDoesNotSupportCyclicDependencies, variable.Node.Lifetime),
206-
factory.Source.Source.GetLocation(),
207+
locationProvider.GetLocation(factory.Source.Source),
207208
LogId.ErrorInvalidMetadata);
208209
}
209210

210211
if (factory.Initializers.Length != inits.Count)
211212
{
212213
throw new CompileErrorException(
213214
Strings.Error_InvalidNumberOfInitializers,
214-
factory.Source.Source.GetLocation(),
215+
locationProvider.GetLocation(factory.Source.Source),
215216
LogId.ErrorInvalidMetadata);
216217
}
217218

src/Pure.DI.Core/Core/Code/FactoryValidator.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace Pure.DI.Core.Code;
22

3-
sealed class FactoryValidator : CSharpSyntaxWalker, IFactoryValidator
3+
sealed class FactoryValidator(ILocationProvider locationProvider)
4+
: CSharpSyntaxWalker, IFactoryValidator
45
{
56
private string? _contextParameterName;
67

@@ -16,7 +17,7 @@ public override void VisitIdentifierName(IdentifierNameSyntax node)
1617
{
1718
if (node.Parent is ArgumentSyntax)
1819
{
19-
throw new CompileErrorException(string.Format(Strings.Error_Template_CannotUseContextDirectly, _contextParameterName), node.GetLocation(), LogId.ErrorInvalidMetadata);
20+
throw new CompileErrorException(string.Format(Strings.Error_Template_CannotUseContextDirectly, _contextParameterName), locationProvider.GetLocation(node), LogId.ErrorInvalidMetadata);
2021
}
2122
}
2223

0 commit comments

Comments
 (0)