diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index d0f7199..5bbc30d 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -10,7 +10,7 @@
Off
true
latest
- Copyright © 2015-2021 Bill Menees
+ Copyright © 2015-$([System.DateTime]::UtcNow.ToString(`yyyy`)) Bill Menees
1701;1702;1705;SA0001
@@ -19,7 +19,7 @@
- 3.0.4
+ 3.0.5
diff --git a/src/Menees.Analyzers/Men002LineTooLong.cs b/src/Menees.Analyzers/Men002LineTooLong.cs
index 342348e..3e1c159 100644
--- a/src/Menees.Analyzers/Men002LineTooLong.cs
+++ b/src/Menees.Analyzers/Men002LineTooLong.cs
@@ -110,12 +110,33 @@ private void HandleSyntaxTree(SyntaxTreeAnalysisContext context)
TextSpan lineSpan = line.Span;
if (lineSpan.Length * tabSize > maxLength)
{
- int displayLength = GetLineDisplayLength(line.ToString(), tabSize, maxLength, out int maxIndex);
+ string lineText = line.ToString();
+ int displayLength = GetLineDisplayLength(lineText, tabSize, maxLength, out int maxIndex);
if (displayLength > maxLength)
{
- TextSpan excess = TextSpan.FromBounds(lineSpan.Start + maxIndex, lineSpan.End);
- Location location = Location.Create(context.Tree, excess);
- context.ReportDiagnostic(Diagnostic.Create(Rule, location, maxLength, displayLength));
+ bool report = true;
+ if (this.settings.AllowLongUriLines)
+ {
+ // Ignore if the whole line minus comment delimiters passes Uri.TryCreate(absolute) (e.g., for http or UNC URLs).
+ string scrubbed = lineText.Trim();
+ if (scrubbed.StartsWith("//"))
+ {
+ scrubbed = scrubbed.Substring(2).Trim();
+ }
+ else if (scrubbed.StartsWith("/*") && scrubbed.EndsWith("*/"))
+ {
+ scrubbed = scrubbed.Substring(2, scrubbed.Length - 4).Trim();
+ }
+
+ report = !Uri.TryCreate(scrubbed, UriKind.Absolute, out _);
+ }
+
+ if (report)
+ {
+ TextSpan excess = TextSpan.FromBounds(lineSpan.Start + maxIndex, lineSpan.End);
+ Location location = Location.Create(context.Tree, excess);
+ context.ReportDiagnostic(Diagnostic.Create(Rule, location, maxLength, displayLength));
+ }
}
}
}
diff --git a/src/Menees.Analyzers/Settings.cs b/src/Menees.Analyzers/Settings.cs
index f4717cd..e2ca88c 100644
--- a/src/Menees.Analyzers/Settings.cs
+++ b/src/Menees.Analyzers/Settings.cs
@@ -104,6 +104,7 @@ private Settings(XElement xml)
this.MaxPropertyAccessorLines = GetSetting(xml, nameof(this.MaxPropertyAccessorLines), this.MaxPropertyAccessorLines);
this.MaxFileLines = GetSetting(xml, nameof(this.MaxFileLines), this.MaxFileLines);
this.MaxUnregionedLines = GetSetting(xml, nameof(this.MaxUnregionedLines), this.MaxUnregionedLines);
+ this.AllowLongUriLines = GetSetting(xml, nameof(this.AllowLongUriLines), this.AllowLongUriLines);
XElement typeFileNameExclusionsElement = xml.Element("TypeFileNameExclusions");
if (typeFileNameExclusionsElement != null)
@@ -186,6 +187,8 @@ private enum NumberBase
public bool HasPreferredTerms => this.preferredTerms.Count > 0;
+ public bool AllowLongUriLines { get; } = true;
+
#endregion
#region Public Methods
@@ -321,13 +324,19 @@ private static Settings LoadSettings(SourceText sourceText)
}
private static int GetSetting(XElement xml, string elementName, int defaultValue)
+ => GetSetting(xml, elementName, defaultValue, (string text, out int value) => int.TryParse(text, out value) && value > 0);
+
+ private static bool GetSetting(XElement xml, string elementName, bool defaultValue)
+ => GetSetting(xml, elementName, defaultValue, bool.TryParse);
+
+ private static T GetSetting(XElement xml, string elementName, T defaultValue, TryParse tryParse)
{
- int result = defaultValue;
+ T result = defaultValue;
XElement element = xml.Element(elementName);
if (element != null)
{
- if (int.TryParse(element.Value, out int value) && value > 0)
+ if (tryParse(element.Value, out T value))
{
result = value;
}
@@ -401,5 +410,11 @@ private static Tuple SplitNumericLiteral(string text)
}
#endregion
+
+ #region Private Delegates
+
+ private delegate bool TryParse(string text, out T value);
+
+ #endregion
}
}
diff --git a/tests/Menees.Analyzers.Test/Men002UnitTests.cs b/tests/Menees.Analyzers.Test/Men002UnitTests.cs
index 22d9708..1675684 100644
--- a/tests/Menees.Analyzers.Test/Men002UnitTests.cs
+++ b/tests/Menees.Analyzers.Test/Men002UnitTests.cs
@@ -38,6 +38,15 @@ class Testing
/// Test
public Testing()
{
+ // AllowLongUriLines=true
+ // https://www.amazon.com/Brain-Games%C2%AE-Large-Print-Searches/dp/1640304606/ref=sr_1_2?crid=3KP7CV3HBJADN&keywords=big+long+search+text&qid=1645375366&sprefix=big+long+search+text%2Caps%2C72&sr=8-2
+ /* https://www.google.com/maps/place/Yellowstone+National+Park/@44.5854032,-111.0744669,9z/data=!3m1!4b1!4m5!3m4!1s0x5351e55555555555:0xaca8f930348fe1bb!8m2!3d44.427963!4d-110.588455 */
+ /*
+ Brazil weather?
+ https://weather.com/weather/today/l/63e18eea74a484c42c3921cf52a8fec98113dbb13f6deb7c477b2f453c95b837
+ Or:
+ \\weatherserver\brazil\sao\paulo\today\63e18eea74a484c42c3921cf52a8fec98113dbb13f6deb7c477b2f453c95b837
+ */
}
}
}";
@@ -64,6 +73,7 @@ class TypeName
///
public TypeName() // This line is also much too long.
{
+ // GT fans: https://www.amazon.com/yourfanshop?selectedTeamName=Georgia%20Tech%20Yellow%20Jackets&asin=&refinement=popular&team=375636011
}
}
}";
@@ -80,6 +90,11 @@ public TypeName() // This line is also much too long.
Message = "Line must be no longer than 40 characters (now 61).",
Locations = new[] { new DiagnosticResultLocation("Test0.cs", 12, 35) }
},
+ new DiagnosticResult(analyzer)
+ {
+ Message = "Line must be no longer than 40 characters (now 149).",
+ Locations = new[] { new DiagnosticResultLocation("Test0.cs", 14, 32) }
+ },
};
this.VerifyCSharpDiagnostic(test, expected);