Parser.st
changeset 7 6c2bc76f0b8f
parent 4 f6fd83437415
child 9 a855c33612fb
equal deleted inserted replaced
6:0cd4e7480440 7:6c2bc76f0b8f
    21                               usedInstVars usedClassVars usedVars
    21                               usedInstVars usedClassVars usedVars
    22                               modifiedInstVars modifiedClassVars
    22                               modifiedInstVars modifiedClassVars
    23                               localVarDefPosition
    23                               localVarDefPosition
    24                               evalExitBlock
    24                               evalExitBlock
    25                               selfNode superNode primNr logged
    25                               selfNode superNode primNr logged
    26 			      warnedUndefVars'
    26                               warnedUndefVars'
    27        classVariableNames:'prevClass prevInstVarNames 
    27        classVariableNames:'prevClass prevInstVarNames 
    28                            prevClassVarNames prevClassInstVarNames'
    28                            prevClassVarNames prevClassInstVarNames'
    29        poolDictionaries:''
    29        poolDictionaries:''
    30        category:'System-Compiler'
    30        category:'System-Compiler'
    31 !
    31 !
    41 
    41 
    42 Parser is also used to find the referenced/modified inst/classvars of
    42 Parser is also used to find the referenced/modified inst/classvars of
    43 a method - this is done by sending parseXXX message to a parser and asking
    43 a method - this is done by sending parseXXX message to a parser and asking
    44 the parser for referencedXVars or modifiedXVars (see SystemBrowser).
    44 the parser for referencedXVars or modifiedXVars (see SystemBrowser).
    45 
    45 
    46 $Header: /cvs/stx/stx/libcomp/Parser.st,v 1.3 1993-10-13 02:41:36 claus Exp $
    46 $Header: /cvs/stx/stx/libcomp/Parser.st,v 1.4 1993-12-11 01:09:03 claus Exp $
    47 '!
    47 '!
    48 
    48 
    49 !Parser class methodsFor:'evaluating expressions'!
    49 !Parser class methodsFor:'evaluating expressions'!
    50 
    50 
    51 evaluate:aString
    51 evaluate:aString
   146     ^ parser
   146     ^ parser
   147 ! !
   147 ! !
   148 
   148 
   149 !Parser class methodsFor:'parsing'!
   149 !Parser class methodsFor:'parsing'!
   150 
   150 
       
   151 selectorInExpression:aString
       
   152     "parse an expression - return the selector. Used for
       
   153      SystemBrowsers implementors/senders query-box initial text"
       
   154 
       
   155     |tree parser|
       
   156 
       
   157     (aString isNil or:[aString isEmpty]) ifTrue:[^ nil].
       
   158 
       
   159     tree := self withSelf:nil parseExpression:aString notifying:nil ignoreErrors:true. 
       
   160     (tree notNil and:[tree ~~ #Error]) ifTrue:[
       
   161 	tree isMessage ifTrue:[
       
   162             ^ tree selector
       
   163 	].
       
   164     ].
       
   165 
       
   166     "mhmh, try expression without receiver"
       
   167 
       
   168     parser := self for:(ReadStream on:aString).
       
   169     parser ignoreErrors.
       
   170     parser nextToken.
       
   171     ^ parser degeneratedKeywordExpressionForSelector
       
   172 
       
   173 "
       
   174     Parser selectorInExpression:'foo at:1 put:(5 * bar)'
       
   175     Parser selectorInExpression:'(foo at:1) at:1'
       
   176     Parser selectorInExpression:'1 + 4'
       
   177     Parser selectorInExpression:'1 negated'
       
   178     Parser selectorInExpression:'at:1 put:5'
       
   179 "
       
   180 !
       
   181 
   151 parseExpression:aString
   182 parseExpression:aString
   152     "parse aString as an expression; return the parseTree"
   183     "parse aString as an expression; return the parseTree"
   153 
   184 
   154     ^ self withSelf:nil parseExpression:aString notifying:nil
   185     ^ self withSelf:nil parseExpression:aString notifying:nil ignoreErrors:false 
   155 !
   186 !
   156 
   187 
   157 withSelf:anObject parseExpression:aString notifying:someOne
   188 withSelf:anObject parseExpression:aString notifying:someOne 
       
   189     "parse aString as an expression with self set to anObject;
       
   190      return the parseTree"
       
   191 
       
   192     ^ self withSelf:anObject parseExpression:aString notifying:someOne ignoreErrors:false 
       
   193 !
       
   194 
       
   195 withSelf:anObject parseExpression:aString notifying:someOne ignoreErrors:ignore
   158     "parse aString as an expression with self set to anObject;
   196     "parse aString as an expression with self set to anObject;
   159      return the parseTree"
   197      return the parseTree"
   160 
   198 
   161     |parser tree|
   199     |parser tree|
   162 
   200 
   163     aString isNil ifTrue:[^ nil].
   201     aString isNil ifTrue:[^ nil].
   164     parser := self for:(ReadStream on:aString).
   202     parser := self for:(ReadStream on:aString).
   165     parser setSelf:anObject.
   203     parser setSelf:anObject.
   166     parser notifying:someOne.
   204     parser notifying:someOne.
       
   205     ignore ifTrue:[parser ignoreErrors].
   167     parser nextToken.
   206     parser nextToken.
   168     tree := parser expression.
   207     tree := parser expression.
   169     (parser errorFlag or:[tree == #Error]) ifTrue:[^ #Error].
   208     (parser errorFlag or:[tree == #Error]) ifTrue:[^ #Error].
   170     ^ tree
   209     ^ tree
   171 !
   210 !
   262         prevInstVarNames := nil.
   301         prevInstVarNames := nil.
   263         prevClassVarNames := nil.
   302         prevClassVarNames := nil.
   264         prevClassInstVarNames := nil.
   303         prevClassInstVarNames := nil.
   265         aClass removeDependent:Parser
   304         aClass removeDependent:Parser
   266     ]
   305     ]
       
   306 !
       
   307 
       
   308 flush
       
   309     "unconditional flush name caches"
       
   310 
       
   311     prevClass notNil ifTrue:[
       
   312         prevClass removeDependent:Parser
       
   313     ].
       
   314     prevClass := nil.
       
   315     prevInstVarNames := nil.
       
   316     prevClassVarNames := nil.
       
   317     prevClassInstVarNames := nil.
       
   318 
       
   319     "Parser flush"
   267 ! !
   320 ! !
   268 
   321 
   269 !Parser methodsFor:'setup'!
   322 !Parser methodsFor:'setup'!
   270 
   323 
   271 setClassToCompileFor:aClass
   324 setClassToCompileFor:aClass
   450 undefError:aName position:pos1 to:pos2
   503 undefError:aName position:pos1 to:pos2
   451     "report an undefined variable error - return true, if it should be
   504     "report an undefined variable error - return true, if it should be
   452      corrected"
   505      corrected"
   453 
   506 
   454     requestor isNil ifTrue:[
   507     requestor isNil ifTrue:[
   455 	warnedUndefVars notNil ifTrue:[
   508         warnedUndefVars notNil ifTrue:[
   456 	    (warnedUndefVars includes:aName) ifTrue:[
   509             (warnedUndefVars includes:aName) ifTrue:[
   457 		"already warned about this one"
   510                 "already warned about this one"
   458 		^ false
   511                 ^ false
   459 	    ].
   512             ].
   460 	].
   513         ].
   461 	self showErrorMessage:('Error: ' , aName , ' is undefined') position:pos1.
   514         self showErrorMessage:('Error: ' , aName , ' is undefined') position:pos1.
   462 	warnedUndefVars isNil ifTrue:[
   515         warnedUndefVars isNil ifTrue:[
   463 	    warnedUndefVars := Set new.
   516             warnedUndefVars := Set new.
   464 	].
   517         ].
   465 	warnedUndefVars add:aName.
   518         warnedUndefVars add:aName.
   466 	^ false
   519         ^ false
   467     ].
   520     ].
   468 
   521 
   469     ^ self correctableError:('Error: ' , aName , ' is undefined') 
   522     ^ self correctableError:('Error: ' , aName , ' is undefined') 
   470                    position:pos1 to:pos2
   523                    position:pos1 to:pos2
   471 !
   524 !
   548     |stats|
   601     |stats|
   549 
   602 
   550     ((tokenType == #BinaryOperator) and:[tokenName = '<']) ifTrue:[
   603     ((tokenType == #BinaryOperator) and:[tokenName = '<']) ifTrue:[
   551         "an ST-80 primitive - parsed but ignored"
   604         "an ST-80 primitive - parsed but ignored"
   552         self nextToken.
   605         self nextToken.
   553         primNr := self parsePrimitive.
   606         primNr := self parseST80Primitive.
   554         (primNr == #Error) ifTrue:[^ #Error].
   607         (primNr == #Error) ifTrue:[^ #Error].
   555         self warning:'ST-80 primitives not supported - ignored'
   608         self warning:'ST-80 primitives not supported - ignored'
   556     ].
   609     ].
   557 
   610 
   558     (self parseMethodBodyVarSpec == #Error) ifTrue:[^ #Error].
   611     (self parseMethodBodyVarSpec == #Error) ifTrue:[^ #Error].
   606         self nextToken
   659         self nextToken
   607     ].
   660     ].
   608     ^ nil
   661     ^ nil
   609 !
   662 !
   610 
   663 
   611 parsePrimitive
   664 parseST80Primitive
   612     "parse an ST-80 type primitive;
   665     "parse an ST-80 type primitive as '< primitive: nr >';
   613     return primitive number or #Error"
   666     return primitive number or #Error"
   614 
   667 
   615     |primNumber|
   668     |primNumber|
   616 
   669 
   617     ((tokenType == #Keyword) and:[tokenName = 'primitive:']) ifFalse:[
   670     ((tokenType == #Keyword) and:[tokenName = 'primitive:']) ifFalse:[
   841         receiver lineNumber:lno
   894         receiver lineNumber:lno
   842     ].
   895     ].
   843     ^ receiver
   896     ^ receiver
   844 !
   897 !
   845 
   898 
       
   899 degeneratedKeywordExpressionForSelector
       
   900     "parse a keyword-expression without receiver - for the selector
       
   901      only. return the selector or nil"
       
   902 
       
   903     |receiver sel arg args pos1 pos2 try lno note|
       
   904 
       
   905     (tokenType == #Keyword) ifTrue:[
       
   906         sel := tokenName.
       
   907         self nextToken.
       
   908         arg := self binaryExpression.
       
   909         (arg == #Error) ifTrue:[^ sel].
       
   910         [tokenType == #Keyword] whileTrue:[
       
   911             sel := sel , tokenName.
       
   912             self nextToken.
       
   913             arg := self binaryExpression.
       
   914             (arg == #Error) ifTrue:[^ sel].
       
   915         ].
       
   916 	^ sel
       
   917     ].
       
   918     ^ nil
       
   919 !
       
   920 
   846 binaryExpression
   921 binaryExpression
   847     "parse a binary-expression; return a node-tree, nil or #Error"
   922     "parse a binary-expression; return a node-tree, nil or #Error"
   848 
   923 
   849     |receiver arg sel pos try lno note|
   924     |receiver arg sel pos try lno note|
   850 
   925 
  1154     ].
  1229     ].
  1155 
  1230 
  1156     "is it a method-variable ?"
  1231     "is it a method-variable ?"
  1157     methodVars notNil ifTrue:[
  1232     methodVars notNil ifTrue:[
  1158         instIndex := methodVarNames indexOf:varName.
  1233         instIndex := methodVarNames indexOf:varName.
  1159         (instIndex ~~ 0) ifTrue:[
  1234         instIndex ~~ 0 ifTrue:[
  1160             var := methodVars at:instIndex.
  1235             var := methodVars at:instIndex.
  1161             var used:true.
  1236             var used:true.
  1162             ^ PrimaryNode type:#MethodVariable
  1237             ^ PrimaryNode type:#MethodVariable
  1163                           name:varName
  1238                           name:varName
  1164                          token:var
  1239                          token:var
  1167     ].
  1242     ].
  1168 
  1243 
  1169     "is it a method-argument ?"
  1244     "is it a method-argument ?"
  1170     methodArgs notNil ifTrue:[
  1245     methodArgs notNil ifTrue:[
  1171         instIndex := methodArgNames indexOf:varName.
  1246         instIndex := methodArgNames indexOf:varName.
  1172         (instIndex ~~ 0) ifTrue:[
  1247         instIndex ~~ 0 ifTrue:[
  1173             ^ PrimaryNode type:#MethodArg
  1248             ^ PrimaryNode type:#MethodArg
  1174                           name:varName
  1249                           name:varName
  1175                          token:(methodArgs at:instIndex)
  1250                          token:(methodArgs at:instIndex)
  1176                          index:instIndex
  1251                          index:instIndex
  1177         ]
  1252         ]
  1190             prevClassInstVarNames := nil.
  1265             prevClassInstVarNames := nil.
  1191             prevClassVarNames := nil.
  1266             prevClassVarNames := nil.
  1192             prevClass addDependent:Parser
  1267             prevClass addDependent:Parser
  1193         ].
  1268         ].
  1194 
  1269 
  1195         instIndex := prevInstVarNames indexOf:varName startingAt:1
  1270         instIndex := prevInstVarNames indexOf:varName startingAt:1.
  1196                                                         ifAbsent:[nil].
  1271         instIndex ~~ 0 ifTrue:[
  1197         instIndex notNil ifTrue:[
       
  1198             usedInstVars isNil ifTrue:[
  1272             usedInstVars isNil ifTrue:[
  1199                 usedInstVars := OrderedCollection new
  1273                 usedInstVars := OrderedCollection new
  1200             ].
  1274             ].
  1201             (usedInstVars includes:varName) ifFalse:[
  1275             (usedInstVars includes:varName) ifFalse:[
  1202                 usedInstVars add:varName
  1276                 usedInstVars add:varName
  1218     classToCompileFor notNil ifTrue:[
  1292     classToCompileFor notNil ifTrue:[
  1219         prevClassInstVarNames isNil ifTrue:[
  1293         prevClassInstVarNames isNil ifTrue:[
  1220             prevClassInstVarNames := classToCompileFor class allInstVarNames
  1294             prevClassInstVarNames := classToCompileFor class allInstVarNames
  1221         ].
  1295         ].
  1222 
  1296 
  1223         instIndex := prevClassInstVarNames indexOf:varName startingAt:1
  1297         instIndex := prevClassInstVarNames indexOf:varName startingAt:1.
  1224                                                              ifAbsent:[nil].
  1298         instIndex ~~ 0 ifTrue:[
  1225 
       
  1226         instIndex notNil ifTrue:[
       
  1227             aClass := self inWhichClassIsClassInstVar:varName.
  1299             aClass := self inWhichClassIsClassInstVar:varName.
  1228             aClass notNil ifTrue:[
  1300             aClass notNil ifTrue:[
  1229                 usedVars isNil ifTrue:[
  1301                 usedVars isNil ifTrue:[
  1230                     usedVars := OrderedCollection new
  1302                     usedVars := OrderedCollection new
  1231                 ].
  1303                 ].
  1253                 ]
  1325                 ]
  1254             ].
  1326             ].
  1255             prevClassVarNames := aClass allClassVarNames
  1327             prevClassVarNames := aClass allClassVarNames
  1256         ].
  1328         ].
  1257 
  1329 
  1258         instIndex := prevClassVarNames indexOf:varName startingAt:1
  1330         instIndex := prevClassVarNames indexOf:varName startingAt:1.
  1259                                                          ifAbsent:[nil].
  1331         instIndex ~~ 0 ifTrue:[
  1260 
       
  1261         instIndex notNil ifTrue:[
       
  1262             aClass := self inWhichClassIsClassVar:varName.
  1332             aClass := self inWhichClassIsClassVar:varName.
  1263             aClass notNil ifTrue:[
  1333             aClass notNil ifTrue:[
  1264                 usedClassVars isNil ifTrue:[
  1334                 usedClassVars isNil ifTrue:[
  1265                     usedClassVars := OrderedCollection new
  1335                     usedClassVars := OrderedCollection new
  1266                 ].
  1336                 ].
  1344 !
  1414 !
  1345 
  1415 
  1346 block
  1416 block
  1347     "parse a block; return a node-tree, nil or #Error"
  1417     "parse a block; return a node-tree, nil or #Error"
  1348 
  1418 
  1349     |stats node args var vars pos|
  1419     |stats node args var vars pos lno b|
  1350 
  1420 
       
  1421     lno := tokenLineNr.
  1351     self nextToken.
  1422     self nextToken.
  1352     (tokenType == $: ) ifTrue:[
  1423     (tokenType == $: ) ifTrue:[
  1353         [tokenType == $:] whileTrue:[
  1424         [tokenType == $:] whileTrue:[
  1354             pos := tokenPosition.
  1425             pos := tokenPosition.
  1355             self nextToken.
  1426             self nextToken.
  1367             self nextToken
  1438             self nextToken
  1368         ].
  1439         ].
  1369         (tokenType ~~ $| ) ifTrue:[
  1440         (tokenType ~~ $| ) ifTrue:[
  1370             "ST-80 allows [:arg ]"
  1441             "ST-80 allows [:arg ]"
  1371             (tokenType == $] ) ifTrue:[
  1442             (tokenType == $] ) ifTrue:[
  1372                 ^ BlockNode arguments:args home:currentBlock variables:nil.
  1443                 b := BlockNode arguments:args home:currentBlock variables:nil.
       
  1444                 b lineNumber:lno.
       
  1445                 ^ b
  1373             ].
  1446             ].
  1374             self syntaxError:'| expected after block-arg declaration'.
  1447             self syntaxError:'| expected after block-arg declaration'.
  1375             ^ #Error
  1448             ^ #Error
  1376         ].
  1449         ].
  1377         self nextToken
  1450         self nextToken
  1393             self nextToken
  1466             self nextToken
  1394         ].
  1467         ].
  1395         self nextToken
  1468         self nextToken
  1396     ].
  1469     ].
  1397     node := BlockNode arguments:args home:currentBlock variables:vars.
  1470     node := BlockNode arguments:args home:currentBlock variables:vars.
       
  1471     node lineNumber:lno.
  1398     currentBlock := node.
  1472     currentBlock := node.
  1399     stats := self blockStatementList.
  1473     stats := self blockStatementList.
  1400     node statements:stats.
  1474     node statements:stats.
  1401     currentBlock := node home.
  1475     currentBlock := node home.
  1402     (stats == #Error) ifTrue:[^ #Error].
  1476     (stats == #Error) ifTrue:[^ #Error].
  1441     ].
  1515     ].
  1442     ^ firstStatement
  1516     ^ firstStatement
  1443 !
  1517 !
  1444 
  1518 
  1445 array
  1519 array
  1446     |arr elem pos1 pos2|
  1520     |arr elem pos1|
  1447 
  1521 
  1448     pos1 := tokenPosition.
  1522     pos1 := tokenPosition.
  1449     arr := OrderedCollection new:200.
  1523     arr := OrderedCollection new:200.
  1450     [tokenType ~~ $) ] whileTrue:[
  1524     [tokenType ~~ $) ] whileTrue:[
  1451         elem := self arrayConstant.
  1525         elem := self arrayConstant.
  1461     ].
  1535     ].
  1462     ^ Array withAll:arr
  1536     ^ Array withAll:arr
  1463 !
  1537 !
  1464 
  1538 
  1465 byteArray
  1539 byteArray
  1466     "for ST-80 R4 - allow byteArray constants"
  1540     "started with ST-80 R4 - allow byteArray constants as #[ ... ]"
       
  1541 
  1467     |arr elem pos1 pos2|
  1542     |arr elem pos1 pos2|
  1468 
  1543 
  1469     pos1 := tokenPosition.
  1544     pos1 := tokenPosition.
  1470     arr := OrderedCollection new.
  1545     arr := OrderedCollection new.
  1471     [tokenType ~~ $] ] whileTrue:[
  1546     [tokenType ~~ $] ] whileTrue:[
  1588     [searchBlock notNil] whileTrue:[
  1663     [searchBlock notNil] whileTrue:[
  1589         args := searchBlock arguments.
  1664         args := searchBlock arguments.
  1590         args notNil ifTrue:[
  1665         args notNil ifTrue:[
  1591             args do:[:aBlockArg |
  1666             args do:[:aBlockArg |
  1592                 names add:(aBlockArg name).
  1667                 names add:(aBlockArg name).
  1593                 dists add:(aString levenshteinTo:(aBlockArg name))
  1668                 dists add:(aString spellAgainst: "levenshteinTo:"(aBlockArg name))
  1594             ]
  1669             ]
  1595         ].
  1670         ].
  1596 
  1671 
  1597         vars := searchBlock variables.
  1672         vars := searchBlock variables.
  1598         vars notNil ifTrue:[
  1673         vars notNil ifTrue:[
  1599             vars do:[:aBlockVar |
  1674             vars do:[:aBlockVar |
  1600                 names add:(aBlockVar name).
  1675                 names add:(aBlockVar name).
  1601                 dists add:(aString levenshteinTo:(aBlockVar name))
  1676                 dists add:(aString spellAgainst: "levenshteinTo:"(aBlockVar name))
  1602             ]
  1677             ]
  1603         ].
  1678         ].
  1604         searchBlock := searchBlock home
  1679         searchBlock := searchBlock home
  1605     ].
  1680     ].
  1606 
  1681 
  1607     "method-variables"
  1682     "method-variables"
  1608     methodVars notNil ifTrue:[
  1683     methodVars notNil ifTrue:[
  1609         methodVarNames do:[:methodVarName |
  1684         methodVarNames do:[:methodVarName |
  1610             names add:methodVarName.
  1685             names add:methodVarName.
  1611             dists add:(aString levenshteinTo:methodVarName)
  1686             dists add:(aString spellAgainst: "levenshteinTo:"methodVarName)
  1612         ]
  1687         ]
  1613     ].
  1688     ].
  1614 
  1689 
  1615     "method-arguments"
  1690     "method-arguments"
  1616     methodArgs notNil ifTrue:[
  1691     methodArgs notNil ifTrue:[
  1617         methodArgNames do:[:methodArgName |
  1692         methodArgNames do:[:methodArgName |
  1618             names add:methodArgName.
  1693             names add:methodArgName.
  1619             dists add:(aString levenshteinTo:methodArgName)
  1694             dists add:(aString spellAgainst: "levenshteinTo:"methodArgName)
  1620         ]
  1695         ]
  1621     ].
  1696     ].
  1622 
  1697 
  1623     "instance-variables"
  1698     "instance-variables"
  1624     classToCompileFor notNil ifTrue:[
  1699     classToCompileFor notNil ifTrue:[
  1625         prevInstVarNames do:[:instVarName |
  1700         prevInstVarNames do:[:instVarName |
  1626             names add:instVarName.
  1701             names add:instVarName.
  1627             dists add:(aString levenshteinTo:instVarName)
  1702             dists add:(aString spellAgainst: "levenshteinTo:"instVarName)
  1628         ]
  1703         ]
  1629     ].
  1704     ].
  1630 
  1705 
  1631     "class-variables"
  1706     "class-variables"
  1632     classToCompileFor notNil ifTrue:[
  1707     classToCompileFor notNil ifTrue:[
       
  1708         prevClassVarNames do:[:classVarName |
       
  1709             names add:classVarName.
       
  1710             dists add:(aString spellAgainst: "levenshteinTo:"classVarName)
       
  1711         ].
       
  1712 
       
  1713 false ifTrue:[
  1633         aClass := classToCompileFor.
  1714         aClass := classToCompileFor.
  1634         aClass isMeta ifTrue:[
  1715         aClass isMeta ifTrue:[
  1635             className := aClass name.
  1716             className := aClass name.
  1636             className := className copyFrom:1 to:(className size - 5).
  1717             className := className copyFrom:1 to:(className size - 5).
  1637             baseClass := Smalltalk at:(className asSymbol).
  1718             baseClass := Smalltalk at:(className asSymbol).
  1640             ]
  1721             ]
  1641         ].
  1722         ].
  1642         [aClass notNil] whileTrue:[
  1723         [aClass notNil] whileTrue:[
  1643             (aClass classVarNames) do:[:classVarName |
  1724             (aClass classVarNames) do:[:classVarName |
  1644                 names add:classVarName.
  1725                 names add:classVarName.
  1645                 dists add:(aString levenshteinTo:classVarName)
  1726                 dists add:(aString spellAgainst: "levenshteinTo:"classVarName)
  1646             ].
  1727             ].
  1647             aClass := aClass superclass
  1728             aClass := aClass superclass
  1648         ]
  1729         ]
       
  1730 ].
  1649     ].
  1731     ].
  1650 
  1732 
  1651     "globals"
  1733     "globals"
  1652     Smalltalk allKeysDo:[:aKey |
  1734     Smalltalk allKeysDo:[:aKey |
  1653         globalVarName := aKey asString.
  1735         globalVarName := aKey asString.
  1654         "only compare strings where length is about right"
  1736         "only compare strings where length is about right"
  1655         ((globalVarName size - aString size) abs < 3) ifTrue:[
  1737         ((globalVarName size - aString size) abs < 3) ifTrue:[
  1656             names add:globalVarName.
  1738             names add:globalVarName.
  1657             dists add:(aString levenshteinTo:globalVarName)
  1739             dists add:(aString spellAgainst: "levenshteinTo:"globalVarName)
  1658         ]
  1740         ]
  1659     ].
  1741     ].
  1660 
  1742 
  1661     "misc"
  1743     "misc"
  1662     #('self' 'super' 'nil') do:[:name |
  1744     #('self' 'super' 'nil' 'thisContext') do:[:name |
  1663         "only compare strings where length is about right"
  1745         "only compare strings where length is about right"
  1664         ((name size - aString size) abs < 3) ifTrue:[
  1746         names add:name.
  1665             names add:name.
  1747         dists add:(aString spellAgainst: "levenshteinTo:"name)
  1666             dists add:(aString levenshteinTo:name)
       
  1667         ]
       
  1668     ].
  1748     ].
  1669 
  1749 
  1670     (dists size ~~ 0) ifTrue:[
  1750     (dists size ~~ 0) ifTrue:[
  1671         dists sortWith:names.
  1751         dists sortWith:names.
       
  1752         dists := dists reverse.             
       
  1753         names := names reverse.
  1672         n := names size min:10.
  1754         n := names size min:10.
  1673         ^ names copyFrom:1 to:n
  1755         ^ names copyFrom:1 to:n
  1674     ].
  1756     ].
  1675     ^ nil
  1757     ^ nil
  1676 !
  1758 !