1
1
package compiler
2
2
3
3
import (
4
+ "context"
4
5
"sync"
5
6
6
7
"github.com/microsoft/typescript-go/internal/ast"
@@ -22,26 +23,28 @@ const (
22
23
CheckerPoolModeDynamic
23
24
)
24
25
25
- type checkerPool struct {
26
+ type CheckerPool struct {
26
27
mode CheckerPoolMode
27
28
maxCheckers int
28
29
program * Program
29
30
30
- mu sync.Mutex
31
- cond * sync.Cond
32
- createCheckersOnce sync.Once
33
- checkers []* checker.Checker
34
- inUse map [* checker.Checker ]bool
35
- fileAssociations map [* ast.SourceFile ]* checker.Checker
31
+ mu sync.Mutex
32
+ cond * sync.Cond
33
+ createCheckersOnce sync.Once
34
+ checkers []* checker.Checker
35
+ inUse map [* checker.Checker ]bool
36
+ fileAssociations map [* ast.SourceFile ]* checker.Checker
37
+ requestAssociations map [string ]* checker.Checker
36
38
}
37
39
38
- func newCheckerPool (mode CheckerPoolMode , maxCheckers int , program * Program ) * checkerPool {
39
- pool := & checkerPool {
40
- mode : mode ,
41
- program : program ,
42
- maxCheckers : maxCheckers ,
43
- checkers : make ([]* checker.Checker , 0 , maxCheckers ),
44
- inUse : make (map [* checker.Checker ]bool ),
40
+ func newCheckerPool (mode CheckerPoolMode , maxCheckers int , program * Program ) * CheckerPool {
41
+ pool := & CheckerPool {
42
+ mode : mode ,
43
+ program : program ,
44
+ maxCheckers : maxCheckers ,
45
+ checkers : make ([]* checker.Checker , 0 , maxCheckers ),
46
+ inUse : make (map [* checker.Checker ]bool ),
47
+ requestAssociations : make (map [string ]* checker.Checker ),
45
48
}
46
49
47
50
if mode == CheckerPoolModeDynamic {
@@ -51,7 +54,7 @@ func newCheckerPool(mode CheckerPoolMode, maxCheckers int, program *Program) *ch
51
54
return pool
52
55
}
53
56
54
- func (p * checkerPool ) getCheckerForFile ( file * ast.SourceFile ) (* checker.Checker , func ()) {
57
+ func (p * CheckerPool ) GetCheckerForFile ( ctx context. Context , file * ast.SourceFile ) (* checker.Checker , func ()) {
55
58
if p .mode == CheckerPoolModeStatic {
56
59
p .createCheckers ()
57
60
checker := p .fileAssociations [file ]
@@ -61,51 +64,74 @@ func (p *checkerPool) getCheckerForFile(file *ast.SourceFile) (*checker.Checker,
61
64
p .mu .Lock ()
62
65
defer p .mu .Unlock ()
63
66
67
+ requestID := core .GetRequestID (ctx )
68
+ if requestID != "" {
69
+ if checker , ok := p .requestAssociations [requestID ]; ok {
70
+ if inUse := p .inUse [checker ]; ! inUse {
71
+ p .inUse [checker ] = true
72
+ return checker , p .createRelease (requestID , checker )
73
+ }
74
+ return checker , noop
75
+ }
76
+ }
77
+
64
78
if p .fileAssociations == nil {
65
79
p .fileAssociations = make (map [* ast.SourceFile ]* checker.Checker )
66
80
}
67
81
68
82
if checker , ok := p .fileAssociations [file ]; ok {
69
83
if inUse := p .inUse [checker ]; ! inUse {
70
84
p .inUse [checker ] = true
71
- return checker , p .createRelease (checker )
85
+ if requestID != "" {
86
+ p .requestAssociations [requestID ] = checker
87
+ }
88
+ return checker , p .createRelease (requestID , checker )
72
89
}
73
90
}
74
91
75
- checker , release := p .getCheckerLocked ()
92
+ checker , release := p .getCheckerLocked (requestID )
76
93
p .fileAssociations [file ] = checker
77
94
return checker , release
78
95
}
79
96
80
- func (p * checkerPool ) getChecker ( ) (* checker.Checker , func ()) {
97
+ func (p * CheckerPool ) GetChecker ( ctx context. Context ) (* checker.Checker , func ()) {
81
98
if p .mode == CheckerPoolModeStatic {
82
99
p .createCheckers ()
83
100
checker := p .checkers [0 ]
84
101
return checker , noop
85
102
}
86
103
p .mu .Lock ()
87
104
defer p .mu .Unlock ()
88
- return p .getCheckerLocked ()
105
+ return p .getCheckerLocked (core . GetRequestID ( ctx ) )
89
106
}
90
107
91
- func (p * checkerPool ) getCheckerLocked () (* checker.Checker , func ()) {
108
+ func (p * CheckerPool ) getCheckerLocked (requestID string ) (* checker.Checker , func ()) {
92
109
if checker := p .getImmediatelyAvailableChecker (); checker != nil {
93
110
p .inUse [checker ] = true
94
- return checker , p .createRelease (checker )
111
+ if requestID != "" {
112
+ p .requestAssociations [requestID ] = checker
113
+ }
114
+ return checker , p .createRelease (requestID , checker )
95
115
}
96
116
97
117
if len (p .checkers ) < p .maxCheckers {
98
118
checker := p .createCheckerLocked ()
99
119
p .inUse [checker ] = true
100
- return checker , p .createRelease (checker )
120
+ if requestID != "" {
121
+ p .requestAssociations [requestID ] = checker
122
+ }
123
+ return checker , p .createRelease (requestID , checker )
101
124
}
102
125
103
126
checker := p .waitForAvailableChecker ()
104
127
p .inUse [checker ] = true
105
- return checker , p .createRelease (checker )
128
+ if requestID != "" {
129
+ p .requestAssociations [requestID ] = checker
130
+ }
131
+ return checker , p .createRelease (requestID , checker )
106
132
}
107
133
108
- func (p * checkerPool ) getImmediatelyAvailableChecker () * checker.Checker {
134
+ func (p * CheckerPool ) getImmediatelyAvailableChecker () * checker.Checker {
109
135
if len (p .checkers ) == 0 {
110
136
return nil
111
137
}
@@ -119,7 +145,7 @@ func (p *checkerPool) getImmediatelyAvailableChecker() *checker.Checker {
119
145
return nil
120
146
}
121
147
122
- func (p * checkerPool ) waitForAvailableChecker () * checker.Checker {
148
+ func (p * CheckerPool ) waitForAvailableChecker () * checker.Checker {
123
149
for {
124
150
p .cond .Wait ()
125
151
checker := p .getImmediatelyAvailableChecker ()
@@ -129,16 +155,17 @@ func (p *checkerPool) waitForAvailableChecker() *checker.Checker {
129
155
}
130
156
}
131
157
132
- func (p * checkerPool ) createRelease (checker * checker.Checker ) func () {
158
+ func (p * CheckerPool ) createRelease (requestId string , checker * checker.Checker ) func () {
133
159
return func () {
134
160
p .mu .Lock ()
135
161
defer p .mu .Unlock ()
162
+
136
163
p .inUse [checker ] = false
137
164
p .cond .Signal ()
138
165
}
139
166
}
140
167
141
- func (p * checkerPool ) createCheckers () {
168
+ func (p * CheckerPool ) createCheckers () {
142
169
if p .mode != CheckerPoolModeStatic {
143
170
panic ("checkerPool.createCheckers() should only be called in static mode" )
144
171
}
@@ -164,13 +191,13 @@ func (p *checkerPool) createCheckers() {
164
191
})
165
192
}
166
193
167
- func (p * checkerPool ) createCheckerLocked () * checker.Checker {
194
+ func (p * CheckerPool ) createCheckerLocked () * checker.Checker {
168
195
checker := checker .NewChecker (p .program )
169
196
p .checkers = append (p .checkers , checker )
170
197
return checker
171
198
}
172
199
173
- func (p * checkerPool ) getAllCheckers () []* checker.Checker {
200
+ func (p * CheckerPool ) getAllCheckers () []* checker.Checker {
174
201
if p .mode != CheckerPoolModeStatic {
175
202
panic ("checkerPool.getAllCheckers() should only be called in static mode" )
176
203
}
0 commit comments