ink_analyzer/
analysis.rs

1//! Types and abstractions for performing semantic analysis of ink! smart contract code.
2
3mod actions;
4mod completions;
5mod diagnostics;
6mod extract;
7mod hover;
8mod inlay_hints;
9mod migrate;
10mod signature_help;
11mod text_edit;
12mod utils;
13
14use crate::Version;
15use ink_analyzer_ir::syntax::{TextRange, TextSize};
16use ink_analyzer_ir::InkFile;
17use itertools::Itertools;
18
19pub use actions::{Action, ActionKind};
20pub use completions::{Completion, CompletionKind};
21pub use diagnostics::{Diagnostic, Severity};
22pub use extract::Extraction;
23pub use hover::Hover;
24pub use inlay_hints::InlayHint;
25pub use signature_help::SignatureHelp;
26pub use text_edit::TextEdit;
27
28/// Entry point for asking for semantic information about ink! smart contract code.
29#[derive(Debug)]
30pub struct Analysis {
31    /// The ink! smart contract code being analyzed.
32    file: InkFile,
33    /// The ink! language version.
34    version: Version,
35}
36
37impl Analysis {
38    /// Creates an analysis instance from smart contract code.
39    pub fn new(code: &str, version: Version) -> Self {
40        Self {
41            file: InkFile::parse(code),
42            version,
43        }
44    }
45
46    /// Returns the intermediate representation (IR) of the smart contract code.
47    pub fn file(&self) -> &InkFile {
48        &self.file
49    }
50
51    /// Runs diagnostics for the smart contract code.
52    pub fn diagnostics(&self) -> Vec<Diagnostic> {
53        diagnostics::diagnostics(&self.file, self.version)
54    }
55
56    /// Computes ink! attribute completions at the given position.
57    pub fn completions(&self, position: TextSize) -> Vec<Completion> {
58        completions::completions(&self.file, position, self.version)
59    }
60
61    /// Computes ink! attribute code/intent actions for the given text range.
62    pub fn actions(&self, range: TextRange) -> Vec<Action> {
63        // Returns quickfixes (for diagnostics) + generic code actions.
64        diagnostics::diagnostics(&self.file, self.version)
65            .into_iter()
66            .filter_map(|it| it.quickfixes)
67            .flatten()
68            // Filters out diagnostics that apply to the given text range.
69            .filter(|action| {
70                range.contains_range(action.range) || action.range.contains_range(range)
71            })
72            // Combines quickfixes and generic actions (with quickfixes taking priority).
73            .chain(actions::actions(&self.file, range, self.version))
74            // Deduplicate by edits.
75            .unique_by(|item| item.edits.clone())
76            // Sorts actions by kind.
77            .sorted_by_key(|item| item.kind)
78            .collect()
79    }
80
81    /// Returns descriptive/informational text for the ink! attribute at the given text range (if any).
82    pub fn hover(&self, range: TextRange) -> Option<Hover> {
83        hover::hover(&self.file, range, self.version)
84    }
85
86    /// Computes ink! attribute argument inlay hints for the given text range (if any).
87    pub fn inlay_hints(&self, range: Option<TextRange>) -> Vec<InlayHint> {
88        inlay_hints::inlay_hints(&self.file, range, self.version)
89    }
90
91    /// Computes ink! attribute signature help for the given position.
92    pub fn signature_help(&self, position: TextSize) -> Vec<SignatureHelp> {
93        signature_help::signature_help(&self.file, position, self.version)
94    }
95
96    /// Computes text edits for migrating the ink! 4.x file to ink! 5.0.
97    pub fn migrate(&self) -> Vec<TextEdit> {
98        migrate::migrate(&self.file)
99    }
100
101    /// Computes text edits for extracting an ink! event at the given text range into
102    /// a standalone package (if possible).
103    pub fn extract(&self, range: TextRange) -> Option<Extraction> {
104        extract::extract(&self.file, range)
105    }
106}