听GPT 讲Rust源代码--src/tools(11)

这篇具有很好参考价值的文章主要介绍了听GPT 讲Rust源代码--src/tools(11)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

听GPT 讲Rust源代码--src/tools(11),后端

File: rust/src/tools/rust-analyzer/crates/hir/src/lib.rs

在Rust源代码中,rust/src/tools/rust-analyzer/crates/hir/src/lib.rs文件的作用是定义了Rust语言的高级抽象层次(Higher-level IR,HIR)。它包含了Rust语言的各种结构和概念的定义,用于进行编译器的语义分析和类型检查。

下面是一些重要的结构、特质和枚举类型的介绍:

  • 结构体(Struct)和联合体(Union):用于定义数据结构的类型,分别表示结构体和联合体的信息。
  • 枚举(Enum)和枚举的变体(Variant):用于定义一组相关的值的类型,分别表示枚举和枚举中的变体。
  • 函数(Function)和参数(Param):用于定义函数和函数参数的类型。
  • 常量(Const)和静态变量(Static):用于定义常量和静态变量的类型。
  • 特质(Trait)和特质别名(TraitAlias):用于定义特质和特质的别名。
  • 类型别名(TypeAlias)和内置类型(BuiltinType):用于定义类型别名和内置类型的类型。
  • 宏(Macro)和本地变量(Local):用于定义宏和本地变量的类型。
  • 衍生助手(DeriveHelper)和内置属性(BuiltinAttr):用于定义衍生助手和内置属性的类型。
  • 工具模块(ToolModule)、标签(Label)、类型参数(TypeParam)和生命周期参数(LifetimeParam):用于定义工具模块、标签、类型参数和生命周期参数的类型。
  • 常量参数或类型参数(TypeOrConstParam)、实现(Impl)、特质引用(TraitRef)和闭包(Closure):用于定义常量参数或类型参数、实现、特质引用和闭包的类型。
  • 可调用类型(Callable)和布局(Layout):用于定义可调用类型和布局的类型。
  • 调整(Adjustment)和重载的Deref(OverloadedDeref):用于定义调整和重载的Deref的类型。

特质(Trait)是一组方法的集合,用于定义类型之间的约束关系。AsAssocItemHasVisibilityHasCrateHasContainer是一些用于特质的附加特质,分别用于提供关于关联项、可见性、编译单元和容器的额外信息。

枚举类型(Enum)用于定义多个可能的值,其中的ModuleDefFieldSourceAdtVariantDefDefWithBodyAccessMacroKindItemInNsAssocItemAssocItemContainerGenericDefGenericParamCaptureKindCalleeCallableKindBindingModeScopeDefAdjustAutoBorrowItemContainerDocLinkDef等是一些与不同类型相关的属性、访问和定义的信息。

通过这些结构、特质和枚举类型,lib.rs文件提供了对Rust语言不同层次的抽象,以支持Rust编译器的语义分析和类型检查等功能。

File: rust/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs

在Rust源代码中,rust-analyzer的source_analyzer.rs文件位于rust/src/tools/rust-analyzer/crates/hir/src/目录中。该文件是rust-analyzer的一部分,负责对Rust源代码进行语法和语义分析。

详细介绍如下:

该文件包含了多个struct,其中最重要的是SourceAnalyzer(以下简称SA)。SA负责分析Rust源代码的各个方面,用于提供优秀的代码编辑支持。对于编写Rust代码的开发者而言,SA可以提供以下几个方面的功能:

  1. 语法分析:SA使用syntax::SourceFile来解析源代码,构建语法树。它可以分析代码中的各种结构,例如模块、函数、变量、表达式等。这使得rust-analyzer可以理解整个代码的结构和组织。

  2. 命名分析:SA基于syntax::ast中的叶节点,分析Rust程序中的命名实体(例如模块、函数、结构体、变量等),确定它们的作用域和可见性。这使得rust-analyzer能够准确地识别Rust代码的符号引用。

  3. 类型推断:SA通过分析表达式的结构和上下文,推导出表达式和变量的类型。它使用hir_ty::Inferencer模块来执行类型推断,并将推断结果应用于代码分析中的其他任务。这使得rust-analyzer能够提供类型检查、自动补全和重构等功能。

  4. 代码解析:SA将代码分解成不同的语义单元,例如函数、结构体、枚举等,并构建它们之间的关系。这使得rust-analyzer可以分析函数调用、结构体成员、trait实现等,并为开发者提供导航、查看文档和重构等功能。

  5. 解析错误处理:SA通过捕获和处理语法和语义错误,为开发者提供有关代码错误的详细信息和修复建议。这提高了编码过程中的可靠性和效率。

SA使用多个辅助struct来进行这些分析和操作。例如,AssocTyValueCache用于缓存关联类型的具体化信息, BindingCache用于缓存名称解析的结果。这些辅助struct协助SA高效地处理和管理大量的代码信息。

总结起来,source_analyzer.rs文件中的SA及其相关struct在rust-analyzer中扮演着非常关键的角色,负责对Rust源代码进行全面分析和理解。它们为rust-analyzer提供了语法高亮、自动补全、错误检查、导航、重构等功能,极大地提升了开发者的编码体验和效率。

File: rust/src/tools/rust-analyzer/crates/hir/src/from_id.rs

在Rust源代码中,rust-analyzer是一个用于实现Rust语言的IDE功能的工具。在该工具的源代码中,from_id.rs文件位于hir crate中,主要用于将HirId(一种用于表示AST节点的唯一标识符)转换为具体的语法节点。

具体来说,该文件的主要目的是定义一个FromId trait,该trait包含一个from_id函数,用于将抽象语法树(AST)节点的唯一标识符转换为具体的语法节点。通过这种转换,可以将HirId映射到具体的语法节点,从而实现对AST的操作和分析。

from_id.rs文件实现了一系列的FromId trait的实现,每个实现都对应着不同类型的AST节点。这些实现通过访问器模式、递归和模式匹配等技术,将HirId转换为对应的语法节点类型,并返回对应的语法节点对象。

通过使用FromId trait和from_id函数,rust-analyzer可以更方便地在代码分析和IDE功能中使用语法节点。这样可以实现更精确的分析和代码解析,支持代码自动补全、重构、错误检查等功能。同时,代码维护者也可以通过这个文件轻松地为新的语法节点类型添加支持。

总之,from_id.rs文件在rust-analyzer工具中扮演着关键的角色,负责将HirId转换为具体的语法节点,从而支持IDE功能的实现和代码分析。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/build.rs

在Rust源代码中,rust-analyzer是一个用于实现Rust语言的跨平台智能IDE(Integrated Development Environment,集成开发环境)的开源项目。在该项目的源代码中,build.rs文件是一个特殊的构建脚本,用于在项目构建期间进行自定义构建过程。

具体来说,rust-analyzer的build.rs文件的作用主要有以下几个方面:

  1. 设置环境变量:构建脚本可以设置环境变量,以便在构建过程中使用。例如,可以设置RUST_LOG环境变量来控制日志输出的级别。
  2. 生成代码:构建脚本可以生成一些运行时所需的代码或配置文件。例如,可以根据编译器版本生成特定的头文件、配置文件或元数据。
  3. 编译原生代码:构建脚本可以调用编译器来编译C或C++代码,并将生成的动态链接库与Rust代码进行链接。这样,Rust项目就可以直接使用这些原生代码。
  4. 执行定制的构建逻辑:构建脚本可以执行任意的构建逻辑,例如下载一些依赖项、生成文档、执行测试等。这使得构建脚本非常灵活,可以根据项目的需求进行自定义操作。

在rust-analyzer的build.rs文件中,通常会使用build脚本的build_script功能(build_script::run_unconfigured)来执行构建脚本。这个功能可以在构建过程的任何阶段运行自定义的构建逻辑,并在构建完成后将生成的代码或文件放置到正确的位置。

总而言之,build.rs文件提供了一种机制,允许在Rust项目构建过程中执行自定义的构建逻辑,包括生成代码、设置环境变量、编译原生代码等。这使得开发者可以更好地控制构建过程,满足项目的特定需求。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/cargo_target_spec.rs

在Rust源代码中的cargo_target_spec.rs文件是Rust分析器(rust-analyzer)工具中的一个文件,它定义了一些与Cargo目标相关的数据结构和功能。

该文件中定义了CargoTargetSpec这个结构体,它有三个变体:PackagePackageAndTargetWorkspace。这些变体分别代表不同的Cargo目标规范和相关信息。

  1. Package结构体用于表示单个Cargo包的目标规范。它包含了一些字段用于指定包的名称、版本和目标平台等信息。这个结构体的作用是为Rust分析器提供关于特定包的目标信息,以便在分析代码时使用。

  2. PackageAndTarget结构体用于表示单个Cargo包中的一个具体目标(如一个二进制可执行文件或库文件)。它与Package结构体类似,但在指定目标时还可以指定目标的名称。这个结构体的作用是在分析特定目标代码时提供相关信息。

  3. Workspace结构体用于表示整个Cargo工作空间的目标规范。它包含一些字段,用于指定工作空间的路径、名称和顶级目录等信息。这个结构体的作用是在Rust分析器的工作空间模式下提供工作空间级的目标信息。

