这是我想出的使用缓存的方法。它似乎仍然不正确,但我希望它比以前的方法更好。这仍然是从 a 调用的GeneratorProvider.Populate
:
public static IEnumerable<ICSharpTypeDeclaration> GetAllPublicTypeDeclarations(this IPsiModule module)
{
var declarationCache = module.GetPsiServices().CacheManager.GetDeclarationsCache(module, false, true);
var declarations = new List<ICSharpTypeDeclaration>();
foreach (var shortName in declarationCache.GetAllShortNames())
{
var declaredElements = declarationCache.GetElementsByShortName(shortName).OfType<ITypeElement>().Where(e =>
{
var elementType = e.GetElementType();
return elementType == CLRDeclaredElementType.CLASS || elementType == CLRDeclaredElementType.INTERFACE || elementType == CLRDeclaredElementType.ENUM;
});
foreach (ITypeElement declaredElement in declaredElements)
{
var declaration = declaredElement.GetDeclarations().OfType<ICSharpTypeDeclaration>().FirstOrDefault(d => d.GetAccessRights() == AccessRights.PUBLIC);
if (declaration != null)
{
declarations.Add(declaration);
}
}
}
return declarations;
}
注意:结果与第一个答案不同,因为我更改了一些限制。此外,在这两种情况下,我都不关心部分类。