# HG changeset patch # User Stefan Vogel # Date 1481557127 -3600 # Node ID 08869106d07e69b2361d83476a505916d15108e4 # Parent ce26f968865ac21bfbf5f18fab5b8dd8eb26ca36 #BUGFIX by stefan class: Parser comment/format in: #checkSelector:for:inClass: changed: #selectorCheck:for:positions: avoid symbol creation better message if method selector is totally unknown diff -r ce26f968865a -r 08869106d07e Parser.st --- a/Parser.st Mon Dec 12 15:15:45 2016 +0100 +++ b/Parser.st Mon Dec 12 16:38:47 2016 +0100 @@ -2914,7 +2914,7 @@ ] ] ] ifFalse:[ - (mthd sendsAny:#( #subclassResponsibility #subclassResponsibility: )) ifTrue:[ + (mthd sendsAny:#(subclassResponsibility subclassResponsibility:)) ifTrue:[ 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" @@ -4214,7 +4214,7 @@ checkAction:[:e | |m| (m := e problemMethod) notNil - and:[(m sends:aSelectorString asSymbol) + and:[(m sends:aSelectorString asSymbolIfInterned) and:[self class implementedInAnyClass:aSelectorString]] ] ]. ]. @@ -4250,72 +4250,64 @@ selClass := self typeOfNode:receiver. (m := e problemMethod) notNil - and:[(m sends:aSelectorString asSymbol) - and:[(self checkSelector:selectorSymbol for:receiver inClass:selClass) notNil]]]. + and:[(m sends:aSelectorString asSymbolIfInterned) + and:[(self checkSelector:aSelectorString for:receiver inClass:selClass) notNil]]]. ]. ]. ]. - (receiver isConstant or:[receiver isBlock]) ifTrue:[ - err notNil ifTrue:[ + nowhereImplemented ifFalse:[ + (receiver isConstant or:[receiver isBlock]) ifTrue:[ err := err, ' in ' , selClass name , ' or any of its superclasses'. - ]. - ] ifFalse:[(((recType := receiver type) == #GlobalVariable) - or:[recType == #PrivateClass]) ifTrue:[ - rec := receiver evaluate. - "/ don't check autoloaded classes - it may work after loading - (rec isNil - or:[rec isBehavior and:[rec isLoaded not]]) ifTrue:[ - ^ aSelectorString - ]. - - err notNil ifTrue:[ + ] ifFalse:[(((recType := receiver type) == #GlobalVariable) + or:[recType == #PrivateClass]) ifTrue:[ + rec := receiver evaluate. + "/ don't check autoloaded classes - it may work after loading + (rec isNil + or:[rec isBehavior and:[rec isLoaded not]]) ifTrue:[ + ^ aSelectorString + ]. + (rec isBehavior and:[rec theNonMetaclass name = receiver name]) ifTrue:[ err := err, ' in ' , rec theNonMetaclass name. ] ifFalse:[ err := err, ' in currently assigned value (is currently ' , rec classNameWithArticle , ')'. - ] - ]. - ] ifFalse:[receiver isSuper ifTrue:[ - receiver isHere ifFalse:[ - err notNil ifTrue:[ - err := err, ' in superclass chain'. - ]. - ] ifTrue:[ - err notNil ifTrue:[ - err := err, ' in this class or superclass chain'. ]. - ] - ] ifFalse:[receiver isSelf ifTrue:[ - err notNil ifTrue:[ - |subErr nOther| - - "/ understood by all subclasses ? - nOther := 0. - classToCompileFor allSubclassesDo:[:eachSubclass | - subErr isNil ifTrue:[ - selClass := eachSubclass. - subErr := self checkSelector:selectorSymbol for:receiver inClass:selClass. + ] ifFalse:[receiver isSuper ifTrue:[ + receiver isHere ifFalse:[ + err := err, ' in superclass chain'. + ] ifTrue:[ + err := err, ' in this class or superclass chain'. + ] + ] ifFalse:[receiver isSelf ifTrue:[ + err notNil ifTrue:[ + |subErr nOther| + + "/ understood by all subclasses ? + nOther := 0. + classToCompileFor allSubclassesDo:[:eachSubclass | + subErr isNil ifTrue:[ + selClass := eachSubclass. + subErr := self checkSelector:selectorSymbol for:receiver inClass:selClass. + ] ifFalse:[ + (self checkSelector:selectorSymbol for:receiver inClass:selClass) notNil ifTrue:[ nOther := nOther + 1 ]. + ] + ]. + subErr notNil ifTrue:[ + nOther > 0 ifTrue:[ + err := subErr, (' in %1 other subclass(es), this class or superclass chain' bindWith:nOther) + ] ifFalse:[ + err := subErr, ', in this class or superclass chain' + ]. ] ifFalse:[ - (self checkSelector:selectorSymbol for:receiver inClass:selClass) notNil ifTrue:[ nOther := nOther + 1 ]. - ] + err := err, ', in this class or superclass chain'. + ]. ]. - subErr notNil ifTrue:[ - nOther > 0 ifTrue:[ - err := subErr, (' in %1 other subclass(es), this class or superclass chain' bindWith:nOther) - ] ifFalse:[ - err := subErr, ', in this class or superclass chain' - ]. - ] ifFalse:[ - err := err, ', in this class or superclass chain'. - ]. - ]. - ] ifFalse:[(receiver isUnaryMessage - and:[receiver selector == #class - and:[receiver receiver isSelf]]) ifTrue:[ - "it's a message to self class - can check this too ..." - err notNil ifTrue:[ + ] ifFalse:[(receiver isUnaryMessage + and:[receiver selector == #class + and:[receiver receiver isSelf]]) ifTrue:[ + "it's a message to self class - can check this too ..." classToCompileFor isMeta ifTrue:[ err := err, ' for the classes class'. (self checkSelector:selectorSymbol for:receiver inClass:classToCompileFor) isNil ifTrue:[ @@ -4329,46 +4321,46 @@ err := err withCRs. ]. ]. - ]. - ] ifFalse:[ - (self isPossiblyUninitializedLocal:receiver) ifTrue:[ -"/ (receiver isLocal and:[receiver token type isNil]) ifTrue:[ - "if it is an uninitialized variable ..." - -"/ ((modifiedLocalVars isNil or:[(modifiedLocalVars includes:receiver name) not]) -"/ and:[hasPrimitiveCode not -"/ and:[((receiver isMethodVariable and:[currentBlock isNil]) -"/ or:[ receiver isBlockVariable and:[receiver block == currentBlock]]) -"/ and:[alreadyWarnedUninitializedVars isNil -"/ or:[(alreadyWarnedUninitializedVars includes:receiver name) not]]]]) -"/ ifTrue:[ - ((#(at: at:put: basicAt: basicAt:put:) includes:selectorSymbol) - or:[(nil respondsTo:selectorSymbol) not]) ifTrue:[ - "/ avoid trouble in miniTalk - "/ during bootstrap - nm := receiver name. - Text notNil ifTrue:[ - nm := nm allItalic - ]. - err := 'sent to possibly uninitialized variable ''' , nm , ''' here (?)'. - alreadyWarnedUninitializedVars isNil ifTrue:[ - alreadyWarnedUninitializedVars := Set new - ]. - alreadyWarnedUninitializedVars add:receiver name - ] -"/ ] - ] ifFalse:[ - (err notNil and:[selClass notNil]) ifTrue:[ - ((selClass == Boolean) - and:[ receiver isMessage - and:[ receiver selector == #'=' ]]) - ifTrue:[ - err := err, ' (message to Boolean; did you mean ":=" instead of "=" in the receiver?)' - ] ifFalse:[ - err := err, ' (message to ' , selClass nameWithArticle , ')'. - ] - ]. - ]]]]]]. + ] ifFalse:[ + (self isPossiblyUninitializedLocal:receiver) ifTrue:[ + "/ (receiver isLocal and:[receiver token type isNil]) ifTrue:[ + "if it is an uninitialized variable ..." + + "/ ((modifiedLocalVars isNil or:[(modifiedLocalVars includes:receiver name) not]) + "/ and:[hasPrimitiveCode not + "/ and:[((receiver isMethodVariable and:[currentBlock isNil]) + "/ or:[ receiver isBlockVariable and:[receiver block == currentBlock]]) + "/ and:[alreadyWarnedUninitializedVars isNil + "/ or:[(alreadyWarnedUninitializedVars includes:receiver name) not]]]]) + "/ ifTrue:[ + ((#(at: at:put: basicAt: basicAt:put:) includes:selectorSymbol) + or:[(nil respondsTo:selectorSymbol) not]) ifTrue:[ + "/ avoid trouble in miniTalk + "/ during bootstrap + nm := receiver name. + Text notNil ifTrue:[ + nm := nm allItalic + ]. + err := 'sent to possibly uninitialized variable ''' , nm , ''' here (?)'. + alreadyWarnedUninitializedVars isNil ifTrue:[ + alreadyWarnedUninitializedVars := Set new + ]. + alreadyWarnedUninitializedVars add:receiver name + ] + "/ ] + ] ifFalse:[ + selClass notNil ifTrue:[ + ((selClass == Boolean) + and:[receiver isMessage + and:[receiver selector == #=]]) + ifTrue:[ + err := err, ' (message to Boolean; did you mean ":=" instead of "=" in the receiver?)' + ] ifFalse:[ + err := err, ' (message to ' , selClass nameWithArticle , ')'. + ] + ]. + ]]]]]]. + ]. ]. err notNil ifTrue:[