@@ -7,6 +7,8 @@ package dotty.tools
7
7
package dotc
8
8
package core
9
9
10
+ import scala .language .{unsafeNulls => _ }
11
+
10
12
import Symbols ._
11
13
import Types .{TermRef , NoPrefix }
12
14
import Flags ._
@@ -50,11 +52,11 @@ object Scopes {
50
52
51
53
/** the next entry in the hash bucket
52
54
*/
53
- var tail : ScopeEntry = null
55
+ var tail : ScopeEntry | Null = null
54
56
55
57
/** the preceding entry in this scope
56
58
*/
57
- var prev : ScopeEntry = null
59
+ var prev : ScopeEntry | Null = null
58
60
59
61
override def toString : String = sym.toString
60
62
}
@@ -88,7 +90,7 @@ object Scopes {
88
90
def iterator (using Context ): Iterator [Symbol ] = toList.iterator
89
91
90
92
/** Is the scope empty? */
91
- def isEmpty : Boolean = lastEntry eq null
93
+ def isEmpty : Boolean = lastEntry == null
92
94
93
95
/** Applies a function f to all Symbols of this Scope. */
94
96
def foreach [U ](f : Symbol => U )(using Context ): Unit = toList.foreach(f)
@@ -98,7 +100,7 @@ object Scopes {
98
100
ensureComplete()
99
101
var syms : List [Symbol ] = Nil
100
102
var e = lastEntry
101
- while ((e ne null ) && e.owner == this ) {
103
+ while ((e != null ) && e.owner == this ) {
102
104
val sym = e.sym
103
105
if (p(sym)) syms = sym :: syms
104
106
e = e.prev
@@ -122,20 +124,20 @@ object Scopes {
122
124
def lookupEntry (name : Name )(using Context ): ScopeEntry | Null
123
125
124
126
/** Lookup next entry with same name as this one */
125
- def lookupNextEntry (entry : ScopeEntry )(using Context ): ScopeEntry
127
+ def lookupNextEntry (entry : ScopeEntry )(using Context ): ScopeEntry | Null
126
128
127
129
/** Lookup a symbol */
128
130
final def lookup (name : Name )(using Context ): Symbol = {
129
131
val e = lookupEntry(name)
130
- if (e eq null ) NoSymbol else e.sym
132
+ if (e == null ) NoSymbol else e.sym
131
133
}
132
134
133
135
/** Returns an iterator yielding every symbol with given name in this scope.
134
136
*/
135
137
final def lookupAll (name : Name )(using Context ): Iterator [Symbol ] = new Iterator [Symbol ] {
136
138
var e = lookupEntry(name)
137
- def hasNext : Boolean = e ne null
138
- def next (): Symbol = { val r = e.sym; e = lookupNextEntry(e); r }
139
+ def hasNext : Boolean = e != null
140
+ def next (): Symbol = { val r = e.uncheckedNN. sym; e = lookupNextEntry(e.uncheckedNN ); r }
139
141
}
140
142
141
143
/** Does this scope contain a reference to `sym` when looking up `name`? */
@@ -163,13 +165,13 @@ object Scopes {
163
165
* a copy with the matching symbols.
164
166
*/
165
167
final def filteredScope (p : Symbol => Boolean )(using Context ): Scope = {
166
- var result : MutableScope = null
168
+ var result : MutableScope | Null = null
167
169
for (sym <- iterator)
168
170
if (! p(sym)) {
169
171
if (result == null ) result = cloneScope
170
- result.unlink(sym)
172
+ result.nn. unlink(sym)
171
173
}
172
- if (result == null ) this else result
174
+ if (result == null ) this else result.nn
173
175
}
174
176
175
177
def implicitDecls (using Context ): List [TermRef ] = Nil
@@ -193,7 +195,7 @@ object Scopes {
193
195
* This is necessary because when run from reflection every scope needs to have a
194
196
* SynchronizedScope as mixin.
195
197
*/
196
- class MutableScope protected [Scopes ](initElems : ScopeEntry , initSize : Int , val nestingLevel : Int )
198
+ class MutableScope protected [Scopes ](initElems : ScopeEntry | Null , initSize : Int , val nestingLevel : Int )
197
199
extends Scope {
198
200
199
201
/** Scope shares elements with `base` */
@@ -213,14 +215,14 @@ object Scopes {
213
215
214
216
/** the hash table
215
217
*/
216
- private var hashTable : Array [ScopeEntry ] = null
218
+ private var hashTable : Array [ScopeEntry | Null ] | Null = null
217
219
218
220
/** a cache for all elements, to be used by symbol iterator.
219
221
*/
220
- private var elemsCache : List [Symbol ] = null
222
+ private var elemsCache : List [Symbol ] | Null = null
221
223
222
224
/** The synthesizer to be used, or `null` if no synthesis is done on this scope */
223
- private var synthesize : SymbolSynthesizer = null
225
+ private var synthesize : SymbolSynthesizer | Null = null
224
226
225
227
/** Use specified synthesize for this scope */
226
228
def useSynthesizer (s : SymbolSynthesizer ): Unit = synthesize = s
@@ -232,7 +234,7 @@ object Scopes {
232
234
def cloneScope (using Context ): MutableScope = {
233
235
val entries = new mutable.ArrayBuffer [ScopeEntry ]
234
236
var e = lastEntry
235
- while ((e ne null ) && e.owner == this ) {
237
+ while ((e != null ) && e.owner == this ) {
236
238
entries += e
237
239
e = e.prev
238
240
}
@@ -247,21 +249,21 @@ object Scopes {
247
249
248
250
/** create and enter a scope entry with given name and symbol */
249
251
protected def newScopeEntry (name : Name , sym : Symbol )(using Context ): ScopeEntry = {
250
- ensureCapacity(if (hashTable ne null ) hashTable.length else MinHashedScopeSize )
252
+ ensureCapacity(if (hashTable != null ) hashTable.uncheckedNN .length else MinHashedScopeSize )
251
253
val e = new ScopeEntry (name, sym, this )
252
254
e.prev = lastEntry
253
255
lastEntry = e
254
- if (hashTable ne null ) enterInHash(e)
256
+ if (hashTable != null ) enterInHash(e)
255
257
size += 1
256
258
elemsCache = null
257
259
e
258
260
}
259
261
260
262
private def enterInHash (e : ScopeEntry )(using Context ): Unit = {
261
- val idx = e.name.hashCode & (hashTable.length - 1 )
262
- e.tail = hashTable(idx)
263
+ val idx = e.name.hashCode & (hashTable.nn. length - 1 )
264
+ e.tail = hashTable.nn (idx)
263
265
assert(e.tail != e)
264
- hashTable(idx) = e
266
+ hashTable.nn (idx) = e
265
267
}
266
268
267
269
/** enter a symbol in this scope. */
@@ -289,21 +291,21 @@ object Scopes {
289
291
private def createHash (tableSize : Int )(using Context ): Unit =
290
292
if (size > tableSize * FillFactor ) createHash(tableSize * 2 )
291
293
else {
292
- hashTable = new Array [ScopeEntry ](tableSize)
294
+ hashTable = new Array [ScopeEntry | Null ](tableSize)
293
295
enterAllInHash(lastEntry)
294
296
// checkConsistent() // DEBUG
295
297
}
296
298
297
- private def enterAllInHash (e : ScopeEntry , n : Int = 0 )(using Context ): Unit =
298
- if (e ne null )
299
+ private def enterAllInHash (e : ScopeEntry | Null , n : Int = 0 )(using Context ): Unit =
300
+ if (e != null )
299
301
if (n < MaxRecursions ) {
300
302
enterAllInHash(e.prev, n + 1 )
301
303
enterInHash(e)
302
304
}
303
305
else {
304
306
var entries : List [ScopeEntry ] = List ()
305
- var ee = e
306
- while (ee ne null ) {
307
+ var ee : ScopeEntry | Null = e
308
+ while (ee != null ) {
307
309
entries = ee :: entries
308
310
ee = ee.prev
309
311
}
@@ -315,18 +317,18 @@ object Scopes {
315
317
if (lastEntry == e)
316
318
lastEntry = e.prev
317
319
else {
318
- var e1 = lastEntry
319
- while (e1.prev != e) e1 = e1.prev
320
+ var e1 = lastEntry.nn
321
+ while (e1.prev != e) e1 = e1.prev.nn
320
322
e1.prev = e.prev
321
323
}
322
- if (hashTable ne null ) {
323
- val index = e.name.hashCode & (hashTable.length - 1 )
324
- var e1 = hashTable(index)
324
+ if (hashTable != null ) {
325
+ val index = e.name.hashCode & (hashTable.nn. length - 1 )
326
+ var e1 = hashTable.nn (index)
325
327
if (e1 == e)
326
- hashTable(index) = e.tail
328
+ hashTable.nn (index) = e.tail
327
329
else {
328
- while (e1.tail != e) e1 = e1.tail
329
- e1.tail = e.tail
330
+ while (e1.nn. tail != e) e1 = e1.nn .tail
331
+ e1.nn. tail = e.tail
330
332
}
331
333
}
332
334
elemsCache = null
@@ -340,7 +342,7 @@ object Scopes {
340
342
/** remove symbol from this scope if it is present under the given name */
341
343
final def unlink (sym : Symbol , name : Name )(using Context ): Unit = {
342
344
var e = lookupEntry(name)
343
- while (e ne null ) {
345
+ while (e != null ) {
344
346
if (e.sym == sym) unlink(e)
345
347
e = lookupNextEntry(e)
346
348
}
@@ -352,7 +354,7 @@ object Scopes {
352
354
final def replace (prev : Symbol , replacement : Symbol )(using Context ): Unit = {
353
355
require(prev.name == replacement.name)
354
356
var e = lookupEntry(prev.name)
355
- while (e ne null ) {
357
+ while (e != null ) {
356
358
if (e.sym == prev) e.sym = replacement
357
359
e = lookupNextEntry(e)
358
360
}
@@ -362,55 +364,55 @@ object Scopes {
362
364
/** Lookup a symbol entry matching given name.
363
365
*/
364
366
override def lookupEntry (name : Name )(using Context ): ScopeEntry | Null = {
365
- var e : ScopeEntry = null
366
- if (hashTable ne null ) {
367
- e = hashTable(name.hashCode & (hashTable.length - 1 ))
368
- while ((e ne null ) && e.name != name)
367
+ var e : ScopeEntry | Null = null
368
+ if (hashTable != null ) {
369
+ e = hashTable.nn (name.hashCode & (hashTable.nn .length - 1 ))
370
+ while ((e != null ) && e.name != name)
369
371
e = e.tail
370
372
}
371
373
else {
372
374
e = lastEntry
373
- while ((e ne null ) && e.name != name)
375
+ while ((e != null ) && e.name != name)
374
376
e = e.prev
375
377
}
376
- if ((e eq null ) && (synthesize != null )) {
377
- val sym = synthesize(name)
378
+ if ((e == null ) && (synthesize != null )) {
379
+ val sym = synthesize.uncheckedNN (name)
378
380
if (sym.exists) newScopeEntry(sym.name, sym) else e
379
381
}
380
382
else e
381
383
}
382
384
383
385
/** lookup next entry with same name as this one */
384
- override final def lookupNextEntry (entry : ScopeEntry )(using Context ): ScopeEntry = {
385
- var e = entry
386
- if (hashTable ne null )
387
- while ({ e = e.tail ; (e ne null ) && e.name != entry.name }) ()
386
+ override final def lookupNextEntry (entry : ScopeEntry )(using Context ): ScopeEntry | Null = {
387
+ var e : ScopeEntry | Null = entry
388
+ if (hashTable != null )
389
+ while ({ e = e.nn. tail ; (e != null ) && e.uncheckedNN .name != entry.name }) ()
388
390
else
389
- while ({ e = e.prev ; (e ne null ) && e.name != entry.name }) ()
391
+ while ({ e = e.nn. prev ; (e != null ) && e.uncheckedNN .name != entry.name }) ()
390
392
e
391
393
}
392
394
393
395
/** Returns all symbols as a list in the order they were entered in this scope.
394
396
* Does _not_ include the elements of inherited scopes.
395
397
*/
396
398
override final def toList (using Context ): List [Symbol ] = {
397
- if (elemsCache eq null ) {
399
+ if (elemsCache == null ) {
398
400
ensureComplete()
399
401
elemsCache = Nil
400
402
var e = lastEntry
401
- while ((e ne null ) && e.owner == this ) {
402
- elemsCache = e.sym :: elemsCache
403
+ while ((e != null ) && e.owner == this ) {
404
+ elemsCache = e.sym :: elemsCache.nn
403
405
e = e.prev
404
406
}
405
407
}
406
- elemsCache
408
+ elemsCache.nn
407
409
}
408
410
409
411
override def implicitDecls (using Context ): List [TermRef ] = {
410
412
ensureComplete()
411
413
var irefs = new mutable.ListBuffer [TermRef ]
412
414
var e = lastEntry
413
- while (e ne null ) {
415
+ while (e != null ) {
414
416
if (e.sym.isOneOf(GivenOrImplicitVal )) {
415
417
val d = e.sym.denot
416
418
irefs += TermRef (NoPrefix , d.symbol.asTerm).withDenot(d)
@@ -433,7 +435,7 @@ object Scopes {
433
435
while (e != null ) {
434
436
var e1 = lookupEntry(e.name)
435
437
while (e1 != e && e1 != null ) e1 = lookupNextEntry(e1)
436
- assert(e1 == e, s " PANIC: Entry ${e.name} is badly linked " )
438
+ assert(e1 == e, s " PANIC: Entry ${e.nn. name} is badly linked " )
437
439
e = e.prev
438
440
}
439
441
}
@@ -463,12 +465,12 @@ object Scopes {
463
465
/** The empty scope (immutable).
464
466
*/
465
467
object EmptyScope extends Scope {
466
- override private [dotc] def lastEntry : ScopeEntry = null
468
+ override private [dotc] def lastEntry : ScopeEntry | Null = null
467
469
override def size : Int = 0
468
470
override def nestingLevel : Int = 0
469
471
override def toList (using Context ): List [Symbol ] = Nil
470
472
override def cloneScope (using Context ): MutableScope = unsupported(" cloneScope" )
471
- override def lookupEntry (name : Name )(using Context ): ScopeEntry = null
472
- override def lookupNextEntry (entry : ScopeEntry )(using Context ): ScopeEntry = null
473
+ override def lookupEntry (name : Name )(using Context ): ScopeEntry | Null = null
474
+ override def lookupNextEntry (entry : ScopeEntry )(using Context ): ScopeEntry | Null = null
473
475
}
474
476
}
0 commit comments