Skip to content
This repository was archived by the owner on Sep 9, 2025. It is now read-only.
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Update="Nerdbank.GitVersioning" Version="3.3.37" />
<PackageReference Update="Nerdbank.GitVersioning" Version="3.4.194" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,15 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Codelyzer.Analysis" Version="1.4.5" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Codelyzer.Analysis" Version="1.4.8-alpha-g29c192f06d" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\CTA.Rules.Config\CTA.Rules.Config.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Update="Nerdbank.GitVersioning" Version="3.3.37" />
<PackageReference Update="Nerdbank.GitVersioning" Version="3.4.194" />
</ItemGroup>

</Project>
301 changes: 129 additions & 172 deletions src/CTA.FeatureDetection.Common/packages.lock.json

Large diffs are not rendered by default.

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

<ItemGroup>
<PackageReference Update="Nerdbank.GitVersioning" Version="3.3.37" />
<PackageReference Update="Nerdbank.GitVersioning" Version="3.4.194" />
</ItemGroup>

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

<ItemGroup>
<PackageReference Update="Nerdbank.GitVersioning" Version="3.3.37" />
<PackageReference Update="Nerdbank.GitVersioning" Version="3.4.194" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion src/CTA.FeatureDetection/CTA.FeatureDetection.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Update="Nerdbank.GitVersioning" Version="3.3.37" />
<PackageReference Update="Nerdbank.GitVersioning" Version="3.4.194" />
</ItemGroup>

</Project>
4 changes: 2 additions & 2 deletions src/CTA.Rules.Actions/ActionsLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@ public Func<SyntaxGenerator, ObjectCreationExpressionSyntax, ExpressionSyntax> G
public Func<string, ProjectType, string> GetProjectLevelActions(string name, dynamic value) =>
GetAction<Func<string, ProjectType, string>>
(projectLevelActions, projectLevelObject, name, value);
public Func<string, ProjectType, List<string>, Dictionary<string, string>, List<string>, string> GetProjectFileActions(string name, dynamic value) =>
GetAction<Func<string, ProjectType, List<string>, Dictionary<string, string>, List<string>, string>>
public Func<string, ProjectType, List<string>, Dictionary<string, string>, List<string>, List<string>, string> GetProjectFileActions(string name, dynamic value) =>
GetAction<Func<string, ProjectType, List<string>, Dictionary<string, string>, List<string>, List<string>, string>>
(projectFileActions, projectFileObject, name, value);
public Func<SyntaxGenerator, ElementAccessExpressionSyntax, ElementAccessExpressionSyntax> GetElementAccessExpressionActions(string name, dynamic value) =>
GetAction<Func<SyntaxGenerator, ElementAccessExpressionSyntax, ElementAccessExpressionSyntax>>
Expand Down
2 changes: 1 addition & 1 deletion src/CTA.Rules.Actions/CTA.Rules.Actions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Update="Nerdbank.GitVersioning" Version="3.3.37" />
<PackageReference Update="Nerdbank.GitVersioning" Version="3.4.194" />
</ItemGroup>

