@@ -673,7 +673,7 @@ trait Printers
673
673
indented {
674
674
val name1 = if (name == " _" ) " this" else name
675
675
this += " " += highlightValDef(name1, color) += " : "
676
- printTypeTree(tpt)
676
+ printTypeTree(tpt, Some (cdef.symbol) )
677
677
this += " =>"
678
678
}
679
679
}
@@ -1037,7 +1037,7 @@ trait Printers
1037
1037
printList(trees, sep, printTree)
1038
1038
1039
1039
def printTypeTrees (trees : List [TypeTree ], sep : String ): Buffer =
1040
- printList(trees, sep, printTypeTree)
1040
+ printList(trees, sep, ( t : TypeTree ) => printTypeTree(t) )
1041
1041
1042
1042
def printTypes (trees : List [Type ], sep : String ): Buffer = {
1043
1043
def printSeparated (list : List [Type ]): Unit = list match {
@@ -1118,12 +1118,12 @@ trait Printers
1118
1118
this
1119
1119
}
1120
1120
1121
- def printTypesOrBounds (types : List [TypeOrBounds ], sep : String ): Buffer = {
1121
+ def printTypesOrBounds (types : List [TypeOrBounds ], sep : String , selfIn : Option [ Symbol ] = None ): Buffer = {
1122
1122
def printSeparated (list : List [TypeOrBounds ]): Unit = list match {
1123
1123
case Nil =>
1124
- case x :: Nil => printTypeOrBound(x)
1124
+ case x :: Nil => printTypeOrBound(x, selfIn )
1125
1125
case x :: xs =>
1126
- printTypeOrBound(x)
1126
+ printTypeOrBound(x, selfIn )
1127
1127
this += sep
1128
1128
printSeparated(xs)
1129
1129
}
@@ -1341,19 +1341,26 @@ trait Printers
1341
1341
this += highlightLiteral(" '" + v.name, color)
1342
1342
}
1343
1343
1344
- def printTypeOrBoundsTree (tpt : TypeOrBoundsTree ): Buffer = tpt match {
1344
+ def printTypeOrBoundsTree (tpt : TypeOrBoundsTree , selfIn : Option [ Symbol ] = None ): Buffer = tpt match {
1345
1345
case TypeBoundsTree (lo, hi) =>
1346
1346
this += " _ >: "
1347
- printTypeTree(lo)
1347
+ printTypeTree(lo, selfIn )
1348
1348
this += " <: "
1349
- printTypeTree(hi)
1349
+ printTypeTree(hi, selfIn )
1350
1350
case tpt @ WildcardTypeTree () =>
1351
- printTypeOrBound(tpt.tpe)
1351
+ printTypeOrBound(tpt.tpe, selfIn )
1352
1352
case IsTypeTree (tpt) =>
1353
- printTypeTree(tpt)
1353
+ printTypeTree(tpt, selfIn )
1354
1354
}
1355
1355
1356
- def printTypeTree (tree : TypeTree ): Buffer = tree match {
1356
+ /** Print type tree
1357
+ *
1358
+ * @param selfIn The current type is a self type in the indicated class.
1359
+ * NoSymbol means the current type is not a self type annotation.
1360
+ * Self type annotation should elide current class prefix to avoid
1361
+ * cyclic type checking error.
1362
+ */
1363
+ def printTypeTree (tree : TypeTree , selfIn : Option [Symbol ] = None ): Buffer = tree match {
1357
1364
case TypeTree .Inferred () =>
1358
1365
// TODO try to move this logic into `printType`
1359
1366
def printTypeAndAnnots (tpe : Type ): Buffer = tpe match {
@@ -1363,25 +1370,25 @@ trait Printers
1363
1370
printAnnotation(annot)
1364
1371
case Type .SymRef (IsClassSymbol (sym), _) if sym.fullName == " scala.runtime.Null$" || sym.fullName == " scala.runtime.Nothing$" =>
1365
1372
// scala.runtime.Null$ and scala.runtime.Nothing$ are not modules, those are their actual names
1366
- printType(tpe)
1373
+ printType(tpe, selfIn )
1367
1374
case tpe @ Type .SymRef (IsClassSymbol (sym), _) if sym.name.endsWith(" $" ) =>
1368
- printType(tpe)
1375
+ printType(tpe, selfIn )
1369
1376
this += " .type"
1370
1377
case tpe @ Type .SymRef (sym, _) if sym.isTerm =>
1371
- printType(tpe)
1378
+ printType(tpe, selfIn )
1372
1379
this += " .type"
1373
- case tpe => printType(tpe)
1380
+ case tpe => printType(tpe, selfIn )
1374
1381
}
1375
1382
printTypeAndAnnots(tree.tpe)
1376
1383
1377
1384
case TypeTree .Ident (name) =>
1378
- printType(tree.tpe)
1385
+ printType(tree.tpe, selfIn )
1379
1386
1380
1387
case TypeTree .Select (qual, name) =>
1381
1388
printTree(qual) += " ." += highlightTypeDef(name, color)
1382
1389
1383
1390
case TypeTree .Projection (qual, name) =>
1384
- printTypeTree(qual) += " #" += highlightTypeDef(name, color)
1391
+ printTypeTree(qual, selfIn ) += " #" += highlightTypeDef(name, color)
1385
1392
1386
1393
case TypeTree .Singleton (ref) =>
1387
1394
printTree(ref)
@@ -1391,35 +1398,35 @@ trait Printers
1391
1398
}
1392
1399
1393
1400
case TypeTree .Refined (tpt, refinements) =>
1394
- printTypeTree(tpt)
1401
+ printTypeTree(tpt, selfIn )
1395
1402
inBlock(printTrees(refinements, " ; " ))
1396
1403
1397
1404
case TypeTree .Applied (tpt, args) =>
1398
- printTypeTree(tpt)
1405
+ printTypeTree(tpt, selfIn )
1399
1406
inSquare(printTypeOrBoundsTrees(args, " , " ))
1400
1407
1401
1408
case TypeTree .Annotated (tpt, annot) =>
1402
1409
val Annotation (ref, args) = annot
1403
1410
ref.tpe match {
1404
1411
case Types .RepeatedAnnotation () =>
1405
1412
val Types .Sequence (tp) = tpt.tpe
1406
- printType(tp)
1413
+ printType(tp, selfIn )
1407
1414
this += highlightTypeDef(" *" , color)
1408
1415
case _ =>
1409
- printTypeTree(tpt)
1416
+ printTypeTree(tpt, selfIn )
1410
1417
this += " "
1411
1418
printAnnotation(annot)
1412
1419
}
1413
1420
1414
1421
case TypeTree .And (left, right) =>
1415
- printTypeTree(left)
1422
+ printTypeTree(left, selfIn )
1416
1423
this += highlightTypeDef(" & " , color)
1417
- printTypeTree(right)
1424
+ printTypeTree(right, selfIn )
1418
1425
1419
1426
case TypeTree .Or (left, right) =>
1420
- printTypeTree(left)
1427
+ printTypeTree(left, selfIn )
1421
1428
this += highlightTypeDef(" | " , color)
1422
- printTypeTree(right)
1429
+ printTypeTree(right, selfIn )
1423
1430
1424
1431
case TypeTree .MatchType (bound, selector, cases) =>
1425
1432
printTypeTree(selector)
@@ -1428,48 +1435,56 @@ trait Printers
1428
1435
1429
1436
case TypeTree .ByName (result) =>
1430
1437
this += highlightTypeDef(" => " , color)
1431
- printTypeTree(result)
1438
+ printTypeTree(result, selfIn )
1432
1439
1433
1440
case TypeTree .LambdaTypeTree (tparams, body) =>
1434
1441
printTargsDefs(tparams.zip(tparams), isDef = false )
1435
1442
this += highlightTypeDef(" => " , color)
1436
- printTypeOrBoundsTree(body)
1443
+ printTypeOrBoundsTree(body, selfIn )
1437
1444
1438
1445
case TypeTree .TypeBind (name, _) =>
1439
1446
this += highlightTypeDef(name, color)
1440
1447
1441
1448
case TypeTree .TypeBlock (aliases, tpt) =>
1442
1449
inBlock {
1443
1450
printTrees(aliases, lineBreak())
1444
- printTypeTree(tpt)
1451
+ printTypeTree(tpt, selfIn )
1445
1452
}
1446
1453
1447
1454
case _ =>
1448
1455
throw new MatchError (tree.show)
1449
1456
1450
1457
}
1451
1458
1452
- def printTypeOrBound (tpe : TypeOrBounds ): Buffer = tpe match {
1459
+ def printTypeOrBound (tpe : TypeOrBounds , selfIn : Option [ Symbol ] = None ): Buffer = tpe match {
1453
1460
case tpe@ TypeBounds (lo, hi) =>
1454
1461
this += " _ >: "
1455
- printType(lo)
1462
+ printType(lo, selfIn )
1456
1463
this += " <: "
1457
- printType(hi)
1458
- case IsType (tpe) => printType(tpe)
1464
+ printType(hi, selfIn )
1465
+ case IsType (tpe) => printType(tpe, selfIn )
1459
1466
}
1460
1467
1461
- def printType (tpe : Type ): Buffer = tpe match {
1468
+ /** Print type
1469
+ *
1470
+ * @param selfIn The current type is a self type in the indicated class.
1471
+ * Self type annotation should elide current class prefix to avoid
1472
+ * cyclic type checking error.
1473
+ */
1474
+ def printType (tpe : Type , selfIn : Option [Symbol ] = None ): Buffer = tpe match {
1462
1475
case Type .ConstantType (const) =>
1463
1476
printConstant(const)
1464
1477
1465
1478
case Type .SymRef (sym, prefix) if sym.isType =>
1466
1479
prefix match {
1467
1480
case Types .EmptyPrefix () =>
1468
1481
case IsType (prefix @ Type .SymRef (IsClassSymbol (_), _)) =>
1469
- printType(prefix)
1482
+ printType(prefix, selfIn )
1470
1483
this += " #"
1484
+ case IsType (Type .ThisType (Type .SymRef (cdef, _)))
1485
+ if selfIn.nonEmpty && cdef == selfIn.get =>
1471
1486
case IsType (prefix) =>
1472
- printType(prefix)
1487
+ printType(prefix, selfIn )
1473
1488
this += " ."
1474
1489
}
1475
1490
this += highlightTypeDef(sym.name.stripSuffix(" $" ), color)
@@ -1479,7 +1494,7 @@ trait Printers
1479
1494
case Types .EmptyPrefix () =>
1480
1495
this += highlightTypeDef(sym.name, color)
1481
1496
case _ =>
1482
- printTypeOrBound(prefix)
1497
+ printTypeOrBound(prefix, selfIn )
1483
1498
if (sym.name != " package" )
1484
1499
this += " ." += highlightTypeDef(sym.name, color)
1485
1500
this
@@ -1490,7 +1505,7 @@ trait Printers
1490
1505
case Type .ThisType (Types .EmptyPackage ()) =>
1491
1506
this += highlightTypeDef(name, color)
1492
1507
case IsType (prefix) =>
1493
- printType(prefix)
1508
+ printType(prefix, selfIn )
1494
1509
if (name != " package" )
1495
1510
this += " ." += highlightTypeDef(name, color)
1496
1511
this
@@ -1501,7 +1516,7 @@ trait Printers
1501
1516
case Type .TypeRef (name, prefix) =>
1502
1517
prefix match {
1503
1518
case NoPrefix () | Type .ThisType (Types .EmptyPackage ()) =>
1504
- case IsType (prefix) => printType(prefix) += " ."
1519
+ case IsType (prefix) => printType(prefix, selfIn ) += " ."
1505
1520
}
1506
1521
if (name.endsWith(" $" )) this += highlightTypeDef(name.stripSuffix(" $" ), color) += " .type"
1507
1522
else this += highlightTypeDef(name, color)
@@ -1514,25 +1529,25 @@ trait Printers
1514
1529
case Type .TypeRef (" <repeated>" , Types .ScalaPackage ()) =>
1515
1530
this += " _*"
1516
1531
case _ =>
1517
- printType(tp)
1532
+ printType(tp, selfIn )
1518
1533
inSquare(printTypesOrBounds(args, " , " ))
1519
1534
}
1520
1535
1521
1536
case Type .AnnotatedType (tp, annot) =>
1522
1537
val Annotation (ref, args) = annot
1523
- printType(tp)
1538
+ printType(tp, selfIn )
1524
1539
this += " "
1525
1540
printAnnotation(annot)
1526
1541
1527
1542
case Type .AndType (left, right) =>
1528
- printType(left)
1543
+ printType(left, selfIn )
1529
1544
this += highlightTypeDef(" & " , color)
1530
- printType(right)
1545
+ printType(right, selfIn )
1531
1546
1532
1547
case Type .OrType (left, right) =>
1533
- printType(left)
1548
+ printType(left, selfIn )
1534
1549
this += highlightTypeDef(" | " , color)
1535
- printType(right)
1550
+ printType(right, selfIn )
1536
1551
1537
1552
case Type .MatchType (bound, scrutinee, cases) =>
1538
1553
printType(scrutinee)
@@ -1561,13 +1576,13 @@ trait Printers
1561
1576
}
1562
1577
1563
1578
case Type .SuperType (thistpe, supertpe) =>
1564
- printType(supertpe)
1579
+ printType(supertpe, selfIn )
1565
1580
this += highlightTypeDef(" .super" , color)
1566
1581
1567
1582
case Type .TypeLambda (paramNames, tparams, body) =>
1568
1583
inSquare(printMethodicTypeParams(paramNames, tparams))
1569
1584
this += highlightTypeDef(" => " , color)
1570
- printTypeOrBound(body)
1585
+ printTypeOrBound(body, selfIn )
1571
1586
1572
1587
case Type .ParamRef (lambda, idx) =>
1573
1588
lambda match {
@@ -1577,7 +1592,7 @@ trait Printers
1577
1592
}
1578
1593
1579
1594
case Type .RecursiveType (tpe) =>
1580
- printType(tpe)
1595
+ printType(tpe, selfIn )
1581
1596
1582
1597
case Type .RecursiveThis (_) =>
1583
1598
this += highlightTypeDef(" this" , color)
0 commit comments