brighterscript 0.70.3 → 0.71.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +3 -0
  2. package/dist/DiagnosticMessages.d.ts +21 -3
  3. package/dist/DiagnosticMessages.js +21 -3
  4. package/dist/DiagnosticMessages.js.map +1 -1
  5. package/dist/LanguageServer.d.ts +24 -0
  6. package/dist/LanguageServer.js +46 -2
  7. package/dist/LanguageServer.js.map +1 -1
  8. package/dist/Program.js +1 -1
  9. package/dist/Program.js.map +1 -1
  10. package/dist/ProgramBuilder.d.ts +1 -1
  11. package/dist/Scope.d.ts +14 -1
  12. package/dist/Scope.js +58 -6
  13. package/dist/Scope.js.map +1 -1
  14. package/dist/astUtils/reflection.d.ts +4 -2
  15. package/dist/astUtils/reflection.js +11 -2
  16. package/dist/astUtils/reflection.js.map +1 -1
  17. package/dist/astUtils/visitors.d.ts +4 -2
  18. package/dist/astUtils/visitors.js.map +1 -1
  19. package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +72 -6
  20. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +392 -110
  21. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  22. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +575 -0
  23. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  24. package/dist/bscPlugin/definition/DefinitionProvider.js +8 -0
  25. package/dist/bscPlugin/definition/DefinitionProvider.js.map +1 -1
  26. package/dist/bscPlugin/definition/DefinitionProvider.spec.js +84 -0
  27. package/dist/bscPlugin/definition/DefinitionProvider.spec.js.map +1 -1
  28. package/dist/bscPlugin/validation/BrsFileValidator.js +2 -1
  29. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
  30. package/dist/bscPlugin/validation/ScopeValidator.d.ts +6 -0
  31. package/dist/bscPlugin/validation/ScopeValidator.js +70 -0
  32. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
  33. package/dist/files/BrsFile.spec.js +251 -0
  34. package/dist/files/BrsFile.spec.js.map +1 -1
  35. package/dist/lexer/TokenKind.js +4 -2
  36. package/dist/lexer/TokenKind.js.map +1 -1
  37. package/dist/lsp/ProjectManager.d.ts +10 -0
  38. package/dist/lsp/ProjectManager.js +21 -4
  39. package/dist/lsp/ProjectManager.js.map +1 -1
  40. package/dist/lsp/ProjectManager.spec.js +30 -0
  41. package/dist/lsp/ProjectManager.spec.js.map +1 -1
  42. package/dist/parser/AstNode.spec.js +21 -0
  43. package/dist/parser/AstNode.spec.js.map +1 -1
  44. package/dist/parser/Expression.d.ts +26 -2
  45. package/dist/parser/Expression.js +47 -6
  46. package/dist/parser/Expression.js.map +1 -1
  47. package/dist/parser/Parser.d.ts +7 -1
  48. package/dist/parser/Parser.js +200 -20
  49. package/dist/parser/Parser.js.map +1 -1
  50. package/dist/parser/Parser.spec.js +418 -0
  51. package/dist/parser/Parser.spec.js.map +1 -1
  52. package/dist/parser/Statement.d.ts +20 -0
  53. package/dist/parser/Statement.js +51 -1
  54. package/dist/parser/Statement.js.map +1 -1
  55. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +70 -0
  56. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
  57. package/dist/parser/tests/statement/Enum.spec.js +318 -0
  58. package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
  59. package/dist/validators/ClassValidator.js +1 -1
  60. package/dist/validators/ClassValidator.js.map +1 -1
  61. package/package.json +6 -13
@@ -1190,6 +1190,136 @@ describe('parser', () => {
1190
1190
  (0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([-100]);
1191
1191
  });
1192
1192
  });