</Project>
10 changes: 9 additions & 1 deletion src/CTA.Rules.Actions/ClassActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,15 @@ public Func<SyntaxGenerator, ClassDeclarationSyntax, ClassDeclarationSyntax> Get
{
ClassDeclarationSyntax AddBaseClass(SyntaxGenerator syntaxGenerator, ClassDeclarationSyntax node)
{
node = (ClassDeclarationSyntax)syntaxGenerator.AddBaseType(node, SyntaxFactory.ParseName(baseClass));
if (syntaxGenerator != null)
{
node = (ClassDeclarationSyntax)syntaxGenerator.AddBaseType(node, SyntaxFactory.ParseName(baseClass));
}
else
{
var baseType = SyntaxFactory.SimpleBaseType(SyntaxFactory.ParseTypeName(baseClass));
node = node.AddBaseListTypes(baseType);
}
return node;
}
return AddBaseClass;
Expand Down
7 changes: 3 additions & 4 deletions src/CTA.Rules.Actions/ProjectFileActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,17 @@ namespace CTA.Rules.Actions
/// </summary>
public class ProjectFileActions
{
public Func<string, ProjectType, List<string>, Dictionary<string, string>, List<string>, string> GetMigrateProjectFileAction(string _)
public Func<string, ProjectType, List<string>, Dictionary<string, string>, List<string>, List<string>, string> GetMigrateProjectFileAction(string _)
{
static string func
(string projectDir, ProjectType projectType, List<string> targetVersion, Dictionary<string, string> packageReferences, List<string> projectReferences)
(string projectDir, ProjectType projectType, List<string> targetVersion, Dictionary<string, string> packageReferences, List<string> projectReferences, List<string> metaReferences)
{
ProjectFileCreator projectFileCreator = new ProjectFileCreator(projectDir, targetVersion,
packageReferences, projectReferences.ToList(), projectType);
packageReferences, projectReferences.ToList(), projectType, metaReferences);

var result = projectFileCreator.Create();
return result ? "Project file created" : string.Empty;
}

return func;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/CTA.Rules.Analysis/CTA.Rules.Analysis.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Update="Nerdbank.GitVersioning" Version="3.3.37" />
<PackageReference Update="Nerdbank.GitVersioning" Version="3.4.194" />
</ItemGroup>

</Project>
30 changes: 30 additions & 0 deletions src/CTA.Rules.Analysis/RulesAnalysis.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
Expand Down Expand Up @@ -47,6 +48,31 @@ public ProjectActions Analyze()
return _projectActions;
}

public ProjectActions AnalyzeFiles(ProjectActions projectActions, List<string> updatedFiles)
{
var options = new ParallelOptions() { MaxDegreeOfParallelism = Constants.ThreadCount };
var selectedSourceFileResults = _sourceFileResults.Where(s => updatedFiles.Contains(s.FileFullPath));

Parallel.ForEach(selectedSourceFileResults, options, result =>
{
var fileAction = new FileActions() { FilePath = result.FileFullPath };

if (AnalyzeChildren(fileAction, result.Children, 0))
{
var existingFileAction = _projectActions.FileActions.FirstOrDefault(f => f.FilePath == fileAction.FilePath);
if (existingFileAction != null)
{
existingFileAction = fileAction;
}
else
{
_projectActions.FileActions.Add(fileAction);
}
}
});
return _projectActions;
}

/// <summary>
/// Analyzes children of nodes in a particular file
/// </summary>
Expand Down Expand Up @@ -523,6 +549,10 @@ private void AddNamedActions(FileActions fileAction, NodeToken token, string ide
{
var nodeToken = token.Clone();
nodeToken.TextSpan = textSpan;
nodeToken.AllActions.ForEach(action =>
{
action.Key = identifier;
});
fileAction.NodeTokens.Add(nodeToken);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/CTA.Rules.Common/CTA.Rules.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Update="Nerdbank.GitVersioning" Version="3.3.37" />
<PackageReference Update="Nerdbank.GitVersioning" Version="3.4.194" />
</ItemGroup>

</Project>
4 changes: 2 additions & 2 deletions src/CTA.Rules.Config/CTA.Rules.Config.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
<PackageReference Include="NJsonSchema" Version="10.3.1" />
<PackageReference Include="NJsonSchema" Version="10.4.1" />
</ItemGroup>

<ItemGroup>
<PackageReference Update="Nerdbank.GitVersioning" Version="3.3.37" />
<PackageReference Update="Nerdbank.GitVersioning" Version="3.4.194" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion src/CTA.Rules.Metrics/CTA.Rules.Metrics.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Update="Nerdbank.GitVersioning" Version="3.3.37" />
<PackageReference Update="Nerdbank.GitVersioning" Version="3.4.194" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion src/CTA.Rules.Models/Actions/ProjectLevelAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace CTA.Rules.Models
public class ProjectLevelAction : GenericAction
{
public Func<string, ProjectType, string> ProjectLevelActionFunc { get; set; }
public Func<string, ProjectType, List<string>, Dictionary<string, string>, List<string>, string> ProjectFileActionFunc { get; set; }
public Func<string, ProjectType, List<string>, Dictionary<string, string>, List<string>, List<string>, string> ProjectFileActionFunc { get; set; }
public override bool Equals(object obj)
{
var action = (ProjectLevelAction)obj;
Expand Down
7 changes: 3 additions & 4 deletions src/CTA.Rules.Models/CTA.Rules.Models.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@


<ItemGroup>
<PackageReference Include="Codelyzer.Analysis" Version="1.4.5" />
<PackageReference Include="Codelyzer.Analysis.Model" Version="1.4.5" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Codelyzer.Analysis" Version="1.4.8-alpha-g29c192f06d" />
<PackageReference Include="Codelyzer.Analysis.Model" Version="1.4.8-alpha-g29c192f06d" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
</ItemGroup>

Expand All @@ -24,7 +23,7 @@


<ItemGroup>
<PackageReference Update="Nerdbank.GitVersioning" Version="3.3.37" />
<PackageReference Update="Nerdbank.GitVersioning" Version="3.4.194" />
</ItemGroup>

</Project>
4 changes: 3 additions & 1 deletion src/CTA.Rules.Models/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ public enum ProjectType
WebApi,
Mvc,
WebClassLibrary,
ClassLibrary
ClassLibrary,
CoreWebApi,
CoreMvc
}
public enum FileTypeCreation
{
Expand Down
1 change: 1 addition & 0 deletions src/CTA.Rules.Models/FileActions/FileActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public List<GenericAction> AllActions
allActions.AddRange(ClassDeclarationActions);
allActions.AddRange(InterfaceDeclarationActions);
allActions.AddRange(ElementAccessActions);
allActions.AddRange(MemberAccessActions);
allActions.AddRange(IdentifierNameActions);
allActions.AddRange(InvocationExpressionActions);
allActions.AddRange(MemberAccessActions);
Expand Down
15 changes: 15 additions & 0 deletions src/CTA.Rules.Models/IDEFileActions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
using Codelyzer.Analysis.Model;

namespace CTA.Rules.Models
{
public class IDEFileActions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a doc comment for the class that describes its use and how it differs from other file actions?

Also, would it make sense to rename anything with the prefix IDE to something more generic? Dependencies shouldn't be aware of the libraries or projects that consume them, but I also don't have full context here about how this model is consumed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't usually add doc comments for models. We can document our models classes at a later stage if needed.

{
public string FilePath { get; set; }
public TextSpan TextSpan { get; set; }
public string Description { get; set; }
public IList<TextChange> TextChanges { get; set; }
}
}
1 change: 1 addition & 0 deletions src/CTA.Rules.Models/ProjectActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public ProjectActions()
public BlockingCollection<PackageAction> PackageActions { get; set; }
public BlockingCollection<string> ProjectReferenceActions { get; set; }
public List<ProjectLevelAction> ProjectLevelActions { get; set; }
public RootNodes ProjectRules { get; set; }

public override string ToString()
{
Expand Down
2 changes: 2 additions & 0 deletions src/CTA.Rules.Models/ProjectConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public ProjectConfiguration()
public string RulesDir;
public Dictionary<string, Tuple<string, string>> PackageReferences;
public bool IsMockRun = false;
public bool PortProject = true;
public bool PortCode = true;
public ProjectType ProjectType = ProjectType.ClassLibrary;
}
}
29 changes: 29 additions & 0 deletions src/CTA.Rules.Models/TextChange.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using Microsoft.CodeAnalysis;

namespace CTA.Rules.Models
{
public class TextChange
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A doc comment for this class would be helpful as well

{
public string NewText { get; set; }
public FileLinePositionSpan FileLinePositionSpan { get; set; }

public bool Equals(TextChange textChange)
{
if (textChange == null) return false;

return NewText == textChange.NewText
&& FileLinePositionSpan.Equals(textChange.FileLinePositionSpan);
}

public override bool Equals(object obj)
{
return Equals(obj as TextChange);
}

public override int GetHashCode()
{
return HashCode.Combine(FileLinePositionSpan, NewText);
}
}
}
29 changes: 27 additions & 2 deletions src/CTA.Rules.Models/Tokens/NodeToken.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using Codelyzer.Analysis.Model;
using System.Collections.Concurrent;
using System.Collections.Generic;
using CTA.Rules.Config;
using TextSpan = Codelyzer.Analysis.Model.TextSpan;

namespace CTA.Rules.Models.Tokens
{
Expand All @@ -24,6 +25,7 @@ public NodeToken()
ProjectLevelActions = new List<ProjectLevelAction>();
ProjectFileActions = new List<ProjectLevelAction>();
TargetCPU = new List<string>();
TextChanges = new List<TextChange>();
}
public string Key { get; set; }
public string TrimmedKey => !string.IsNullOrEmpty(Key) ? Utils.EscapeAllWhitespace(Key) : string.Empty;
Expand All @@ -32,6 +34,7 @@ public NodeToken()
public string FullKey { get; set; }
public TextSpan TextSpan { get; set; }
public string Description { get; set; }
public IList<TextChange> TextChanges { get; set; }
public List<string> TargetCPU { get; set; }
public List<AttributeAction> AttributeActions { get; set; }
public List<AttributeAction> AttributeListActions { get; set; }
Expand All @@ -51,5 +54,27 @@ public NodeToken()

public NodeToken Clone() => (NodeToken)this.MemberwiseClone();

public List<GenericAction> AllActions
{
get
{
var allActions = new List<GenericAction>();
allActions.AddRange(AttributeActions);
allActions.AddRange(AttributeListActions);
allActions.AddRange(MethodDeclarationActions);
allActions.AddRange(ClassDeclarationActions);
allActions.AddRange(InterfaceDeclarationActions);
allActions.AddRange(ElementAccessActions);
allActions.AddRange(MemberAccessActions);
allActions.AddRange(IdentifierNameActions);
allActions.AddRange(InvocationExpressionActions);
allActions.AddRange(MemberAccessActions);
allActions.AddRange(UsingActions);
allActions.AddRange(ObjectCreationExpressionActions);
allActions.AddRange(NamespaceActions);
return allActions;
}
}
Comment on lines +57 to +77
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a specific reason or requirement for creating a new List when this property is called? If not, convert allActions to a private class variable and reassign a value to it in the getter to prevent a potential memory leak.

If this behavior is intentional, it may be more appropriate to convert this property to a method as properties are used to retrieve state rather than generate new objects.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand. How would this cause a memory leak?

Copy link
Contributor

@jonlouie jonlouie Apr 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Memory leak might not be the best term here, but my thought is that it's possible to inadvertently consume more resources than expected. See the below example for what I was thinking, but if this is a nonconcern, we can forgo this modification.


Trivial example:

var allActions1 = nodeToken.AllActions;
var allActions2 = nodeToken.AllActions;

With the current implementation, this would allocate 2x the memory than the suggested implementation:

private List<GenericAction> _allActions;
public List<GenericAction> AllActions
{
    get
    {
        _allActions = new List<GenericAction>();
        _allActions.AddRange(AttributeActions);
        _allActions.AddRange(AttributeListActions);
        _allActions.AddRange(MethodDeclarationActions);
        _allActions.AddRange(ClassDeclarationActions);
        _allActions.AddRange(InterfaceDeclarationActions);
        _allActions.AddRange(ElementAccessActions);
        _allActions.AddRange(MemberAccessActions);
        _allActions.AddRange(IdentifierNameActions);
        _allActions.AddRange(InvocationExpressionActions);
        _allActions.AddRange(MemberAccessActions);
        _allActions.AddRange(UsingActions);
        _allActions.AddRange(ObjectCreationExpressionActions);
        _allActions.AddRange(NamespaceActions);
        return _allActions;
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, this wouldn't allocate 2x memory because it's a local variable that gets disposed after the getter exits. We can look into this and the same behavior in fileactions to see if there's a better way to do it.


}
}
Loading