Skip to content

Commit

Permalink
Reworked RedefinitionChain and renamed it back to AnnotationChain
Browse files Browse the repository at this point in the history
…; fixed minor bugs
  • Loading branch information
SpontanCombust committed Aug 21, 2024
1 parent 5341fec commit 7e15b56
Show file tree
Hide file tree
Showing 6 changed files with 270 additions and 94 deletions.
2 changes: 1 addition & 1 deletion crates/analysis/src/jobs/scan_symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ impl SyntaxNodeVisitor for SymbolScannerVisitor<'_> {
}
},
(Ok(AnnotationKind::ReplaceMethod), Some(class_name)) => {
let path = MemberCallableWrapperSymbolPath::new(&class_name, &func_name);
let path = MemberCallableReplacerSymbolPath::new(&class_name, &func_name);
if self.check_contains(&path, name_node.range(), SymbolType::MemberFunctionReplacer) {
let (loc, specs, flav, rt) = self.parse_member_function(n);
let mut sym = MemberFunctionReplacerSymbol::new(path, loc);
Expand Down
100 changes: 79 additions & 21 deletions crates/analysis/src/symbol_analysis/symbol_table/marcher.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use witcherscript_project::SourceMask;
use crate::symbol_analysis::symbol_path::{SymbolPath, SymbolPathBuf};
use super::{ClassSymbol, PathOccupiedError, StateSymbol, Symbol, SymbolTable, SymbolVariant};
use super::*;


/// A type that can perform data fetching operations on many symbol tables
Expand Down Expand Up @@ -121,13 +121,16 @@ impl<'a> SymbolTableMarcher<'a> {
StateHierarchy::new(self.clone(), state_path)
}

/// Iterate over symbols with the same symbol path accross the marcher.
/// Normally a path conflict (i.e. redefinition) in the dependency tree means an error.
/// It is not the case with @wrapMethod/@replaceMethod symbols however.
/// This way you can check for example the location of the wrapped method.
/// Iterate over callable symbols in the annotation chain accross the marcher.
#[inline]
pub fn redefinition_chain(&self, annotated_sympath: &SymbolPath) -> RedefinitionChain<'a> {
RedefinitionChain::new(self.clone(), annotated_sympath)
pub fn annotation_chain_for_member_callable(&self, member_callable_sympath: &MemberCallableSymbolPath) -> AnnotationChain<'a> {
AnnotationChain::for_member_callable(self.clone(), member_callable_sympath)
}

/// Iterate over callable symbols in the annotation chain accross the marcher.
#[inline]
pub fn annotation_chain_for_global_callable(&self, global_callable_sympath: &GlobalCallableSymbolPath) -> AnnotationChain<'a> {
AnnotationChain::for_global_callable(self.clone(), global_callable_sympath)
}


Expand Down Expand Up @@ -304,35 +307,90 @@ impl<'a> Iterator for StateHierarchy<'a> {



pub struct RedefinitionChain<'a> {
sympath: SymbolPathBuf,
pub struct AnnotationChain<'a> {
symtabs: Vec<MaskedSymbolTable<'a>>,
idx: usize,
symtab_idx: usize,

regular_sympath: SymbolPathBuf,
replaced_sympath: SymbolPathBuf,
wrapped_sympath: Option<SymbolPathBuf>,

regular_visited: bool,
replaced_visited: bool,
wrapped_visited: bool
}

