Skip to content

Commit

Permalink
Making QDots in IdQualified resolvable
Browse files Browse the repository at this point in the history
  • Loading branch information
ihji committed May 1, 2024
1 parent cbe54b6 commit 179c781
Show file tree
Hide file tree
Showing 15 changed files with 72 additions and 43 deletions.
2 changes: 1 addition & 1 deletion languages/cairo/generic/Parse_cairo_tree_sitter.ml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ let rec map_qualified_name (env : env) (x : CST.qualified_name) :

{
name_last = (last_name, type_arguments);
name_middle = Some (G.QDots path);
name_middle = Some (G.QDots (path, G.empty_id_info ()));
name_top = None;
name_info = G.empty_id_info ();
}
Expand Down
3 changes: 2 additions & 1 deletion languages/cpp/generic/cpp_to_generic.ml
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,8 @@ let rec map_name env (v1, v2, v3) : G.name =
{
G.name_last = v3;
name_top = v1;
name_middle = (if v2 =*= [] then None else Some (QDots v2));
name_middle =
(if v2 =*= [] then None else Some (QDots (v2, G.empty_id_info ())));
name_info = G.empty_id_info ();
}

Expand Down
2 changes: 1 addition & 1 deletion languages/java/generic/java_to_generic.ml
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ and class_type v =
{
G.name_last = (id, None);
name_top = None;
name_middle = Some (G.QDots (List.rev xs));
name_middle = Some (G.QDots (List.rev xs, G.empty_id_info ()));
name_info = G.empty_id_info ();
})
|> G.t
Expand Down
3 changes: 2 additions & 1 deletion languages/ql/generic/QL_to_generic.ml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ and qualified_info { name_last = v1, v2; name_middle } =
let name_middle =
Some
(G.QDots
(list (fun (x, y) -> (ident x, option type_arguments y)) name_middle))
( list (fun (x, y) -> (ident x, option type_arguments y)) name_middle,
G.empty_id_info () ))
in
G.{ name_last; name_middle; name_top = None; name_info = G.empty_id_info () }