以上这些结构体的定义和使用,使得Rust分析器能够根据Cargo目标信息正确地分析和理解工程目录结构,以便提供更准确和有用的代码智能提示、自动补全、代码导航等功能。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs

在Rust的源代码中,rust-analyzer/src/global_state.rs是rust-analyzer工具中的一个文件,其作用是定义和实现全局状态(GlobalState)的结构体和方法。

全局状态是rust-analyzer中的一个重要概念,它代表了整个工具的运行时状态和数据。在rust-analyzer中,全局状态由GlobalState结构体进行表示。该结构体包含了所有会被多个线程共享和访问的数据。它负责管理和维护与Rust项目相关的各种信息,如解析的源代码、语义分析的结果、模块图谱等。

GlobalState结构体中包含了多个字段和方法,用于存储和处理这些数据。其中比较重要的字段是AnalysisHost,它是一个Rust笔记本服务器,负责处理编辑器的请求。GlobalState还负责创建和管理诸如Document(代表源文件)、Change(代表源代码的更改)等其他核心数据结构。

除了GlobalState结构体外,global_state.rs文件还定义了其他与全局状态相关的结构体,如GlobalStateSnapshotHandle

  • GlobalStateSnapshot结构体代表GlobalState的不可变快照。它允许读取全局状态的数据,但不能修改它。GlobalStateSnapshot的目的是确保在处理请求时对全局状态的读取操作是原子的、一致的,并且不会被其他线程的修改所影响。

  • Handle是一个智能指针,它封装了对全局状态的引用,并提供了一些方便的方法来访问和修改全局状态。通过使用Handle,可以确保在并发下对全局状态的访问是安全的,减少数据竞争。

总结来说,rust-analyzer/src/global_state.rs文件中定义了GlobalState结构体和相关的数据结构,它们负责管理和维护rust-analyzer工具的全局状态和数据。GlobalStateSnapshotHandle提供了安全的并发访问方式,使得多个线程能够同时读取和修改全局状态。这些结构体的设计和实现确保了rust-analyzer的高性能和可靠性。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp.rs

在Rust源代码中,rust/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp.rs文件的作用是实现了Rust语言服务器协议(Language Server Protocol,LSP)的功能。LSP是一种协议,用于在编辑器和语言服务器之间进行通信,以提供语言相关的功能,如自动补全、符号定义、重构等。

lsp.rs文件定义了Rust语言服务器的主要功能,包括响应各种LSP请求、解析和处理LSP消息等。在该文件中,有一个叫做LspError的struct,是用来处理LSP过程中可能出现的错误的。

LspError struct定义了几个不同的错误情况,用于表示不同类型的LSP错误。这些错误类型包括:

  1. ParseError:解析LSP请求或消息时出现错误。
  2. InvalidParams:无效的LSP请求参数。
  3. MethodNotFound:无法找到请求的LSP方法。
  4. ServerError:在处理LSP请求过程中发生了服务器端错误。
  5. UnknownAction:未知的LSP动作。
  6. GenericError:其他未分类的LSP错误。

这些错误类型对于Rust语言服务器来说是非常重要的,因为它们可以帮助开发人员快速定位问题并采取适当的处理方法。通过使用LspError struct,Rust语言服务器能够明确表示错误类型,从而更好地与客户端进行通信,并提供有关错误的详细信息。

总结来说,rust/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp.rs文件实现了Rust语言服务器的LSP功能,并定义了LspError struct用于处理LSP过程中可能出现的错误。这些功能有助于提供更好的编辑器支持,提高开发人员的编码效率。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/caps.rs

该文件是Rust语言的语法分析器(rust-analyzer)中的一个关键文件,用于定义代码分析器所使用的能力(capabilities)。

在Rust语法分析器中,代码分析器需要一些特定的功能来进行正确的语法分析和效果性的代码建议。这些功能被称为“能力”或“capabilities”,并在代码分析器的初始化过程中用于向Rust编译器注册。

caps.rs文件中定义了许多用于Rust语法分析器的能力,包括语义分析、类型推断、代码引用、代码跳转、符号搜索、重命名、自动填充等功能。这些能力的定义遵循Language Server Protocol (LSP)规范,以便Rust语法分析器与其他编辑器和开发工具进行通信。

在caps.rs文件中,每个能力都被定义为一个结构体,并实现了LSP规范中对应的trait,以确保能力的正确注册和使用。这些能力结构体中包含了各种方法和属性,用于语法分析器进行相应的代码分析和处理。

通过定义和实现这些能力,Rust语法分析器能够提供强大而准确的代码建议和智能补全功能。它能够理解Rust语言的语法和语义,从而在实时编辑过程中为开发者提供更好的编程体验和工具支持。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/dispatch.rs

在Rust源代码中,rust/src/tools/rust-analyzer/crates/rust-analyzer/src/dispatch.rs文件的作用是实现Rust分析器的请求和通知的分发功能。该文件定义了两个重要的struct:RequestDispatcher<'a>和NotificationDispatcher<'a>。

RequestDispatcher<'a>是一个请求分发器,它负责处理来自客户端的请求,并将其分发给相应的处理器进行处理。这里的请求通常是通过LSP(Language Server Protocol)发送的,用于获取有关代码分析的信息,例如代码建议、类型检查和定义跳转等。RequestDispatcher<'a>的主要作用是根据请求类型将请求路由到正确的处理器,并返回相应的结果给客户端。

NotificationDispatcher<'a>是一个通知分发器,它负责处理来自客户端的通知。通知是一种用于向服务器发送信息,但不需要接收任何响应的机制。通常,通知用于通知服务器有关代码的更改或其他与代码分析相关的事件。NotificationDispatcher<'a>的主要作用是将通知路由到正确的处理器进行处理。

这两个分发器在Rust分析器中起到了关键的作用。它们负责将来自客户端的请求和通知分发给相应的处理器,以便进行代码分析和生成相应的响应或执行相应的操作。这样,Rust分析器可以根据客户端的需求提供准确的代码分析结果,并与客户端进行交互。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs

文件main_loop.rs是Rust源代码中rust-analyzer工具的一部分,这个文件的主要作用是实现rust-analyzer的主循环逻辑。主循环是一个事件驱动的循环,负责处理用户操作、后台任务以及缓存优化。

下面是main_loop.rs文件中几个重要的类型的介绍:

  1. Event枚举类型:表示用户的操作事件,如文件打开、代码修改、光标移动等。Event枚举有多种不同的变体来表示不同类型的事件,每个事件都有相应的参数。

  2. Task枚举类型:表示rust-analyzer的后台任务,用于执行一些长时间运行的操作,比如通过网络更新依赖、分析大型代码库等。Task枚举有不同的变体来表示不同类型的任务,每个任务都有相应的参数和结果。

  3. PrimeCachesProgress枚举类型:用于指示缓存优化的进度。PrimeCachesProgress枚举有多个变体来表示不同的进度阶段,比如正在加载缓存、正在预热缓存等。

main_loop.rs文件中,会使用一个无限循环来等待并处理各种事件和任务。主循环会根据不同的事件调用相应的处理函数对代码进行解析、分析和补全。根据不同的任务类型,主循环会启动后台线程来执行任务,并通过通道(channel)来与主循环进行交互,任务执行完成后将结果返回给主循环再进行后续处理。

主循环还包含了缓存优化的逻辑,通过预热和异步加载缓存,以减少用户在编辑代码时的延迟。当缓存优化任务启动时,主循环会根据不同的进度阶段更新用户界面,显示任务的执行状态。

总之,main_loop.rs文件实现了rust-analyzer的主循环逻辑,负责处理用户操作事件、后台任务和缓存优化等功能。EventTaskPrimeCachesProgress这些枚举类型分别用于表示不同类型的事件、任务和缓存优化进度。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs

rust-analyzer是一个用Rust编写的IDE后端,用于提供代码分析和语法高亮等功能。rustc_wrapper.rs是rust-analyzer中的一个文件,它的作用是将rust-analyzer与Rust编译器(rustc)进行集成。

在Rust中,编译器通常以rustc命令的形式执行,而rust-analyzer需要通过调用编译器来获取程序的抽象语法树等信息。rustc_wrapper.rs的主要目的就是封装rustc命令,以便可以通过调用rust-analyzer提供的API来执行编译器,并获取结果。

具体来说,rustc_wrapper.rs文件定义了一个名为main的函数,用于解析命令行参数、设置环境变量并调用rust-analyzer Crate提供的run函数。run函数会调用Runfiles::collect来获取编译源文件及其依赖文件的路径,并将这些路径作为rustc命令的参数传递,最后执行编译操作。

