How to group in CQLinq?

77 views Asked by At

I have an autogenerated interface and implementation which define 3000+ methods and for each one the respective asynchronous signature. All in all 6,000+ methods.

I would like to figure out which ones are NOT used. Here is the CQLinq I have so far:

// Unused methods in the interface
let notUsed1 = new HashSet<IMethod>( 
from t in JustMyCode.Types 
where t.Name == "IDataProcessor"
from m in t.Methods 
where !m.HasAttribute("xyz.CoreService.CoreServiceOperationAttribute") &&  !m.MethodsCallingMe.Any()
select m)
// Unused methods in the concrete implementation of the interface
let notUsed2 =
from t in JustMyCode.Types 
where t.Name == "DataProcessor"
from m in t.Methods 
where m.HasAttribute("System.CodeDom.Compiler.GeneratedCodeAttribute") && !m.MethodsCallingMe.Any()
// Obtain the methods in the intersection
select m
from m in notUsed2 where notUsed1.Contains(m.OverriddensBase.Single())
let baseName = m.SimpleName.Replace("Async", "")
group m by baseName into g
select new { g } 

Alas, this does not work. The error message is:

Ln 18  Col 8  Type {IGrouping`2<String,IMethod>} not accepted to type first result argument.
Only IMethod, IField, IType, INamespace, IAssembly, IMember, ICodeElement, ICodeElementParent, ICodeContainer, IIssue and IRule are accepted to type first result argument.

Looks like group is out of the question. My idea is to group the methods by the base name (which is the same for synchronous and asynchronous signatures) and select those entries which have 2 items. But it looks like my plan would not work because grouping is not supported.

How would you do it?

1

There are 1 answers

1
mark On

I managed to solve it by changing the grouping key to be an IMethod object:

// Collect the sync methods
let syncMethods = (
from t in JustMyCode.Types 
where t.Name == "IDataProcessor"
from m in t.Methods 
where !m.HasAttribute("xyz.CoreService.CoreServiceOperationAttribute") && !m.IsAsync
select m).ToDictionary(m => m.SimpleName)
// Unused methods in the interface
let notUsed1 = new HashSet<IMethod>( 
from t in JustMyCode.Types 
where t.Name == "IDataProcessor"
from m in t.Methods 
where !m.HasAttribute("xyz.CoreService.CoreServiceOperationAttribute") && !m.MethodsCallingMe.Any()
select m)
// Unused methods in the concrete implementation of the interface
let notUsed2 =
from t in JustMyCode.Types 
where t.Name == "DataProcessor"
from m in t.Methods 
where m.HasAttribute("System.CodeDom.Compiler.GeneratedCodeAttribute") && !m.MethodsCallingMe.Any()
// Select methods in the intersection
select m
from m in notUsed2 where notUsed1.Contains(m.OverriddensBase.Single())
let syncMethod = syncMethods[m.SimpleName.Replace("Async", "")]
group m by syncMethod into g     // group by the respective sync method
where g.Count() == 2     // return if both sync and async signatures are not used
select new { g.Key }

I wonder how this can be simplified.