Skip to content

Commit

Permalink
Update application_env to pick up map keys
Browse files Browse the repository at this point in the history
Summary: As title

Differential Revision: D53270739

fbshipit-source-id: 204a1e6677e19d282898a0de88a322db19db97aa
  • Loading branch information
alanz authored and facebook-github-bot committed Feb 1, 2024
1 parent c07e9cf commit 0efa33e
Showing 1 changed file with 49 additions and 7 deletions.
56 changes: 49 additions & 7 deletions crates/ide/src/diagnostics/application_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
// The originial motivation and discussion is in T107133234

use elp_ide_db::elp_base_db::FileId;
use hir::AnyExprId;
use hir::ExprId;
use hir::FunctionDef;
use hir::InFunctionClauseBody;
use hir::Semantic;
use lazy_static::lazy_static;

Expand Down Expand Up @@ -62,13 +64,22 @@ pub(crate) enum BadEnvCallAction {
/// The `tag` must match, and we check the `index`th part of the
/// second tuple element
/// e.g. `our_mod:a_fun(Context, Location, [..., {cfg, {Application, Flag}}, ...], Format, Args)
#[allow(dead_code)] // @oss-only
#[allow(dead_code)]
OptionsArg {
/// Which argument contains the list of options to be checked
arg_index: usize,
/// The option tag we are looking for
tag: String,
},
#[allow(dead_code)] // @oss-only
MapArg {
/// Which argument contains the map of options to be checked
arg_index: usize,
/// The sequence of map keys we are looking for. we chain
/// through, expecting each to return a map that we check the
/// next in
keys: Vec<String>,
},
}

pub(crate) fn check_function(diags: &mut Vec<Diagnostic>, sema: &Semantic, def: &FunctionDef) {
Expand Down Expand Up @@ -117,12 +128,7 @@ pub(crate) fn process_badmatches(
let val = exprs.get(1)?;
let key_name = in_clause.as_atom_name(sema.db, key)?;
if tag == key_name.as_str() {
if let hir::Expr::Tuple { exprs } = &in_clause[*val] {
let app = exprs.get(0)?;
check_valid_application(sema, in_clause, app, def)
} else {
None
}
check_tuple(in_clause, val, sema, def)
} else {
None
}
Expand All @@ -133,6 +139,28 @@ pub(crate) fn process_badmatches(
_ => None,
}
}
BadEnvCallAction::MapArg { arg_index, keys } => {
// We expect the `arg_index`'th argument to contain a
// map. We chase through the keys, expecting each to
// return another map, which we look up the next key
// in. At the end we expect a tuple, and check the
// first arg of that.
let arg = args.get(*arg_index)?;
match &in_clause[*arg] {
hir::Expr::Map { fields: _ } => {
if let Some(AnyExprId::Expr(rhs)) = in_clause.body().lookup_map_path(
sema.db.upcast(),
AnyExprId::Expr(*arg),
keys,
) {
check_tuple(in_clause, &rhs, sema, def)
} else {
None
}
}
_ => None,
}
}
},
move |_sema, def_fb, _target, _call_id, diag_extra, _fix_extra, range| {
let diag = Diagnostic::new(DiagnosticCode::ApplicationGetEnv, diag_extra, range)
Expand All @@ -143,6 +171,20 @@ pub(crate) fn process_badmatches(
);
}

fn check_tuple(
in_clause: &InFunctionClauseBody<&FunctionDef>,
val: &ExprId,
sema: &Semantic,
def: &FunctionDef,
) -> Option<(String, String)> {
if let hir::Expr::Tuple { exprs } = &in_clause[*val] {
let app = exprs.get(0)?;
check_valid_application(sema, in_clause, app, def)
} else {
None
}
}

fn check_valid_application(
sema: &Semantic,
def_fb: &hir::InFunctionClauseBody<&FunctionDef>,
Expand Down

0 comments on commit 0efa33e

Please sign in to comment.