Skip to content

Commit

Permalink
Goto: all expressions #13
Browse files Browse the repository at this point in the history
  • Loading branch information
SpontanCombust committed May 20, 2024
1 parent 5d4bc2e commit 131014f
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 95 deletions.
100 changes: 39 additions & 61 deletions crates/lsp/src/providers/common.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::{cell::RefCell, rc::Rc};
use tower_lsp::lsp_types as lsp;
use witcherscript::{ast::*, script_document::ScriptDocument, tokens::*};
use witcherscript_analysis::symbol_analysis::symbol_table::marcher::SymbolTableMarcher;
use witcherscript_analysis::symbol_analysis::{symbol_path::SymbolPathBuf, unqualified_name_lookup::UnqualifiedNameLookup};
use witcherscript_analysis::utils::{PositionFilterPayload, SymbolPathBuilderPayload};
use witcherscript_analysis::utils::{evaluate_expression, PositionFilterPayload, SymbolPathBuilderPayload};


/// A node visitor that can resolve a code identifier/symbol if a specified position points to such.
Expand All @@ -11,6 +12,7 @@ pub(super) struct TextDocumentPositionResolver<'a> {
pos: lsp::Position,
doc: &'a ScriptDocument,
pos_filter_payload: Rc<RefCell<PositionFilterPayload>>,
symtab_marcher: SymbolTableMarcher<'a>,
sympath_builder_payload: Rc<RefCell<SymbolPathBuilderPayload>>,
unl_builder_payload: Rc<RefCell<UnqualifiedNameLookup>>,
pub found_target: Option<PositionTarget>
Expand All @@ -20,8 +22,7 @@ pub(super) struct TextDocumentPositionResolver<'a> {
pub(super) struct PositionTarget {
pub range: lsp::Range,
pub kind: PositionTargetKind,
pub sympath_ctx: SymbolPathBuf,
pub unl_ctx: UnqualifiedNameLookup
pub sympath_ctx: SymbolPathBuf
}

#[derive(Debug, Clone)]
Expand All @@ -33,13 +34,7 @@ pub(super) enum PositionTargetKind {
DataDeclarationNameIdentifier(String),
CallableDeclarationNameIdentifier, // more info can be fetched using sympath_ctx

// unqualified - a freely present identifier in the code
UnqualifiedDataIdentifier(String),
UnqualifiedCallableIdentifier(String),

// qualified - an identifier with an additional context of an accessor from `MemberFieldExpression`
QualifiedDataIdentifier(String),
QualifiedCallableIdentifier(String),
ExpressionIdentifier(SymbolPathBuf),

ThisKeyword,
SuperKeyword,
Expand All @@ -52,13 +47,15 @@ impl<'a> TextDocumentPositionResolver<'a> {
pos: lsp::Position,
doc: &'a ScriptDocument,
pos_filter_payload: Rc<RefCell<PositionFilterPayload>>,
symtab_marcher: SymbolTableMarcher<'a>,
sympath_builder_payload: Rc<RefCell<SymbolPathBuilderPayload>>,
unl_builder_payload: Rc<RefCell<UnqualifiedNameLookup>>
) -> Rc<RefCell<Self>> {
Rc::new(RefCell::new(Self {
pos,
doc,
pos_filter_payload,
symtab_marcher,
sympath_builder_payload,
unl_builder_payload,
found_target: None
Expand All @@ -71,7 +68,7 @@ impl<'a> TextDocumentPositionResolver<'a> {
range: n.range(),
kind: PositionTargetKind::TypeIdentifier(n.value(self.doc).to_string()),
sympath_ctx: self.sympath_builder_payload.borrow().current_sympath.clone(),
unl_ctx: self.unl_builder_payload.borrow().clone()

});
}

Expand All @@ -80,7 +77,7 @@ impl<'a> TextDocumentPositionResolver<'a> {
range: name.range(),
kind: PositionTargetKind::StateDeclarationNameIdentifier,
sympath_ctx: self.sympath_builder_payload.borrow().current_sympath.clone(),
unl_ctx: self.unl_builder_payload.borrow().clone()

});
}

Expand All @@ -89,7 +86,7 @@ impl<'a> TextDocumentPositionResolver<'a> {
range: base.range(),
kind: PositionTargetKind::StateDeclarationBaseIdentifier,
sympath_ctx: self.sympath_builder_payload.borrow().current_sympath.clone(),
unl_ctx: self.unl_builder_payload.borrow().clone()

});
}

Expand All @@ -98,7 +95,7 @@ impl<'a> TextDocumentPositionResolver<'a> {
range: n.range(),
kind: PositionTargetKind::DataDeclarationNameIdentifier(n.value(self.doc).to_string()),
sympath_ctx: self.sympath_builder_payload.borrow().current_sympath.clone(),
unl_ctx: self.unl_builder_payload.borrow().clone()

});
}

