Skip to content

Commit e1352fe

Browse files
committed
Refactor: TryGetType
1 parent 1471af0 commit e1352fe

6 files changed

Lines changed: 163 additions & 181 deletions

File tree

AspNetCoreAnalyzers/Analyzers/AttributeAnalyzer.cs

Lines changed: 70 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -190,56 +190,83 @@ private static bool HasWrongType(ParameterPair pair, out string correctType)
190190
foreach (var constraint in constraints)
191191
{
192192
// https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-2.2#route-constraint-reference
193-
switch (constraint.Span.Text)
193+
if (TryGetType(constraint.Span.Text, out var type))
194194
{
195-
case "bool":
196-
correctType = constraint.Span.Text;
197-
return parameter.Type != KnownSymbol.Boolean;
198-
case "decimal":
199-
correctType = constraint.Span.Text;
200-
return parameter.Type != KnownSymbol.Decimal;
201-
case "double":
202-
correctType = constraint.Span.Text;
203-
return parameter.Type != KnownSymbol.Double;
204-
case "float":
205-
correctType = constraint.Span.Text;
206-
return parameter.Type != KnownSymbol.Float;
207-
case "int":
208-
correctType = constraint.Span.Text;
209-
return parameter.Type != KnownSymbol.Int32;
210-
case "long":
211-
correctType = constraint.Span.Text;
212-
return parameter.Type != KnownSymbol.Int64;
213-
case "datetime" when parameter.Type != KnownSymbol.DateTime:
214-
correctType = "System.DateTime";
215-
return true;
216-
case "guid" when parameter.Type != KnownSymbol.Guid:
217-
correctType = "System.Guid";
218-
return true;
219-
case "alpha" when parameter.Type != KnownSymbol.String:
220-
correctType = "string";
221-
return true;
222-
case "required":
223-
continue;
224-
case string text when parameter.Type != KnownSymbol.String &&
225-
(text.StartsWith("regex(", StringComparison.OrdinalIgnoreCase) ||
226-
text.StartsWith("length(", StringComparison.OrdinalIgnoreCase) ||
227-
text.StartsWith("minlength(", StringComparison.OrdinalIgnoreCase) ||
228-
text.StartsWith("maxlength(", StringComparison.OrdinalIgnoreCase)):
229-
correctType = "string";
230-
return true;
231-
case string text when parameter.Type != KnownSymbol.Int64 &&
232-
(text.StartsWith("min(", StringComparison.OrdinalIgnoreCase) ||
233-
text.StartsWith("max(", StringComparison.OrdinalIgnoreCase) ||
234-
text.StartsWith("range(", StringComparison.OrdinalIgnoreCase)):
235-
correctType = "long";
236-
return true;
195+
correctType = parameter.Type == type ? null : type.Alias ?? type.FullName;
196+
return correctType != null;
237197
}
238198
}
239199
}
240200

241201
correctType = null;
242202
return false;
203+
204+
bool TryGetType(string constraint, out QualifiedType type)
205+
{
206+
if (constraint.Equals("bool", StringComparison.Ordinal))
207+
{
208+
type = KnownSymbol.Boolean;
209+
return true;
210+
}
211+
212+
if (constraint.Equals("decimal", StringComparison.Ordinal))
213+
{
214+
type = KnownSymbol.Decimal;
215+
return true;
216+
}
217+
218+
if (constraint.Equals("double", StringComparison.Ordinal))
219+
{
220+
type = KnownSymbol.Double;
221+
return true;
222+
}
223+
224+
if (constraint.Equals("float", StringComparison.Ordinal))
225+
{
226+
type = KnownSymbol.Float;
227+
return true;
228+
}
229+
230+
if (constraint.Equals("int", StringComparison.Ordinal))
231+
{
232+
type = KnownSymbol.Int32;
233+
return true;
234+
}
235+
236+
if (constraint.Equals("long", StringComparison.Ordinal) ||
237+
constraint.StartsWith("min(", StringComparison.OrdinalIgnoreCase) ||
238+
constraint.StartsWith("max(", StringComparison.OrdinalIgnoreCase) ||
239+
constraint.StartsWith("range(", StringComparison.OrdinalIgnoreCase))
240+
{
241+
type = KnownSymbol.Int64;
242+
return true;
243+
}
244+
245+
if (constraint.Equals("datetime", StringComparison.Ordinal))
246+
{
247+
type = KnownSymbol.DateTime;
248+
return true;
249+
}
250+
251+
if (constraint.Equals("guid", StringComparison.Ordinal))
252+
{
253+
type = KnownSymbol.Guid;
254+
return true;
255+
}
256+
257+
if (constraint.Equals("alpha", StringComparison.OrdinalIgnoreCase) ||
258+
constraint.StartsWith("regex(", StringComparison.OrdinalIgnoreCase) ||
259+
constraint.StartsWith("length(", StringComparison.OrdinalIgnoreCase) ||
260+
constraint.StartsWith("minlength(", StringComparison.OrdinalIgnoreCase) ||
261+
constraint.StartsWith("maxlength(", StringComparison.OrdinalIgnoreCase))
262+
{
263+
type = KnownSymbol.String;
264+
return true;
265+
}
266+
267+
type = null;
268+
return false;
269+
}
243270
}
244271

