Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kill VariableNotDeclared #13471

Merged
merged 4 commits into from
Apr 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/AST-Core-Tests/RBCodeSnippet.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -336,12 +336,14 @@ RBCodeSnippet class >> badExpressions [
(self new
source: 'a | ';
nodeAt: '1000';
raise: UndeclaredVariableRead;
notices:
#( #( 1 1 1 'Undeclared variable' )
#( 5 4 5 'Variable or expression expected' ) )).
(self new
source: 'a || ';
nodeAt: '10000';
raise: UndeclaredVariableRead;
notices:
#( #( 1 1 1 'Undeclared variable' )
#( 6 5 6 'Variable or expression expected' ) )).
Expand Down Expand Up @@ -847,6 +849,7 @@ RBCodeSnippet class >> badMethods [
(self new
source: 'foo < bar: baz > ';
nodeAt: '00002222222666555';
raise: UndeclaredVariableRead;
notices: #( #( 12 11 12 'Literal constant expected' )
#( 5 11 12 '''>'' expected' )
#( 12 14 12 'Undeclared variable' )
Expand Down
37 changes: 0 additions & 37 deletions src/Kernel/UndefinedObject.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -93,50 +93,13 @@ UndefinedObject >> deepCopy [
with self."
]

{ #category : #'reflective operations' }
UndefinedObject >> doesNotUnderstand: aMessage [

"Handle the fact that there was an attempt to send the given message to an Undeclared variable (nil), hence the receiver does not understand this message (typically #new)."

"Testing: (nil activeProcess)"

<debuggerCompleteToSender>
| exception resumeValue node |
[
node := self findUndeclaredVariableIn:
thisContext outerContext sender sourceNodeExecuted ] onErrorDo: [ :ex |
"This is ugly, but we have a dependency with Opal compiler and
it should be extracted. If there is a failure during the bootstrap, this
dependency produces an infinite loop"
].
node ifNil: [ ^ super doesNotUnderstand: aMessage ].

(exception := VariableNotDeclared new)
message: aMessage;
variableNode: node;
receiver: self.

resumeValue := exception signal.
^ exception reachedDefaultHandler
ifTrue: [ aMessage sentTo: self ]
ifFalse: [ resumeValue ]
]

{ #category : #'class hierarchy' }
UndefinedObject >> environment [
"Necessary to support disjoint class hierarchies."

^self class environment
]

{ #category : #'reflective operations' }
UndefinedObject >> findUndeclaredVariableIn: ast [
"Walk the ast of the current statment and find the undeclared variable node, or nil (if none).
Assumes there is only one such variable in an executing statement"

^ast variableNodes detect: [:node | node isUndeclaredVariable] ifNone: [ nil ]
]

{ #category : #testing }
UndefinedObject >> haltIfNil [
<debuggerCompleteToSender>
Expand Down
5 changes: 5 additions & 0 deletions src/Kernel/VariableNotDeclared.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ Class {
#category : #'Kernel-Exceptions'
}

{ #category : #testing }
VariableNotDeclared class >> isDeprecated [
^true
]

{ #category : #accessing }
VariableNotDeclared >> classSymbol [
^ self variableNode name
Expand Down
15 changes: 1 addition & 14 deletions src/OpalCompiler-Core/OCASTTranslator.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -744,20 +744,7 @@ OCASTTranslator >> visitVariableNode: aVariableNode [

"Because we are producing a CompiledMethod, register undeclared variables to `Undeclared`"
aVariableNode variable isUndeclaredVariable ifTrue: [
aVariableNode variable register.

(aVariableNode parent isMessage and: [ aVariableNode parent receiver == aVariableNode ]) ifTrue: [
"Let's try to hack a hack!
StDebugger expects some `VariableNotDeclared` (badly named class) when a message
is send to a `nil` that comes from an undeclared variable (awful fragile heuristics are used).
To be compatible, we can either emulate the hack (that seems to be very ugly and complex),
or we can just compile the undelared variable used as a receiver as a literal read.
Therefore, if the variable become declared, the emmited code is compatible, and if
the variable is still undeclared at runtime, then `nil` from an undeclared is used and
the debugger is fooled.
Once the debugger learn to deal with `UndeclaredVariableRead`, this hack can be removed."
methodBuilder pushLiteralVariable: aVariableNode variable.
^ self ] ].
aVariableNode variable register ].

aVariableNode variable emitValue: methodBuilder
]