Skip to content

Commit

Permalink
fix: fix failed test case
Browse files Browse the repository at this point in the history
Signed-off-by: zongz <[email protected]>
  • Loading branch information
zong-zhe committed Oct 11, 2023
1 parent e22d10d commit add7585
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 49 deletions.
5 changes: 4 additions & 1 deletion kclvm/sema/src/resolver/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ impl<'ctx> Resolver<'ctx> {
}
}

fn init_scope_with_assign_stmt(
pub fn init_scope_with_assign_stmt(
&mut self,
assign_stmt: &'ctx ast::AssignStmt,
unique_check: bool,
Expand All @@ -227,6 +227,9 @@ impl<'ctx> Resolver<'ctx> {
}
let name = &target.node.names[0].node;
let (start, end) = target.get_span_pos();
if !unique_check && self.contains_object(name) {
continue;
}
if self.contains_object(name) && !is_private_field(name) && unique_check {
self.handler.add_error(
ErrorKind::ImmutableError,
Expand Down
58 changes: 12 additions & 46 deletions kclvm/sema/src/resolver/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::rc::Rc;

use crate::info::is_private_field;
use crate::ty::{
is_upper_bound, sup, DictType, FunctionType, Parameter, Type, TypeInferMethods, TypeKind,
sup, DictType, FunctionType, Parameter, Type, TypeInferMethods, TypeKind,
RESERVED_TYPE_IDENTIFIERS,
};

Expand Down Expand Up @@ -185,51 +185,6 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> {
self.ctx.ty_ctx.infer_to_variable_type(value_ty.clone()),
);
}
// If the assign statement has a type annotation like: `a: str = "test_str"`,
} else if assign_stmt.type_annotation.is_some() {
// Get the type annotation.
if let Some(ty_annotation) = &assign_stmt.ty {
let annotation_ty = self
.parse_ty_with_scope(&ty_annotation.node, ty_annotation.get_span_pos());
// Set the type annotation as the target type.
self.set_type_to_scope(name, annotation_ty.clone(), target.get_span_pos());
// Check the type of target whether is upper bound of the type annotation.
if let Some(obj) = self.scope.borrow().elems.get(name) {
let obj = obj.borrow();
if !is_upper_bound(obj.ty.clone(), annotation_ty.clone()) {
self.handler.add_error(
ErrorKind::TypeError,
&[
Message {
range: target.get_span_pos(),
style: Style::LineAndColumn,
message: format!(
"can not change the type of '{}' to {}",
name,
annotation_ty.ty_str()
),
note: None,
suggested_replacement: None,
},
Message {
range: obj.get_span_pos(),
style: Style::LineAndColumn,
message: format!("expected {}", obj.ty.ty_str()),
note: None,
suggested_replacement: None,
},
],
);
}
}
// Check the type of value and the type annotation of target
self.must_assignable_to(
value_ty.clone(),
annotation_ty,
target.get_span_pos(),
None,
)
}
}
} else {
self.lookup_type_from_scope(name, target.get_span_pos());
Expand All @@ -240,6 +195,9 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> {
self.must_assignable_to(value_ty.clone(), expected_ty, target.get_span_pos(), None)
}
}
// Check type annotation if exists.
self.check_assignment_type_annotation(assign_stmt, value_ty.clone());

value_ty
}

Expand Down Expand Up @@ -1026,6 +984,14 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> {
);
}
}

// In the scope of lambda body, init the scope for assign stmt
for stmt in &lambda_expr.body {
if let ast::Stmt::Assign(assign_stmt) = &stmt.node {
self.init_scope_with_assign_stmt(assign_stmt, false)
}
}

let real_ret_ty = self.stmts(&lambda_expr.body);
self.leave_scope();
self.ctx.in_lambda_expr.pop();
Expand Down
16 changes: 16 additions & 0 deletions kclvm/sema/src/resolver/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -539,3 +539,19 @@ fn test_resolve_assignment_in_lambda() {
let images_scope_obj = lambda_scope.borrow().elems.get("images").unwrap().clone();
assert_eq!(images_scope_obj.borrow().ty.ty_str(), "[str]");
}

