Repository: astral-sh/ruff
File: crates/ty_ide/src/completion.rs (Rust)

Code before:
                        ImportRequest::import_from(module_name.as_str(), symbol)
                    },
                    &mut completions,
                );
            }
        }

        if let Some(arg_completions) = detect_function_arg_completions(db, file, &parsed, offset) {
            completions.extend(arg_completions);
        }
    }

    if is_raising_exception(tokens) {
        completions.tag_raisable();

        // As a special case, and because it's a common footgun, we
        // specifically disallow `NotImplemented` in this context.
        // `NotImplementedError` should be used instead. So if we can
        // definitively detect `NotImplemented`, then we can safely
        // omit it from suggestions.
        completions.retain(|item| {
            let Some(ty) = item.ty else { return true };
            !ty.is_notimplemented(db)
        });
    }
    completions.into_completions()
}

/// Detect and construct completions for unset function arguments.
///
/// Suggestions are only provided if the cursor is currently inside a
/// function call and the function arguments have not 1) already been
/// set and 2) been defined as positional-only.
fn detect_function_arg_completions<'db>(
    db: &'db dyn Db,
    file: File,
    parsed: &ParsedModuleRef,
    offset: TextSize,
) -> Option<Vec<Completion<'db>>> {
    let sig_help = signature_help(db, file, offset)?;
    let set_function_args = detect_set_function_args(parsed, offset);

    let completions = sig_help
        .signatures
        .iter()
        .flat_map(|sig| &sig.parameters)
        .filter(|p| !p.is_positional_only && !set_function_args.contains(&p.name.as_str()))
        .map(|p| {
            let name = Name::new(&p.name);
            let documentation = p
                .documentation

Review comment (performance):
I guess we don't technically have to call this unless we know we've added some keywords to the completions. And that only happens for scope based completions. So this will do an unnecessary AST check for `object.attr` and import completions.

But maybe we'll eventually rule out other things here besides keywords that we know can't be iterable. So I'm not sure it's worth trying to optimize this out?

I think part of my problem is that I don't have an intuition for the costs associated with calling `covering_node`. Maybe I'm tilting at windmills.

Code after:
                        ImportRequest::import_from(module_name.as_str(), symbol)
                    },
                    &mut completions,
                );
            }
        }

        if let Some(arg_completions) = detect_function_arg_completions(db, file, &parsed, offset) {
            completions.extend(arg_completions);
        }
    }

    if is_raising_exception(tokens) {
        completions.tag_raisable();

        // As a special case, and because it's a common footgun, we
        // specifically disallow `NotImplemented` in this context.
        // `NotImplementedError` should be used instead. So if we can
        // definitively detect `NotImplemented`, then we can safely
        // omit it from suggestions.
        completions.retain(|item| {
            let Some(ty) = item.ty else { return true };
            !ty.is_notimplemented(db)
        });
    }
    if is_specifying_for_statement_iterable(&parsed, offset, typed.as_deref()) {
        // Remove all keywords that doesn't make sense given the context,
        // even if they are syntatically valid, e.g. `None`.
        completions.retain(|item| {
            let Some(kind) = item.kind else { return true };
            if kind != CompletionKind::Keyword {
                return true;
            }
            matches!(item.name.as_str(), "await" | "lambda" | "yield")
        });
    }
    completions.into_completions()
}

/// Detect and construct completions for unset function arguments.
///
/// Suggestions are only provided if the cursor is currently inside a
/// function call and the function arguments have not 1) already been
/// set and 2) been defined as positional-only.
fn detect_function_arg_completions<'db>(
    db: &'db dyn Db,
    file: File,
    parsed: &ParsedModuleRef,
    offset: TextSize,
) -> Option<Vec<Completion<'db>>> {
    let sig_help = signature_help(db, file, offset)?;