Skip to content

Commit

Permalink
feat: find right value def from schema mixin and protocol (kcl-lang#1632
Browse files Browse the repository at this point in the history
)

Signed-off-by: he1pa <[email protected]>
  • Loading branch information
He1pa authored Sep 9, 2024
1 parent d5f4a27 commit d99b01f
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 58 deletions.
115 changes: 62 additions & 53 deletions kclvm/sema/src/core/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,65 +493,74 @@ impl Scope for LocalSymbolScope {
) -> Option<SymbolRef> {
match self.defs.get(name) {
Some(symbol_ref) => return Some(*symbol_ref),
None => match (local, get_def_from_owner) {
// Search in the current scope and owner
(true, true) => {
None => {
// Try to get the attributes in the schema's protocol and mixin, and get the schema attr by `get_def_from_owner`
if let LocalSymbolScopeKind::SchemaDef = self.kind {
if let Some(owner) = self.owner.as_ref() {
let owner_symbol = symbol_data.get_symbol(*owner)?;
if let Some(symbol_ref) =
owner_symbol.get_attribute(name, symbol_data, module_info)
{
return Some(symbol_ref);
if let Some(owner_schema) = symbol_data.get_schema_symbol(*owner) {
let attrs =
owner_schema.get_protocol_and_mixin_attrs(symbol_data, module_info);
for attr in attrs {
if let Some(symbol) = symbol_data.get_symbol(attr) {
if symbol.get_name() == name {
return Some(attr);
}
}
}
}
}
None
}
// Search only in the current scope
(true, false) => {
let parent = scope_data.get_scope(&self.parent)?;
return parent.look_up_def(
name,
scope_data,
symbol_data,
module_info,
local,
get_def_from_owner,
);
}
// Search in the current scope, parent scope and owner
(false, true) => {
if let Some(owner) = self.owner.as_ref() {
let owner_symbol = symbol_data.get_symbol(*owner)?;
if let Some(symbol_ref) =
owner_symbol.get_attribute(name, symbol_data, module_info)
{
return Some(symbol_ref);

match (local, get_def_from_owner) {
// Search in the current scope and owner
(true, true) => {
if let Some(owner) = self.owner.as_ref() {
let owner_symbol = symbol_data.get_symbol(*owner)?;
if let Some(symbol_ref) =
owner_symbol.get_attribute(name, symbol_data, module_info)
{
return Some(symbol_ref);
}
}
};

let parent = scope_data.get_scope(&self.parent)?;
return parent.look_up_def(
name,
scope_data,
symbol_data,
module_info,
local,
get_def_from_owner,
);
}
// Search in the current and parent scope
(false, false) => {
let parent = scope_data.get_scope(&self.parent)?;
return parent.look_up_def(
name,
scope_data,
symbol_data,
module_info,
local,
get_def_from_owner,
);
None
}
// Search only in the current scope
(true, false) => None,
// Search in the current scope, parent scope and owner
(false, true) => {
if let Some(owner) = self.owner.as_ref() {
let owner_symbol = symbol_data.get_symbol(*owner)?;
if let Some(symbol_ref) =
owner_symbol.get_attribute(name, symbol_data, module_info)
{
return Some(symbol_ref);
}
};

let parent = scope_data.get_scope(&self.parent)?;
return parent.look_up_def(
name,
scope_data,
symbol_data,
module_info,
local,
get_def_from_owner,
);
}
// Search in the current and parent scope
(false, false) => {
let parent = scope_data.get_scope(&self.parent)?;
return parent.look_up_def(
name,
scope_data,
symbol_data,
module_info,
local,
get_def_from_owner,
);
}
}
},
}
}
}

Expand Down
20 changes: 15 additions & 5 deletions kclvm/sema/src/core/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1253,16 +1253,12 @@ impl SchemaSymbol {
}
}

pub fn get_self_attr(
pub fn get_protocol_and_mixin_attrs(
&self,
data: &SymbolData,
module_info: Option<&ModuleInfo>,
) -> Vec<SymbolRef> {
let mut result = vec![];
for attribute in self.attributes.values() {
result.push(*attribute);
}

if let Some(for_host) = self.for_host {
if let Some(for_host) = data.get_symbol(for_host) {
result.append(&mut for_host.get_all_attributes(data, module_info))
Expand All @@ -1273,6 +1269,20 @@ impl SchemaSymbol {
result.append(&mut mixin.get_all_attributes(data, module_info))
}
}

result
}

pub fn get_self_attr(
&self,
data: &SymbolData,
module_info: Option<&ModuleInfo>,
) -> Vec<SymbolRef> {
let mut result = vec![];
for attribute in self.attributes.values() {
result.push(*attribute);
}
result.extend(self.get_protocol_and_mixin_attrs(data, module_info));
result
}
}
Expand Down
14 changes: 14 additions & 0 deletions kclvm/tools/src/LSP/src/goto_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,4 +551,18 @@ mod tests {
33,
10
);

goto_def_test_snapshot!(
goto_protocol_attr,
"src/test_data/goto_def_test/goto_protocol/goto_protocol.k",
6,
17
);

goto_def_test_snapshot!(
goto_protocol_attr_1,
"src/test_data/goto_def_test/goto_protocol/goto_protocol.k",
8,
13
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: tools/src/LSP/src/goto_def.rs
expression: "format!(\"{:?}\", { fmt_resp(& res) })"
---
"path: \"src/test_data/goto_def_test/goto_protocol/goto_protocol.k\", range: Range { start: Position { line: 1, character: 4 }, end: Position { line: 1, character: 8 } }"
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: tools/src/LSP/src/goto_def.rs
expression: "format!(\"{:?}\", { fmt_resp(& res) })"
---
"path: \"src/test_data/goto_def_test/goto_protocol/goto_protocol.k\", range: Range { start: Position { line: 1, character: 4 }, end: Position { line: 1, character: 8 } }"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
protocol AProtocol:
name?: str

mixin AMixin for AProtocol:
config = {
data = name
}
data = name

0 comments on commit d99b01f

Please sign in to comment.