impl<'a> RedefinitionChain<'a> {
fn new(marcher: SymbolTableMarcher<'a>, path: &SymbolPath) -> Self {
impl<'a> AnnotationChain<'a> {
fn for_member_callable(marcher: SymbolTableMarcher<'a>, path: &MemberCallableSymbolPath) -> Self {
Self {
sympath: path.to_owned(),
symtabs: marcher.inner,
idx: 0
symtab_idx: 0,

regular_sympath: path.to_owned().into(),
replaced_sympath: MemberCallableReplacerSymbolPath::from(path.to_owned()).into(),
wrapped_sympath: Some(MemberCallableWrapperSymbolPath::from(path.to_owned()).into()),

regular_visited: false,
replaced_visited: false,
wrapped_visited: false
}
}

fn for_global_callable(marcher: SymbolTableMarcher<'a>, path: &GlobalCallableSymbolPath) -> Self {
Self {
symtabs: marcher.inner,
symtab_idx: 0,

regular_sympath: path.to_owned().into(),
replaced_sympath: GlobalCallableReplacerSymbolPath::from(path.to_owned()).into(),
wrapped_sympath: None,

regular_visited: false,
replaced_visited: false,
wrapped_visited: false
}
}
}

impl<'a> Iterator for RedefinitionChain<'a> {
impl<'a> Iterator for AnnotationChain<'a> {
type Item = &'a SymbolVariant;

fn next(&mut self) -> Option<Self::Item> {
while self.idx < self.symtabs.len() {
let symvar = self.symtabs[self.idx]
.get_symbol(&self.sympath);
while self.symtab_idx < self.symtabs.len() {
if !self.wrapped_visited {
self.wrapped_visited = true;
if let Some(wrapped_sympath) = &self.wrapped_sympath {
let symvar = self.symtabs[self.symtab_idx].get_symbol(wrapped_sympath);

if symvar.is_some() {
return symvar;
}
}
}

if !self.replaced_visited {
self.replaced_visited = true;
let symvar = self.symtabs[self.symtab_idx].get_symbol(&self.replaced_sympath);

self.idx += 1;
if symvar.is_some() {
return symvar;
}
}

if !self.regular_visited {
self.regular_visited = true;
let symvar = self.symtabs[self.symtab_idx].get_symbol(&self.regular_sympath);

if symvar.is_some() {
return symvar;
if symvar.is_some() {
return symvar;
}
}

self.wrapped_visited = false;
self.replaced_visited = false;
self.regular_visited = false;

self.symtab_idx += 1;
}

None
Expand Down
25 changes: 20 additions & 5 deletions crates/analysis/src/symbol_analysis/symbols/annotated_symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ impl MemberFunctionInjectorSymbol {
/// Corresponding to @replaceMethod(Class) functions
#[derive(Debug, Clone)]
pub struct MemberFunctionReplacerSymbol {
path: MemberCallableWrapperSymbolPath,
path: MemberCallableReplacerSymbolPath,
location: SymbolLocation,
pub specifiers: SymbolSpecifiers<MemberFunctionSpecifier>,
pub flavour: Option<MemberFunctionFlavour>,
pub return_type_path: TypeSymbolPath
}

impl Symbol for MemberFunctionReplacerSymbol {
type PathType = MemberCallableWrapperSymbolPath;
type PathType = MemberCallableReplacerSymbolPath;

fn typ(&self) -> SymbolType {
SymbolType::MemberFunctionReplacer
Expand All @@ -81,7 +81,7 @@ impl LocatableSymbol for MemberFunctionReplacerSymbol {
impl PrimarySymbol for MemberFunctionReplacerSymbol { }

impl MemberFunctionReplacerSymbol {
pub fn new(path: MemberCallableWrapperSymbolPath, location: SymbolLocation) -> Self {
pub fn new(path: MemberCallableReplacerSymbolPath, location: SymbolLocation) -> Self {
Self {
path,
location,
Expand All @@ -94,6 +94,11 @@ impl MemberFunctionReplacerSymbol {
pub fn return_type_name(&self) -> &str {
self.return_type_path.components().next().map(|c| c.name).unwrap_or_default()
}

#[inline]
pub fn function_name(&self) -> &str {
self.path.function_name()
}
}


Expand Down Expand Up @@ -142,6 +147,11 @@ impl GlobalFunctionReplacerSymbol {
pub fn return_type_name(&self) -> &str {
self.return_type_path.components().next().map(|c| c.name).unwrap_or_default()
}

#[inline]
pub fn function_name(&self) -> &str {
self.path.function_name()
}
}


Expand Down Expand Up @@ -187,6 +197,11 @@ impl MemberFunctionWrapperSymbol {
pub fn return_type_name(&self) -> &str {
self.return_type_path.components().next().map(|c| c.name).unwrap_or_default()
}

#[inline]
pub fn function_name(&self) -> &str {
self.path.function_name()
}
}


Expand All @@ -213,18 +228,18 @@ impl WrappedMethodSymbol {
pub fn new(wrapper_path: &MemberCallableWrapperSymbolPath) -> Self {
Self {
path: MemberCallableSymbolPath::new(&wrapper_path, WRAPPED_METHOD_NAME),
//FIXME remove this
wrapped_path: wrapper_path.to_owned().into(), // wrapped and wrapper paths are the same
}
}

/// Path to the original method
pub fn wrapped_path(&self) -> &MemberCallableSymbolPath {
&self.wrapped_path
}
}



//FIXME appears twice in document outline
/// Corresponding to @addField(Class) vars
#[derive(Debug, Clone)]
pub struct MemberVarInjectorSymbol {
Expand Down
82 changes: 82 additions & 0 deletions crates/analysis/src/symbol_analysis/symbols/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,10 @@ impl GlobalCallableReplacerSymbolPath {

Self(path)
}

pub fn function_name(&self) -> &str {
self.0.components().last().and_then(|c| c.name.strip_suffix(CALLABLE_REPLACER_PATH_SUFFIX)).unwrap_or_default()
}
}

impl From<GlobalCallableReplacerSymbolPath> for SymbolPathBuf {
Expand All @@ -353,6 +357,32 @@ impl From<GlobalCallableReplacerSymbolPath> for SymbolPathBuf {
}
}

impl From<GlobalCallableSymbolPath> for GlobalCallableReplacerSymbolPath {
fn from(value: GlobalCallableSymbolPath) -> Self {
let name = value.components()
.last().unwrap()
.name.to_string();

Self::new(&name)
}
}

impl From<GlobalCallableReplacerSymbolPath> for GlobalCallableSymbolPath {
fn from(value: GlobalCallableReplacerSymbolPath) -> Self {
let name = value.components()
.next().unwrap()
.name
.strip_suffix(CALLABLE_REPLACER_PATH_SUFFIX).unwrap()
.to_string();

let mut path = value.0.clone();
path.pop();
path.push(&name, SymbolCategory::Callable);

GlobalCallableSymbolPath(path)
}
}


#[derive(Debug, Clone, Shrinkwrap)]
pub struct MemberCallableReplacerSymbolPath(SymbolPathBuf);
Expand All @@ -364,6 +394,10 @@ impl MemberCallableReplacerSymbolPath {

Self(path)
}

pub fn function_name(&self) -> &str {
self.0.components().last().and_then(|c| c.name.strip_suffix(CALLABLE_REPLACER_PATH_SUFFIX)).unwrap_or_default()
}
}

impl From<MemberCallableReplacerSymbolPath> for SymbolPathBuf {
Expand All @@ -372,6 +406,36 @@ impl From<MemberCallableReplacerSymbolPath> for SymbolPathBuf {
}
}

impl From<MemberCallableSymbolPath> for MemberCallableReplacerSymbolPath {
fn from(value: MemberCallableSymbolPath) -> Self {
let name = value.components()
.last().unwrap()
.name.to_string();

let mut path = value.0;
path.pop();
path.push(&format!("{}{}", name, CALLABLE_REPLACER_PATH_SUFFIX), SymbolCategory::Callable);

MemberCallableReplacerSymbolPath(path)
}
}

impl From<MemberCallableReplacerSymbolPath> for MemberCallableSymbolPath {
fn from(value: MemberCallableReplacerSymbolPath) -> Self {
let name = value.components()
.last().unwrap()
.name
.strip_suffix(CALLABLE_REPLACER_PATH_SUFFIX).unwrap()
.to_string();

let mut path = value.0.clone();
path.pop();
path.push(&name, SymbolCategory::Callable);

MemberCallableSymbolPath(path)
}
}


#[derive(Debug, Clone, Shrinkwrap)]
pub struct MemberCallableWrapperSymbolPath(SymbolPathBuf);
Expand All @@ -383,6 +447,10 @@ impl MemberCallableWrapperSymbolPath {

Self(path)
}

pub fn function_name(&self) -> &str {
self.0.components().last().and_then(|c| c.name.strip_suffix(CALLABLE_WRAPPER_PATH_SUFFIX)).unwrap_or_default()
}
}

impl From<MemberCallableWrapperSymbolPath> for SymbolPathBuf {
Expand All @@ -405,4 +473,18 @@ impl From<MemberCallableWrapperSymbolPath> for MemberCallableSymbolPath {

MemberCallableSymbolPath(path)
}
}

impl From<MemberCallableSymbolPath> for MemberCallableWrapperSymbolPath {
fn from(value: MemberCallableSymbolPath) -> Self {
let name = value.components()
.last().unwrap()
.name.to_string();

let mut path = value.0;
path.pop();
path.push(&format!("{}{}", name, CALLABLE_WRAPPER_PATH_SUFFIX), SymbolCategory::Callable);

MemberCallableWrapperSymbolPath(path)
}
}
Loading

0 comments on commit 7e15b56

Please sign in to comment.