ExitCode是一个枚举类型,用来表示命令执行的结果。它包含了几个枚举值,分别表示不同的执行状态,如成功、出错等。这些枚举值有助于在程序中判断和处理不同的执行结果,并根据需要进行相应的操作。

总的来说,rustc_wrapper.rs文件的作用是作为rust-analyzer的入口点,通过调用编译器封装实现IDE功能,获取源代码的分析结果。ExitCode结构体则用于表示执行结果,用于进一步处理程序的执行状态。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs

在Rust源代码中,rust/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs文件是Rust语言分析器(Rust Analyzer)的主要入口点。它是一个可执行文件,负责启动Rust Analyzer的运行时环境和功能。

Rust Analyzer是一个用Rust编写的,用于分析和理解Rust代码的工具。它可以理解Rust语言的语法、类型系统和语义,并提供诸如代码补全、语法高亮、符号搜索、重构支持、导航等功能。

main.rs文件中,主要包含以下内容:

  1. 导入需要的Rust模块和库:通过使用use关键字导入需要的Rust模块和库,包括从标准库和其他自定义模块中导入的功能。

  2. 定义命令行选项:使用clap库(Rust的一个命令行解析库)来定义命令行选项,这些选项可用于配置和控制Rust Analyzer的运行时行为。这些选项包括语言服务器(Language Server)的地址、日志级别、插件等。

  3. 初始化运行时环境:创建和初始化Rust Analyzer的运行时环境,包括日志记录器、语言服务器(Language Server)和其他相关组件。这些组件将提供Rust语言分析和代码编辑功能。

  4. 注册和启动语言服务器:将已创建的语言服务器实例注册到运行时环境中,并通过调用相关函数来监听和响应从客户端(如IDE或编辑器)接收到的请求。

  5. 启动事件循环:通过调用main_loop函数启动主事件循环,该循环用于处理客户端发送的请求和发送响应。

总体来说,main.rs文件是Rust Analyzer工具的入口点,负责设置运行时环境、解析命令行参数、启动语言服务器并处理与客户端之间的通信。它作为整个工具的核心,充当了Rust代码分析和编辑的桥梁。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/logger.rs

在Rust源代码的目录rust/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/logger.rs中,logger.rs是一个用于日志记录的模块。它定义了一些用于配置日志记录的结构体和函数。

首先,LoggerConfig结构体是用来配置日志记录器的。它包含一些字段,可以控制日志级别、输出位置和格式等。这个结构体定义了一系列的方法,可以用来创建和配置日志记录器。

接下来是MakeWriterStderr结构体,它是一个实现了Write trait的结构体,用于将日志消息写入标准错误流(stderr)中。它提供了write方法,允许将日志消息写入到标准错误流中。

最后,LoggerFormatter结构体是一个日志格式化器。它提供了format方法,用于将日志消息格式化成字符串。它还提供了一些方法,用来配置日志输出的颜色和时间格式等。

这些结构体结合起来,可以通过LoggerConfig来配置日志记录器,使用MakeWriterStderr将日志消息写入标准错误流中,然后使用LoggerFormatter对日志消息进行格式化,并最终输出到标准错误流中。

总而言之,logger.rs文件定义了一套用于配置和记录日志的结构体和函数,可以帮助开发者在Rust源代码中添加和管理日志记录功能。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/config/patch_old_style.rs

rust-analyzer是一个Rust语言的实时代码分析工具,用于提供IDE(集成开发环境)功能。在rust-analyzer的源代码中,rust-analyzer/src/config/patch_old_style.rs文件的作用是为了解决旧版本Rust语法中遗留的问题。

在编程语言的更新迭代过程中,有时候会对语法进行调整和改进,以提高代码的可读性、可维护性和性能等方面。然而,这样的改进会导致旧版本代码与新版本语法不兼容的问题。为了兼容旧版本的代码,通常需要对旧版本代码进行适应性修改,以保证旧版本代码仍然能够在新版本的环境中正常运行。

在rust-analyzer工具的开发中,为了能够提供对旧版本Rust语法的支持,同时也能够利用新版本Rust语法的优势,就需要在代码中添加针对旧版本语法的适应性修改。而rust-analyzer/src/config/patch_old_style.rs文件就是用来记录和管理这些适应性修改的。

具体来说,rust-analyzer/src/config/patch_old_style.rs文件会包含一些旧版本语法的封装函数、类型别名、宏等内容,用于模拟旧版本语法的行为或提供旧版本语法的简化替代方式。这样,在rust-analyzer工具解析代码时,如果遇到使用了旧版本语法的代码,就会使用这些封装函数、类型别名、宏等来解析和处理代码,以保证在新版本环境中仍然能够正确分析和提供IDE功能。

总结来说,rust-analyzer/src/config/patch_old_style.rs文件的作用是为了支持旧版本Rust语法,在rust-analyzer工具中添加对旧版本语法的适应性修改,以提供对旧版本代码的正常解析和IDE功能。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs

rust-analyzer是一个Rust语言的LSP服务器实现,用于提供IDE功能,例如代码补全、引用查找、语法检查等。在rust/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs文件中,定义了一些集成测试的benchmark用例。

具体而言,该文件中定义了用于集成测试的benchmark套件,并提供了执行和输出结果的接口。这些benchmark套件是用于评估rust-analyzer在处理大型Rust代码仓库时的性能和吞吐量。

在代码中,首先使用bench_suite宏定义了一个benchmark套件,可以为它指定一个名称和一组benchmark用例。每个benchmark用例由一个名称和一个闭包组成,闭包中包含了需要进行benchmark的代码逻辑。

benchmark用例可以通过SingleRun函数来创建,该函数接受一个名称和一个闭包。闭包中的代码会被执行,并根据执行次数和消耗时间等指标生成benchmark报告。

在benchmark套件定义之后,可以通过调用run_benches函数来执行benchmark,并打印输出结果。这个函数将依次执行每个benchmark用例,并输出每个用例的名称、执行次数、总共消耗的时间以及每次执行的平均时间等指标。

通过集成测试的benchmark,可以快速而准确地评估rust-analyzer的性能,并找出可能存在的性能瓶颈或问题,进而进行优化和改进。这对于保证rust-analyzer在大型Rust代码仓库中具备高效的代码分析和IDE功能非常重要。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs

在Rust源代码中,rust-analyzer的工具包中的diagnostics.rs文件的作用是处理语义诊断信息,为Rust代码静态分析提供支持。

DiagnosticsMapConfig是一个结构体,用于配置语义诊断的映射关系。它有一个成员变量by_extension,是一个哈希映射表,用于存储由文件扩展名映射到诊断的规则。通过该结构体可以根据文件扩展名获取相应的诊断规则。

DiagnosticCollection结构体用于收集和管理一个源文件的诊断信息。它的主要职责是在诊断过程中收集诊断信息,并将其存储在内部的diagnostics字段中。DiagnosticCollection提供了一些方法,比如push用于添加新的诊断信息,take用于获取并清空收集到的诊断信息。

Fix结构体代表一个修复动作。它包含了修复的位置(range字段)和修复的建议(label字段)。在诊断过程中,当发现代码存在错误时,可以为该错误提供修复建议,并将修复信息封装在Fix结构体中返回给用户。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs

在Rust源代码中,rust/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs这个文件的作用是定义了Rust Analyzer的任务池,用于并发执行异步任务。

详细介绍如下:

  1. TaskPool 结构体:这是Rust Analyzer的任务池结构体,用于并发执行异步任务。它包含一个async_std::task::JoinHandle 类型的字段inner,用于存储异步任务的JoinHandle。TaskPool 实现了Drop trait,在其析构函数中,会检查如果任务还未完成,则会调用cancel方法来取消任务。

  2. TaskPool::new():这是TaskPool 的关联函数,用于创建一个新的任务池。它返回一个TaskPool 实例。

  3. TaskPool::spawn():这是TaskPool 的方法,用于将一个异步任务加入到任务池中。它接受一个闭包作为参数,闭包的返回值类型需要与TaskPool 的类型参数T保持一致。TaskPool::spawn()会将闭包封装为异步任务,并将其加入到任务池中。

  4. TaskPool::cancel():这是TaskPool 的方法,用于取消当前正在执行的任务。它先获取inner字段中存储的JoinHandle,然后调用async_std::task::JoinHandle::cancel()方法来取消任务的执行。

总结来说,rust/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs文件定义了Rust Analyzer的任务池,提供了创建任务池、添加任务、取消任务的方法。通过使用任务池,Rust Analyzer能够并发执行多个异步任务,提高整体性能。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/semantic_tokens.rs

在Rust源代码中,rust/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/semantic_tokens.rs文件的作用是实现语义令牌(Semantic Tokens)相关的逻辑。语义令牌是一种用于描述代码中不同元素(如变量、函数、方法等)的统一颜色编码的机制。

