diff --git a/kclvm/ast/src/ast.rs b/kclvm/ast/src/ast.rs index 4aae79d3b..6c9c80702 100644 --- a/kclvm/ast/src/ast.rs +++ b/kclvm/ast/src/ast.rs @@ -83,7 +83,7 @@ impl Into for Pos { /// that all AST nodes need to contain. /// In fact, column and end_column are the counts of character, /// For example, `\t` is counted as 1 character, so it is recorded as 1 here, but generally col is 4. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct Node { pub node: T, pub filename: String, @@ -165,7 +165,7 @@ impl Node { } /// Spanned is the span information that all AST nodes need to contain. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct Spanned { pub node: T, #[serde(skip)] @@ -231,21 +231,21 @@ impl TryInto> for Node { pub type NodeRef = Box>; /// KCL command line argument spec, e.g. `kcl main.k -E pkg_name=pkg_path` -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct CmdExternalPkgSpec { pub pkg_name: String, pub pkg_path: String, } /// KCL command line argument spec, e.g. `kcl main.k -D name=value` -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct CmdArgSpec { pub name: String, pub value: String, } /// KCL command line override spec, e.g. `kcl main.k -O pkgpath:path.to.field=field_value` -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct OverrideSpec { pub pkgpath: String, pub field_path: String, @@ -253,7 +253,7 @@ pub struct OverrideSpec { pub action: OverrideAction, } -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum OverrideAction { Delete, #[serde(other)] @@ -261,7 +261,7 @@ pub enum OverrideAction { } /// Program is the AST collection of all files of the running KCL program. -#[derive(Serialize, Deserialize, Debug, Clone, Default)] +#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)] pub struct Program { pub root: String, pub main: String, @@ -290,7 +290,7 @@ impl Program { } /// Module is an abstract syntax tree for a single KCL file. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct Module { pub filename: String, pub pkg: String, @@ -328,7 +328,7 @@ impl Module { */ /// A statement -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum Stmt { TypeAlias(TypeAliasStmt), Expr(ExprStmt), @@ -347,7 +347,7 @@ pub enum Stmt { /// ```kcl /// type StrOrInt = str | int /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct TypeAliasStmt { pub type_name: NodeRef, pub type_value: NodeRef, @@ -360,7 +360,7 @@ pub struct TypeAliasStmt { /// 1 /// """A long string""" /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct ExprStmt { pub exprs: Vec>, } @@ -369,7 +369,7 @@ pub struct ExprStmt { /// ```kcl /// data: ASchema {} /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct UnificationStmt { pub target: NodeRef, pub value: NodeRef, @@ -379,7 +379,7 @@ pub struct UnificationStmt { /// ```kcl /// a: int = 1 /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct AssignStmt { pub targets: Vec>, pub value: NodeRef, @@ -392,7 +392,7 @@ pub struct AssignStmt { /// ```kcl /// a += 1 /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct AugAssignStmt { pub target: NodeRef, pub value: NodeRef, @@ -403,7 +403,7 @@ pub struct AugAssignStmt { /// ```kcl /// assert True if condition, "Assert failed message" /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct AssertStmt { pub test: NodeRef, pub if_cond: Option>, @@ -420,7 +420,7 @@ pub struct AssertStmt { /// else: /// c = 3 /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct IfStmt { pub body: Vec>, pub cond: NodeRef, @@ -431,7 +431,7 @@ pub struct IfStmt { /// ```kcl /// import pkg as pkg_alias /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct ImportStmt { /// `path` is the import path, if 'import a.b.c' in kcl, `path` is a.b.c pub path: String, @@ -464,7 +464,7 @@ pub struct ImportStmt { /// protocol ProtocolExample: /// attr: int /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct SchemaStmt { pub doc: String, pub name: NodeRef, @@ -553,7 +553,7 @@ impl SchemaStmt { /// schema SchemaIndexSignatureExample: /// [str]: int /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct SchemaIndexSignature { pub key_name: Option, pub key_type: NodeRef, @@ -570,7 +570,7 @@ pub struct SchemaIndexSignature { /// x: int /// y: str /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct SchemaAttr { pub doc: String, pub name: NodeRef, @@ -589,7 +589,7 @@ pub struct SchemaAttr { /// a > 1 /// b < 0 /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct RuleStmt { pub doc: String, pub name: NodeRef, @@ -601,7 +601,7 @@ pub struct RuleStmt { } /// A expression -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum Expr { Identifier(Identifier), Unary(UnaryExpr), @@ -642,7 +642,7 @@ pub enum Expr { /// _c /// pkg.a /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct Identifier { pub names: Vec>, pub pkgpath: String, @@ -669,7 +669,7 @@ impl Identifier { /// ~3 /// not True /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct UnaryExpr { pub op: UnaryOp, pub operand: NodeRef, @@ -682,7 +682,7 @@ pub struct UnaryExpr { /// 5 / 2 /// a is None /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct BinaryExpr { pub left: NodeRef, pub op: BinOrCmpOp, @@ -693,7 +693,7 @@ pub struct BinaryExpr { /// ```kcl /// 1 if condition else 2 /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct IfExpr { pub body: NodeRef, pub cond: NodeRef, @@ -705,7 +705,7 @@ pub struct IfExpr { /// x.y /// x?.y /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct SelectorExpr { pub value: NodeRef, pub attr: NodeRef, @@ -719,7 +719,7 @@ pub struct SelectorExpr { /// func2(1) /// func3(x=2) /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct CallExpr { pub func: NodeRef, pub args: Vec>, @@ -730,7 +730,7 @@ pub struct CallExpr { /// ```kcl /// 1 + (2 - 3) /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct ParenExpr { pub expr: NodeRef, } @@ -742,7 +742,7 @@ pub struct ParenExpr { /// map x in collection {x + 1} /// filter x in collection {x > 1} /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct QuantExpr { pub target: NodeRef, pub variables: Vec>, @@ -752,7 +752,7 @@ pub struct QuantExpr { pub ctx: ExprContext, } -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum QuantOperation { All, Any, @@ -777,7 +777,7 @@ impl From for String { /// ```kcl /// [1, 2, 3] /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct ListExpr { pub elts: Vec>, pub ctx: ExprContext, @@ -787,7 +787,7 @@ pub struct ListExpr { /// ```kcl /// [1, if condition: 2, 3] /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct ListIfItemExpr { pub if_cond: NodeRef, pub exprs: Vec>, @@ -803,7 +803,7 @@ pub enum CompType { /// ```kcl /// [x ** 2 for x in [1, 2, 3]] /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct ListComp { pub elt: NodeRef, pub generators: Vec>, @@ -813,7 +813,7 @@ pub struct ListComp { /// ```kcl /// [1, 2, *[3, 4]] /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct StarredExpr { pub value: NodeRef, pub ctx: ExprContext, @@ -823,7 +823,7 @@ pub struct StarredExpr { /// ```kcl /// {k: v + 1 for k, v in {k1 = 1, k2 = 2}} /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct DictComp { pub entry: ConfigEntry, pub generators: Vec>, @@ -837,7 +837,7 @@ pub struct DictComp { /// k2 = 2 /// } /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct ConfigIfEntryExpr { pub if_cond: NodeRef, pub items: Vec>, @@ -848,7 +848,7 @@ pub struct ConfigIfEntryExpr { /// ```kcl /// i, a in [1, 2, 3] if i > 1 and a > 1 /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct CompClause { pub targets: Vec>, pub iter: NodeRef, @@ -862,7 +862,7 @@ pub struct CompClause { /// attr2 = 2 /// } /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct SchemaExpr { pub name: NodeRef, pub args: Vec>, @@ -877,12 +877,12 @@ pub struct SchemaExpr { /// attr2 = 2 /// } /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct ConfigExpr { pub items: Vec>, } -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum ConfigEntryOperation { Union, Override, @@ -915,7 +915,7 @@ impl ConfigEntryOperation { /// c += [0] /// } /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct ConfigEntry { pub key: Option>, pub value: NodeRef, @@ -927,7 +927,7 @@ pub struct ConfigEntry { /// ```kcl /// len(attr) > 3 if attr, "Check failed message" /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct CheckExpr { pub test: NodeRef, pub if_cond: Option>, @@ -941,7 +941,7 @@ pub struct CheckExpr { /// z + y /// } /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct LambdaExpr { pub args: Option>, pub return_type_str: Option, @@ -956,7 +956,7 @@ pub struct LambdaExpr { /// b["k"] /// c?[1] /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct Subscript { pub value: NodeRef, pub index: Option>, @@ -971,7 +971,7 @@ pub struct Subscript { /// ```kcl /// arg=value /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct Keyword { pub arg: NodeRef, pub value: Option>, @@ -983,7 +983,7 @@ pub struct Keyword { /// x + y /// } /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct Arguments { pub args: Vec>, pub defaults: Vec>>, @@ -1007,7 +1007,7 @@ impl Arguments { /// b is not None /// c != d /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct Compare { pub left: NodeRef, pub ops: Vec, @@ -1021,7 +1021,7 @@ pub struct Compare { /// "string literal" /// """long string literal""" /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum Literal { Number(NumberLit), String(StringLit), @@ -1029,7 +1029,7 @@ pub enum Literal { } #[allow(non_camel_case_types)] -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum NumberBinarySuffix { n, u, @@ -1084,7 +1084,7 @@ impl NumberBinarySuffix { } } -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum NumberLitValue { Int(i64), Float(f64), @@ -1096,7 +1096,7 @@ pub enum NumberLitValue { /// 1K /// 1Mi /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct NumberLit { pub binary_suffix: Option, pub value: NumberLitValue, @@ -1107,7 +1107,7 @@ pub struct NumberLit { /// "string literal" /// """long string literal""" /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct StringLit { pub is_long_string: bool, pub raw_value: String, @@ -1134,7 +1134,7 @@ impl TryFrom for StringLit { /// None /// Undefined /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum NameConstant { True, False, @@ -1175,13 +1175,13 @@ impl TryFrom for NameConstant { } } -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct NameConstantLit { pub value: NameConstant, } /// JoinedString, e.g. abc in the string interpolation "${var1} abc ${var2}" -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct JoinedString { pub is_long_string: bool, pub values: Vec>, @@ -1189,7 +1189,7 @@ pub struct JoinedString { } /// FormattedValue, e.g. var1 and var2 in the string interpolation "${var1} abc ${var2}" -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct FormattedValue { pub is_long_string: bool, pub value: NodeRef, @@ -1197,14 +1197,14 @@ pub struct FormattedValue { } /// MissingExpr placeholder for error recovery. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct MissingExpr; /// Comment, e.g. /// ```kcl /// # This is a comment /// ``` -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct Comment { pub text: String, } @@ -1214,7 +1214,7 @@ pub struct Comment { */ /// BinOp is the set of all binary operators in KCL. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum BinOp { /// The `+` operator (addition) Add, @@ -1291,7 +1291,7 @@ impl BinOp { } /// BinOp is the set of all argument operators in KCL. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum AugOp { // The `=` operator (assign) Assign, @@ -1364,7 +1364,7 @@ impl TryInto for AugOp { } /// UnaryOp is the set of all unary operators in KCL. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum UnaryOp { /// The `+` operator for positive UAdd, @@ -1388,7 +1388,7 @@ impl UnaryOp { } /// CmpOp is the set of all comparison operators in KCL. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum CmpOp { /// The `==` operator (equality) Eq, @@ -1449,14 +1449,14 @@ impl CmpOp { } /// BinOrCmpOp is the set of all binary and comparison operators in KCL. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum BinOrCmpOp { Bin(BinOp), Cmp(CmpOp), } /// BinOrAugOp is the set of all binary and argument operators in KCL. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum BinOrAugOp { Bin(BinOp), Aug(AugOp), @@ -1465,14 +1465,14 @@ pub enum BinOrAugOp { /// ExprContext represents the location information of the AST node. /// The left side of the assignment symbol represents `Store`, /// and the right side represents `Load`. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum ExprContext { Load, Store, } /// A expression -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum Type { Any, Named(Identifier), @@ -1483,7 +1483,7 @@ pub enum Type { Literal(LiteralType), } -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum BasicType { Bool, Int, @@ -1491,23 +1491,23 @@ pub enum BasicType { Str, } -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct ListType { pub inner_type: Option>, } -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct DictType { pub key_type: Option>, pub value_type: Option>, } -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct UnionType { pub type_elements: Vec>, } -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum LiteralType { Bool(bool), Int(i64, Option), // value + suffix diff --git a/kclvm/sema/src/lint/lints_def.rs b/kclvm/sema/src/lint/lints_def.rs index d2d778d6f..637bad30e 100644 --- a/kclvm/sema/src/lint/lints_def.rs +++ b/kclvm/sema/src/lint/lints_def.rs @@ -99,17 +99,19 @@ impl LintPass for UnusedImport { let scope_objs = &scope.elems; for (_, scope_obj) in scope_objs { let scope_obj = scope_obj.borrow(); - if let ScopeObjectKind::Module(_) = &scope_obj.kind { + if let ScopeObjectKind::Module(m) = &scope_obj.kind { if !scope_obj.used { - handler.add_warning( - WarningKind::UnusedImportWarning, - &[Message { - range: scope_obj.get_span_pos(), - style: Style::Line, - message: format!("Module '{}' imported but unused", scope_obj.name), - note: Some("Consider removing this statement".to_string()), - }], - ); + for stmt in &m.import_stmts { + handler.add_warning( + WarningKind::UnusedImportWarning, + &[Message { + range: stmt.get_span_pos(), + style: Style::Line, + message: format!("Module '{}' imported but unused", scope_obj.name), + note: Some("Consider removing this statement".to_string()), + }], + ); + } } } } diff --git a/kclvm/sema/src/resolver/import.rs b/kclvm/sema/src/resolver/import.rs index 1927d64b4..ade7b75cb 100644 --- a/kclvm/sema/src/resolver/import.rs +++ b/kclvm/sema/src/resolver/import.rs @@ -111,6 +111,15 @@ impl<'ctx> Resolver<'ctx> { let is_user_module = match scope.elems.get(&import_stmt.path) { Some(scope_obj) => { let mut obj = scope_obj.borrow_mut(); + match &mut obj.kind { + ScopeObjectKind::Module(m) => { + m.import_stmts.push(stmt.clone()) + }, + _ => bug!( + "invalid module type in the import check function {}", + scope_obj.borrow().ty.ty_str() + ) + } match &obj.ty.kind { TypeKind::Module(module_ty) => { let mut module_ty = module_ty.clone(); @@ -152,6 +161,7 @@ impl<'ctx> Resolver<'ctx> { Some(name) => name.clone(), None => import_stmt.name.clone(), }; + scope.elems.insert( name.clone(), Rc::new(RefCell::new(ScopeObject { @@ -160,10 +170,7 @@ impl<'ctx> Resolver<'ctx> { end: end.clone(), ty: Rc::new(ty.clone()), kind: ScopeObjectKind::Module(Module { - path: import_stmt.path.clone(), - rawpath: import_stmt.rawpath.clone(), - name: import_stmt.name.clone(), - asname: import_stmt.asname.clone(), + import_stmts: vec![stmt.clone()], }), used: true, doc: None, @@ -177,15 +184,13 @@ impl<'ctx> Resolver<'ctx> { end, ty: Rc::new(ty), kind: ScopeObjectKind::Module(Module { - path: import_stmt.path.clone(), - rawpath: import_stmt.rawpath.clone(), - name: import_stmt.name.clone(), - asname: import_stmt.asname.clone(), + import_stmts: vec![stmt.clone()], }), used: false, doc: None, })), ); + matches!(kind, ModuleKind::User) } }; diff --git a/kclvm/sema/src/resolver/scope.rs b/kclvm/sema/src/resolver/scope.rs index d0c98426e..e127d1805 100644 --- a/kclvm/sema/src/resolver/scope.rs +++ b/kclvm/sema/src/resolver/scope.rs @@ -1,6 +1,9 @@ use anyhow::bail; use compiler_base_session::Session; use indexmap::{IndexMap, IndexSet}; +use kclvm_ast::ast::NodeRef; +use kclvm_ast::ast::Stmt; +use kclvm_ast::ast::Stmt::Import; use kclvm_ast::{ast, MAIN_PKG}; use kclvm_error::diagnostic::Range; use kclvm_error::{Handler, Level}; @@ -78,10 +81,7 @@ pub enum ScopeObjectKind { /// is used to record information on the AST #[derive(PartialEq, Clone, Debug)] pub struct Module { - pub path: String, - pub rawpath: String, - pub name: String, - pub asname: Option, + pub import_stmts: Vec>, } /// A Scope maintains a set of objects and links to its containing @@ -135,7 +135,11 @@ impl Scope { for (name, obj) in &self.elems { match &obj.borrow().kind { ScopeObjectKind::Module(module) => { - res.insert(module.name.clone(), obj.clone()); + for stmt in &module.import_stmts { + if let Import(import_stmt) = &stmt.node { + res.insert(import_stmt.name.clone(), obj.clone()); + } + } } _ => { res.insert(name.clone(), obj.clone()); diff --git a/kclvm/tools/src/LSP/src/completion.rs b/kclvm/tools/src/LSP/src/completion.rs index c727062c2..811c170fd 100644 --- a/kclvm/tools/src/LSP/src/completion.rs +++ b/kclvm/tools/src/LSP/src/completion.rs @@ -101,9 +101,16 @@ fn completion_variable(pos: &KCLPos, prog_scope: &ProgramScope) -> IndexSet { - completions.insert(KCLCompletionItem { - label: module.name.clone(), - }); + for stmt in &module.import_stmts { + match &stmt.node { + Stmt::Import(import_stmtt) => { + completions.insert(KCLCompletionItem { + label: import_stmtt.name.clone(), + }); + } + _ => {} + } + } } _ => { completions.insert(KCLCompletionItem { label: name }); diff --git a/kclvm/tools/src/lint/test_data/lint.k b/kclvm/tools/src/lint/test_data/lint.k index 41436a31a..9e2fc7327 100644 --- a/kclvm/tools/src/lint/test_data/lint.k +++ b/kclvm/tools/src/lint/test_data/lint.k @@ -2,6 +2,7 @@ import import_test.a # UnusedImport import import_test.a # ReImport import abc + schema Person: name: str age: int diff --git a/kclvm/tools/src/lint/tests.rs b/kclvm/tools/src/lint/tests.rs index 883e58bc7..220e5e4bd 100644 --- a/kclvm/tools/src/lint/tests.rs +++ b/kclvm/tools/src/lint/tests.rs @@ -8,6 +8,7 @@ fn test_lint() { "Importstmt should be placed at the top of the module", "Module 'a' is reimported multiple times", "Module 'import_test.a' imported but unused", + "Module 'import_test.a' imported but unused", "Module 'abc' imported but unused", ]; assert_eq!(warnings.len(), msgs.len());