Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@
<ItemGroup Label="Code Analyzers">
<PackageReference Include="Atc.Analyzer" Version="0.1.23" PrivateAssets="All" />
<PackageReference Include="AsyncFixer" Version="2.1.0" PrivateAssets="All" />
<PackageReference Include="Meziantou.Analyzer" Version="3.0.136" PrivateAssets="All" />
<PackageReference Include="Meziantou.Analyzer" Version="3.0.177" PrivateAssets="All" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.435" PrivateAssets="All" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.31.0.145097" PrivateAssets="All" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.33.0.1635" PrivateAssets="All" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.10" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.10" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.10" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.11" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.11" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.11" />
<PackageReference Include="Spectre.Console" Version="0.57.2" />
<PackageReference Include="Spectre.Console.Cli" Version="0.55.0" />
</ItemGroup>
Expand Down
6 changes: 3 additions & 3 deletions sample/Demo.Atc.Dotnet.Cli/Demo.Atc.Dotnet.Cli.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.10" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.10" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.10" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.11" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.11" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.11" />
<PackageReference Include="Spectre.Console" Version="0.57.2" />
<PackageReference Include="Spectre.Console.Cli" Version="0.55.0" />
</ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Atc.Console.Spectre/Atc.Console.Spectre.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.10" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.11" />
<PackageReference Include="Spectre.Console" Version="0.57.2" />
<PackageReference Include="Spectre.Console.Cli" Version="0.55.0" />
</ItemGroup>
Expand Down
38 changes: 27 additions & 11 deletions src/Atc.DotNet/DotnetCsProjFileHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,24 +178,25 @@ public static DotnetProjectType GetProjectType(string fileContent)