在这个文件中,主要包含了两个结构体:ModifierSetSemanticTokensBuilder

ModifierSet结构体是定义语义令牌的修饰符集合。修饰符可以用于进一步描述语义令牌的属性,例如表示是否是只读变量、是否是静态方法等。这个结构体的pub(crate)属性意味着它可以在当前crate中被访问。

SemanticTokensBuilder结构体是用于构建语义令牌的生成器。它提供了一组方法,用于将不同类型的语义令牌和修饰符添加到生成的语义令牌序列中。通过调用这些方法,开发者可以根据源代码的语义信息来构建结构化的语义令牌。

总的来说,semantic_tokens.rs文件的作用是为Rust语言服务器(Language Server)的语义高亮、语法突出显示等功能提供支持。通过解析代码的语义信息,并使用语义令牌标记不同元素,可以提供更加丰富和精确的代码编辑体验。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs

在Rust源代码中,rust/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs文件的作用是将rust-analyzer的内部数据结构转换为Language Server Protocol (LSP)中定义的数据结构。

Language Server Protocol是一种定义了编辑器和语言服务器之间通信的协议。语言服务器用于为编辑器提供代码分析、自动完成功能和错误检查等服务。而rust-analyzer则是一个用于提供Rust语言支持的语言服务器。

在to_proto.rs文件中,定义了一系列将rust-analyzer内部数据结构转换为LSP数据结构的函数。这些函数将rust-analyzer中定义的类型,例如语法树、语义模块等,转换为LSP中定义的类型,例如LSP请求、通知和响应等。

该文件中的函数主要涉及到两个方面的转换。一是将rust-analyzer类型转换为LSP类型,这些类型包括Position、Range、Location等。二是将rust-analyzer的特定数据结构转换为LSP通用数据结构,如CompletionItem、TextEdit等。这些转换函数将rust-analyzer的内部数据映射到LSP定义的数据结构上,以便与LSP协议兼容的编辑器进行交互。

通过to_proto.rs文件中的函数,rust-analyzer能够将其内部分析结果转换为LSP数据结构,然后在与支持LSP协议的编辑器进行通信时,能够正确地传递和解析数据,使编辑器能够准确地显示和操作Rust代码,同时将结果返回给rust-analyzer进行进一步的分析和处理。这样,rust-analyzer就能够充分利用编辑器的功能来提供更好的Rust语言支持。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs

文件utils.rs位于Rust源代码中的路径rust/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs,主要用于提供一些与LSP(Language Server Protocol,语言服务器协议)相关的实用工具函数和结构体。

该文件中定义的Progress枚举类型是用于表示LSP的进度报告的不同状态的。它包含以下几个成员:

  1. Init: 表示进度报告的初始状态。
  2. Begin: 表示进度报告的开始状态。当某个长时间运行的任务开始进行时,可以使用该状态来通知客户端。
  3. Report: 表示进度报告的进行状态。可以使用此状态来更新当前任务的进度信息。
  4. Done: 表示进度报告的完成状态。任务已经完成,可以使用该状态来通知客户端。
  5. Show: 表示进度报告的可见状态。当某个任务需要在用户界面上显示时,可以使用该状态。
  6. Hide: 表示进度报告的隐藏状态。当某个任务不再需要在用户界面上显示时,可以使用该状态。

通过使用这些不同的状态,可以在LSP通信过程中有效地对长时间运行的任务进行进度报告、更新和通知。这有助于提供更好的用户体验和可视化效果。

此外,utils.rs文件中还包含其他一些与LSP相关的工具函数和结构体,例如用于解析和处理LSP请求、响应和通知的函数,以及用于将Rust代码的位置(行、列)转换为LSP位置(字符偏移量)的函数等。这些工具函数和结构体的存在使得Rust语言服务器能够更好地与客户端进行通信和协作。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/from_proto.rs

在Rust源代码中,rust-analyzer/src/lsp/from_proto.rs 文件的作用是负责将LSP(Language Server Protocol)协议中的数据结构转换为Rust语言内部的数据结构。

首先,LSP是一种用于提供编辑器和语言服务交互的协议。它定义了一组标准化的JSON-RPC方法,这些方法包括语法检查、自动补全、符号搜索等功能。Rust Analyzer是一个基于LSP协议实现的Rust语言分析器,它通过接收和处理LSP协议的请求来提供对Rust代码的分析和编辑功能。

from_proto.rs 文件中的代码用于处理从LSP协议接收到的请求或通知,并将其转换为Rust Analyzer内部使用的数据结构。这个文件中包含了多个函数,每个函数负责处理一个特定的LSP请求或通知。

其中一些重要的函数包括:

  • from_initialize_params:负责将 initialize请求的参数转换为Rust Analyzer可理解的数据结构,并返回初始化时需要的信息,例如客户端的功能支持和首选项设置。
  • from_completion:负责将 completion请求的参数转换为Rust Analyzer可理解的数据结构,并返回代码自动完成建议的结果。
  • from_did_change_text_document:负责将 textDocument/didChange通知的参数转换为Rust Analyzer可理解的数据结构,并更新相应的文档内容与版本信息。
  • from_hover:负责将 hover请求的参数转换为Rust Analyzer可理解的数据结构,并返回符号的相应信息,例如类型、定义位置等。

这些函数通过解析LSP协议中的JSON数据,将其转换为Rust自己定义的数据结构,从而使Rust Analyzer能够根据这些数据进行代码分析和处理。在转换完成后,Rust Analyzer可以使用其内部的分析引擎对代码进行语义分析、语法检查、代码跳转等操作,并将相应的结果转换为LSP协议可接受的格式进行返回给客户端。

因此,from_proto.rs 文件在Rust Analyzer中起着非常重要的作用,它充当了LSP协议与Rust Analyzer内部数据结构之间的桥梁,让Rust代码能够通过LSP协议与编辑器或IDE进行交互。这样就实现了LSP协议作为中间层的目标,使得Rust Analyzer成为了用于提供丰富编辑和工具功能的Rust语言服务器。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs

在Rust源代码中,rust-analyzer是一种用于提供Rust语言助手(LSP)功能的工具。在该工具的源代码中,rust-analyzer/src/lsp/ext.rs文件定义了一系列结构体(struct)和枚举(enum),用于扩展LSP协议,以支持rust-analyzer所独有的功能。

下面是对一些重要结构体的详细介绍:

  1. AnalyzerStatusParams:表示获取分析器状态的请求参数。
  2. CrateInfoResult:表示获取包信息的结果。
  3. FetchDependencyListParams:表示获取依赖列表的请求参数。
  4. FetchDependencyListResult:表示获取依赖列表的结果。
  5. SyntaxTreeParams:表示获取语法树的请求参数。
  6. ViewCrateGraphParams:表示查看包图的请求参数。
  7. ViewItemTreeParams:表示查看项目树的请求参数。
  8. ExpandMacroParams:表示展开宏的请求参数。
  9. ExpandedMacro:表示展开后的宏定义。
  10. RecursiveMemoryLayout:表示递归的内存布局。
  11. MemoryLayoutNode:表示内存布局的节点。
  12. RunFlycheckParams:表示运行静态检查的请求参数。
  13. MatchingBraceParams:表示获取匹配括号的请求参数。
  14. JoinLinesParams:表示合并行的请求参数。
  15. RunnablesParams:表示获取可运行项的请求参数。
  16. Runnable:表示可运行项。
  17. CargoRunnable:表示Cargo可运行项。
  18. TestInfo:表示测试信息。
  19. InlayHintsParams:表示获取内联提示的请求参数。
  20. SsrParams:表示进行模式替换的请求参数。
  21. ServerStatusParams:表示服务器状态的请求参数。
  22. CodeAction:表示代码动作。
  23. CodeActionData:表示代码动作的数据。
  24. SnippetWorkspaceEdit:表示片段式的工作区编辑。
  25. SnippetTextDocumentEdit:表示片段式的文档编辑。
  26. SnippetTextEdit:表示片段式的文本编辑。
  27. HoverParams:表示获取悬停信息的请求参数。
  28. Hover:表示悬停信息。
  29. CommandLinkGroup:表示命令链接组。
  30. CommandLink:表示命令链接。
  31. ExternalDocsPair:表示外部文档对。
  32. OpenCargoTomlParams:表示打开Cargo.toml的请求参数。
  33. CodeLensResolveData:表示代码镜像解析数据。
  34. MoveItemParams:表示移动项的请求参数。
  35. WorkspaceSymbolParams:表示搜索工作区符号的请求参数。
  36. CompletionResolveData:表示完成结果的数据。
  37. InlayHintResolveData:表示内联提示的解析数据。
  38. CompletionImport:表示补全导入。
  39. ClientCommandOptions:表示客户端命令选项。

