Skip to content

Commit

Permalink
Parse indexer methods in C# (#2311)
Browse files Browse the repository at this point in the history
E.g.
```
public string this[int i] { get { ... } }
```

Related to #1392
  • Loading branch information
Sjord committed Dec 28, 2020
1 parent 53fdad9 commit 516fe38
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 7 deletions.
48 changes: 41 additions & 7 deletions semgrep-core/parsing/Parse_csharp_tree_sitter.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1091,7 +1091,8 @@ and expression (env : env) (x : CST.expression) : AST.expr =
| `Throw_exp (v1, v2) ->
let v1 = token env v1 (* "throw" *) in
let v2 = expression env v2 in
todo env (v1, v2)
let throw = Throw (v1, v2, sc) in
OtherExpr (OE_StmtExpr, [AST.S (AST.s throw)])
| `Tuple_exp (v1, v2, v3, v4) ->
let v1 = token env v1 (* "(" *) in
let v2 = argument env v2 in
Expand Down Expand Up @@ -1939,7 +1940,7 @@ let bracketed_parameter_list (env : env) ((v1, v2, v3, v4) : CST.bracketed_param
) v3
in
let v4 = token env v4 (* "]" *) in
todo env (v1, v2 :: v3, v4)
List.map (fun p -> ParamClassic p) (v2 :: v3)

let constructor_initializer (env : env) ((v1, v2, v3) : CST.constructor_initializer) =
let v1 = token env v1 (* ":" *) in
Expand Down Expand Up @@ -2282,21 +2283,54 @@ and declaration (env : env) (x : CST.declaration) : stmt =
let v3 = type_constraint env v3 in
let v4 =
(match v4 with
| Some x -> explicit_interface_specifier env x
| None -> todo env ())
| Some x -> Some (explicit_interface_specifier env x)
| None -> None)
in
let v5 = token env v5 (* "this" *) in
let v6 = bracketed_parameter_list env v6 in
let v7 =
let open_br, funcs, close_br =
(match v7 with
| `Acce_list x -> accessor_list env x
| `Acce_list x ->
let open_br, accs, close_br = accessor_list env x in
let funcs = accs |> List.map (fun (attrs, id, fbody) ->
let iname, itok = id in
match iname with
| "get" -> (
let ent = basic_entity ("get_Item", itok) attrs in
let funcdef = FuncDef {
fkind = (Method, itok);
fparams = v6;
frettype = Some v3;
fbody;
} in
DefStmt (ent, funcdef) |> AST.s
)
| "set" -> (
let valparam = ParamClassic {
pname = Some ("value", fake "value");
ptype = Some v3;
pdefault = None; pattrs = [];
pinfo = empty_id_info ();
} in
let ent = basic_entity ("set_Item", itok) attrs in
let funcdef = FuncDef {
fkind = (Method, itok);
fparams = v6 @ [valparam];
frettype = None;
fbody;
} in
DefStmt (ent, funcdef) |> AST.s
)
| _ -> raise Impossible
) in
open_br, funcs, close_br
| `Arrow_exp_clause_SEMI (v1, v2) ->
let v1 = arrow_expression_clause env v1 in
let v2 = token env v2 (* ";" *) in
todo env (v1, v2)
)
in
todo env (v1, v2, v3, v4, v5, v6, v7)
Block (open_br, funcs, close_br) |> AST.s
| `Meth_decl (v1, v2, v3, v4, v5, v6, v7, v8, v9) ->
(*
[Attr] static int IList<T>.MyMethod<T>(int p1) where T : Iterator { ... }
Expand Down
25 changes: 25 additions & 0 deletions semgrep-core/tests/csharp/parsing/indexer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;

class HelloWorldIndexer
{
public static void Main()
{
var instance = new HelloWorldIndexer();
Console.WriteLine(instance[0]);
Console.WriteLine(instance[1]);
}

private string this[int i]
{
get
{
switch (i)
{
case 0: return "hello";
case 1: return "world";
default: throw new IndexOutOfRangeException();
}
}
set => throw new NotImplementedException();
}
}

0 comments on commit 516fe38

Please sign in to comment.