1193
+ describe('grouped type expressions', () => {
1194
+ it('is not allowed in brightscript mode', () => {
1195
+ let parser = parse(`
1196
+ sub main(param as (string or integer))
1197
+ print param
1198
+ end sub
1199
+ `, Parser_1.ParseMode.BrightScript);
1200
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.functionParameterTypeIsInvalid('param', '(')]);
1201
+ });
1202
+ it('allows group type expressions in parameters', () => {
1203
+ let { diagnostics } = parse(`
1204
+ sub main(param as (string or integer))
1205
+ print param
1206
+ end sub
1207
+ `, Parser_1.ParseMode.BrighterScript);
1208
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1209
+ });
1210
+ it('allows group type expressions in type casts', () => {
1211
+ let { diagnostics } = parse(`
1212
+ sub main(val)
1213
+ printThing(val as (string or integer))
1214
+ end sub
1215
+ sub printThing(thing as (string or integer))
1216
+ print thing
1217
+ end sub
1218
+ `, Parser_1.ParseMode.BrighterScript);
1219
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1220
+ });
1221
+ it('allows union of grouped type expressions', () => {
1222
+ let { diagnostics } = parse(`
1223
+ sub main(param as (string or integer) or (float or dynamic))
1224
+ print param
1225
+ end sub
1226
+ `, Parser_1.ParseMode.BrighterScript);
1227
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1228
+ });
1229
+ it('allows nested grouped type expressions', () => {
1230
+ let { diagnostics } = parse(`
1231
+ sub main(param as ((string or integer) or (float or dynamic)))
1232
+ print param
1233
+ end sub
1234
+ `, Parser_1.ParseMode.BrighterScript);
1235
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1236
+ });
1237
+ it('allows complicated grouped type expression', () => {
1238
+ let { diagnostics } = parse(`
1239
+ sub main(param as (({name as string} and {age as integer}) or (string and SomeInterface) or Klass and roAssociativeArray) )
1240
+ print param
1241
+ end sub
1242
+ `, Parser_1.ParseMode.BrighterScript);
1243
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1244
+ });
1245
+ });
1246
+ describe('union types', () => {
1247
+ it('is not allowed in brightscript mode', () => {
1248
+ let parser = parse(`
1249
+ sub main(param as string or integer)
1250
+ print param
1251
+ end sub
1252
+ `, Parser_1.ParseMode.BrightScript);
1253
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.expectedStatementOrFunctionCallButReceivedExpression()]);
1254
+ });
1255
+ it('allows union types in parameters', () => {
1256
+ let { diagnostics } = parse(`
1257
+ sub main(param as string or integer)
1258
+ print param
1259
+ end sub
1260
+ `, Parser_1.ParseMode.BrighterScript);
1261
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1262
+ });
1263
+ it('allows union types in type casts', () => {
1264
+ let { diagnostics } = parse(`
1265
+ sub main(val)
1266
+ printThing(val as string or integer)
1267
+ end sub
1268
+ sub printThing(thing as string or integer)
1269
+ print thing
1270
+ end sub
1271
+ `, Parser_1.ParseMode.BrighterScript);
1272
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1273
+ });
1274
+ });
1275
+ describe('intersection types', () => {
1276
+ it('is not allowed in brightscript mode', () => {
1277
+ let parser = parse(`
1278
+ sub main(param as string and integer)
1279
+ print param
1280
+ end sub
1281
+ `, Parser_1.ParseMode.BrightScript);
1282
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.expectedStatementOrFunctionCallButReceivedExpression()]);
1283
+ });
1284
+ it('allows intersection types in parameters', () => {
1285
+ let { diagnostics } = parse(`
1286
+ sub main(param as string and integer)
1287
+ print param
1288
+ end sub
1289
+ `, Parser_1.ParseMode.BrighterScript);
1290
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1291
+ });
1292
+ it('allows intersection types in type casts', () => {
1293
+ let { diagnostics } = parse(`
1294
+ sub main(val)
1295
+ printThing(val as string and integer)
1296
+ end sub
1297
+ sub printThing(thing as string and integer)
1298
+ print thing
1299
+ end sub
1300
+ `, Parser_1.ParseMode.BrighterScript);
1301
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1302
+ });
1303
+ describe('invalid syntax', () => {
1304
+ it('flags union type with missing sides', () => {
1305
+ let { diagnostics } = parse(`
1306
+ sub main(param as Thing or )
1307
+ print param
1308
+ end sub
1309
+ `, Parser_1.ParseMode.BrighterScript);
1310
+ (0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('or').message]);
1311
+ });
1312
+ it('flags missing type inside binary type', () => {
1313
+ var _a;
1314
+ let { diagnostics } = parse(`
1315
+ sub main(param as string or and float)
1316
+ print param
1317
+ end sub
1318
+ `, Parser_1.ParseMode.BrighterScript);
1319
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
1320
+ });
1321
+ });
1322
+ });
1193
1323
  describe('typecast statement', () => {
1194
1324
  it('allows typecast statement ', () => {
1195
1325
  let { ast, diagnostics } = parse(`
@@ -1297,6 +1427,294 @@ describe('parser', () => {
1297
1427
  (0, chai_config_spec_1.expect)(ast.statements[0].func.body.statements[0].name.text).to.eq('alias');
1298
1428
  });
1299
1429
  });
1430
+ describe('type statement', () => {
1431
+ it('allows type statement ', () => {
1432
+ let { ast, diagnostics } = parse(`
1433
+ TYPE x = string
1434
+ `, Parser_1.ParseMode.BrighterScript);
1435
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1436
+ (0, chai_config_spec_1.expect)((0, reflection_1.isTypeStatement)(ast.statements[0])).to.be.true;
1437
+ const stmt = ast.statements[0];
1438
+ (0, chai_config_spec_1.expect)(stmt.tokens.type.text).to.eq('TYPE');
1439
+ (0, chai_config_spec_1.expect)(stmt.tokens.value).to.exist;
1440
+ });
1441
+ it('is disallowed in brightscript mode', () => {
1442
+ let { diagnostics } = parse(`
1443
+ type x = string
1444
+ `, Parser_1.ParseMode.BrightScript);
1445
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
1446
+ DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('type statements')
1447
+ ]);
1448
+ });
1449
+ it('disallows `type` for function name', () => {
1450
+ let { diagnostics } = parse(`
1451
+ function type() as integer
1452
+ return 1
1453
+ end function
1454
+ `, Parser_1.ParseMode.BrighterScript);
1455
+ (0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
1456
+ DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier('type').message
1457
+ ]);
1458
+ });
1459
+ it('disallows `type` for variable name', () => {
1460
+ let { diagnostics } = parse(`
1461
+ function foo() as integer
1462
+ type = 1
1463
+ return type
1464
+ end function
1465
+ `, Parser_1.ParseMode.BrighterScript);
1466
+ (0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
1467
+ DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier('type').message
1468
+ ]);
1469
+ });
1470
+ it('has error when rhs is not a type', () => {
1471
+ let { diagnostics } = parse(`
1472
+ type x = 123
1473
+ `, Parser_1.ParseMode.BrighterScript);
1474
+ (0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
1475
+ DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('=').message
1476
+ ]);
1477
+ });
1478
+ it('allows type statement with complicated type', () => {
1479
+ let { ast, diagnostics } = parse(`
1480
+ type x = string or CustomKlass or roAssociativeArray
1481
+ `, Parser_1.ParseMode.BrighterScript);
1482
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1483
+ (0, chai_config_spec_1.expect)((0, reflection_1.isTypeStatement)(ast.statements[0])).to.be.true;
1484
+ const stmt = ast.statements[0];
1485
+ (0, chai_config_spec_1.expect)(stmt.tokens.type.text).to.eq('type');
1486
+ (0, chai_config_spec_1.expect)(stmt.tokens.value).to.exist;
1487
+ });
1488
+ });
1489
+ describe('inline interfaces', () => {
1490
+ it('inline interface param types disallowed in brightscript mode', () => {
1491
+ let { diagnostics } = parse(`
1492
+ sub test(foo as {x as string})
1493
+ print foo.x
1494
+ end sub
1495
+ `, Parser_1.ParseMode.BrightScript);
1496
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
1497
+ DiagnosticMessages_1.DiagnosticMessages.functionParameterTypeIsInvalid('foo', '{').message
1498
+ ]);
1499
+ });
1500
+ it('inline interface return types disallowed in brightscript mode', () => {
1501
+ let { diagnostics } = parse(`
1502
+ function test() as {x as string}
1503
+ print {x: "hello"}
1504
+ end function
1505
+ `, Parser_1.ParseMode.BrightScript);
1506
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
1507
+ DiagnosticMessages_1.DiagnosticMessages.invalidFunctionReturnType('{').message
1508
+ ]);
1509
+ });
1510
+ it('inline interface as param type', () => {
1511
+ let { ast, diagnostics } = parse(`
1512
+ sub test(foo as {x as string})
1513
+ print foo.x
1514
+ end sub
1515
+ `, Parser_1.ParseMode.BrighterScript);
1516
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1517
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
1518
+ });
1519
+ it('inline interface as return type', () => {
1520
+ let { ast, diagnostics } = parse(`
1521
+ function test() as {x as string}
1522
+ print {x: "hello"}
1523
+ end function
1524
+ `, Parser_1.ParseMode.BrighterScript);
1525
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1526
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
1527
+ });
1528
+ it('parses a big inline interface as param type', () => {
1529
+ let { ast, diagnostics } = parse(`
1530
+ sub test(foo as {
1531
+ x as string,
1532
+ y as {a as integer}
1533
+ z})
1534
+ print foo.x + y.a.toStr()
1535
+ end sub
1536
+ `, Parser_1.ParseMode.BrighterScript);
1537
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1538
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
1539
+ });
1540
+ it('allows optional members', () => {
1541
+ let { ast, diagnostics } = parse(`
1542
+ sub test(p as {x as string, optional y})
1543
+ end sub
1544
+ `, Parser_1.ParseMode.BrighterScript);
1545
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1546
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
1547
+ });
1548
+ it('is allowed as typecast', () => {
1549
+ let { diagnostics } = parse(`
1550
+ sub test(p)
1551
+ print (p as {name as string}).name
1552
+ end sub
1553
+ `, Parser_1.ParseMode.BrighterScript);
1554
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1555
+ });
1556
+ it('is allowed as class and interface field', () => {
1557
+ let { diagnostics } = parse(`
1558
+ class Klass
1559
+ x as {name as string}
1560
+ end class
1561
+ interface Iface
1562
+ y as {age as integer}
1563
+ end interface
1564
+ `, Parser_1.ParseMode.BrighterScript);
1565
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1566
+ });
1567
+ it('can have custom type as member type', () => {
1568
+ let { diagnostics } = parse(`
1569
+ interface IFace
1570
+ name as string
1571
+ end interface
1572
+ function test(z as {foo as IFace})
1573
+ return z.foo.name
1574
+ end function
1575
+ `, Parser_1.ParseMode.BrighterScript);
1576
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1577
+ });
1578
+ it('can have per-member doc comment', () => {
1579
+ let { diagnostics } = parse(`
1580
+ interface IFace
1581
+ inline as {
1582
+ ' comment 1
1583
+ name as string
1584
+ ' comment 2
1585
+ age as integer
1586
+ }
1587
+ end interface
1588
+ function test(z as {foo as IFace})
1589
+ return z.foo.inline.name
1590
+ end function
1591
+ `, Parser_1.ParseMode.BrighterScript);
1592
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1593
+ });
1594
+ it('can have string literals as members', () => {
1595
+ let { diagnostics } = parse(`
1596
+ function test(z as {"this is a stringliteral" as string})
1597
+ return z["this is a stringliteral"]
1598
+ end function
1599
+ `, Parser_1.ParseMode.BrighterScript);
1600
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1601
+ });
1602
+ });
1603
+ describe('for each with types', () => {
1604
+ it('parses without errors', () => {
1605
+ let { diagnostics } = parse(`
1606
+ function main()
1607
+ for each item as string in ["a", "b", "c"]
1608
+ print item
1609
+ end for
1610
+ end function
1611
+ `, Parser_1.ParseMode.BrighterScript);
1612
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1613
+ });
1614
+ it('allows complicated expressions', () => {
1615
+ let { diagnostics } = parse(`
1616
+ function main(data)
1617
+ for each item as {a as integer or boolean, b as SomeInterface[], c as {id as string} } or string in data
1618
+ print item
1619
+ end for
1620
+ end function
1621
+ `, Parser_1.ParseMode.BrighterScript);
1622
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1623
+ });
1624
+ });
1625
+ describe('typed functions as types', () => {
1626
+ it('disallowed in brightscript mode', () => {
1627
+ let { diagnostics } = parse(`
1628
+ function test(func as function())
1629
+ return func()
1630
+ end function
1631
+ `, Parser_1.ParseMode.BrightScript);
1632
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
1633
+ DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(')')
1634
+ ]);
1635
+ });
1636
+ it('can be passed as param types', () => {
1637
+ let { diagnostics } = parse(`
1638
+ function test(func as function())
1639
+ return func()
1640
+ end function
1641
+ `, Parser_1.ParseMode.BrighterScript);
1642
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1643
+ });
1644
+ it('can have a return type', () => {
1645
+ let { diagnostics } = parse(`
1646
+ function test(func as sub() as integer) as integer
1647
+ return func()
1648
+ end function
1649
+ `, Parser_1.ParseMode.BrighterScript);
1650
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1651
+ });
1652
+ it('can use sub or function', () => {
1653
+ let { diagnostics } = parse(`
1654
+ function test(func as sub() as integer) as integer
1655
+ return func()
1656
+ end function
1657
+
1658
+ function test2(func as function() as integer) as integer
1659
+ return func()
1660
+ end function
1661
+ `, Parser_1.ParseMode.BrighterScript);
1662
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1663
+ });
1664
+ it('can have primitive parameters', () => {
1665
+ let { diagnostics } = parse(`
1666
+ function test(func as function(name as string, num as integer) as integer) as integer
1667
+ return func("hello", 123)
1668
+ end function
1669
+ `, Parser_1.ParseMode.BrighterScript);
1670
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1671
+ });
1672
+ it('can have complex parameters', () => {
1673
+ let { diagnostics } = parse(`
1674
+ interface IFace
1675
+ name as string
1676
+ end interface
1677
+
1678
+ function test(func as function(thing as IFace) as integer) as integer
1679
+ return func({name: "hello"})
1680
+ end function
1681
+ `, Parser_1.ParseMode.BrighterScript);
1682
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1683
+ });
1684
+ it('can have compound parameters', () => {
1685
+ let { diagnostics } = parse(`
1686
+ interface IFace
1687
+ name as string
1688
+ end interface
1689
+
1690
+ function test(func as function(arg1 as string or integer, arg2 as IFace) as integer) as integer
1691
+ return func("hello", {name: "hello"})
1692
+ end function
1693
+ `, Parser_1.ParseMode.BrighterScript);
1694
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1695
+ });
1696
+ it('can be used as return types', () => {
1697
+ let { diagnostics } = parse(`
1698
+ function test() as function() as integer
1699
+ return function() as integer
1700
+ return 123
1701
+ end function
1702
+ end function
1703
+ `, Parser_1.ParseMode.BrighterScript);
1704
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1705
+ });
1706
+ it('can have a union as return type', () => {
1707
+ let { diagnostics } = parse(`
1708
+ type foo = function() as integer or string
1709
+ function test() as foo
1710
+ return function() as integer
1711
+ return 123
1712
+ end function
1713
+ end function
1714
+ `, Parser_1.ParseMode.BrighterScript);
1715
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1716
+ });
1717
+ });
1300
1718
  });
1301
1719
  function parse(text, mode) {
1302
1720
  let { tokens } = Lexer_1.Lexer.scan(text);