首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用Dart的分析服务器方法search.findTopLevelDeclarations?

如何使用Dart的分析服务器方法search.findTopLevelDeclarations?
EN

Stack Overflow用户
提问于 2022-01-21 15:26:17
回答 1查看 80关注 0票数 0

我试图通过Dart的分析服务器获得顶级类声明的列表。所以,我发送search.findTopLevelDeclarations请求,但是搜索结果总是空的。

在我看来,分析服务器不知道在哪里搜索。我尝试将项目的根设置为执行上下文(execution.createContext)根和/或分析根(analysis.setAnalysisRoots),但搜索结果仍然是空的。

我应该怎么做才能让服务器了解在哪里搜索声明?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-21 18:52:00

以前从没玩过这个所以我开始了一段相当长的旅程..。

我不知道您是如何与分析服务器交互的,但是我已经使用analysis_server_client包做了一个工作示例。这样做的一个问题是,pub.dev上的版本非常老,所以我最终从Dart的稳定分支获取了该版本:

https://github.com/dart-lang/sdk/tree/stable/pkg/analysis_server_client

然后,您可以通过以下操作导入pubspec.yaml中的包:

代码语言:javascript
运行
复制
dependencies:
  analysis_server_client:
    path: /path/to/analysis_server_client

然后,我从以下方面编写了示例代码的简化版本:

https://github.com/dart-lang/sdk/blob/stable/pkg/analysis_server_client/example/example.dart

代码语言:javascript
运行
复制
import 'dart:io' show exit;

import 'package:analysis_server_client/handler/connection_handler.dart';
import 'package:analysis_server_client/handler/notification_handler.dart';
import 'package:analysis_server_client/protocol.dart';
import 'package:analysis_server_client/server.dart';

final server = Server();

Future<void> main(List<String> args) async {
  const targetDirPath = r'C:\tmp\simple_project';
  const searchPattern = 'main';

  // Launch the server
  await server.start();

  // Connect to the server
  final handler = _Handler(server);
  server.listenToOutput(notificationProcessor: handler.handleEvent);
  if (!await handler.serverConnected(timeLimit: const Duration(seconds: 15))) {
    exit(1);
  }

  await server.send(ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS,
      AnalysisSetAnalysisRootsParams([targetDirPath], const []).toJson());
  await server.send(SEARCH_REQUEST_FIND_TOP_LEVEL_DECLARATIONS,
      SearchFindTopLevelDeclarationsParams(searchPattern).toJson());
}

class _Handler with NotificationHandler, ConnectionHandler {
  @override
  final Server server;

  _Handler(this.server);

  @override
  void onSearchResults(SearchResultsParams params) {
    print('-- Start of result --');
    params.results.forEach(print);
    print('--  End of result  --');
    server.stop();
  }
}

C:\tmp\simple_project上的项目是一个简单的项目,由以下内容创建,这意味着它只包含一个main方法:

代码语言:javascript
运行
复制
dart create -t console-simple simple_project

当我运行我的分析器程序时,我得到以下输出:

代码语言:javascript
运行
复制
-- Start of result --
{"location":{"file":"C:\\tmp\\simple_project\\bin\\simple_project.dart","offset":5,"length":4,"startLine":1,"startColumn":6,"endLine":1,"endColumn":10},"kind":"DECLARATION","isPotential":false,"path":[{"kind":"FUNCTION","name":"main","location":{"file":"C:\\tmp\\simple_project\\bin\\simple_project.dart","offset":5,"length":4,"startLine":1,"startColumn":6,"endLine":1,"endColumn":10},"flags":8,"parameters":"(List<String> arguments)","returnType":"void"},{"kind":"COMPILATION_UNIT","name":"simple_project.dart","location":{"file":"C:\\tmp\\simple_project\\bin\\simple_project.dart","offset":0,"length":0,"startLine":1,"startColumn":1,"endLine":1,"endColumn":1},"flags":16},{"kind":"LIBRARY","name":"","location":{"file":"C:\\tmp\\simple_project\\bin\\simple_project.dart","offset":0,"length":0,"startLine":1,"startColumn":1,"endLine":1,"endColumn":1},"flags":0}]}
--  End of result  --

如果我将searchPattern更改为空的String,就会得到一个关于默认包含的Dart库的顶级声明的长列表。我相信有一种方法可以排除这些问题。

但据我所见,searchPattern是一个针对每个顶级声明的名称进行测试的正则表达式,如果它的名称包含正则表达式的任何部分,则包括声明。

我在这里找到了负责搜索的代码:

代码语言:javascript
运行
复制
  @override
  Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern) async {
    var allElements = <Element>{};
    var regExp = RegExp(pattern);
    var drivers = _drivers.toList();
    for (var driver in drivers) {
      var elements = await driver.search.topLevelElements(regExp);
      allElements.addAll(elements);
    }
    return allElements.map(SearchMatchImpl.forElement).toList();
  }

https://github.com/dart-lang/sdk/blob/1278bd5adb6a857580f137e47bc521976222f7b9/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart#L113-L123

这就要求:

代码语言:javascript
运行
复制
  /// Returns top-level elements with names matching the given [regExp].
  Future<List<Element>> topLevelElements(RegExp regExp) async {
    List<Element> elements = <Element>[];

    void addElement(Element element) {
      if (!element.isSynthetic && regExp.hasMatch(element.displayName)) {
        elements.add(element);
      }
    }

    List<FileState> knownFiles = _driver.fsState.knownFiles.toList();
    for (FileState file in knownFiles) {
      var unitResult = await _driver.getUnitElement(file.path);
      if (unitResult is UnitElementResult) {
        CompilationUnitElement unitElement = unitResult.element;
        unitElement.accessors.forEach(addElement);
        unitElement.classes.forEach(addElement);
        unitElement.enums.forEach(addElement);
        unitElement.extensions.forEach(addElement);
        unitElement.functions.forEach(addElement);
        unitElement.mixins.forEach(addElement);
        unitElement.topLevelVariables.forEach(addElement);
        unitElement.typeAliases.forEach(addElement);
      }
    }
    return elements;
  }

https://github.com/dart-lang/sdk/blob/1278bd5adb6a857580f137e47bc521976222f7b9/pkg/analyzer/lib/src/dart/analysis/search.dart#L166-L192

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70803685

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档