@@ -601,151 +601,6 @@ fn recurse_call_arguments_default(
601601 ( ) . ok ( )
602602}
603603
604- // This is commented out because:
605- //
606- // - The package not installed lint is a bit too distracting. Should it become
607- // an assist?
608- // https://github.com/posit-dev/positron/issues/2672
609- // - We'd like to avoid running R code during diagnostics
610- // https://github.com/posit-dev/positron/issues/2321
611- // - The diagnostic meshes R and tree-sitter objects in a way that's not
612- // perfectly safe and we have a known crash logged:
613- // https://github.com/posit-dev/positron/issues/2630. This diagnostic uses R for
614- // argument matching but since we prefer to avoid running `r_task()` in LSP code
615- // we should just reimplement argument matching on the Rust side.
616-
617- // struct TreeSitterCall<'a> {
618- // // A call of the form <fun>(list(0L, <ptr>), foo = list(1L, <ptr>))
619- // pub call: RObject,
620- // node_phantom: PhantomData<&'a Node<'a>>,
621- // }
622- //
623- // impl<'a> TreeSitterCall<'a> {
624- // pub unsafe fn new(
625- // node: Node<'a>,
626- // function: &str,
627- // context: &mut DiagnosticContext,
628- // ) -> Result<Self> {
629- // // start with a call to the function: <fun>()
630- // let sym = r_symbol!(function);
631- // let call = RObject::new(Rf_lang1(sym));
632- //
633- // // then augment it with arguments
634- // let mut tail = *call;
635- //
636- // if let Some(arguments) = node.child_by_field_name("arguments") {
637- // let mut cursor = arguments.walk();
638- // let children = arguments.children_by_field_name("argument", &mut cursor);
639- // let mut i = 0;
640- // for child in children {
641- // let arg_list = RObject::from(Rf_allocVector(VECSXP, 2));
642- //
643- // // set the argument to a list<2>, with its first element: a scalar integer
644- // // that corresponds to its O-based position. The position is used below to
645- // // map back to the Node
646- // SET_VECTOR_ELT(*arg_list, 0, Rf_ScalarInteger(i as i32));
647- //
648- // // Set the second element of the list to an external pointer
649- // // to the child node.
650- // if let Some(value) = child.child_by_field_name("value") {
651- // // TODO: Wrap this in a nice constructor
652- // let node_size = std::mem::size_of::<Node>();
653- // let node_storage = Rf_allocVector(RAWSXP, node_size as isize);
654- // SET_VECTOR_ELT(*arg_list, 1, node_storage);
655- //
656- // let p_node_storage: *mut Node<'a> = RAW(node_storage) as *mut Node<'a>;
657- // std::ptr::copy_nonoverlapping(&value, p_node_storage, 1);
658- // }
659- //
660- // SETCDR(tail, Rf_cons(*arg_list, R_NilValue));
661- // tail = CDR(tail);
662- //
663- // // potentially add the argument name
664- // if let Some(name) = child.child_by_field_name("name") {
665- // let name = context.contents.node_slice(&name)?.to_string();
666- // let sym_name = r_symbol!(name);
667- // SET_TAG(tail, sym_name);
668- // }
669- //
670- // i = i + 1;
671- // }
672- // }
673- //
674- // Ok(Self {
675- // call,
676- // node_phantom: PhantomData,
677- // })
678- // }
679- // }
680- //
681- // fn recurse_call_arguments_custom(
682- // node: Node,
683- // context: &mut DiagnosticContext,
684- // diagnostics: &mut Vec<Diagnostic>,
685- // function: &str,
686- // diagnostic_function: &str,
687- // ) -> Result<()> {
688- // r_task(|| unsafe {
689- // // Build a call that mixes treesitter nodes (as external pointers)
690- // // library(foo, pos = 2 + 2)
691- // // ->
692- // // library([0, <node0>], pos = [1, <node1>])
693- // // where:
694- // // - node0 is an external pointer to a treesitter Node for the identifier `foo`
695- // // - node1 is an external pointer to a treesitter Node for the call `2 + 2`
696- // //
697- // // The TreeSitterCall object holds on to the nodes, so that they can be
698- // // safely passed down to the R side as external pointers
699- // let call = TreeSitterCall::new(node, function, context)?;
700- //
701- // let custom_diagnostics = RFunction::from(diagnostic_function)
702- // .add(r_expr_quote(call.call))
703- // .add(ExternalPointer::new(context.contents))
704- // .call()?;
705- //
706- // if !r_is_null(*custom_diagnostics) {
707- // let n = Rf_xlength(*custom_diagnostics);
708- // for i in 0..n {
709- // // diag is a list with:
710- // // - The kind of diagnostic: skip, default, simple
711- // // - The node external pointer, i.e. the ones made in TreeSitterCall::new
712- // // - The message, when kind is "simple"
713- // let diag = VECTOR_ELT(*custom_diagnostics, i);
714- //
715- // let kind: String = RObject::view(VECTOR_ELT(diag, 0)).try_into()?;
716- //
717- // if kind == "skip" {
718- // // skip the diagnostic entirely, e.g.
719- // // library(foo)
720- // // ^^^
721- // continue;
722- // }
723- //
724- // let ptr = VECTOR_ELT(diag, 1);
725- // let value: Node<'static> = *(RAW(ptr) as *mut Node<'static>);
726- //
727- // if kind == "default" {
728- // // the R side gives up, so proceed as normal, e.g.
729- // // library(foo, pos = ...)
730- // // ^^^
731- // recurse(value, context, diagnostics)?;
732- // } else if kind == "simple" {
733- // // Simple diagnostic from R, e.g.
734- // // library("ggplot3")
735- // // ^^^^^^^ Package 'ggplot3' is not installed
736- // let message: String = RObject::view(VECTOR_ELT(diag, 2)).try_into()?;
737- // let range = value.range();
738- // let range = convert_tree_sitter_range_to_lsp_range(context.contents, range);
739- // let diagnostic = Diagnostic::new_simple(range, message.into());
740- // diagnostics.push(diagnostic);
741- // }
742- // }
743- // }
744- //
745- // ().ok()
746- // })
747- // }
748-
749604fn recurse_call (
750605 node : Node ,
751606 context : & mut DiagnosticContext ,
0 commit comments