Skip to content

Commit 00a81a1

Browse files
Copilotjackfirth
andauthored
Add function-expression-analyzer for identifying application subexpressions (#708)
Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: jackfirth <[email protected]>
1 parent 2460d2e commit 00a81a1

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#lang resyntax/test
2+
3+
4+
require: resyntax/default-recommendations/analyzers/function-expression-analyzer function-expression-analyzer
5+
header: - #lang racket/base
6+
7+
8+
analysis-test: "applied functions should be annotated"
9+
--------------------
10+
(define (f)
11+
(list 1 2 3))
12+
--------------------
13+
@within - (list 1 2 3)
14+
@inspect - list
15+
@property application-subexpression-kind
16+
@assert function
17+
18+
19+
analysis-test: "applied function arguments should be annotated"
20+
--------------------
21+
(define (f x y z)
22+
(list x y z))
23+
--------------------
24+
@within - (list x y z)
25+
@inspect - y
26+
@property application-subexpression-kind
27+
@assert argument
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#lang racket/base
2+
3+
4+
(require racket/contract/base)
5+
6+
7+
(provide
8+
(contract-out
9+
[function-expression-analyzer expansion-analyzer?]))
10+
11+
12+
(require racket/stream
13+
rebellion/streaming/transducer
14+
resyntax/private/analyzer
15+
resyntax/private/syntax-path
16+
resyntax/private/syntax-property-bundle
17+
resyntax/private/syntax-traversal
18+
syntax/parse)
19+
20+
21+
;@----------------------------------------------------------------------------------------------------
22+
23+
24+
(define (annotate-application-subexpressions expanded-stx)
25+
(let loop ([expanded-stx expanded-stx] [phase 0])
26+
(syntax-search expanded-stx
27+
#:literal-sets ([kernel-literals #:phase phase])
28+
29+
;; Phase mismatch - recurse with correct phase
30+
[(id:id _ ...)
31+
#:do [(define id-phase (syntax-property (attribute id) 'phase))]
32+
#:when (not (equal? id-phase phase))
33+
(loop this-syntax id-phase)]
34+
35+
;; Skip quote-syntax - no function applications inside
36+
[(quote-syntax _) (stream)]
37+
38+
;; Function application - annotate function and arguments
39+
;; Note: In fully expanded code, we need to match #%plain-app using identifier comparison
40+
[(app-id:id func arg ...)
41+
#:when (free-identifier=? (attribute app-id) #'#%plain-app)
42+
#:do [(define func-path (syntax-property (attribute func) 'expansion-path))]
43+
#:when func-path
44+
(define func-entry (syntax-property-entry func-path 'application-subexpression-kind 'function))
45+
(define arg-entries
46+
(for/stream ([arg-stx (in-list (attribute arg))])
47+
(define arg-path (syntax-property arg-stx 'expansion-path))
48+
(and arg-path
49+
(syntax-property-entry arg-path 'application-subexpression-kind 'argument))))
50+
(stream-cons func-entry (stream-filter values arg-entries))])))
51+
52+
53+
(define function-expression-analyzer
54+
(make-expansion-analyzer
55+
#:name 'function-expression-analyzer
56+
(λ (expanded-stx)
57+
(define labeled-stx (syntax-label-paths expanded-stx 'expansion-path))
58+
(transduce (annotate-application-subexpressions labeled-stx)
59+
#:into into-syntax-property-bundle))))

0 commit comments

Comments
 (0)