--- 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!