#FEATURE by cg
class: Parser
better warnings about uninitialized locals
added: #warnIfPossiblyUninitializedLocal:
comment/format in:
#binaryExpressionFor:
#showErrorMessage:position:
changed:
#checkPlausibilityOf:from:to:
#isPossiblyUninitializedLocal:
#keywordExpressionFor:
#unaryExpressionFor:
--- a/Parser.st Fri Feb 08 11:23:51 2019 +0100
+++ b/Parser.st Fri Feb 08 17:24:08 2019 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1989 by Claus Gittinger
All Rights Reserved
@@ -2837,6 +2839,15 @@
parserFlags warnPlausibilityChecks ifFalse:[^ self].
(ParserFlags isFlag:#warnPlausibilityChecks enabledForClass:classToCompileFor selector:selector) ifFalse:[^ self].
+ aNode isMessage ifTrue:[
+ (#('isNil' 'notNil') includes:aNode selector) ifFalse:[
+ self warnIfPossiblyUninitializedLocal:aNode receiver.
+ ].
+ aNode arguments do:[:eachArg |
+ self warnIfPossiblyUninitializedLocal:eachArg
+ ].
+ ].
+
note := self plausibilityCheck:aNode.
note notNil ifTrue:[
"/ this is a hack (which I don't like)
@@ -2865,6 +2876,7 @@
].
"Created: / 19-01-2012 / 10:44:05 / cg"
+ "Modified: / 08-02-2019 / 17:22:07 / Claus Gittinger"
!
checkReturnedValues
@@ -3012,7 +3024,7 @@
!
isPossiblyUninitializedLocal:aNode
- |varName|
+ |varName scope|
aNode isLocalVariable ifFalse:[^ false].
hasPrimitiveCode ifTrue:[^ false]. "/ because I do not look into it, yet
@@ -3022,15 +3034,27 @@
and:[(alreadyWarnedUninitializedVars includes:varName)]) ifTrue:[^ false].
aNode isMethodVariable ifTrue:[
- currentBlock notNil ifTrue:[^ false].
(modifiedLocalVars notNil and:[(modifiedLocalVars includes:varName)]) ifTrue:[^ false].
+ (scope := currentBlock) notNil ifTrue:[
+ [scope notNil] whileTrue:[
+ ((scope modifiedLocalVars ? #()) includes:varName) ifTrue:[^ false].
+ scope := scope home
+ ].
+ ].
] ifFalse:[
aNode isBlockVariable ifTrue:[
- aNode block == currentBlock ifFalse:[^ false].
(currentBlock modifiedLocalVars notNil and:[(currentBlock modifiedLocalVars includes:varName)]) ifTrue:[^ false].
+ (scope := currentBlock home) notNil ifTrue:[
+ [scope notNil] whileTrue:[
+ ((scope modifiedLocalVars ? #()) includes:varName) ifTrue:[^ false].
+ scope := scope home
+ ].
+ ].
].
].
^ true.
+
+ "Modified: / 08-02-2019 / 17:18:29 / Claus Gittinger"
! !
!Parser methodsFor:'dummy-syntax detection'!
@@ -4859,6 +4883,16 @@
"Modified: / 02-11-2010 / 13:32:21 / cg"
!
+warnIfPossiblyUninitializedLocal:expr
+ (self isPossiblyUninitializedLocal:expr) ifTrue:[
+ self
+ warning:'"',expr name,'" is uninitialized here (always nil)'
+ position:(expr startPosition) to:(expr endPosition).
+ ].
+
+ "Created: / 08-02-2019 / 17:14:16 / Claus Gittinger"
+!
+
warnSTXHereExtensionUsedAt:position
ignoreWarnings ifFalse:[
didWarnAboutSTXHereExtensionUsed ifFalse:[
@@ -6895,12 +6929,6 @@
expr lineNumber:lno.
expr selectorPosition:pos1.
- (self isPossiblyUninitializedLocal:arg) ifTrue:[
- self
- warning:'"',arg name,'" is uninitialized here (always nil)'
- position:(arg startPosition) to:(arg endPosition).
- ].
-
self checkPlausibilityOf:expr from:pos1 to:pos2.
parseForCode ifFalse:[
self rememberSelectorUsed:sel receiver:receiver
@@ -6912,6 +6940,7 @@
"Modified: / 09-01-1998 / 19:05:18 / stefan"
"Modified: / 19-01-2012 / 10:44:22 / cg"
+ "Modified: / 08-02-2019 / 17:21:16 / Claus Gittinger"
!
byteArray
@@ -7431,14 +7460,6 @@
args := args copyWith:arg.
].
- args do:[:eachArg |
- (self isPossiblyUninitializedLocal:eachArg) ifTrue:[
- self
- warning:'"',eachArg name,'" is uninitialized here (always nil)'
- position:(eachArg startPosition) to:(eachArg endPosition).
- ].
- ].
-
selectorPartPositions do:[:p |
self markSelector:sel from:p start to:p stop receiverNode:receiver.
].
@@ -7496,6 +7517,7 @@
"Modified: / 19-01-2012 / 10:44:42 / cg"
"Modified: / 27-08-2013 / 10:43:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 08-02-2019 / 17:21:34 / Claus Gittinger"
!
literalInlineObjectFor:namesAndValues
@@ -8911,6 +8933,10 @@
arguments size - 1 timesRepeat:[ sel := sel , 'with:' ].
].
sel := self selectorCheck:sel for:receiver position:pos to:pos2.
+ self warnIfPossiblyUninitializedLocal:receiver.
+ arguments do:[:eachArg |
+ self warnIfPossiblyUninitializedLocal:eachArg
+ ].
expr := MessageNode receiver:receiver selector:sel args:arguments fold:foldConstants.
expr isErrorNode ifTrue:[
self parseError:(expr errorString) position:pos to:pos2.
@@ -8958,6 +8984,7 @@
"Modified: / 30-08-2013 / 13:02:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 03-07-2017 / 13:57:55 / cg"
+ "Modified: / 08-02-2019 / 17:19:56 / Claus Gittinger"
!
variable