Skip to content
This repository was archived by the owner on Sep 9, 2025. It is now read-only.

Commit aee65e7

Browse files
authored
Merge pull request #192 from github/java-the-hutt
Update Java rules to support imports
2 parents eab5048 + 4221d1e commit aee65e7

File tree

6 files changed

+170
-39
lines changed

6 files changed

+170
-39
lines changed

languages/tree-sitter-stack-graphs-java/src/stack-graphs.tsg

Lines changed: 107 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -64,25 +64,54 @@ attribute node_symbol = node => symbol = (source-text node), source_n
6464
node @decl.lexical_scope
6565
}
6666

67-
(import_declaration
68-
(scoped_identifier
69-
name: (identifier) @scope_name)
70-
) @import {
67+
(program
68+
(package_declaration
69+
(identifier)@pkg_name)? @package) @prog {
70+
if none @package {
71+
edge ROOT_NODE -> @prog.defs
72+
} else {
73+
node pkg_def
74+
attr (pkg_def) node_definition = @pkg_name
75+
edge pkg_def -> @prog.defs
76+
edge ROOT_NODE -> pkg_def
77+
}
78+
}
79+
80+
(import_declaration (_) @ref) @import {
81+
edge @ref.lexical_scope -> @import.lexical_scope
82+
}
83+
84+
;; X
85+
(identifier) @name {
86+
node @name.lexical_scope
87+
node @name.type
88+
89+
node @name.ref
90+
attr (@name.ref) node_reference = @name
91+
edge @name.ref -> @name.lexical_scope
92+
}
93+
94+
;; _.X
95+
(scoped_identifier scope: (_) @scope name: (_) @name) @scoped_name {
96+
node @scoped_name.lexical_scope
97+
98+
edge @scope.lexical_scope -> @scoped_name.lexical_scope
7199

72-
node @scope_name.value
73-
attr (@scope_name.value) node_definition = @scope_name
100+
edge @name.lexical_scope -> @scope.ref
74101

75-
edge @import.defs -> @scope_name.value
102+
node @scoped_name.ref
103+
edge @scoped_name.ref -> @name.ref
76104
}
77105

78-
(import_declaration
79-
(scoped_identifier
80-
scope: (scoped_identifier
81-
name: (identifier) @name))) @import {
82-
node @name.value
83-
attr (@name.value) node_definition = @name
106+
[
107+
(import_declaration (identifier) @scope @name)
108+
(import_declaration (scoped_identifier scope: (_) @scope name: (identifier) @name))
109+
] @import {
110+
node def
111+
attr (def) node_definition = @name
112+
edge def -> @name.ref
84113

85-
edge @import.defs -> @name.value
114+
edge @import.defs -> def
86115
}
87116

88117
;;;;;;;;;;;;;;;;;;;;
@@ -110,6 +139,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n
110139
attr (@class_body.lexical_scope -> @class_body.defs) precedence = 1
111140
edge @class.defs -> def
112141
edge def -> @class_body.defs
142+
edge def -> @class_body.static_defs
113143

114144
node this__expr_def
115145
node @class.type
@@ -121,6 +151,11 @@ attribute node_symbol = node => symbol = (source-text node), source_n
121151

122152
attr (@class.type) pop_symbol = ":"
123153

154+
node def__typeof
155+
attr (def__typeof) pop_symbol = ":"
156+
edge def -> def__typeof
157+
edge def__typeof -> @class_body.static_defs
158+
124159
edge @class.type -> ref
125160
attr (@class.type -> ref) precedence = 1
126161
}
@@ -183,15 +218,18 @@ attribute node_symbol = node => symbol = (source-text node), source_n
183218
(class_body) @class_body {
184219
node @class_body.lexical_scope
185220
node @class_body.defs
221+
node @class_body.static_defs
186222
}
187223

188224
(class_body (_)@declaration)@class_body {
189225
edge @class_body.defs -> @declaration.defs
226+
edge @class_body.static_defs -> @declaration.static_defs
190227
edge @declaration.lexical_scope -> @class_body.lexical_scope
191228
}
192229

193230
(class_body (block) @block) {
194231
node @block.defs
232+
node @block.static_defs
195233
node @block.lexical_scope
196234
edge @block.lexical_scope -> @block.before_scope
197235
}
@@ -217,6 +255,7 @@ attribute node_symbol = node => symbol = (source-text node), source_n
217255
; FIXME: can we get away with defining one and only one thing for each of these, and therefore having a `.def` node instead of `.defs`?
218256
node @decl.defs
219257
node @decl.lexical_scope
258+
node @decl.static_defs
220259
}
221260

222261
(annotation_type_declaration
@@ -379,14 +418,20 @@ attribute node_symbol = node => symbol = (source-text node), source_n
379418
}
380419

381420
(method_declaration
421+
(modifiers "static"?@is_static)?
382422
type: (_) @type
383423
name: (identifier) @name
384424
body: (block) @block) @method
385425
{
386426
edge @type.lexical_scope -> @method.lexical_scope
387427

388428
node member
389-
edge @method.defs -> member
429+
430+
if none @is_static {
431+
edge @method.defs -> member
432+
} else {
433+
edge @method.static_defs -> member
434+
}
390435

391436
attr (member) pop_symbol = "."
392437

@@ -825,9 +870,6 @@ attribute node_symbol = node => symbol = (source-text node), source_n
825870
}
826871