Expand Down
10 changes: 5 additions & 5 deletions languages/ruby/generic/ruby_to_generic.ml
Original file line number Diff line number Diff line change
Expand Up @@ -320,20 +320,20 @@ and scope_resolution x : G.name =
let e = expr e in
let qualif =
match e with
| { G.e = G.N (G.Id (id, _info)); _ } -> G.QDots [ (id, None) ]
| { G.e = G.N (G.Id (id, info)); _ } -> G.QDots ([ (id, None) ], info)
| {
G.e =
G.N
(G.IdQualified
{
name_last;
name_middle = Some (G.QDots middle);
name_middle = Some (G.QDots (middle, _info));
name_top = None;
_;
name_info;
});
_;
} ->
G.QDots (middle @ [ name_last ])
G.QDots (middle @ [ name_last ], name_info)
| _ -> G.QExpr (e, t)
in
IdQualified
Expand Down Expand Up @@ -718,7 +718,7 @@ and pattern pat =
G.IdQualified
{
G.name_last = (last, None);
name_middle = Some (G.QDots qualifier);
name_middle = Some (G.QDots (qualifier, G.empty_id_info ()));
name_top = None;
name_info = G.empty_id_info ();
}
Expand Down
2 changes: 1 addition & 1 deletion libs/ast_generic/AST_generic.ml
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ and qualified_info = {

and qualifier =
(* Java/C++/Rust *)
| QDots of (ident * type_arguments option) list
| QDots of (ident * type_arguments option) list * id_info
(* Ruby/Lua *)
| QExpr of expr * tok

Expand Down
24 changes: 16 additions & 8 deletions libs/ast_generic/AST_generic_helpers.ml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ let name_of_ids_with_opt_typeargs xs =
| [] -> failwith "name_of_ids_with_opt_typeargs: empty ids"
| [ (x, None) ] -> Id (x, empty_id_info ())
| (x, topt) :: xs ->
let qualif = if xs =*= [] then None else Some (QDots (xs |> List.rev)) in
let qualif =
if xs =*= [] then None
else Some (QDots (xs |> List.rev, empty_id_info ()))
in
IdQualified
{
name_last = (x, topt);
Expand All @@ -55,7 +58,7 @@ let name_to_qualifier = function
let rest =
match qu with
| None -> []
| Some (QDots xs) -> xs
| Some (QDots (xs, _idinfo)) -> xs
(* TODO, raise exn? *)
| Some (QExpr _) -> []
in
Expand All @@ -68,7 +71,7 @@ let add_id_opt_type_args_to_name name (id, topt) =
IdQualified
{
name_last = (id, topt);
name_middle = Some (QDots qdots);
name_middle = Some (QDots (qdots, empty_id_info ()));
name_top = None;
name_info = empty_id_info () (* TODO reuse from name?*);
}
Expand Down Expand Up @@ -108,7 +111,11 @@ let name_of_ids ?(case_insensitive = false) xs =
| x :: xs ->
let qualif =
if xs =*= [] then None
else Some (QDots (xs |> List.rev |> List_.map (fun id -> (id, None))))
else
Some
(QDots
( xs |> List.rev |> List_.map (fun id -> (id, None)),
empty_id_info () ))
in
IdQualified
{
Expand All @@ -124,10 +131,11 @@ let add_suffix_to_name suffix name =
| IdQualified ({ name_last; name_middle; _ } as q_info) ->
let new_name_middle =
match name_middle with
| Some (QDots qualifiers) -> Some (G.QDots (qualifiers @ [ name_last ]))
| Some (QDots (qualifiers, _)) ->
Some (G.QDots (qualifiers @ [ name_last ], empty_id_info ()))
| Some (QExpr (expr, tok)) ->
Some (G.QExpr ({ expr with e = N name }, tok))
| None -> Some (G.QDots [ name_last ])
| None -> Some (G.QDots ([ name_last ], empty_id_info ()))
in
IdQualified
{
Expand All @@ -146,7 +154,7 @@ let name_of_dot_access e =
let* name_middle =
match name_middle with
| None -> Some []
| Some (QDots xs) -> Some (List.map (fun (id, _) -> id) xs)
| Some (QDots (xs, _)) -> Some (List.map (fun (id, _) -> id) xs)
| Some (QExpr _) -> None
in
let name_last = fst name_last in
Expand All @@ -171,7 +179,7 @@ let dotted_ident_of_name (n : name) : dotted_ident =
let before =
match name_middle with
(* we skip the type parts in ds ... *)
| Some (QDots ds) -> ds |> List_.map fst
| Some (QDots (ds, _)) -> ds |> List_.map fst
| Some (QExpr _) ->
Logs.err (fun m -> m ~tags "unexpected qualifier type");
[]
Expand Down
3 changes: 2 additions & 1 deletion libs/ast_generic/AST_generic_to_v1.ml
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ and map_qualified_info { name_last; name_middle; name_top; name_info } =
{ B.name_last; name_middle; name_top; name_info }

and map_qualifier = function
| QDots v1 ->
| QDots (v1, v2) ->
let v1 =
map_of_list
(fun (v1, v2) ->
Expand All @@ -211,6 +211,7 @@ and map_qualifier = function
(v1, v2))
v1
in
let _v2 = map_id_info v2 in
`QDots v1
| QExpr (e, t) ->
let e = map_expr e in
Expand Down
5 changes: 3 additions & 2 deletions libs/ast_generic/Meta_AST.ml
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,10 @@ and vof_resolved_name_kind = function
OCaml.VSum ("GlobalName", [ v1; v2 ])

let rec vof_qualifier = function
| QDots v1 ->
| QDots (v1, v2) ->
let v1 = OCaml.vof_list vof_ident_and_targs_opt v1 in
OCaml.VSum ("QDots", [ v1 ])
let v2 = vof_id_info v2 in
OCaml.VSum ("QDots", [ v1; v2 ])
| QExpr (v1, v2) ->
let v1 = vof_expr v1 in
let v2 = vof_tok v2 in
Expand Down
8 changes: 5 additions & 3 deletions src/analyzing/Dataflow_svalue.ml
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,11 @@ let eval_builtin_func lang env func args =
name_middle =
Some
(QDots
( [ (("String", _), _) ]
| [ (("java", _), _); (("lang", _), _); (("String", _), _) ]
));
( ( [ (("String", _), _) ]
| [
(("java", _), _); (("lang", _), _); (("String", _), _);
] ),
_ ));
_;
} ) ->
Some (eval_format env args)
Expand Down
6 changes: 4 additions & 2 deletions src/analyzing/Eval_generic_partial.ml
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,10 @@ and eval_call env name args =
name_middle =
Some
(QDots
( [ (("String", _), _) ]
| [ (("java", _), _); (("lang", _), _); (("String", _), _) ] ));
( ( [ (("String", _), _) ]
| [ (("java", _), _); (("lang", _), _); (("String", _), _) ]
),
_ ));
_;
},
_args ) ->
Expand Down
40 changes: 26 additions & 14 deletions src/matching/Generic_vs_generic.ml
Original file line number Diff line number Diff line change
Expand Up @@ -208,15 +208,24 @@ let m_dotted_name a b =
(* This is for languages like Python where foo.arg.func is not parsed
* as a qualified name but as a chain of DotAccess.
*)
let make_dotted xs =
match xs with
let make_dotted ?(id_info = None) xs =
(* attach id_info to the last ident component *)
let ids =
match List.rev xs with
| [] -> []
| x :: xs ->
(x, id_info |> Option.value ~default:(B.empty_id_info ()))
:: (xs |> List_.map (fun x -> (x, B.empty_id_info ())))
|> List.rev
in
match ids with
| [] -> raise Impossible
| x :: xs ->
let base = B.N (B.Id (x, B.empty_id_info ())) |> G.e in
| (id, id_info) :: xs ->
let base = B.N (B.Id (id, id_info)) |> G.e in
List.fold_left
(fun acc e ->
let tok = Tok.fake_tok (snd x) "." in
B.DotAccess (acc, tok, B.FN (B.Id (e, B.empty_id_info ()))) |> G.e)
(fun acc (e, e_info) ->
let tok = Tok.fake_tok (snd id) "." in
B.DotAccess (acc, tok, B.FN (B.Id (e, e_info))) |> G.e)
base xs

(* similar to m_list_prefix but binding $X to the whole list *)
Expand Down Expand Up @@ -474,7 +483,7 @@ let rec m_name_inner a b =
let new_middle =
match new_qualifier with
| [] -> None
| xs -> Some (B.QDots xs)
| xs -> Some (B.QDots (xs, B.empty_id_info ()))
in
m_name a
(B.IdQualified
Expand Down Expand Up @@ -620,9 +629,12 @@ and m_ident_and_type_arguments (a1, a2) (b1, b2) =
and m_qualifier a b =
match (a, b) with
(* Like for m_dotted_name, [$X] should match anything *)
| G.QDots [ ((str, t), _) ], B.QDots b when MV.is_metavar_name str ->
envf (str, t) (MV.E (make_dotted (List_.map fst b)))
| G.QDots a, B.QDots b -> m_list m_ident_and_type_arguments a b
| G.QDots ([ ((str, t), _) ], a2), B.QDots (b1, b2)
when MV.is_metavar_name str ->
m_id_info a2 b2 >>= fun () ->
envf (str, t) (MV.E (make_dotted ~id_info:(Some b2) (List_.map fst b1)))
| G.QDots (a1, a2), B.QDots (b1, b2) ->
m_id_info a2 b2 >>= fun () -> m_list m_ident_and_type_arguments a1 b1
| G.QExpr (a1, a2), B.QExpr (b1, b2) -> m_expr a1 b1 >>= fun () -> m_tok a2 b2
| G.QDots _, _
| G.QExpr _, _ ->
Expand Down Expand Up @@ -850,14 +862,14 @@ and m_expr ?(is_root = false) ?(arguments_have_changed = true) a b =
(G.IdQualified
{
G.name_last = alabel, None;
name_middle = Some (G.QDots names);
name_middle = Some (G.QDots (names, _));
name_top = None;
_;
name_info;
}),
_b ) ->
(* TODO: double check names does not have any type_args *)
let full = (names |> List_.map fst) @ [ alabel ] in
m_expr (make_dotted full) b
m_expr (make_dotted ~id_info:(Some name_info) full) b
| G.DotAccess (_, _, _), B.N b1 ->
(* Reinterprets a DotAccess expression such as a.b.c as a name, when
* a,b,c are all identifiers. Note that something like a.b.c could get
Expand Down
2 changes: 1 addition & 1 deletion src/naming/Naming_AST.ml
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ let resolve lang prog =
name_top = None;
} ->
(match name_middle with
| Some (QDots ((m, None) :: rest_of_middle)) -> (
| Some (QDots ((m, None) :: rest_of_middle, _)) -> (
match lookup_scope_opt m env with
(* Resolve modules for OCaml *)
| Some { entname = ImportedModule xs, _sidm; _ }
Expand Down
2 changes: 1 addition & 1 deletion src/printing/Pretty_print_AST.ml
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,7 @@ and id_qualified env { name_last = id, _toptTODO; name_middle; name_top; _ } =
| Some _t -> "::")
^
match name_middle with
| Some (QDots dot_ids) ->
| Some (QDots (dot_ids, _)) ->
(* TODO: do not do fst, look also at type qualification *)
F.sprintf "%s.%s" (dotted_access env (List_.map fst dot_ids)) (ident id)
| Some (QExpr (e, _t)) -> expr env e ^ "::"
Expand Down
3 changes: 2 additions & 1 deletion src/typing/Typing.ml
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,8 @@ let name_and_targs_of_named_type lang = function
| Type.UnresolvedName (str, targs) ->
Some (str, targs)
| Type.N
( ( G.IdQualified { G.name_last; name_middle = Some (QDots middle); _ },
( ( G.IdQualified
{ G.name_last; name_middle = Some (QDots (middle, _)); _ },
targs ),
_ ) ->
let (str_last, _), _ = name_last in
Expand Down

0 comments on commit 179c781

Please sign in to comment.