Parser.st
changeset 1512 52986e9b02af
parent 1507 bd29313cd901
child 1514 cf0c183c5ad9
--- a/Parser.st	Thu May 13 00:05:45 2004 +0200
+++ b/Parser.st	Tue May 18 16:13:07 2004 +0200
@@ -2165,6 +2165,12 @@
     ^ nil.
 !
 
+checkIfAllSubclassesOf:aClass implement:aSelector
+    (aClass subclasses 
+        contains:[:cls | (cls implements:selector) not]) ifTrue:[^ false].
+    ^ true.
+!
+
 checkSelector:selector for:receiver inClass:cls
     "check wether a method with selector exists in class cls and
      that the method is not obsolete.
@@ -2211,7 +2217,7 @@
         (mthd sends:#shouldNotImplement) ifTrue:[
             err := 'is not (should not be) implemented'
         ] ifFalse:[(mthd sends:#subclassResponsibility) ifTrue:[
-            allowed := cls == classToCompileFor.      "methods in abstract classes may send messages to abstract methods in the same class"
+            allowed := (cls == classToCompileFor).      "methods in abstract classes may send messages to abstract methods in the same class"
             allowed ifFalse:[
                 "methods in abstract classes may send messages to abstract methods in meta class"
                 (cls == classToCompileFor class) ifTrue:[
@@ -2219,7 +2225,7 @@
                 ].
             ].
             allowed ifTrue:[
-                (cls subclasses contains:[:cls | (cls implements:selector) not]) ifTrue:[
+                (self checkIfAllSubclassesOf:cls implement:selector) ifFalse:[
                     "if not all subclasses implement the selector - this is a possible bug"
                     allowed := false
                 ].
@@ -3963,7 +3969,7 @@
 "/    ].
     (stats notNil
     and:[stats ~~ #Error]) ifTrue:[
-        stats last isReturnNode ifFalse:[
+        (self isStatementAnUnconditionalReturn:stats last) ifFalse:[
             "/ remember a returned self here.
             self rememberReturnedValue:(self selfNode)
         ].
@@ -6858,6 +6864,29 @@
     "Modified: / 18.6.1998 / 15:45:29 / cg"
 !
 
+isStatementAnUnconditionalReturn:aStatementNode
+    |expr selector block1 block2 stats1 stats2|
+
+    aStatementNode isReturnNode ifTrue:[^ true ].
+    ((expr := aStatementNode expression) notNil
+    and:[expr isMessage]) ifTrue:[
+        selector := expr selector.
+        (selector == #'ifTrue:ifFalse:' or:[selector == #'ifFalse:ifTrue:']) ifTrue:[
+            block1 := expr arg1.
+            block2 := expr arguments at:2.
+            (block1 isBlockNode and:[ block2 isBlockNode]) ifTrue:[
+                stats1 := block1 statements.
+                stats2 := block2 statements.
+                    (stats1 notEmptyOrNil and:[ stats2 notEmptyOrNil]) ifTrue:[
+                        ^ (self isStatementAnUnconditionalReturn:stats1 last)
+                        and:[self isStatementAnUnconditionalReturn:stats2 last]
+                ].
+            ].
+        ].
+    ].
+    ^ false.
+!
+
 makeReferenceFor:aNode
     |rec sel indexNode contextNode arg1 arg2|
 
@@ -7468,7 +7497,7 @@
 !Parser class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libcomp/Parser.st,v 1.418 2004-04-01 13:19:59 penk Exp $'
+    ^ '$Header: /cvs/stx/stx/libcomp/Parser.st,v 1.419 2004-05-18 14:13:07 cg Exp $'
 ! !
 
 Parser initialize!