Skip to content

Commit 5680667

Browse files
Improved diagnostics of error and warning locations
1 parent e37fb19 commit 5680667

11 files changed

Lines changed: 151 additions & 48 deletions

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public T GetAttribute<TMdAttribute, T>(
1313
SemanticModel semanticModel,
1414
in ImmutableArray<TMdAttribute> metadata,
1515
ISymbol member,
16+
bool isTag,
1617
T defaultValue)
1718
where TMdAttribute : IMdAttribute
1819
{
@@ -43,7 +44,8 @@ public T GetAttribute<TMdAttribute, T>(
4344
if (attr.ApplicationSyntaxReference?.GetSyntax() is AttributeSyntax { ArgumentList: {} argumentList }
4445
&& attributeMetadata.ArgumentPosition < argumentList.Arguments.Count)
4546
{
46-
return semantic.GetConstantValue<T>(semanticModel, argumentList.Arguments[attributeMetadata.ArgumentPosition].Expression) ?? defaultValue;
47+
return semantic.GetConstantValue<T>(semanticModel, argumentList.Arguments[attributeMetadata.ArgumentPosition].Expression, isTag ? SmartTagKind.Tag : SmartTagKind.Unknown)
48+
?? defaultValue;
4749
}
4850

4951
throw new CompileErrorException(

src/Pure.DI.Core/Core/BindingsFactory.cs

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
class BindingsFactory(
44
Func<IBuilder<RewriterContext<MdFactory>, MdFactory>> factoryRewriterFactory,
55
ITypes types,
6-
IMarker marker,
7-
IRegistryManager<MdBinding> registryManager)
6+
IMarker marker)
87
: IBindingsFactory
98
{
109
public MdBinding CreateGenericBinding(
@@ -25,8 +24,8 @@ public MdBinding CreateGenericBinding(
2524

2625
return sourceNode.Binding with
2726
{
28-
OriginalId = sourceNode.Binding.Id,
2927
Id = newId,
28+
OriginalIds = ImmutableArray.Create(sourceNode.Binding.Id),
3029
TypeConstructor = typeConstructor,
3130
Contracts = newContracts,
3231
Implementation = sourceNode.Binding.Implementation.HasValue
@@ -130,37 +129,42 @@ public MdBinding CreateConstructBinding(
130129
elementType = elementType.WithNullableAnnotation(NullableAnnotation.NotAnnotated);
131130
var dependencyContracts = new List<MdContract>();
132131
var contracts = new HashSet<Injection>();
133-
foreach (var nestedBinding in setup.Bindings.Where(i => i != targetNode.Binding))
132+
var originalIds = new HashSet<int>();
133+
if (constructKind is MdConstructKind.Array or MdConstructKind.AsyncEnumerable or MdConstructKind.Enumerable or MdConstructKind.Span)
134134
{
135-
var matchedContracts = GetMatchedMdContracts(setup, elementType, nestedBinding, typeConstructor).ToList();
136-
if (matchedContracts.Count == 0)
135+
foreach (var nestedBinding in setup.Bindings.Where(i => i != targetNode.Binding))
137136
{
138-
continue;
139-
}
137+
var matchedContracts = GetMatchedMdContracts(setup, elementType, nestedBinding, typeConstructor).ToList();
138+
if (matchedContracts.Count == 0)
139+
{
140+
continue;
141+
}
140142

141-
var tags = matchedContracts.First().Tags
142-
.Concat(nestedBinding.Tags)
143-
.Select((i, position) => i with { Position = position })
144-
.ToImmutableArray();
143+
var tags = matchedContracts.First().Tags
144+
.Concat(nestedBinding.Tags)
145+
.Select((i, position) => i with { Position = position })
146+
.ToImmutableArray();
145147

146-
var isDuplicate = false;
147-
if (constructKind is MdConstructKind.Enumerable or MdConstructKind.Array or MdConstructKind.Span or MdConstructKind.AsyncEnumerable)
148-
{
149-
foreach (var mdTag in tags.DefaultIfEmpty(new MdTag(0, null)))
148+
var isDuplicate = false;
149+
if (constructKind is MdConstructKind.Enumerable or MdConstructKind.Array or MdConstructKind.Span or MdConstructKind.AsyncEnumerable)
150150
{
151-
if (!contracts.Add(new Injection(InjectionKind.Construct, elementType, mdTag)))
151+
foreach (var mdTag in tags.DefaultIfEmpty(new MdTag(0, null)))
152152
{
153-
isDuplicate = true;
153+
if (!contracts.Add(new Injection(InjectionKind.Construct, elementType, mdTag)))
154+
{
155+
isDuplicate = true;
156+
}
154157
}
155158
}
156-
}
157159

158-
if (isDuplicate)
159-
{
160-
continue;
161-
}
160+
if (isDuplicate)
161+
{
162+
continue;
163+
}
162164

163-
dependencyContracts.Add(new MdContract(targetNode.Binding.SemanticModel, targetNode.Binding.Source, elementType, ContractKind.Implicit, tags));
165+
originalIds.Add(nestedBinding.Id);
166+
dependencyContracts.Add(new MdContract(targetNode.Binding.SemanticModel, targetNode.Binding.Source, elementType, ContractKind.Implicit, tags));
167+
}
164168
}
165169

166170
var newTags = tag is not null
@@ -187,9 +191,9 @@ public MdBinding CreateConstructBinding(
187191
dependencyContracts.ToImmutableArray(),
188192
hasExplicitDefaultValue,
189193
explicitDefaultValue,
190-
state));
194+
state),
195+
OriginalIds: originalIds.ToImmutableArray());
191196

192-
registryManager.Register(setup, newBinding);
193197
return newBinding;
194198
}
195199

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

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ sealed class BindingsValidator(
1010
{
1111
public bool Validate(DependencyGraph graph)
1212
{
13-
foreach (var binding in graph.Source.Bindings.Where(i => i.SourceSetup.Kind == CompositionKind.Public && i.Contracts.Any(c => c.Kind == ContractKind.Explicit)))
13+
foreach (var binding in graph.Source.Bindings.Where(i => i.SourceSetup.Kind == CompositionKind.Public && i.Contracts.All(c => c.Kind == ContractKind.Explicit)))
1414
{
15-
if (!registry.IsRegistered(graph.Source, binding.OriginalId ?? binding.Id))
15+
if (!GetIds(binding).Any(id => registry.IsRegistered(graph.Source, id)))
1616
{
1717
logger.CompileWarning(
1818
Strings.Warning_BindingIsNotUsed,
@@ -23,4 +23,17 @@ public bool Validate(DependencyGraph graph)
2323

2424
return true;
2525
}
26+
27+
private IEnumerable<int> GetIds(MdBinding binding)
28+
{
29+
if (!binding.OriginalIds.IsDefaultOrEmpty)
30+
{
31+
foreach (var id in binding.OriginalIds)
32+
{
33+
yield return id;
34+
}
35+
}
36+
37+
yield return binding.Id;
38+
}
2639
}

src/Pure.DI.Core/Core/GeneratorDiagnostic.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@ namespace Pure.DI.Core;
33
sealed class GeneratorDiagnostic(SourceProductionContext sourceProductionContext)
44
: IGeneratorDiagnostic
55
{
6-
public void ReportDiagnostic(Diagnostic diagnostic) =>
7-
sourceProductionContext.ReportDiagnostic(diagnostic);
6+
public void ReportDiagnostic(Diagnostic diagnostic)
7+
{
8+
try
9+
{
10+
sourceProductionContext.ReportDiagnostic(diagnostic);
11+
}
12+
catch
13+
{
14+
//
15+
}
16+
}
817
}

src/Pure.DI.Core/Core/IAttributes.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ T GetAttribute<TMdAttribute, T>(
66
SemanticModel semanticModel,
77
in ImmutableArray<TMdAttribute> metadata,
88
ISymbol member,
9+
bool isTag,
910
T defaultValue)
1011
where TMdAttribute : IMdAttribute;
1112

src/Pure.DI.Core/Core/ImplementationDependencyNodeBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public IEnumerable<DependencyNode> Build(DependencyNodeBuildContext ctx)
5454
constructors.Add(
5555
new DpMethod(
5656
constructor,
57-
attributes.GetAttribute(setup.SemanticModel, setup.OrdinalAttributes, constructor, default(int?)),
57+
attributes.GetAttribute(setup.SemanticModel, setup.OrdinalAttributes, constructor, false, default(int?)),
5858
instanceDpProvider.GetParameters(setup, constructor.Parameters, ctx.TypeConstructor),
5959
locationProvider));
6060
}

src/Pure.DI.Core/Core/InstanceDpProvider.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ public InstanceDp Get(
3737
case IMethodSymbol method:
3838
if (method.MethodKind == MethodKind.Ordinary)
3939
{
40-
var ordinal = attributes.GetAttribute(setup.SemanticModel, setupAttributes, member, default(int?))
40+
var ordinal = attributes.GetAttribute(setup.SemanticModel, setupAttributes, member, false, default(int?))
4141
?? method.Parameters
42-
.Select(param => attributes.GetAttribute(setup.SemanticModel, setupAttributes, param, default(int?)))
42+
.Select(param => attributes.GetAttribute(setup.SemanticModel, setupAttributes, param, false, default(int?)))
4343
.FirstOrDefault(i => i.HasValue);
4444

4545
if (ordinal.HasValue)
@@ -53,7 +53,7 @@ public InstanceDp Get(
5353
case IFieldSymbol field:
5454
if (field is { IsReadOnly: false, IsStatic: false, IsConst: false })
5555
{
56-
var ordinal = attributes.GetAttribute(setup.SemanticModel, setupAttributes, member, default(int?));
56+
var ordinal = attributes.GetAttribute(setup.SemanticModel, setupAttributes, member, false, default(int?));
5757
if (field.IsRequired || ordinal.HasValue)
5858
{
5959
var type = field.Type.WithNullableAnnotation(NullableAnnotation.NotAnnotated);
@@ -63,7 +63,7 @@ public InstanceDp Get(
6363
ordinal,
6464
new Injection(
6565
InjectionKind.Field,
66-
attributes.GetAttribute(setup.SemanticModel, setup.TypeAttributes, field, typeConstructor.Construct(setup, type)),
66+
attributes.GetAttribute(setup.SemanticModel, setup.TypeAttributes, field, false, typeConstructor.Construct(setup, type)),
6767
GetTagAttribute(setup, field))));
6868
}
6969
}
@@ -73,7 +73,7 @@ public InstanceDp Get(
7373
case IPropertySymbol property:
7474
if (property is { IsReadOnly: false, IsStatic: false, IsIndexer: false })
7575
{
76-
var ordinal = attributes.GetAttribute(setup.SemanticModel, setupAttributes, member, default(int?));
76+
var ordinal = attributes.GetAttribute(setup.SemanticModel, setupAttributes, member, false, default(int?));
7777
if (ordinal.HasValue || property.IsRequired)
7878
{
7979
var type = property.Type.WithNullableAnnotation(NullableAnnotation.NotAnnotated);
@@ -83,7 +83,7 @@ public InstanceDp Get(
8383
ordinal,
8484
new Injection(
8585
InjectionKind.Property,
86-
attributes.GetAttribute(setup.SemanticModel, setup.TypeAttributes, property, typeConstructor.Construct(setup, type)),
86+
attributes.GetAttribute(setup.SemanticModel, setup.TypeAttributes, property, false, typeConstructor.Construct(setup, type)),
8787
GetTagAttribute(setup, property))));
8888
}
8989
}
@@ -117,7 +117,7 @@ public ImmutableArray<DpParameter> GetParameters(
117117
parameter,
118118
new Injection(
119119
InjectionKind.Parameter,
120-
attributes.GetAttribute(setup.SemanticModel, setup.TypeAttributes, parameter, typeConstructor.Construct(setup, type)),
120+
attributes.GetAttribute(setup.SemanticModel, setup.TypeAttributes, parameter, false, typeConstructor.Construct(setup, type)),
121121
GetTagAttribute(setup, parameter))));
122122
}
123123

@@ -145,7 +145,7 @@ private static IEnumerable<ISymbol> GetMembers(ITypeSymbol type)
145145
private object? GetTagAttribute(
146146
MdSetup setup,
147147
ISymbol member) =>
148-
attributes.GetAttribute(setup.SemanticModel, setup.TagAttributes, member, default(object?))
148+
attributes.GetAttribute(setup.SemanticModel, setup.TagAttributes, member, true, default(object?))
149149
?? TryCreateTagOnSite(setup, member);
150150

151151
private object? TryCreateTagOnSite(

src/Pure.DI.Core/Core/Models/MdBinding.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ record MdBinding(
1313
in MdArg? Arg = null,
1414
in MdConstruct? Construct = null,
1515
ITypeConstructor? TypeConstructor = null,
16-
int? OriginalId = null)
16+
ImmutableArray<int> OriginalIds = default)
1717
{
1818
public ITypeSymbol Type => Implementation?.Type ?? Factory?.Type ?? Arg?.Type ?? Construct?.Type!;
1919

src/Pure.DI.Core/Core/Semantic.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,14 +247,14 @@ when memberAccessExpressionSyntax.IsKind(SyntaxKind.SimpleMemberAccessExpression
247247
}
248248

249249
var operation = semanticModel.GetOperation(node);
250-
if (operation?.ConstantValue.Value is not null)
250+
if (operation?.ConstantValue.Value is T value)
251251
{
252-
return (T)operation.ConstantValue.Value!;
252+
return value;
253253
}
254254

255-
if (typeof(T) == typeof(object) && operation is ITypeOfOperation typeOfOperation)
255+
if (typeof(T) == typeof(object) && operation is ITypeOfOperation { TypeOperand: T val })
256256
{
257-
return (T)typeOfOperation.TypeOperand;
257+
return val;
258258
}
259259

260260
throw new CompileErrorException(

src/Pure.DI.Core/Core/VariationalDependencyGraphBuilder.cs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,13 @@ sealed class VariationalDependencyGraphBuilder(
125125
{
126126
foreach (var dependency in dependencyGraph.Graph.Edges)
127127
{
128-
registryManager.Register(setup, dependency.Target.Binding.OriginalId ?? dependency.Target.Binding.Id);
129-
registryManager.Register(setup, dependency.Source.Binding.OriginalId ?? dependency.Source.Binding.Id);
128+
RegisterNode(setup, dependency.Target);
129+
RegisterNode(setup, dependency.Source);
130130
}
131131

132132
foreach (var node in dependencyGraph.Graph.Vertices)
133133
{
134-
registryManager.Register(setup, node.Binding.OriginalId ?? node.Binding.Id);
134+
RegisterNode(setup, node);
135135
}
136136

137137
return dependencyGraph;
@@ -155,6 +155,19 @@ IProcessingNode CreateProcessingNode(DependencyNode dependencyNode) =>
155155
}
156156
}
157157
}
158+
private void RegisterNode(MdSetup setup, DependencyNode node)
159+
{
160+
var binding = node.Binding;
161+
if (!binding.OriginalIds.IsDefaultOrEmpty)
162+
{
163+
foreach (var id in binding.OriginalIds)
164+
{
165+
registryManager.Register(setup, id);
166+
}
167+
}
168+
169+
registryManager.Register(setup, binding.Id);
170+
}
158171

159172
[SuppressMessage("ReSharper", "NotDisposedResourceIsReturned")]
160173
private static IEnumerable<Variation> CreateVariants(IEnumerable<IProcessingNode> nodes) =>

0 commit comments

Comments
 (0)