Expand All @@ -107,43 +104,23 @@ impl<'a> TextDocumentPositionResolver<'a> {
range: n.range(),
kind: PositionTargetKind::CallableDeclarationNameIdentifier,
sympath_ctx: self.sympath_builder_payload.borrow().current_sympath.clone(),
unl_ctx: self.unl_builder_payload.borrow().clone()

});
}

fn found_unqualified_data_ident(&mut self, n: &IdentifierNode) {
self.found_target = Some(PositionTarget {
range: n.range(),
kind: PositionTargetKind::UnqualifiedDataIdentifier(n.value(self.doc).to_string()),
sympath_ctx: self.sympath_builder_payload.borrow().current_sympath.clone(),
unl_ctx: self.unl_builder_payload.borrow().clone()
});
}

fn found_unqualified_callable_ident(&mut self, n: &IdentifierNode) {
self.found_target = Some(PositionTarget {
range: n.range(),
kind: PositionTargetKind::UnqualifiedCallableIdentifier(n.value(self.doc).to_string()),
sympath_ctx: self.sympath_builder_payload.borrow().current_sympath.clone(),
unl_ctx: self.unl_builder_payload.borrow().clone()
});
}

fn found_qualified_data_ident(&mut self, n: &IdentifierNode) {
self.found_target = Some(PositionTarget {
range: n.range(),
kind: PositionTargetKind::QualifiedDataIdentifier(n.value(self.doc).to_string()),
sympath_ctx: self.sympath_builder_payload.borrow().current_sympath.clone(),
unl_ctx: self.unl_builder_payload.borrow().clone()
});
}
fn found_expression_ident(&mut self, n: &IdentifierNode, expr: ExpressionNode, ctx: Option<ExpressionTraversalContext>) {
let expr_typ = evaluate_expression(
expr, ctx,
self.doc,
self.symtab_marcher.clone(),
self.sympath_builder_payload.clone(),
self.unl_builder_payload.clone()
);

fn found_qualified_callable_ident(&mut self, n: &IdentifierNode) {
self.found_target = Some(PositionTarget {
range: n.range(),
kind: PositionTargetKind::QualifiedCallableIdentifier(n.value(self.doc).to_string()),
kind: PositionTargetKind::ExpressionIdentifier(expr_typ),
sympath_ctx: self.sympath_builder_payload.borrow().current_sympath.clone(),
unl_ctx: self.unl_builder_payload.borrow().clone()
});
}

Expand All @@ -152,7 +129,6 @@ impl<'a> TextDocumentPositionResolver<'a> {
range: n.range(),
kind: PositionTargetKind::ThisKeyword,
sympath_ctx: self.sympath_builder_payload.borrow().current_sympath.clone(),
unl_ctx: self.unl_builder_payload.borrow().clone()
});
}

Expand All @@ -161,7 +137,6 @@ impl<'a> TextDocumentPositionResolver<'a> {
range: n.range(),
kind: PositionTargetKind::SuperKeyword,
sympath_ctx: self.sympath_builder_payload.borrow().current_sympath.clone(),
unl_ctx: self.unl_builder_payload.borrow().clone()
});
}

Expand All @@ -170,7 +145,6 @@ impl<'a> TextDocumentPositionResolver<'a> {
range: n.range(),
kind: PositionTargetKind::ParentKeyword,
sympath_ctx: self.sympath_builder_payload.borrow().current_sympath.clone(),
unl_ctx: self.unl_builder_payload.borrow().clone()
});
}

Expand All @@ -179,7 +153,6 @@ impl<'a> TextDocumentPositionResolver<'a> {
range: n.range(),
kind: PositionTargetKind::VirtualParentKeyword,
sympath_ctx: self.sympath_builder_payload.borrow().current_sympath.clone(),
unl_ctx: self.unl_builder_payload.borrow().clone()
});
}

Expand Down Expand Up @@ -301,7 +274,8 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> {
let member = n.member();

if member.spans_position(self.pos) {
self.found_unqualified_data_ident(&member);
// self.found_unqualified_data_ident(&member);
self.found_expression_ident(&member, member.clone().into(), None);
}
}

Expand All @@ -313,7 +287,8 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> {
let member = n.member();

if member.spans_position(self.pos) {
self.found_unqualified_data_ident(&member);
// self.found_unqualified_data_ident(&member);
self.found_expression_ident(&member, member.clone().into(), None);
}
}

Expand All @@ -324,7 +299,8 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> {
let member = n.member();

if member.spans_position(self.pos) {
self.found_unqualified_data_ident(&member);
// self.found_unqualified_data_ident(&member);
self.found_expression_ident(&member, member.clone().into(), None);
}
}

Expand Down Expand Up @@ -419,23 +395,25 @@ impl SyntaxNodeVisitor for TextDocumentPositionResolver<'_> {
}

fn visit_identifier_expr(&mut self, n: &IdentifierNode, cx: ExpressionTraversalContext) {
if cx == ExpressionTraversalContext::FunctionCallExpressionFunc {
self.found_unqualified_callable_ident(n);
} else {
self.found_unqualified_data_ident(n);
};
// if cx == ExpressionTraversalContext::FunctionCallExpressionFunc {
// self.found_unqualified_callable_ident(n);
// } else {
// self.found_unqualified_data_ident(n);
// };
self.found_expression_ident(n, n.clone().into(), Some(cx));
}

