我试图找到特定方法的用法。在这种情况下,我想查找foo.go()
的使用/调用,但不是bar.go()
。以下代码将在任何类上查找go()
的所有调用。在下面的代码中,node.target
只给我x
这是var名称,但我正在努力弄清楚该方法属于哪个类。
void main() {
var x = new Foo();
x.go();
x = new Bar();
x.go();
}
class Foo {
go() {
print('I am foo');
}
}
class Bar {
go() {
print('I am bar');
}
}
import 'package:analyzer/analyzer.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
void main() {
var targetFile = parseDartFile('test.dart');
var visitor = new UsageVisitor('foo.go');
targetFile.visitChildren(visitor);
}
class UsageVisitor extends UnifyingAstVisitor {
String _class;
String _method;
UsageVisitor(this._class, this._method);
@override
visitMethodInvocation(MethodInvocation node) {
print({
'target' : node.target.toString(), // in both cases, gives "x" -- I need "Foo" and "Bar", respectively
'methodName': node.methodName.toString() // gives "go"
});
return super.visitNode(node);
}
}
如何区分(在分析器级别),foo.go()
和bar.go()
之间的差异?
答案 0 :(得分:2)
问题是<input type="file" name="files[]" multiple="multiple" />
正在解析而没有上下文来解析其中包含的元素。
analyzer package within the Dart SDK
中包含了一个例子将其分解为您的步骤:
test.dart
PhysicalResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE;
DartSdk sdk = new FolderBasedDartSdk(resourceProvider, resourceProvider.getFolder(args[0]));
var resolvers = [
new DartUriResolver(sdk),
new ResourceUriResolver(resourceProvider)
];
AnalysisContext
AnalysisContext context = AnalysisEngine.instance.createAnalysisContext()
..sourceFactory = new SourceFactory(resolvers);
添加到Source
ChangeSet
Source source = new FileSource(resourceProvider.getFile(args[1]));
ChangeSet changeSet = new ChangeSet()..addedSource(source);
应用于ChangeSet
AnalysisContext
context.applyChanges(changeSet);
我不确定是否总是需要它。也许它可以跳过简单的文件。¯(◉◡◔)/¯
LibraryElement
LibraryElement libElement = context.computeLibraryElement(source);
!Source
CompilationUnit resolvedUnit = context.resolveCompilationUnit(source, libElement);
Visitor
不幸的是,很多代码而不是仅仅调用resolvedUnit.accept(visitor)
,但好消息是您的parseDartFile()
应该无需进一步更改即可使用。
答案 1 :(得分:1)
我发现了一些东西,但我不熟悉分析仪,也许它可以简化,它只适用于你的情况。
@override
visitMethodInvocation(MethodInvocation node) {
if (node.methodName.toString() == "go" && node.target.toString() == "x") {
for (dynamic child in node.parent?.parent?.childEntities) {
if (child is VariableDeclarationStatement) {
if ((child.childEntities.first as VariableDeclarationList).type.toString() == "Foo" &&
((child.childEntities.first as VariableDeclarationList).childEntities.elementAt(1) as VariableDeclaration)
.beginToken
.toString() ==
"x") {
print(node);
}
}
}
}
return super.visitNode(node);
}