// #[test]
// fn test_xxxx() {
// let sess = Arc::new(ParseSession::default());
// let mut program = load_program(
// sess.clone(),
// &["/Users/zongz/Workspace/kusionstack/KCLVM/kclvm/tools/src/LSP/src/test_data/hover_test/assign_in_lambda.k"],
// // &["/Users/zongz/Workspace/kusionstack/KCLVM/kclvm/tools/src/LSP/src/test_data/goto_def_test/goto_def copy.k"],
// None,
// )
// .unwrap();
// let scope = resolve_program(&mut program);
// let main_scope = scope.scope_map.get("__main__").unwrap().clone();
// println!("{:?}", main_scope.borrow().children);
// println!("{:?}", main_scope.borrow().elems);
// }
62 changes: 61 additions & 1 deletion kclvm/sema/src/resolver/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::rc::Rc;

use crate::resolver::Resolver;
use crate::ty::parser::parse_type_str;
use crate::ty::{assignable_to, Attr, DictType, SchemaType, Type, TypeKind};
use crate::ty::{assignable_to, is_upper_bound, Attr, DictType, SchemaType, Type, TypeKind};
use indexmap::IndexMap;
use kclvm_ast::ast;
use kclvm_ast::pos::GetPos;
Expand Down Expand Up @@ -118,6 +118,66 @@ impl<'ctx> Resolver<'ctx> {
}
}

/// Check the type assignment statement between type annotation and target.
pub fn check_assignment_type_annotation(
&mut self,
assign_stmt: &kclvm_ast::ast::AssignStmt,
value_ty: Rc<Type>,
) {
if assign_stmt.type_annotation.is_none() {
return;
}
for target in &assign_stmt.targets {
if target.node.names.is_empty() {
continue;
}
let name = &target.node.names[0].node;
// If the assignment statement has type annotation, check the type of value and the type annotation of target

if let Some(ty_annotation) = &assign_stmt.ty {
let annotation_ty =
self.parse_ty_with_scope(&ty_annotation.node, ty_annotation.get_span_pos());
// If the target defined in the scope, check the type of value and the type annotation of target
let target_ty = if let Some(obj) = self.scope.borrow().elems.get(name) {
let obj = obj.borrow();
if !is_upper_bound(obj.ty.clone(), annotation_ty.clone()) {
self.handler.add_error(
ErrorKind::TypeError,
&[
Message {
range: target.get_span_pos(),
style: Style::LineAndColumn,
message: format!(
"can not change the type of '{}' to {}",
name,
annotation_ty.ty_str()
),
note: None,
suggested_replacement: None,
},
Message {
range: obj.get_span_pos(),
style: Style::LineAndColumn,
message: format!("expected {}", obj.ty.ty_str()),
note: None,
suggested_replacement: None,
},
],
);
}
obj.ty.clone()
} else {
annotation_ty
};

self.set_type_to_scope(name, target_ty.clone(), target.get_span_pos());

// Check the type of value and the type annotation of target
self.must_assignable_to(value_ty.clone(), target_ty, target.get_span_pos(), None)
}
}
}

/// The check type main function, returns a boolean result.
#[inline]
pub fn check_type(&mut self, ty: Rc<Type>, expected_ty: Rc<Type>, range: &Range) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion kclvm/tools/src/LSP/src/test_data/goto_def_test/goto_def.k
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ schema Reviewer:
teams?: [int]
users?: [int]

reviewers: [Reviewer] = [{team: [1]}]
reviewers: [Reviewer] = [Reviewer {teams: [1]}]

schema Fib:
n1 = n - 1
Expand Down

0 comments on commit add7585

Please sign in to comment.