fn visit_member_field_expr(&mut self, n: &MemberFieldExpressionNode, cx: ExpressionTraversalContext) -> MemberFieldExpressionTraversalPolicy {
if self.pos_filter_payload.borrow().done {
let member = n.member();

if member.spans_position(self.pos) {
if cx == ExpressionTraversalContext::FunctionCallExpressionFunc {
self.found_qualified_callable_ident(&member);
} else {
self.found_qualified_data_ident(&member);
};
// if cx == ExpressionTraversalContext::FunctionCallExpressionFunc {
// self.found_qualified_callable_ident(&member);
// } else {
// self.found_qualified_data_ident(&member);
// };
self.found_expression_ident(&member, n.clone().into(), Some(cx));
}
}

Expand Down
58 changes: 24 additions & 34 deletions crates/lsp/src/providers/goto.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use std::str::FromStr;
use tower_lsp::lsp_types as lsp;
use tower_lsp::jsonrpc::Result;
use abs_path::AbsPath;
use witcherscript::ast::SyntaxNodeVisitorChain;
use witcherscript::tokens::Keyword;
use witcherscript_analysis::symbol_analysis::symbol_table::{SymbolLocation, marcher::{SymbolTableMarcher, IntoSymbolTableMarcher}};
use witcherscript_analysis::symbol_analysis::symbol_path::SymbolPathBuf;
use witcherscript_analysis::symbol_analysis::symbols::*;
Expand Down Expand Up @@ -190,39 +188,30 @@ async fn inspect_symbol_at_position(backend: &Backend, content_path: &AbsPath, d
.and_then(|v| v.try_as_special_var_ref())
.map(|sym| sym.type_path().clone())
},
PositionTargetKind::UnqualifiedDataIdentifier(name) => {
if Keyword::from_str(&name).map(|kw| kw.is_global_var()).unwrap_or(false) {
symtabs_marcher.clone()
.get(&SymbolPathBuf::new(&name, SymbolCategory::Data))
.and_then(|v| v.try_as_global_var_ref())
.map(|sym| sym.type_path().clone())
}
else if let Some(path) = position_target.unl_ctx.get(&name, SymbolCategory::Data) {
Some(path.to_owned())
}
else {
Some(GlobalDataSymbolPath::new(&name).into())
}
}
PositionTargetKind::UnqualifiedCallableIdentifier(name) => {
if let Some(path) = position_target.unl_ctx.get(&name, SymbolCategory::Callable) {
Some(path.to_owned())
}
else {
Some(GlobalCallableSymbolPath::new(&name).into())
}
}
// other stuff not reliably possible yet
//TODO expression evaluator
_ => {
None
PositionTargetKind::ExpressionIdentifier(expr_type_path) => {
Some(expr_type_path)
}
};

let (symvar, loc) = sympath
.and_then(|sympath| symtabs_marcher.get_with_location(&sympath))
.map(|(symvar, loc)| (symvar.to_owned(), loc))
.unzip();
let symvar = sympath
.and_then(|sympath| symtabs_marcher.clone().get(&sympath))
.and_then(|symvar| {
let rerouted_path = match symvar {
SymbolVariant::Constructor(s) => Some(s.parent_type_path.as_sympath()),
SymbolVariant::GlobalVar(s) => Some(s.type_path().as_sympath()),
SymbolVariant::SpecialVar(s) => Some(s.type_path().as_sympath()),
_ => None
};

if let Some(rerouted_path) = rerouted_path {
symtabs_marcher.clone().get(rerouted_path)
} else {
Some(symvar)
}
})
.map(|symvar| symvar.to_owned());

let loc = symvar.as_ref().and_then(|symvar| symtabs_marcher.clone().locate(symvar.path()));

Some(Inspected {
origin_selection_range: position_target.range,
Expand All @@ -239,11 +228,12 @@ fn resolve_position<'a>(position: lsp::Position, script_state: &'a ScriptState,
detail_pos_filter.filter_statements = true;

let (sympath_builder, sympath_builder_payload) = SymbolPathBuilder::new(&script_state.buffer);
let (unl_builder, unl_payload) = UnqualifiedNameLookupBuilder::new(&script_state.buffer, sympath_builder_payload.clone(), symtab_marcher);
let (unl_builder, unl_payload) = UnqualifiedNameLookupBuilder::new(&script_state.buffer, sympath_builder_payload.clone(), symtab_marcher.clone());
let resolver = TextDocumentPositionResolver::new_rc(
position,
&script_state.buffer,
detail_pos_filter_payload.clone(),
detail_pos_filter_payload.clone(),
symtab_marcher,
sympath_builder_payload.clone(),
unl_payload.clone(),
);
Expand Down

0 comments on commit 131014f

Please sign in to comment.