private static DotnetProjectType ProjectSdkElement(XElement rootElement)
{
if (rootElement.FirstAttribute is not null)
var sdk = GetSdk(rootElement);
if (sdk is not null)
{
if (rootElement.FirstAttribute.Value.StartsWith("Aspire.AppHost.Sdk", StringComparison.OrdinalIgnoreCase))
if (sdk.StartsWith("Aspire.AppHost.Sdk", StringComparison.OrdinalIgnoreCase))
{
return DotnetProjectType.AspireAppHost;
}

if (rootElement.FirstAttribute.Value.Equals("Microsoft.NET.Sdk.BlazorWebAssembly", StringComparison.Ordinal))
if (sdk.Equals("Microsoft.NET.Sdk.BlazorWebAssembly", StringComparison.Ordinal))
{
return DotnetProjectType.BlazorWAsmApp;
}

if (rootElement.FirstAttribute.Value.Equals("Microsoft.NET.Sdk.Razor", StringComparison.Ordinal))
if (sdk.Equals("Microsoft.NET.Sdk.Razor", StringComparison.Ordinal))
{
return DotnetProjectType.RazorLibrary;
}

if (rootElement.FirstAttribute.Value.Equals("Microsoft.NET.Sdk.Worker", StringComparison.Ordinal))
if (sdk.Equals("Microsoft.NET.Sdk.Worker", StringComparison.Ordinal))
{
return DotnetProjectType.WorkerService;
}
Expand Down Expand Up @@ -224,8 +225,7 @@ private static DotnetProjectType ProjectSdkElement(XElement rootElement)

private static DotnetProjectType ProjectElementForSdk(XElement rootElement)
{
if (rootElement.FirstAttribute is not null &&
!rootElement.FirstAttribute.Value.Equals("Microsoft.NET.Sdk", StringComparison.Ordinal))
if (!IsSdk(rootElement, "Microsoft.NET.Sdk"))
{
return DotnetProjectType.None;
}
Expand Down Expand Up @@ -285,8 +285,7 @@ private static DotnetProjectType ProjectElementForSdk(XElement rootElement)
private static DotnetProjectType ProjectElementForSdkTest(
XElement rootElement)
{
if (rootElement.FirstAttribute is not null &&
!rootElement.FirstAttribute.Value.Equals("Microsoft.NET.Sdk", StringComparison.Ordinal))
if (!IsSdk(rootElement, "Microsoft.NET.Sdk"))
{
return DotnetProjectType.None;
}
Expand Down Expand Up @@ -317,8 +316,7 @@ private static DotnetProjectType ProjectElementForSdkTest(
private static DotnetProjectType ProjectElementForSdkWeb(
XElement rootElement)
{
if (rootElement.FirstAttribute is not null &&
!rootElement.FirstAttribute.Value.Equals("Microsoft.NET.Sdk.Web", StringComparison.Ordinal))
if (!IsSdk(rootElement, "Microsoft.NET.Sdk.Web"))
{
return DotnetProjectType.None;
}
Expand Down Expand Up @@ -367,6 +365,24 @@ private static DotnetProjectType ProjectElementForToolsVersion(
return DotnetProjectType.None;
}

/// <summary>
/// Reads the <c>Sdk</c> attribute of the project element. The attribute is looked up by name
/// instead of using <see cref="XElement.FirstAttribute"/>, since any other attribute - an
/// <c>xmlns</c> declaration included - can be written ahead of it.
/// </summary>
private static string? GetSdk(XElement rootElement)
=> rootElement.Attribute("Sdk")?.Value;

private static bool IsSdk(
XElement rootElement,
string sdk)
{
var value = GetSdk(rootElement);

return value is null ||
value.Equals(sdk, StringComparison.Ordinal);
}

private static bool HasPackageReference(
XElement rootElement,
string packageReference)
Expand Down
41 changes: 35 additions & 6 deletions src/Atc.DotNet/DotnetNugetHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,24 @@ public static List<DotnetNugetPackageMetadataBase> GetAllPackageReferences(
throw new ArgumentNullException(nameof(fileContent));
}

if (!fileContent.StartsWith('<'))
// A project file can start with a byte-order-mark remnant, a blank line or indentation
// before the XML declaration, none of which stops it from being valid XML.
var trimmedFileContent = fileContent.TrimStart();

if (!trimmedFileContent.StartsWith('<'))
{
throw new DataException("Expect xml content");
}

var xDoc = XDocument.Parse(fileContent);
var xDoc = XDocument.Parse(trimmedFileContent);
var data = xDoc
.Descendants("PackageReference")
.Descendants()
.Where(e => e.Name.LocalName.Equals("PackageReference", StringComparison.Ordinal))
.Select(e => new
{
PackageId = e.Attribute("Include")?.Value,
Version = e.Attribute("Version")?.Value
?? e.Element("Version")?.Value,
PackageId = GetAttributeValue(e, "Include"),
Version = GetAttributeValue(e, "Version")
?? GetElementValue(e, "Version"),
})
.Where(x => !string.IsNullOrEmpty(x.PackageId) && !string.IsNullOrEmpty(x.Version))
.Select(x => new DotnetNugetPackageMetadataBase(x.PackageId!, x.Version!))
Expand All @@ -65,4 +70,28 @@ public static List<DotnetNugetPackageMetadataBase> GetAllPackageReferences(

return data;
}

/// <summary>
/// Reads an attribute by its local name, so project files declaring the legacy MSBuild
/// namespace are handled the same way as SDK-style ones.
/// </summary>
private static string? GetAttributeValue(
XElement element,
string attributeName)
=> element
.Attributes()
.FirstOrDefault(x => x.Name.LocalName.Equals(attributeName, StringComparison.Ordinal))
?.Value;

/// <summary>
/// Reads a child element by its local name, so project files declaring the legacy MSBuild
/// namespace are handled the same way as SDK-style ones.
/// </summary>
private static string? GetElementValue(
XElement element,
string elementName)
=> element
.Elements()
.FirstOrDefault(x => x.Name.LocalName.Equals(elementName, StringComparison.Ordinal))
?.Value;
}
2 changes: 1 addition & 1 deletion src/Atc.OpenApi/Atc.OpenApi.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.OpenApi.Readers" Version="1.6.29" />
<PackageReference Include="Microsoft.OpenApi.Readers" Version="1.6.31" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AwesomeAssertions" Version="9.5.0" />
<PackageReference Include="AwesomeAssertions" Version="9.6.0" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Atc.Rest.HealthChecks/Atc.Rest.HealthChecks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="10.0.10" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="10.0.11" />
</ItemGroup>

<ItemGroup>
Expand Down
8 changes: 4 additions & 4 deletions src/Atc.XUnit/Atc.XUnit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@

<ItemGroup>
<PackageReference Include="EPPlus" Version="[7.5.3]" /> <!-- EPPlus is version-pinned because versions newer than 7.5.3 require a paid license -->
<PackageReference Include="ICSharpCode.Decompiler" Version="10.1.1.8388" />
<PackageReference Include="ICSharpCode.Decompiler" Version="11.0.0.9375" />
<PackageReference Include="Mono.Reflection" Version="2.0.0">
<NoWarn>NU1701</NoWarn>
</PackageReference>
<PackageReference Include="xunit.v3.assert" Version="3.2.2" />
<PackageReference Include="xunit.v3.common" Version="3.2.2" />
<PackageReference Include="xunit.v3.extensibility.core" Version="3.2.2" />
<PackageReference Include="xunit.v3.assert" Version="4.0.0" />
<PackageReference Include="xunit.v3.common" Version="4.0.0" />
<PackageReference Include="xunit.v3.extensibility.core" Version="4.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
24 changes: 7 additions & 17 deletions src/Atc.XUnit/Internal/AbstractSyntaxTree/DecompilerHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ internal static Tuple<MethodInfo, MethodDeclaration>[] GetTestMethodsWithDecompi
Tuple<Type, MethodInfo[]>[] testTypeMethods)
{
var testMethods = new List<Tuple<MethodInfo, MethodDeclaration>>();
foreach ((Type testType, MethodInfo[] testMethodInfos) in testTypeMethods)
foreach (var (testType, testMethodInfos) in testTypeMethods)
{
if (testType.FullName is null)
{
Expand All @@ -43,28 +43,18 @@ internal static Tuple<MethodInfo, MethodDeclaration>[] GetTestMethodsWithDecompi
var syntaxTree = decompiler.DecompileType(fullTypeName);
var astNodes = syntaxTree
.Descendants
.Where(x => x.NodeType == NodeType.Member)
.OfType<MethodDeclaration>()
.ToArray();

foreach (var testMethodInfo in testMethodInfos)
{
foreach (var astNode in astNodes)
{
if (astNode is not MethodDeclaration methodDeclaration)
{
continue;
}

if (!methodDeclaration.Name.Equals(testMethodInfo.Name, StringComparison.Ordinal))
{
continue;
}

testMethods.Add(new Tuple<MethodInfo, MethodDeclaration>(testMethodInfo, methodDeclaration));
}
testMethods.AddRange(
astNodes
.Where(methodDeclaration => methodDeclaration.Name.Equals(testMethodInfo.Name, StringComparison.Ordinal))
.Select(methodDeclaration => new Tuple<MethodInfo, MethodDeclaration>(testMethodInfo, methodDeclaration)));
}
}

return testMethods.ToArray();
return [.. testMethods];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,9 @@ testMethodsWithDeclaration is null ||
}

internal static AstNode? GetAstNodeForMethod(
AstNode astNode,
AstNode? astNode,
string methodName)
=> astNode.Descendants
=> astNode?.Descendants
.Where(x => x.IsType(typeof(InvocationExpression)))
.Select(node => node.Descendants.FirstOrDefault(x => x.IsType(typeof(Identifier)) && string.Equals(x.ToString(), methodName, StringComparison.Ordinal)))
.FirstOrDefault(x => x is not null);
Expand Down Expand Up @@ -207,7 +207,7 @@ testMethodsWithDeclaration is null ||
}

internal static AstNode? GetAstNodeForMethodWithParameters(
AstNode astNode,
AstNode? astNode,
string methodName)
=> GetAstNodeForMethod(astNode, methodName)?.Parent?.Parent;

Expand All @@ -220,10 +220,12 @@ internal static List<AstNode> GetAstNodesForMethodParameters(
return new List<AstNode>();
}

// Check if there are complex expressions (DirectionExpression or ObjectCreateExpression) as direct children
// Check if there are complex expressions (DirectionExpression, OutVarDeclarationExpression or ObjectCreateExpression) as direct children
// If so, we need to extract from direct children to get these nodes properly
var hasComplexExpressions = astNode.Children
.Any(x => x.IsType(typeof(DirectionExpression)) || x.IsType(typeof(ObjectCreateExpression)));
.Any(x => x.IsType(typeof(DirectionExpression)) ||
x.IsType(typeof(OutVarDeclarationExpression)) ||
x.IsType(typeof(ObjectCreateExpression)));

if (hasComplexExpressions)
{
Expand Down Expand Up @@ -251,6 +253,7 @@ internal static List<AstNode> GetAstNodesForMethodParameters(
.Where(x => x.IsType(typeof(InvocationExpression)) ||
x.IsType(typeof(ObjectCreateExpression)) ||
x.IsType(typeof(DirectionExpression)) ||
x.IsType(typeof(OutVarDeclarationExpression)) ||
x.IsType(typeof(LambdaExpression)) ||
x.IsType(typeof(AnonymousMethodExpression)) ||
x.ToString().Contains("=>", StringComparison.Ordinal))
Expand Down Expand Up @@ -291,6 +294,7 @@ private static List<AstNode> FilterDirectChildArguments(AstNode astNode)
return child.IsType(typeof(InvocationExpression)) ||
child.IsType(typeof(ObjectCreateExpression)) ||
child.IsType(typeof(DirectionExpression)) ||
child.IsType(typeof(OutVarDeclarationExpression)) ||
child.IsType(typeof(IdentifierExpression)) ||
child.IsType(typeof(PrimitiveExpression)) ||
child.IsType(typeof(NullReferenceExpression)) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,8 @@ private static bool ParameterCheckForDirectionExpression(
ParameterInfo parameter,
AstNode astNode)
{
if (!astNode.IsType(typeof(DirectionExpression)))
if (!astNode.IsType(typeof(DirectionExpression)) &&
!astNode.IsType(typeof(OutVarDeclarationExpression)))
{
return false;
}
Expand Down
8 changes: 4 additions & 4 deletions src/Atc/Atc.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Meziantou.Polyfill" Version="1.0.158">
<PackageReference Include="Meziantou.Polyfill" Version="1.0.161">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.10" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.11" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="10.0.10" />
<PackageReference Include="System.Text.Json" Version="10.0.11" />
</ItemGroup>

<ItemGroup>
Expand Down Expand Up @@ -77,7 +77,7 @@
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="10.0.10" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="10.0.11" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.301" PrivateAssets="All" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.400" PrivateAssets="All" />
<PackageReference Include="Nerdbank.GitVersioning" Version="3.10.91" PrivateAssets="All" />
</ItemGroup>

Expand Down
Loading