Port NDepend CQLINQ query to c# LINQ



是否可以用于将 CQLinq 查询移植到简单的 C# LINQ 查询?

我正在使用NDepend API创建代码分析器工具,并且我想使用CQLinq查询。

有些很容易移植。例如

from m in Methods
where m.ILCyclomaticComplexity > 10 
orderby m.ILCyclomaticComplexity descending
select new { m }

易于移植到

using NDepend.CodeModel;
using NDepend.CodeQuery;
public List<IMethod> GetUnitTestFromType(ICodeBase codeBase)
{
    var complexMethods = (from m in codeBase.Application.Methods
                      where m.ILCyclomaticComplexity > 10
                      orderby m.ILCyclomaticComplexity descending
                      select m).ToList();
    return complexMethods;
} 

但我想使用更强大的CQLinq方法,即AllowNoMatch((

from t in codeBase.Application.Types
where t.Implement("System.IDisposable".AllowNoMatch())
select t;

事实上,直接使用 CQLinq 查询会很棒。如何?

我可以看到有一个NDepend.CodeQuery命名空间,其中包含CreateQuery,Compile和Execute等方法。谁能给我看一下用法的例子?

谢谢!

事实上,

CQLinq 提供了许多在命名空间 NDepend.Reserved.CQLinq 中定义的方便的扩展方法。这些扩展方法在 CQLinq 编译后时得到特殊处理,并且本身在 C# 中不可用。

在 CQLinq 查询中写入时:t.Implement("System.IDisposable".AllowNoMatch())

。解决了特殊的 ExtensionMethodsCQLinqDependency.Implement(( 扩展方法。CQLinq 后 C# 编译/预执行步骤尝试在执行之前解析一次指定为字符串 ("System.IDisposable".AllowNoMatch()( 的类型,并在 IType 上推断谓词。

  • 如果未找到名为 "System.IDisposable" 的完整类型,则始终返回 false
  • 如果找到名为 "System.IDisposable" 的 full 类型,则对于实现它的类型返回 true .。

在 ExtensionMethodsCQLinqDependency.Implement(( 的文档中,声明该方法只能在ICQLinqExecutionContext中调用,否则必须调用方法NDepend.CodeModel.IType.NDepend.CodeModel.IType.Implement

因此,通过使用NDepend.API,您必须自己完成CQLinq编译后工作,但它非常直接:

var iDisposable = codebase.Types.SingleOrDefault(t.FullName == "System.IDisposable");
if(iDisposable == null) {
  return new IType[0];
}
return from t in codeBase.Application.Types
       where t.Implement(iDisposable)
       select t;

我可以看到有一个NDepend.CodeQuery命名空间,其中包含CreateQuery,Compile和Execute等方法。谁能给我看一下用法的例子?

事实上,使用 NDepend.API,您可以编译 CQLinq 查询字符串,执行它并使用结果。OSS Power Tools Query code with CQLinq$NDependRedistributable$\NDepend.PowerTools\CodeQueryConsole\CodeQueryConsolePowerTool 中提供了示例用法.cs

     var codeBase = analysisResult.CodeBase;
     Func<string, IQueryCompiled> compileQueryProc = queryString => queryString.Compile( codeBase);
     // ... but if we can get a compareContext, then compile and execute the query against the compareContext
     ICompareContext compareContext;
     if (ProjectAnalysisUtils.TryGetCompareContextDefinedByBaseline(analysisResult, out compareContext)) {
        Debug.Assert(compareContext != null);
        compileQueryProc = queryString => queryString.Compile(compareContext);
     }
...
       IQueryCompiled queryCompiled;
       using (var queryEditSession = new QueryEditSession(queriesPreviouslyEdited)) {
           var queryString = queryEditSession.GetQueryString();
COMPILE_QUERY:
           Console.BackgroundColor = ConsoleColor.Black;
           Console.ForegroundColor = ConsoleColor.White;
           if (queryString == null) { break; }
           // Try compile query
           queryCompiled = compileQueryProc(queryString);
           var queryCompiledError = queryCompiled.QueryCompiledError;
           if (queryCompiledError != null) {
              queryString = queryEditSession.ShowCompilatioErrorsAndThenGetQueryString(queryCompiledError);
              goto COMPILE_QUERY;
           }
        }
        // Execute query compiled
        var queryCompiledSuccess = queryCompiled.QueryCompiledSuccess;
        Debug.Assert(queryCompiledSuccess != null);
        var result = queryCompiledSuccess.Execute();
        if (result.Status != QueryExecutionStatus.Success) {
           var exception = result.Exception;
           // The error must be an Exception thrown by the query, since we don't use the Execute(...) overload with time-out!
           Debug.Assert(exception != null);
           DisplayQueryThrowAnException(exception);
           continue;
        }
        QueryExecutionResultDisplayer.Go(result.SuccessResult);
        Console.WriteLine();
     }

相关内容

  • 没有找到相关文章

最新更新