下面是对一些重要枚举的详细介绍:

  1. AnalyzerStatus:表示分析器的状态。
  2. FetchDependencyList:表示获取依赖列表。
  3. MemoryUsage:表示内存使用情况。
  4. ShuffleCrateGraph:表示重新排列包图。
  5. ReloadWorkspace:表示重新加载工作区。
  6. RebuildProcMacros:表示重新构建过程宏。
  7. SyntaxTree:表示语法树。
  8. ViewHir:表示查看HIR。
  9. ViewMir:表示查看MIR。
  10. InterpretFunction:表示解释函数。
  11. ViewFileText:表示查看文件文本。
  12. ViewCrateGraph:表示查看包图。
  13. ViewItemTree:表示查看项目树。
  14. ExpandMacro:表示展开宏。
  15. ViewRecursiveMemoryLayout:表示查看递归内存布局。
  16. CancelFlycheck:表示取消静态检查。
  17. RunFlycheck:表示运行静态检查。
  18. ClearFlycheck:表示清除静态检查。
  19. OpenServerLogs:表示打开服务器日志。
  20. MatchingBrace:表示匹配括号。
  21. ParentModule:表示父模块。
  22. JoinLines:表示合并行。
  23. OnEnter:表示键入回车。
  24. Runnables:表示可运行项。
  25. RunnableKind:表示可运行项的类型。
  26. RelatedTests:表示相关测试。
  27. Ssr:表示模式替换。
  28. ServerStatusNotification:表示服务器状态通知。
  29. Health:表示服务器健康状态。
  30. CodeActionRequest:表示代码动作的请求。
  31. CodeActionResolveRequest:表示代码动作解析的请求。
  32. SnippetDocumentChangeOperation:表示片段式文档更改操作。
  33. HoverRequest:表示悬停信息的请求。
  34. PositionOrRange:表示位置或范围。
  35. ExternalDocs:表示外部文档。
  36. ExternalDocsResponse:表示外部文档的响应。
  37. OpenCargoToml:表示打开Cargo.toml文件。
  38. CodeLensResolveDataKind:表示代码镜像解析数据的类型。
  39. MoveItem:表示移动项。
  40. MoveItemDirection:表示移动项的方向。
  41. WorkspaceSymbol:表示工作区符号。
  42. WorkspaceSymbolSearchScope:表示工作区符号搜索范围。
  43. WorkspaceSymbolSearchKind:表示工作区符号搜索类型。
  44. OnTypeFormatting:表示键入格式化。

这些结构体和枚举定义了rust-analyzer在LSP协议之上的扩展功能,使得其可以提供更丰富、更实用的Rust语言分析和代码编辑功能。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs

在Rust源代码中,rust-analyzer是一个用于提供Rust语言代码分析的工具。其中,analysis_stats.rs文件是用于收集和显示代码分析统计信息的工具的一部分。

该文件的作用是提供了一个命令行界面(CLI),用于显示代码分析的统计信息。它可以显示分析的总时间、已经分析的文件数量、缓存的filesize等等。这对于了解代码分析的性能和进度非常有用。

analysis_stats.rs文件中,Snap<DB>(DB)结构体起到了非常重要的作用。它是一个具有泛型的结构体,用于创建一个快照对象。Snap结构体的目的是为了达到并发读取数据库的效果,避免在读取过程中对数据库的修改导致出现问题。

具体来说,Snap结构体内部包含一个数据库的实例DB,并在创建快照时将数据库传递给DB。然后,可以使用快照对象Snap进行读取操作,而不需要担心其他线程对数据库进行修改。

Snap结构体的作用是提供一种线程安全的方式来读取数据库内容,保证在读取过程中不会受其他线程的修改影响。这对于代码分析过程中需要对数据库进行读取操作的情况非常有用。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/progress_report.rs

文件rust/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/progress_report.rs提供了Rust分析器的进度报告功能。它是用于在Rust源代码分析过程中向用户报告进度的模块。

模块中定义了一个名为ProgressReport的结构体,它通过实例化ProgressReport结构体来创建和管理进度报告。ProgressReport提供了一些方法来更新进度和报告统计信息。

该模块还定义了三个结构体:ProgressMessage、ProgressBar和MeasureDuration。这些结构体都是为了辅助进度报告而定义的。

  1. ProgressReport<'a>是主要的进度报告结构体,它通过实例化该结构体来创建和管理进度报告。它接受一个名为name的参数,用于标识当前进度报告的名称。通过调用ProgressReport的方法,可以更新进度、报告统计信息和完成报告。

  2. ProgressMessage结构体用于表示进度报告的消息。它包含一个名为message的字符串,用于存储要报告的内容。ProgressReport通过向ProgressMessage发送消息来更新进度。

  3. ProgressBar结构体用于显示进度条。它接受一个名为name的参数,用于确定进度条的名称。ProgressBar通过调用基于Termion库的底层方法来显示和更新进度条的状态。

  4. MeasureDuration结构体用于测量代码块的执行时间。它接受一个名为name的参数和一个名为msg的可选参数,用于确定要测量的代码块名称以及在测量结束时报告的消息。通过实例化MeasureDuration并调用其方法,可以记录时间并在代码块执行完成时更新进度报告。

总之,文件progress_report.rs提供了为Rust分析器中的源代码分析过程提供进度报告的功能。ProgressReport结构体和其衍生的辅助结构体提供了方法和工具来更新进度、报告统计信息和完成报告,并显示进度条和测量代码块执行时间。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/symbols.rs

这个文件的作用是定义了 Rust Analyzer CLI 的 symbols 子命令。Rust Analyzer 是一个用于代码分析和代码编辑的工具,symbols 子命令用于从代码中提取符号信息。

该文件首先导入了一些必要的模块和依赖项,包括 clap、ide、cli、cfg、vfs、symbol_index 等。然后定义了一个 pub(crate) 的函数 symbols,该函数使用 clap 定义了一个子命令,设置相关的配置信息,包括子命令的名称、描述、参数、选项等。

在函数 symbols 的实现中,首先根据参数解析和配置信息加载代码库,创建一个 ide::AnalysisHost 实例,并根据配置信息设置该实例的一些属性。之后,通过代码库的路径获取 lib.rs 文件,并对其进行解析,最终返回解析的结果。

接下来,函数 process_crate 被定义用于处理单个代码库。它首先设置一些运行时参数,创建 cli::load_cargo::Config 实例并通过 cli::load_cargo::load_workspace 加载工作区。接着,调用 ide::AnalysisHost::reload 方法对代码库进行重新加载。

然后,通过 ide::AnalysisHost 实例的 crate_graph 方法获取代码库的图形表示,对图形中的每个节点(代码库)调用 process_module 函数进行处理。函数 process_module 会获得代码库的根模块,并将其解析为符号信息。符号信息通过 symbol_index::Symbols::from_defs 方法创建,并最终返回。

最后,函数 symbols 调用 process_crate 处理代码库,并打印出符号信息,包括名称、类型等。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs

在Rust源代码中,rust-analyzer/src/cli/lsif.rs文件是一个命令行工具,用于将Rust项目的源代码转换为Language Server Index Format(LSIF)文件。LSIF是一种用于跨多种代码编辑器和开发工具进行代码导航和代码智能提示的格式。

在该文件中,Snap<DB>(DB)是一个泛型结构体,表示一个数据库的快照,其中DB是数据库的类型参数。这个结构体的作用是提供一种访问数据库的方式,以便进行代码索引和查询。

LsifManager<'a>是一个LSIF文件管理器的结构体,其中'a是一个生命周期参数。这个结构体的作用是管理LSIF文件的生成和更新过程。它提供了一组方法,用于处理源代码文件、生成索引数据,并将其写入LSIF文件。

Id(i32)是一个辅助结构体,代表一个标识符,并将其作为整数值封装。它主要用于在LSIF文件中跟踪和引用代码实体(如变量、函数、模块等)。

总的来说,rust-analyzer/src/cli/lsif.rs文件是Rust源代码中负责将Rust项目转换为LSIF格式的命令行工具的实现。它使用Snap<DB>结构体提供数据库访问功能,使用LsifManager<'a>结构体管理LSIF文件的生成和更新过程,并使用Id(i32)结构体来跟踪和引用代码实体。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs

ssr.rs文件在Rust语言的Rust Analyzer项目中,扮演着重要的角色。它实现了Rust Analyzer的Stuctural Search and Replace(结构搜索和替换)功能。

结构搜索和替换是一种通过语法树分析源代码并进行模式匹配的技术,主要用于在代码库中进行代码重构和改造。通过使用特定的搜索模式,我们可以识别出需要修改的代码片段,并将其替换为目标代码。这种技术可极大地简化大规模代码改造的过程,提高了开发效率。

