MCPcopy Create free account
hub / github.com/PHPantom-dev/phpantom_lsp / resolve_extract_function

Method resolve_extract_function

src/code_actions/extract_function.rs:2141–2339  ·  view source on GitHub ↗

Resolve a deferred "Extract Function/Method" code action. This is **Phase 2** of the two-phase code-action model. Phase 1 (`collect_extract_function_actions`) already validated the selection and emitted a lightweight `CodeAction` with a title but no edit. Here we re-run the full extraction logic from the selection range stored in `data` and produce the workspace edit.

(
        &self,
        data: &CodeActionData,
        content: &str,
    )

Source from the content-addressed store, hash-verified

2139 /// but no edit. Here we re-run the full extraction logic from the
2140 /// selection range stored in `data` and produce the workspace edit.
2141 pub(crate) fn resolve_extract_function(
2142 &self,
2143 data: &CodeActionData,
2144 content: &str,
2145 ) -> Option<WorkspaceEdit> {
2146 let uri = &data.uri;
2147 let range = &data.range;
2148
2149 // ── Re-validate the selection (content may have changed) ────
2150 let start_offset = position_to_byte_offset(content, range.start);
2151 let end_offset = position_to_byte_offset(content, range.end);
2152
2153 let (start, end) = trim_selection(content, start_offset, end_offset)?;
2154
2155 if !selection_covers_complete_statements(content, start, end) {
2156 return None;
2157 }
2158
2159 // ── Scope map & classification ──────────────────────────────
2160 let scope_map = build_scope_map(content, start as u32);
2161 let classification = scope_map.classify_range(start as u32, end as u32);
2162
2163 let return_value_count = classification.return_values.len();
2164 let return_strategy = analyse_returns(content, start, end, return_value_count);
2165
2166 if return_strategy == ReturnStrategy::Unsafe {
2167 return None;
2168 }
2169
2170 let uses_this = if scope_map.has_this_or_self {
2171 classification.uses_this
2172 } else {
2173 false
2174 };
2175
2176 if scope_map.uses_reference_params() && !classification.reference_writes.is_empty() {
2177 return None;
2178 }
2179
2180 if classification.return_values.len() > 4 {
2181 return None;
2182 }
2183
2184 // ── Enclosing context ───────────────────────────────────────
2185 let enclosing = find_enclosing_context(content, start as u32, uses_this)?;
2186
2187 // ── Naming ──────────────────────────────────────────────────
2188 let body_line_start_for_naming = find_line_start(content, start);
2189 let body_text_for_naming = &content[body_line_start_for_naming..end];
2190 let pre_trailing_return_type = if matches!(return_strategy, ReturnStrategy::TrailingReturn)
2191 {
2192 resolve_enclosing_return_type(content, start as u32)
2193 } else {
2194 PhpType::untyped()
2195 };
2196 let naming_ctx = NamingContext {
2197 enclosing_name: &enclosing.enclosing_name,
2198 return_strategy: &return_strategy,

Callers 1

resolve_code_actionMethod · 0.80

Calls 15

position_to_byte_offsetFunction · 0.85
trim_selectionFunction · 0.85
analyse_returnsFunction · 0.85
find_enclosing_contextFunction · 0.85
generate_function_nameFunction · 0.85
indent_atFunction · 0.85
detect_line_indentFunction · 0.85

Tested by

no test coverage detected