245272
private static bool HasWrongSyntax(PathSegment segment, out Location location, out string correctSyntax)

AspNetCoreAnalyzers/Helpers/PathSegment.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ public struct PathSegment
77
{
88
public PathSegment(StringLiteral literal, int start, int end)
99
{
10-
this.Span = new Span(literal, start, end);
10+
this.Span = new StringLiteralSpan(literal, start, end);
1111
this.Parameter = TemplateParameter.TryParse(this.Span, out var parameter)
1212
? parameter
1313
: (TemplateParameter?)null;
1414
}
1515

16-
public Span Span { get; }
16+
public StringLiteralSpan Span { get; }
1717

1818
public TemplateParameter? Parameter { get; }
1919

AspNetCoreAnalyzers/Helpers/RouteConstraint.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ namespace AspNetCoreAnalyzers
66
[DebuggerDisplay("{this.Span.Text}")]
77
public struct RouteConstraint : IEquatable<RouteConstraint>
88
{
9-
public RouteConstraint(Span span)
9+
public RouteConstraint(StringLiteralSpan span)
1010
{
1111
this.Span = span;
1212
}
1313

14-
public Span Span { get; }
14+
public StringLiteralSpan Span { get; }
1515

1616
public static bool operator ==(RouteConstraint left, RouteConstraint right)
1717
{
@@ -23,7 +23,7 @@ public RouteConstraint(Span span)
2323
return !left.Equals(right);
2424
}
2525

26-
public static bool TryRead(Span span, int pos, out RouteConstraint constraint)
26+
public static bool TryRead(StringLiteralSpan span, int pos, out RouteConstraint constraint)
2727
{
2828
if (pos >= span.TextSpan.End ||
2929
span.Text[pos] != ':')

AspNetCoreAnalyzers/Helpers/Span.cs

Lines changed: 0 additions & 130 deletions
This file was deleted.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
namespace AspNetCoreAnalyzers
2+
{
3+
using System;
4+
using Microsoft.CodeAnalysis;
5+
using Microsoft.CodeAnalysis.CSharp.Syntax;
6+
using Microsoft.CodeAnalysis.Text;
7+
8+
public struct StringLiteralSpan : IEquatable<StringLiteralSpan>
9+
{
10+
public StringLiteralSpan(StringLiteral literal, int start, int end)
11+
{
12+
this.Literal = literal;
13+
this.TextSpan = new TextSpan(start, end - start);
14+
this.Text = literal.LiteralExpression.Token.ValueText.Substring(this.TextSpan.Start, this.TextSpan.Length);
15+
}
16+
17+
public StringLiteral Literal { get; }
18+
19+
public TextSpan TextSpan { get; }
20+
21+
public string Text { get; }
22+
23+
public static bool operator ==(StringLiteralSpan left, StringLiteralSpan right)
24+
{
25+
return left.Equals(right);
26+
}
27+
28+
public static bool operator !=(StringLiteralSpan left, StringLiteralSpan right)
29+
{
30+
return !left.Equals(right);
31+
}
32+
33+
public bool Equals(StringLiteralSpan other)
34+
{
35+
return this.Literal.Equals(other.Literal) && this.TextSpan == other.TextSpan;
36+
}
37+
38+
public override bool Equals(object obj)
39+
{
40+
return obj is StringLiteralSpan other &&
41+
this.Equals(other);
42+
}
43+
44+
public override int GetHashCode()
45+
{
46+
unchecked
47+
{
48+
var hashCode = this.Literal.GetHashCode();
49+
hashCode = (hashCode * 397) ^ this.TextSpan.GetHashCode();
50+
return hashCode;
51+
}
52+
}
53+
54+
public override string ToString() => this.Literal.LiteralExpression.Token.ValueText.Substring(this.TextSpan.Start, this.TextSpan.Length);
55+
56+
public Location GetLocation() => this.Literal.GetLocation(this.TextSpan);
57+
58+
public Location GetLocation(int start, int length) => this.Literal.GetLocation(new TextSpan(this.TextSpan.Start + start, length));
59+
60+
internal StringLiteralSpan Slice(int start, int end)
61+
{
62+
if (start > end)
63+
{
64+
throw new InvalidOperationException("Expected start to be less than end.");
65+
}
66+
67+
if (end > this.TextSpan.End)
68+
{
69+
throw new InvalidOperationException("Expected end to be less than TextSpan.End.");
70+
}
71+
72+
return new StringLiteralSpan(this.Literal, this.TextSpan.Start + start, this.TextSpan.Start + end);
73+
}
74+
75+
internal StringLiteralSpan Substring(int index, int length)
76+
{
77+
return new StringLiteralSpan(this.Literal, this.TextSpan.Start + index, this.TextSpan.Start + index + length);
78+
}
79+
80+
internal StringLiteralSpan Substring(int index)
81+
{
82+
return new StringLiteralSpan(this.Literal, this.TextSpan.Start + index, this.TextSpan.Start + index + this.TextSpan.Length);
83+
}
84+
}
85+
}

0 commit comments

Comments
 (0)