ssr.rs文件中的代码主要包含以下几个部分:

  1. SsrMatches结构体:定义了模式匹配的结果,用于存储匹配到的代码片段的信息。

  2. SsrExpansion结构体:定义了代码替换操作的结果,用于存储替换后的代码片段信息。

  3. ssr_operation函数:实现了结构搜索和替换的主要逻辑。它接受输入的代码,使用指定的模式进行匹配,并执行相应的替换操作。

  4. SsrDatabase结构体:用于存储和管理代码库中的结构搜索和替换模式。

  5. ssr命令行工具:通过解析命令行参数,调用ssr_operation函数执行结构搜索和替换功能。

ssr.rs文件的主要作用是提供了一种方便的方式,使得开发者可以在Rust Analyzer的代码库中进行结构搜索和替换操作。它实现了核心的匹配算法和替换逻辑,使得开发者能够通过输入模式和目标代码来执行大规模的代码改造。

总结来说,ssr.rs文件在Rust源代码中扮演着实现Rust Analyzer中结构搜索和替换功能的关键角色,通过它,开发者能够方便地对代码库进行重构,并提高开发效率。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs

在Rust源代码中,rust/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs文件的作用是实现rust-analyzer的命令行解析逻辑。

在具体介绍该文件之前,首先需要了解一下rust-analyzer是什么。rust-analyzer是一个Rust语言的静态分析工具和IDE(集成开发环境)插件,它提供了快速准确的代码补全、代码语法检查、跳转定义、重构等功能。scip.rs文件是rust-analyzer的一部分,它负责解析命令行参数,以便启动rust-analyzer的各种功能。

其中,MyStructStBar$0Bar是该文件中的一些结构体(struct)定义。这些结构体用于封装不同的命令行参数。具体来说:

  1. MyStruct 是一个通用的命令行选项结构体,用于表示一般的命令行参数。它包含了一些字段,如 cfgspecificproject_overlayglob等,用于表示不同的命令行选项。

  2. StMyStruct 的一个子结构体,它在 MyStruct 的基础上添加了一些特定的命令行选项字段。例如,st.specific 表示具有特定路径的选项。这个结构体用于表示 stab 命令的特定参数。

  3. Bar$0 是一个名为 Bar 的结构体的具体实例。该结构体用于表示 bar 命令的参数,其中的 file 字段用于指定要处理的文件路径。

  4. BarMyStruct 的另一个子结构体,它在 MyStruct 的基础上添加了一些特定的命令行选项字段。Bar 结构体用于表示 bar 命令的参数,例如 etch 表示解析器行为等。

除了这些结构体,scip.rs文件还定义了一些 trait(trait)。

  1. MyTrait 是一个通用的特性(接口),它定义了一些用于处理命令行参数的方法。具体来说,它包括 help(), from_ctx(), process()等方法,用于处理不同命令的逻辑。

  2. trait MyTrait 的实现分别扩展了各个结构体(struct),以便实现各自的方法逻辑。通过实现不同结构体的 MyTrait 特性,可以根据不同的命令行参数调用相应实现的方法来处理参数并执行相应的功能。

以上是对 rust-analyzerscip.rs 文件中几个重要结构体和特性的简要介绍。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/parse.rs

在Rust源代码中, rust-analyzer/src/cli/parse.rs 文件是 Rust 解析器(Rust Analyzer)中的一个关键组件。Rust 解析器是一个用于分析和解析 Rust 代码的工具,它将 Rust 代码转换为抽象语法树(AST),并提供了各种静态分析和信息提取功能。

parse.rs 文件的作用是解析命令行参数,将用户通过命令行传入的参数解析为解析器所需的配置选项。它定义了一个 Args 结构体,该结构体包含了解析器需要的各种配置参数。

下面是 parse.rs 文件的基本结构和功能:

  1. 引入 Rust 的标准库和其他必要的依赖项。这些依赖项包括命令行参数解析库 clap、错误处理库等。

  2. 定义 Args 结构体。这个结构体描述了解析器的配置选项,包括:

    • change:标记要解析的源文件是否发生了更改。
    • disable_analysis_cache:是否禁用分析缓存。
    • only_hover: 是否只显示光标下的信息。
    • log_file: 日志文件路径。
    • log_syntax_trees: 是否记录语法树节点。
    • log_with_thread_id: 是否在日志中包含线程ID。
  3. 使用 clap 库初始化一个命令行解析器对象。在这个对象中,我们定义了解析器支持的命令和参数,并与结构体 Args 关联。这些命令和参数定义了用户可以在命令行中使用的选项,并提供了相关的帮助信息和默认值。

  4. 解析命令行参数。使用 clap 库提供的 get_matches 方法解析用户通过命令行传递的参数,并返回一个包含解析结果的 Matches 对象。根据该对象中的参数值,更新 Args 结构体中的字段。

  5. 对解析的命令行参数进行验证和处理。这可能涉及到一些逻辑相关的处理,例如如果用户传递了一个日志文件路径,需要确保该路径有效并可写。

  6. 返回已解析的配置选项。将最终的 Args 结构体返回给调用者,以便 Rust 解析器根据这些选项执行相应操作。

总之,parse.rs 文件中的代码负责解析和处理用户通过命令行传入的参数,并将其转换为 Rust 解析器所需的内部配置选项。这个文件是 Rust 解析器的一个重要组成部分,它确保解析器能够以正确的配置运行,并准备好处理传入的 Rust 代码。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs

在Rust源代码中,rust-analyzer/src/cli/diagnostics.rs文件的主要作用是实现了一个命令行界面(CLI)的诊断功能。该文件定义了用于获取Rust代码诊断信息的函数和结构体。

具体而言,该文件实现了以下功能:

  1. 提供一个diagnostics函数,用于处理传入的Rust代码,并返回与之对应的诊断信息。该函数接受一个字符串类型的代码输入,将其解析为语法树,并将解析后的语法树作为参数传递给check函数。

  2. check函数是诊断功能的核心部分,用于对传入的语法树进行静态检查,并返回诊断结果。该函数将语法树作为参数,遍历语法树并检查其中可能出现的错误、警告或其他问题。检查的过程中,可能会调用其他函数或方法来获取更详细的信息,这些函数和方法通常在其他文件中定义。

  3. diagnostics函数会将check函数返回的诊断信息进行处理,将其转换为可读性良好的格式,然后输出到命令行界面供用户查看。诊断信息可能包含错误代码、错误位置、错误描述、建议修复方案等内容,以帮助用户理解并解决代码中存在的问题。

总的来说,rust-analyzer/src/cli/diagnostics.rs文件是Rust编译器工具中的一个重要组成部分,提供了命令行界面下的代码诊断功能,帮助开发者找出代码中的错误、警告和潜在问题,以提高代码质量和可靠性。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/highlight.rs

在Rust源代码中的rust-analyzer工具包中,文件highlight.rs的作用是实现代码高亮功能。该文件包含了用于语法高亮处理的相关代码。

代码高亮是一种为了提高代码可读性和理解性而将不同代码部分以不同颜色或样式进行标记的技术。在编程语言中,代码高亮通常用于突出显示关键字、变量、注释等。

highlight.rs文件在Rust分析器中定义了一个名为highlight的函数,该函数接收源代码和语法树作为输入,并返回一个包含高亮信息的数据结构。具体来说,highlight函数通过遍历语法树的节点来分析代码的结构,并根据不同的节点类型为每个代码标记生成相应的高亮信息。

该文件中的代码逐行解析源代码,根据不同代码元素的语法规则来生成对应的高亮信息。例如,对于关键字和操作符,会生成相应的颜色或样式标记。对于标识符和字面量,也会生成相应的标记。此外,代码注释和字符串常量也会被突出显示。

要实现高亮功能,highlight.rs文件还依赖于其他与语法分析和标记生成相关的模块和函数。这些模块和函数负责解析代码和处理不同类型的语法元素,包括标识符、关键字、操作符等。

总之,highlight.rs文件在Rust源代码中的位置是rust/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/,它实现了实现代码高亮的功能,通过解析源代码的语法树并生成相应的高亮信息,以提高代码的可读性和理解性。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs

rust-analyzer是一个用于分析Rust源代码的工具,而rust-analyzer/crates/rust-analyzer/src/cli/flags.rs文件则定义了该工具的命令行参数的相关内容。

该文件中定义了多个结构体和枚举类型。这些结构体和枚举类型用于定义不同的命令行参数,并提供了相应的处理逻辑。