827872
(resource . (identifier) @name .) @this {
828-
node @name.lexical_scope
829-
node @name.type
830-
831873
node ref
832874
node ref__typeof
833875

@@ -1043,24 +1085,45 @@ attribute node_symbol = node => symbol = (source-text node), source_n
10431085
; Expressions have a lexical scope (propagated to child expressions) and a type. The lexical scope is used for lexical name lookup, while types enable type-based name lookup (for field accesses, method lookup, and so forth).
10441086

10451087
[
1046-
(array_access)
10471088
(array_initializer)
1048-
(expression)
1049-
(field_access)
1089+
(assignment_expression)
1090+
(binary_expression)
1091+
(instanceof_expression)
1092+
(lambda_expression)
1093+
(ternary_expression)
1094+
(update_expression)
1095+
(decimal_integer_literal)
1096+
(hex_integer_literal)
1097+
(octal_integer_literal)
1098+
(binary_integer_literal)
1099+
(decimal_floating_point_literal)
1100+
(hex_floating_point_literal)
1101+
(true)
1102+
(false)
1103+
(character_literal)
1104+
(string_literal)
1105+
(null_literal)
1106+
(class_literal)
1107+
(this)
1108+
; (identifier)
10501109
(parenthesized_expression)
1051-
(primary_expression)
1110+
(object_creation_expression)
1111+
(field_access)
1112+
(array_access)
1113+
(method_invocation)
1114+
(method_reference)
1115+
(array_creation_expression)
1116+
(unary_expression)
1117+
(cast_expression)
1118+
(switch_expression)
10521119
(super)
1053-
(this)
10541120
] @expr
10551121
{
10561122
node @expr.type
10571123
node @expr.lexical_scope
10581124
}
10591125

10601126
(assignment_expression left: (identifier) @name) @this {
1061-
; FIXME: can we combine this with primary_expression/identifier?
1062-
node @name.lexical_scope
1063-
node @name.type
10641127
node member
10651128
node implicit_this
10661129
node implicit_this__typeof
@@ -1251,6 +1314,10 @@ attribute node_symbol = node => symbol = (source-text node), source_n
12511314
edge @type.lexical_scope -> @this.lexical_scope
12521315
}
12531316

1317+
(scoped_type_identifier . (_) @name) @this {
1318+
edge @name.lexical_scope -> @this.lexical_scope
1319+
}
1320+
12541321
(wildcard) @this
12551322
{
12561323
node @this.lexical_scope
@@ -1261,6 +1328,16 @@ attribute node_symbol = node => symbol = (source-text node), source_n
12611328
edge @this.type -> @this.lexical_scope
12621329
}
12631330

1331+
(scoped_type_identifier
1332+
(type_identifier) @imported_class_name (type_identifier) @method_name) {
1333+
1334+
node member
1335+
attr (member) push_symbol = "."
1336+
1337+
edge @method_name.type -> member
1338+
edge member -> @imported_class_name.type
1339+
}
1340+
12641341
;; ==========
12651342
;; Comments
12661343
;; ==========
@@ -1271,6 +1348,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n
12711348
node @line_comment.lexical_defs
12721349
node @line_comment.lexical_scope
12731350
node @line_comment.defs
1351+
node @line_comment.ref
1352+
node @line_comment.static_defs
12741353

12751354
edge @line_comment.after_scope -> @line_comment.before_scope
12761355
}
@@ -1279,6 +1358,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n
12791358
node @block_comment.before_scope
12801359
node @block_comment.after_scope
12811360
node @block_comment.defs
1361+
node @block_comment.ref
1362+
node @block_comment.static_defs
12821363
node @block_comment.lexical_scope
12831364

12841365
edge @block_comment.after_scope -> @block_comment.before_scope
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*--- path: Importer.java ---*/
2+
import foo.Foo;
3+
4+
public class Importer {
5+
public static void main(String[] args) {
6+
Foo.bar();
7+
// ^ defined: 16
8+
9+
}
10+
}
11+
12+
/* --- path: foo/Foo.java ---*/
13+
package foo;
14+
15+
public class Foo {
16+
public static void bar() {
17+
}
18+
}
Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
1-
/*--- path: a.java ---*/
2-
import foo.bar.Baz;
1+
/*--- path: Importer.java ---*/
2+
import foo.Foo;
3+
// ^ defined: 14
34

45
public class Importer {
5-
public static void main(String[] args) {
6-
Baz.some_method();
7-
// ^ defined: 2
6+
public Foo test() {
7+
// ^ defined: 2, 14
88
}
99
}
1010

11+
/* --- path: foo/Foo.java ---*/
12+
package foo;
1113

12-
/* --- path: b.java ---*/
13-
14-
import foo.bar.Baz;
15-
16-
public class AnotherImporter {
17-
public static void main(String[] args) {
18-
Baz.some_method();
19-
}
14+
public class Foo {
2015
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*--- path: Importer.java ---*/
2+
public class Importer {
3+
public Foo test() {
4+
// ^ defined: 9
5+
}
6+
}
7+
8+
/* --- path: Foo.java ---*/
9+
public class Foo {
10+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*--- path: Importer.java ---*/
2+
public class Importer {
3+
public static void main(String[] args) {
4+
Foo.bar();
5+
// ^ defined: 12
6+
7+
}
8+
}
9+
10+
/* --- path: Foo.java ---*/
11+
public class Foo {
12+
public static void bar() {
13+
}
14+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/*--- path: Importer.java ---*/
2+
public class Importer {
3+
public static void main(String[] args) {
4+
bar();
5+
// ^ defined:
6+
}
7+
}
8+
9+
/* --- path: Foo.java ---*/
10+
public class Foo {
11+
public static void bar() {
12+
}
13+
}

0 commit comments

Comments
 (0)