Skip to content

Development netstandard2.0 #265

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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: 3 additions & 1 deletion .github/workflows/build_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ jobs:
- name: Build
run: dotnet build --configuration Release --no-restore src/Codelyzer.sln
- name: Test
run: dotnet test --configuration Release --no-build --no-restore --verbosity normal src/Codelyzer.sln
run: dotnet test --configuration Release --no-build --no-restore --verbosity normal src/Codelyzer.sln --filter "FullyQualifiedName!~Codelyzer.Analysis.Workspace.Tests"
- name: Tests for Workspaces
run: dotnet test --configuration Release --no-build --no-restore --verbosity normal src/Codelyzer.sln --filter "FullyQualifiedName~Codelyzer.Analysis.Workspace.Tests"
- name: Pack
if: ${{ github.event_name == 'push' }}
run: dotnet pack --configuration Release --no-restore -o dist src/Codelyzer.sln
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
using Codelyzer.Analysis.Build;
using Codelyzer.Analysis.Common;
using Codelyzer.Analysis.Common;
using Codelyzer.Analysis.CSharp;
using Codelyzer.Analysis.Model;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Codelyzer.Analysis.Model.Build;

namespace Codelyzer.Analysis.Analyzer
namespace Codelyzer.Analysis.Analyzers
{
class CSharpAnalyzer : LanguageAnalyzer
{
public CSharpAnalyzer(AnalyzerConfiguration configuration, ILogger logger)
: base(configuration, logger)
{
}
: base(configuration, logger) {}
public override string Language => LanguageOptions.CSharp;
public override string ProjectFilePath { set; get; }
public override RootUstNode AnalyzeFile(SourceFileBuildResult sourceFileBuildResult, string projectRootPath)
{
CodeContext codeContext = new CodeContext(sourceFileBuildResult.PrePortSemanticModel,
var codeContext = new CodeContext(sourceFileBuildResult.PrePortSemanticModel,
sourceFileBuildResult.SemanticModel,
sourceFileBuildResult.SyntaxTree,
projectRootPath,
Expand All @@ -33,14 +27,15 @@ public override RootUstNode AnalyzeFile(SourceFileBuildResult sourceFileBuildRes

Logger.LogDebug("Analyzing: " + sourceFileBuildResult.SourceFileFullPath);

using CSharpRoslynProcessor processor = new CSharpRoslynProcessor(codeContext);

var result = (RootUstNode) processor.Visit(codeContext.SyntaxTree.GetRoot());
using (var processor = new CSharpRoslynProcessor(codeContext))
{
var result = (RootUstNode)processor.Visit(codeContext.SyntaxTree.GetRoot());

result.LinesOfCode = sourceFileBuildResult.SyntaxTree.GetRoot().DescendantTrivia()
.Where(t => t.IsKind(SyntaxKind.EndOfLineTrivia)).Count();
result.LinesOfCode = sourceFileBuildResult.SyntaxTree.GetRoot()
.DescendantTrivia().Count(t => t.IsKind(SyntaxKind.EndOfLineTrivia));

return result as RootUstNode;
return result as RootUstNode;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@
using System.Text;
using System.Threading.Tasks;

namespace Codelyzer.Analysis.Analyzer
namespace Codelyzer.Analysis.Analyzers
{
class CSharpAnalyzerFactory : LanguageAnalyzerFactory
public class CSharpAnalyzerFactory : LanguageAnalyzerFactory
{
protected readonly AnalyzerConfiguration _analyzerConfiguration;
protected readonly ILogger _logger;
protected readonly AnalyzerConfiguration AnalyzerConfiguration;
protected readonly ILogger Logger;

public CSharpAnalyzerFactory(AnalyzerConfiguration analyzerConfiguration, ILogger logger)
{
_analyzerConfiguration = analyzerConfiguration;
_logger = logger;
AnalyzerConfiguration = analyzerConfiguration;
Logger = logger;
}
public override LanguageAnalyzer GetLanguageAnalyzer()
{
return new CSharpAnalyzer(_analyzerConfiguration, _logger);
return new CSharpAnalyzer(AnalyzerConfiguration, Logger);
}
}

Expand Down
180 changes: 180 additions & 0 deletions src/Analysis/Codelyzer.Analysis.Analyzer/CodeAnalyzer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Codelyzer.Analysis.Common;
using Codelyzer.Analysis.Model;
using Codelyzer.Analysis.Model.Build;
using Codelyzer.Analysis.Workspace;
using Microsoft.CodeAnalysis;
using Microsoft.Extensions.Logging;

namespace Codelyzer.Analysis.Analyzers
{
public class CodeAnalyzer
{
protected readonly AnalyzerConfiguration AnalyzerConfiguration;
protected readonly ILogger Logger;

public CodeAnalyzer(AnalyzerConfiguration configuration, ILogger logger)
{
AnalyzerConfiguration = configuration;
Logger = logger;
}

public async Task<List<AnalyzerResult>> Analyze(Solution solution)
{
var projectBuildResults = await new WorkspaceHelper(Logger).GetProjectBuildResults(solution);
return await Analyze(projectBuildResults);
}

public async IAsyncEnumerable<AnalyzerResult> AnalyzeGeneratorAsync(Solution solution)
{
var projectBuildResultEnumerator = new WorkspaceHelper(Logger)
.GetProjectBuildResultsGeneratorAsync(solution)
.GetAsyncEnumerator();
try
{
while (await projectBuildResultEnumerator.MoveNextAsync().ConfigureAwait(false))
{
var projectBuildResult = projectBuildResultEnumerator.Current;
yield return await AnalyzeProjectBuildResult(projectBuildResult);
}
}
finally
{
await projectBuildResultEnumerator.DisposeAsync();
}
}

public async Task<List<AnalyzerResult>> Analyze(IEnumerable<ProjectBuildResult> projectBuildResults)
{
var analyzerResults = new List<AnalyzerResult>();

foreach (var projectBuildResult in projectBuildResults)
{
analyzerResults.Add(await AnalyzeProjectBuildResult(projectBuildResult));
}
await GenerateOptionalOutput(analyzerResults);
return analyzerResults;
}

public async Task<AnalyzerResult> AnalyzeProjectBuildResult(ProjectBuildResult projectBuildResult)
{
var workspaceResult = await Task.Run(() => AnalyzeProject(projectBuildResult));
workspaceResult.ProjectGuid = projectBuildResult.ProjectGuid;
workspaceResult.ProjectType = projectBuildResult.ProjectType;

//Generate Output result
return AnalyzerConfiguration.MetaDataSettings.LoadBuildData
? new AnalyzerResult()
{
ProjectResult = workspaceResult,
ProjectBuildResult = projectBuildResult
}
: new AnalyzerResult()
{
ProjectResult = workspaceResult
};
}

public async Task<AnalyzerResult> AnalyzeFile(
string filePath,
ProjectBuildResult incrementalBuildResult,
AnalyzerResult analyzerResult)
{
var newSourceFileBuildResult =
incrementalBuildResult.SourceFileBuildResults.FirstOrDefault(sourceFile =>
sourceFile.SourceFileFullPath == filePath);
var languageAnalyzer = GetLanguageAnalyzerByFileType(Path.GetExtension(filePath));
var fileAnalysis = languageAnalyzer.AnalyzeFile(newSourceFileBuildResult,
analyzerResult.ProjectResult.ProjectRootPath);
analyzerResult.ProjectResult.SourceFileResults.Add(fileAnalysis);
return analyzerResult;
}

public async Task GenerateOptionalOutput(List<AnalyzerResult> analyzerResults)
{
if (AnalyzerConfiguration.ExportSettings.GenerateJsonOutput)
{
Directory.CreateDirectory(AnalyzerConfiguration.ExportSettings.OutputPath);
foreach (var analyzerResult in analyzerResults)
{
Logger.LogDebug("Generating Json file for " + analyzerResult.ProjectResult.ProjectName);
var jsonOutput = SerializeUtils.ToJson<ProjectWorkspace>(analyzerResult.ProjectResult);
var jsonFilePath = await FileUtils.WriteFileAsync(AnalyzerConfiguration.ExportSettings.OutputPath,
analyzerResult.ProjectResult.ProjectName + ".json", jsonOutput);
analyzerResult.OutputJsonFilePath = jsonFilePath;
Logger.LogDebug("Generated Json file " + jsonFilePath);
}
}
}

public LanguageAnalyzer GetLanguageAnalyzerByProjectType(string projType)
{
LanguageAnalyzerFactory languageAnalyzerFactory;
switch (projType.ToLower())
{
case ".vbproj":
languageAnalyzerFactory = new VbAnalyzerFactory(AnalyzerConfiguration, Logger);
break;
case ".csproj":
languageAnalyzerFactory = new CSharpAnalyzerFactory(AnalyzerConfiguration, Logger);
break;

default:
throw new Exception($"invalid project type {projType}");
}
return languageAnalyzerFactory.GetLanguageAnalyzer();
}

private ProjectWorkspace AnalyzeProject(ProjectBuildResult projectResult)
{
// Logger.LogDebug("Analyzing the project: " + projectResult.ProjectPath);
var projType = Path.GetExtension(projectResult.ProjectPath)?.ToLower();
LanguageAnalyzer languageAnalyzer = GetLanguageAnalyzerByProjectType(projType);
ProjectWorkspace workspace = new ProjectWorkspace(projectResult.ProjectPath)
{
SourceFiles = new UstList<string>(projectResult.SourceFiles),
BuildErrors = projectResult.BuildErrors,
BuildErrorsCount = projectResult.BuildErrors.Count
};

if (AnalyzerConfiguration.MetaDataSettings.ReferenceData)
{
workspace.ExternalReferences = projectResult.ExternalReferences;
}
workspace.TargetFramework = projectResult.TargetFramework;
workspace.TargetFrameworks = projectResult.TargetFrameworks;
workspace.LinesOfCode = 0;
foreach (var fileBuildResult in projectResult.SourceFileBuildResults)
{
var fileAnalysis = languageAnalyzer.AnalyzeFile(fileBuildResult, workspace.ProjectRootPath);
workspace.LinesOfCode += fileAnalysis.LinesOfCode;
workspace.SourceFileResults.Add(fileAnalysis);
}

return workspace;
}

public LanguageAnalyzer GetLanguageAnalyzerByFileType(string fileType)
{
LanguageAnalyzerFactory languageAnalyzerFactory;
switch (fileType.ToLower())
{
case ".vb":
languageAnalyzerFactory = new VbAnalyzerFactory(AnalyzerConfiguration, Logger);
break;
case ".cs":
languageAnalyzerFactory = new CSharpAnalyzerFactory(AnalyzerConfiguration, Logger);
break;

default:
throw new Exception($"invalid project type {fileType}");
}
return languageAnalyzerFactory.GetLanguageAnalyzer();

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>10</LangVersion>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Codelyzer.Analysis.Common\Codelyzer.Analysis.Common.csproj" />
<ProjectReference Include="..\Codelyzer.Analysis.CSharp\Codelyzer.Analysis.CSharp.csproj" />
<ProjectReference Include="..\Codelyzer.Analysis.Model\Codelyzer.Analysis.Model.csproj" />
<ProjectReference Include="..\Codelyzer.Analysis.VisualBasic\Codelyzer.Analysis.VisualBasic.csproj" />
<ProjectReference Include="..\Codelyzer.Analysis.Workspace\Codelyzer.Analysis.Workspace.csproj" />
</ItemGroup>

</Project>
Loading