下面是对各个结构体和枚举类型的作用的详细介绍:

  1. RustAnalyzer结构体:用于表示Rust代码分析器的配置参数,如代码的搜索路径,加载的扩展等。
  2. LspServer结构体:用于表示语言服务器的配置参数,如LSP协议的通信地址和超时时间等。
  3. Parse结构体:用于表示解析Rust源代码的配置参数,如是否启用属性解析和解析深度等。
  4. Symbols结构体:用于表示符号索引的配置参数,如索引的最大深度和忽略的函数等。
  5. Highlight结构体:用于表示语法高亮的配置参数,如启用的高亮种类和响应时间等。
  6. AnalysisStats结构体:用于表示分析统计的配置参数,如是否启用统计和调试等。
  7. RunTests结构体:用于表示运行测试的配置参数,如测试运行的超时时间和测试过滤器等。
  8. Diagnostics结构体:用于表示诊断信息的配置参数,如错误等级和警告等级等。
  9. Ssr结构体:用于表示结构化编辑和重构的配置参数,如重命名操作和替换的具体规则等。
  10. Search结构体:用于表示代码搜索的配置参数,如搜索模式和匹配的文件类型等。
  11. Lsif结构体:用于表示LSIF(Language Server Index Format)的配置参数,如生成索引的路径和过滤规则等。
  12. Scip结构体:用于表示基于Scipio的服务器的配置参数,如服务器地址和SSL证书等。

同时,该文件还定义了两个枚举类型:

  1. RustAnalyzerCmd枚举:用于表示rust-analyzer命令的执行方式,如启动语言服务器、生成代码文档等。
  2. OutputFormat枚举:用于表示输出结果的格式,如文本、JSON或其他格式。

这些结构体和枚举类型的定义提供了对rust-analyzer命令行参数的类型安全和明确的表示,使用户能够通过命令行参数来配置rust-analyzer的行为和输出结果的形式。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs

在Rust源代码中,rust/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs文件的作用是实现了用于重新加载Rust项目的相关功能。该文件定义了一些结构和枚举类型,用于表示重新加载过程中的各种状态和进度。

具体来说,ProjectWorkspaceProgress枚举表示项目工作空间的进度,它包含以下几个成员:

  1. Begin - 表示重新加载过程的开始。
  2. RepositoriesLoaded - 表示仓库已加载完成。
  3. PackagesWithProcMacroLoaded - 表示包含 procedural macro 的包已加载完成。
  4. WorkspaceLoaded - 表示工作空间已加载完成。
  5. BuildData - 表示构建数据加载的进度。
  6. BuildScripts - 表示构建脚本的进度。
  7. Finish - 表示重新加载过程的结束。

BuildDataProgress枚举表示构建数据的加载进度,它包含以下几个成员:

  1. Compilations - 表示编译过程中的进度。
  2. SourceRoots - 表示源代码根目录的加载进度。
  3. DependecyEdges - 表示依赖关系的加载进度。

ProcMacroProgress枚举表示 procedural macro 的加载进度,它包含以下几个成员:

  1. Begin - 表示 procedural macro 的加载开始。
  2. LoadData - 表示加载 macro 数据的进度。
  3. Finish - 表示加载 macro 数据的结束。

这些枚举类型和相关实现可以帮助 Rust 编译器和解析器在进行重新加载时跟踪进度和状态,以提供准确的反馈和显示进度条等功能。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/cli.rs

在Rust源代码中,rust/src/tools/rust-analyzer/crates/rust-analyzer/src/cli.rs文件的作用是用于处理Rust Analyzer的命令行接口(CLI)。它定义了与解析命令行参数、执行对应操作相关的结构体、函数和宏。

该文件首先定义了用于输出详细信息的Verbosity枚举。该枚举有三个成员:

  1. Verbosity::Error: 表示仅输出错误级别的信息。
  2. Verbosity::Info: 表示除了错误信息外还输出一些详细的提示信息。
  3. Verbosity::Debug: 表示输出包括错误信息在内的所有详细信息。

在命令行参数解析相关的结构体方面,该文件定义了Args结构体,用于存储解析后的命令行参数。Args结构体包含了多个字段,包括:

  1. config: 用于指定配置文件的路径。
  2. verbosity: 用于指定输出详细信息的级别。
  3. log_file: 用于指定输出日志的文件路径。
  4. watch: 用于指定是否监视文件变化并重新解析。

除此之外,该文件还定义了一些函数和宏来处理命令行参数和执行相应操作。例如,parse_args函数用于解析命令行参数并返回Args结构体;handle_command函数用于根据命令行参数执行相应的操作;exit_on_error宏用于在遇到错误时打印错误信息并退出程序。

总之,rust/src/tools/rust-analyzer/crates/rust-analyzer/src/cli.rs文件是Rust Analyzer命令行接口的关键部分,用于处理命令行参数的解析和执行相应操作的逻辑,并提供了不同级别的详细信息输出选项。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/diff.rs

在Rust源代码中,rust/src/tools/rust-analyzer/crates/rust-analyzer/src/diff.rs文件的作用是实现了一个用于计算文本差异的算法。

文本差异算法在版本控制、文本编辑和其他领域中经常使用。它能够比较两个文本之间的差异,例如新增、删除或修改的文本行,以便展示修改的部分或合并不同版本之间的差异。

该文件实现了最经典的差异算法之一,即Myer's算法,该算法由Eugene Myers在1986年提出。它是一种最小编辑距离算法,用于计算最短编辑序列,以将一个字符串转换为另一个字符串。

diff.rs文件中的核心函数是diff函数。该函数接收两个文本作为输入,并返回一个表示差异的数据结构。在计算差异时,该函数使用了动态规划的思想。它通过构建一个二维矩阵来计算最长公共子序列(LCS)的长度,进而确定差异的位置和类型。

除了计算差异之外,该文件还提供了一些辅助函数,用于对差异进行解析和渲染。这些函数可以将差异表示为类似于Unified Diff格式的字符串,或者将差异的位置进行映射,以便在编辑器中进行精确的高亮显示。

总体而言,rust-analyzer/src/diff.rs文件提供了一个完整的差异算法实现,支持计算文本之间的差异和生成表示差异的字符串。该算法在rust-analyzer这个项目中用于识别和可视化代码变更,以提供更好的代码编辑和自动补全功能。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/mem_docs.rs

在Rust源代码中,mem_docs.rs文件是Rust语言分析器(Rust Analyzer)的一部分,负责处理内存文档(Memory Docs),为代码的类型、变量、函数等元素提供文档注释的信息。

具体而言,mem_docs.rs定义了两个重要的结构体:MemDocsDocumentData

MemDocs结构体是内存文档的容器,它存储了所有文档注释的信息。它包含了一个DocumentData的Vec,每个DocumentData项都表示一个具体的文档。

DocumentData结构体则表示一条文档注释的数据。它包含了以下字段:

  • docs: 存储文档注释的文本内容。
  • label: 表示文档注释所属的元素名称(例如函数名、变量名等)。
  • path: 存储元素的路径信息,以便能够准确定位到具体的代码位置。
  • range: 表示元素在源代码中的起止位置范围,用于准确定位。

通过分析代码,Rust分析器可以提取源代码中的文档注释,并将其存储在MemDocs中。开发人员可以通过查询MemDocs数据结构,按需获取源代码中特定元素的文档注释信息,并将其用于提供代码补全、文档查看以及代码导航等功能。

总之,mem_docs.rs文件负责解析和存储源代码中的文档注释信息,以便Rust Analyzer可以使用这些信息来提供更好的代码智能补全和代码导航功能。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs

在Rust源代码中,rust/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs文件的作用是将Rust语言分析器生成的诊断信息转换为protobuf格式,以便于在不同平台和语言之间进行传输和处理。

具体来说,这个文件中定义了一系列结构体和枚举,用于将源代码中的诊断信息转换为protobuf消息。其中包括:

  • SubDiagnostic结构体表示一个子诊断,包含了与主诊断相关的附加信息,如代码位置、消息等。
  • MappedRustDiagnostic结构体表示一个映射的Rust诊断,在诊断过程中使用,包含了主诊断和相关的子诊断,用于构建完整的诊断信息。
  • std::cmp::PartialEq<&str>是一个用于比较字符串的特性(trait),可以进行部分相等性比较,即只比较字符串的一部分内容。
  • MappedRustChildDiagnostic枚举表示一个映射的Rust子诊断,在诊断过程中使用,用于表示不同类型的子诊断,如错误、警告等。

通过定义这些结构体和枚举,to_proto.rs文件提供了将Rust语言分析器生成的诊断信息转换为protobuf格式的功能,从而方便在不同平台和语言之间进行传输和处理。这对于Rust语言分析器的开发和使用非常重要,可以帮助开发者更好地理解和处理代码中的问题和错误。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs

这个文件的作用是Rust语言的LSP(Language Server Protocol)服务器实现,为Rust项目提供代码编辑功能和智能代码补全、错误检查和代码跳转等功能。

具体来说,lib.rs文件是Rust编写的Rust Analyzer库的入口点。Rust Analyzer是一个用于Rust语言的IDE插件,旨在提供高性能和完善的Rust语言支持。

lib.rs文件定义了Rust Analyzer的主要逻辑,包括Rust Analyzer服务器的启动和初始化,以及处理来自客户端的LSP请求和通知。它还负责解析和构建Rust项目的语法树,生成语法分析树并执行各种代码分析任务。

在lib.rs中,使用了一系列的Rust Analyzer模块,来处理不同的功能,比如处理工程目录、解析代码、提供补全、错误检查和代码跳转等。这些模块的代码被组织在多个文件和目录中,根据需要被动态加载。

