mirror of https://github.com/abpframework/abp.git
5 changed files with 160 additions and 51 deletions
@ -1,42 +1,83 @@ |
|||||
using System.Collections.Generic; |
using System; |
||||
|
using System.Collections.Generic; |
||||
using System.IO; |
using System.IO; |
||||
using System.Linq; |
using System.Linq; |
||||
using Microsoft.CodeAnalysis.CSharp; |
using Microsoft.CodeAnalysis.CSharp; |
||||
using Microsoft.CodeAnalysis.CSharp.Syntax; |
using Microsoft.CodeAnalysis.CSharp.Syntax; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Microsoft.Extensions.Logging.Abstractions; |
||||
using Volo.Abp.DependencyInjection; |
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
namespace Volo.Abp.Cli.ProjectModification |
namespace Volo.Abp.Cli.ProjectModification |
||||
{ |
{ |
||||
public class DerivedClassFinder : ITransientDependency |
public class DerivedClassFinder : ITransientDependency |
||||
{ |
{ |
||||
|
public ILogger<DerivedClassFinder> Logger { get; set; } |
||||
|
|
||||
|
public DerivedClassFinder() |
||||
|
{ |
||||
|
Logger = NullLogger<DerivedClassFinder>.Instance; |
||||
|
} |
||||
|
|
||||
public virtual List<string> Find(string csprojFilePath, string baseClass) |
public virtual List<string> Find(string csprojFilePath, string baseClass) |
||||
{ |
{ |
||||
var moduleFilePaths = new List<string>(); |
var moduleFilePaths = new List<string>(); |
||||
|
var csprojFileDirectory = Path.GetDirectoryName(csprojFilePath); |
||||
|
var binFile = Path.Combine(csprojFileDirectory, "bin"); |
||||
|
var objFile = Path.Combine(csprojFileDirectory, "obj"); |
||||
|
|
||||
|
|
||||
var csFiles = new DirectoryInfo(Path.GetDirectoryName(csprojFilePath)) |
var csFiles = new DirectoryInfo(csprojFileDirectory) |
||||
.GetFiles("*.cs", SearchOption.AllDirectories) |
.GetFiles("*.cs", SearchOption.AllDirectories) |
||||
|
.Where(f => !f.DirectoryName.StartsWith(binFile)) |
||||
|
.Where(f => !f.DirectoryName.StartsWith(objFile)) |
||||
.Select(f => f.FullName) |
.Select(f => f.FullName) |
||||
.ToList(); |
.ToList(); |
||||
|
|
||||
foreach (var csFile in csFiles) |
foreach (var csFile in csFiles) |
||||
{ |
{ |
||||
if (IsDerivedFromAbpModule(csFile, baseClass)) |
try |
||||
{ |
{ |
||||
moduleFilePaths.Add(csFile); |
if (IsDerived(csFile, baseClass)) |
||||
|
{ |
||||
|
moduleFilePaths.Add(csFile); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception) |
||||
|
{ |
||||
|
Logger.LogDebug($"Couldn't parse {csFile}."); |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
return moduleFilePaths; |
return moduleFilePaths; |
||||
} |
} |
||||
|
|
||||
protected bool IsDerivedFromAbpModule(string csFile, string baseClass) |
protected bool IsDerived(string csFile, string baseClass) |
||||
{ |
{ |
||||
|
Logger.LogDebug(csFile); |
||||
var root = CSharpSyntaxTree.ParseText(File.ReadAllText(csFile)).GetRoot(); |
var root = CSharpSyntaxTree.ParseText(File.ReadAllText(csFile)).GetRoot(); |
||||
var namespaceSyntax = root.DescendantNodes().OfType<NamespaceDeclarationSyntax>().First(); |
var namespaceSyntax = root.DescendantNodes().OfType<NamespaceDeclarationSyntax>().First(); |
||||
var classDeclaration = (namespaceSyntax.DescendantNodes().OfType<ClassDeclarationSyntax>()).First(); |
var classDeclaration = (namespaceSyntax.DescendantNodes().OfType<ClassDeclarationSyntax>()).First(); |
||||
|
var baseTypeList = classDeclaration.BaseList?.Types.Select(t => t.ToString()).ToList(); |
||||
|
|
||||
|
if (baseTypeList == null) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
foreach (var baseType in baseTypeList) |
||||
|
{ |
||||
|
if (baseType.Contains('<') && baseType.Substring(0, baseType.IndexOf('<')) == baseClass) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
if (baseType == baseClass) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
return classDeclaration.BaseList?.Types |
return false; |
||||
.Any(t => t.ToString().Equals(baseClass)) ?? false; |
|
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,65 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.Cli.ProjectModification |
||||
|
{ |
||||
|
public class UsingStatementAdder : ITransientDependency |
||||
|
{ |
||||
|
public string Add(string fileContent, string nameSpace) |
||||
|
{ |
||||
|
if (fileContent.Contains(nameSpace)) |
||||
|
{ |
||||
|
return fileContent; |
||||
|
} |
||||
|
|
||||
|
var index = GetIndexOfTheEndOfTheLastUsingStatement(fileContent); |
||||
|
|
||||
|
if (index < 0 || index >= fileContent.Length) |
||||
|
{ |
||||
|
index = 0; |
||||
|
} |
||||
|
|
||||
|
var usingStatement = GetUsingStatement(nameSpace); |
||||
|
|
||||
|
return fileContent.Insert(index, usingStatement); |
||||
|
} |
||||
|
|
||||
|
protected string GetUsingStatement(string nameSpace) |
||||
|
{ |
||||
|
return Environment.NewLine + "using " + nameSpace + ";"; |
||||
|
} |
||||
|
|
||||
|
protected virtual int GetIndexOfTheEndOfTheLastUsingStatement(string fileContent) |
||||
|
{ |
||||
|
var indexOfNamespaceDeclaration = fileContent.IndexOf("namespace", StringComparison.Ordinal); |
||||
|
|
||||
|
if (indexOfNamespaceDeclaration < 0) |
||||
|
{ |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
fileContent = fileContent.Substring(0, indexOfNamespaceDeclaration); |
||||
|
|
||||
|
var indexOfTheStartOfLastUsingStatement = |
||||
|
fileContent.LastIndexOf("using ", StringComparison.Ordinal); |
||||
|
|
||||
|
if (indexOfTheStartOfLastUsingStatement < 0) |
||||
|
{ |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
var indexOfFirstSemiColonAfterLastUsingStatement = |
||||
|
fileContent.Substring(indexOfTheStartOfLastUsingStatement).IndexOf(';'); |
||||
|
|
||||
|
if (indexOfFirstSemiColonAfterLastUsingStatement < 0) |
||||
|
{ |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
return indexOfTheStartOfLastUsingStatement |
||||
|
+ indexOfFirstSemiColonAfterLastUsingStatement + 1; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue