#FEATURE by cg
authorClaus Gittinger <cg@exept.de>
Fri, 08 Feb 2019 17:24:08 +0100
changeset 4332 2699fc023e49
parent 4331 b4baf7ebed5a
child 4333 06e11aae91bd
#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:
Parser.st
--- 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