lib.rs文件还处理了与客户端的LSP通信,监听来自客户端的请求和通知,并相应地调用相应的函数或模块,以提供所需的功能。通过与LSP协议的交互,Rust Analyzer可以将代码编辑器转变为一个功能强大的Rust IDE,提供了许多与Rust语言相关的代码分析和编辑功能。

总而言之,lib.rs文件是Rust Analyzer的核心逻辑文件,负责启动和初始化Rust Analyzer服务器,处理LSP协议的通信,以及提供代码编辑和分析功能。它是Rust Analyzer这个IDE插件的关键组成部分,为Rust语言开发者提供了良好的开发体验。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/line_index.rs

在Rust源代码中,rust/src/tools/rust-analyzer/crates/rust-analyzer/src/line_index.rs文件的作用是提供对文本行进行索引和处理的功能。

该文件定义了几个重要类型:LineIndexLineColPositionEncodingLineEndings

  1. LineIndex是一个包含文本行索引的结构体。它负责将文本分成行,并提供根据行索引查找行号、列号和字符偏移的方法。此外,LineIndex还提供了从行号、列号和字符偏移获取行索引的能力。

  2. LineCol是一个用于表示行号和列号的元组结构体。他实现了一些方法,如比较、加减操作符等,方便进行行列号的计算和比较。

  3. PositionEncoding是一个表示字符偏移编码的枚举类型。它定义了三种不同的编码方式:Utf8Utf16Utf32。这些编码方式在计算字符偏移时考虑了不同编码的字符长度。

  4. LineEndings是一个表示行结束符的枚举类型。它定义了四种可能的行结束符:UnixWindowsMacMixed。这些枚举项表示了不同操作系统下行结束符的表示方式。

这些类型一起协同工作,提供了对源代码进行行级索引和处理的能力,使得Rust分析器能够更高效地进行语法解析、代码跳转等操作。

File: rust/src/tools/rust-analyzer/crates/rust-analyzer/src/op_queue.rs

在Rust源代码中,rust-analyzer是一个Rust语言的语义分析器,用于静态代码分析和IDE支持。op_queue.rs文件是其中的一部分,它实现了一个操作队列(Operation Queue),用于处理并发的并行操作。

操作队列在并发编程中非常常见,它用于处理多个操作并保证它们按照正确的顺序执行,以避免竞态条件和数据不一致性。OpQueue是一个操作队列的具体实现。

OpQueue结构体是操作队列的主要部分,其中包含了多个字段和方法:

  1. tx字段:表示发送端(sender),是用于发送操作的通道的发送端。
  2. rx字段:表示接收端(receiver),是用于接收操作的通道的接收端。
  3. worker字段:表示操作的执行者(worker),是一个线程池,用于并发执行操作。
  4. local字段:表示一个本地操作队列,用于将操作缓存在同一线程中。
  5. finish_all字段:表示是否等待所有操作执行完毕后再结束队列。
  6. task字段:表示当前要执行的任务,是一个函数指针。
  7. task_data字段:表示当前要执行的任务所需的数据。
  8. requests字段:表示已经发送的请求数量,用于识别操作的先后顺序。

OpQueue结构体还实现了一系列方法来操作操作队列,其中最重要的是:

  1. new方法:用于创建一个新的操作队列实例。
  2. enqueue方法:用于将操作添加到操作队列中。
  3. deque_task方法:用于从接收端获取操作并将其设置为当前要执行的任务。
  4. tick方法:用于在主循环中执行任务执行器,处理接收到的操作。

Args结构体是一个通用的参数结构体,用于向操作队列提交操作。其作用是提供与操作相关的参数和数据,并在提交操作时传递给操作队列。

总的来说,op_queue.rs文件中的OpQueue结构体和Args结构体是rust-analyzer中实现并发操作队列的重要组成部分。通过使用操作队列,rust-analyzer能够处理并发的操作请求,并保证它们按照正确的顺序执行,从而提高代码分析和IDE支持的性能和稳定性。

本文由 mdnice 多平台发布文章来源地址https://www.toymoban.com/news/detail-756908.html

到了这里,关于听GPT 讲Rust源代码--src/tools(11)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 听GPT 讲Rust源代码--library/std(16)

    题图来自 EVALUATION OF RUST USAGE IN SPACE APPLICATIONS BY DEVELOPING BSP AND RTOS TARGETING SAMV71 [1] 在Rust标准库中, rust/library/std/src/sync/mpmc/select.rs 文件的作用是实现一个多生产者多消费者的选择操作(select operation)。选择操作指的是一组操作中正好可以执行的操作,而其他操作则会被阻塞

    2024年02月05日
    浏览(30)
  • 听GPT 讲Rust源代码--library/std(9)

    题图来自 Rust 101 — Everything you need to know about Rust [1] 在Rust源代码中, rust/library/std/src/sys/wasi/io.rs 文件的作用是实现了与WASI(WebAssembly System Interface)IO相关的功能。 WASI是一个定义了WebAssembly程序与主机环境之间的系统接口的规范。在Rust中, io.rs 文件实现了一些WASI IO相关的数

    2024年02月06日
    浏览(28)
  • 听GPT 讲Rust源代码--library/std(7)

    题图来自 Programming languages: How Google is using Rust to reduce memory safety vulnerabilities in Android [1] 在Rust的标准库中, kernel_copy.rs 文件位于 sys/unix 目录下,其主要作用是实现特定于UNIX系统的内核级拷贝操作。 在该文件中,有以下几个struct: CopyParams :负责存储拷贝操作的参数信息,包

    2024年02月08日
    浏览(40)
  • 听GPT 讲Rust源代码--library/std(15)

    题图来自 An In-Depth Comparison of Rust and C++ [1] 文件路径:rust/library/std/src/os/wasi/io/fd.rs 该文件的作用是实现与文件描述符(File Descriptor)相关的操作,具体包括打开文件、读写文件、修改文件状态等功能。 以下是该文件的详细内容介绍: 引用 该文件首先引入了一些需要使用到的

    2024年02月05日
    浏览(33)
  • 听GPT 讲Rust源代码--library/std(10)

    题图来自 Rust Development Roadmap [1] 在Rust源代码的 rust/library/std/src/sys/windows/c.rs 文件中,主要定义了Rust对于Windows操作系统的系统调用接口。该文件定义了各种Windows特定的结构体、枚举和常量,以支持与操作系统的交互。 以下是对每个结构体的详细介绍: ip_mreq : 该结构体用于表

    2024年02月06日
    浏览(40)
  • 听GPT 讲Rust源代码--library/proc_macro

    在Rust源代码中,rust/library/proc_macro/src/bridge/rpc.rs文件的作用是实现了Rust编程语言的编译过程中的远程过程调用(RPC)机制。 这个文件定义了与编译器的交互过程中使用的各种数据结构和接口。 具体来说,UnknownPanicMessage结构是用于表示编译器返回的未知错误信息。它包含一个

    2024年02月03日
    浏览(37)
  • php 系列题目,包含查看后端源代码

    1.字符串和数字比较,字符串回被转换成数字。 \\\"admin\\\" ==0(true) admin被转换成数字,由于admin是字符串,转换失败,变成0 int(admin)=0,所以比较结果是ture 2.混合字符串转换成数字,看字符串的第一个 “1admin” == 1 ‘’2admin“ == 2  3.字符串开头以xex开头,x代表数字。会被转换成科

    2024年02月11日
    浏览(53)
  • 听GPT 讲Prometheus源代码--discovery

    Prometheus是一个开源的系统监控和警报工具包,以下是Prometheus源代码中一些主要的文件夹及其作用: cmd/ :这个目录包含了Prometheus主要的命令行工具,如 prometheus/ , promtool/ 等。每个子目录都代表一个可执行的命令行应用。 storage/ :这个目录包含了Prometheus的存储引擎的代码

    2024年02月12日
    浏览(34)
  • 听GPT 讲Prometheus源代码--util

    Prometheus的util目录包含了一些通用的工具模块,主要包含以下文件: buckets.go 这个文件定义了一些常用的指标采样值范围(Quantile buckets),如:0.001,0.01,0.05,0.5,0.9,0.95,0.99,0.999等。这些buckets常用于计算指标的分位数线。 regex.go 这个文件定义了一些正则表达式匹配的通用函数,主要包括利

    2024年02月11日
    浏览(32)
  • 听GPT 讲Prometheus源代码--rules

    Prometheus的rules目录主要包含规则引擎和管理规则的文件: engine.go 该文件定义了规则引擎的接口和主要结构,包括Rule,Record,RuleGroup等。它提供了规则的加载、匹配、评估和结果记录的功能。 api.go 定义了用于管理和查询规则的RESTful API,包括获取、添加、删除规则等方法。 recordin

    2024年02月12日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包