Skip to content
8 changes: 8 additions & 0 deletions src/AST-Core/RBNotice.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,11 @@ RBNotice >> printOn: aStream [
nextPutAll: self messageText;
nextPutAll: ')'
]

{ #category : #signalling }
RBNotice >> signalError [

CodeError new
notice: self;
signal
]
9 changes: 5 additions & 4 deletions src/AST-Core/RBProgramNode.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,12 @@ RBProgramNode >> addReplacement: aStringReplacement [
{ #category : #notice }
RBProgramNode >> addWarning: aMessage [

| notice |
"Add a warning information to the node.
Semantic passes that check the validity of AST are the targetted clients of this method."
self addNotice: (RBWarningNotice new messageText: aMessage)
notice := RBWarningNotice new messageText: aMessage.
self addNotice: notice.
^ notice
]

{ #category : #accessing }
Expand Down Expand Up @@ -313,9 +316,7 @@ RBProgramNode >> checkFaulty: aBlock [

aBlock ifNotNil: [ aBlock cull: errorNotice messageText cull: errorNotice position cull: self ].

CodeError new
notice: errorNotice;
signal.
errorNotice signalError.

"If resumed, just return"
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,6 @@ STCommandLineHandler >> handleError: error [
STCommandLineHandler >> handleError: error reference: aReference [
"Print a header before failing on an errro / syntax notification from the the script loaded by the given request"

"We ignore warnings for now"
(error isKindOf: OCSemanticWarning)
ifTrue: [ ^ error pass ].

"Display CodeError nicely"
(error isKindOf: CodeError)
ifTrue: [ self class printCodeError: error ].
Expand All @@ -142,7 +138,7 @@ STCommandLineHandler >> handleError: error reference: aReference [
{ #category : #installing }
STCommandLineHandler >> handleErrorsDuring: aBlock reference: aReference [
aBlock
on: Error, OCSemanticWarning
on: Error
do: [ :e | self handleError: e reference: aReference ]
]

Expand Down
13 changes: 3 additions & 10 deletions src/OpalCompiler-Core/OCASTSemanticAnalyzer.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -150,28 +150,21 @@ OCASTSemanticAnalyzer >> undeclared [
{ #category : #'error handling' }
OCASTSemanticAnalyzer >> undeclaredVariable: variableNode [

| varName var |
| varName var notice |
varName := variableNode name asSymbol.

"If a invalid variable exists, we use it witout warning"
self invalidVariables at: varName ifPresent: [ :v | ^ v ].

variableNode addWarning: 'Undeclared variable'.
notice := OCUndeclaredVariableNotice new messageText: 'Undeclared variable'.
variableNode addNotice: notice.
"If a registered undeclared variable exists, use it. Otherwise create an unregistered one."
"It will be registered only at backend when a CompiledMethod is produced.
Or never if compilation is aborted or if only frontend is requested."
var := self undeclared
at: varName
ifAbsentPut: [
UndeclaredVariable possiblyRegisteredWithName: varName ].
compilationContext permitFaulty ifTrue: [ ^ var ].

OCUndeclaredVariableWarning new
node: variableNode;
compilationContext: compilationContext;
messageText: 'Undeclared variable';
signal.

^ var
]

Expand Down
64 changes: 0 additions & 64 deletions src/OpalCompiler-Core/OCSemanticWarning.class.st

This file was deleted.

13 changes: 13 additions & 0 deletions src/OpalCompiler-Core/OCUndeclaredVariableNotice.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Class {
#name : #OCUndeclaredVariableNotice,
#superclass : #RBNotice,
#category : #'OpalCompiler-Core-FrontEnd'
}

{ #category : #signalling }
OCUndeclaredVariableNotice >> signalError [

OCUndeclaredVariableWarning new
notice: self;
signal
]
54 changes: 51 additions & 3 deletions src/OpalCompiler-Core/OCUndeclaredVariableWarning.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ I get signalled when a temporary variable is used that is not defined. My defau
"
Class {
#name : #OCUndeclaredVariableWarning,
#superclass : #OCSemanticWarning,
#superclass : #Notification,
#instVars : [
'notice'
],
#category : #'OpalCompiler-Core-Exception'
}

Expand All @@ -13,15 +16,60 @@ OCUndeclaredVariableWarning >> defaultAction [
className := self methodClass name.
selector := self methodNode selector.

NewUndeclaredWarning signal: node name in: (selector
NewUndeclaredWarning signal: self node name in: (selector
ifNotNil: [className, '>>', selector]
ifNil: ['<unknown>']).

^ super defaultAction
]

{ #category : #accessing }
OCUndeclaredVariableWarning >> description [

^ self class name , ':' , self notice description
]

{ #category : #accessing }
OCUndeclaredVariableWarning >> methodClass [
^ self methodNode methodClass
]

{ #category : #accessing }
OCUndeclaredVariableWarning >> methodNode [
^ self node methodNode
]

{ #category : #accessing }
OCUndeclaredVariableWarning >> node [
^ self notice node
]

{ #category : #accessing }
OCUndeclaredVariableWarning >> notice [

^ notice
]

{ #category : #accessing }
OCUndeclaredVariableWarning >> notice: anObject [

notice := anObject
]

{ #category : #accessing }
OCUndeclaredVariableWarning >> position [

^ self notice position
]

{ #category : #correcting }
OCUndeclaredVariableWarning >> reparator [

^ OCCodeReparator new node: node
^ OCCodeReparator new node: self node
]

{ #category : #accessing }
OCUndeclaredVariableWarning >> sourceCode [

^ self methodNode sourceCode
]
63 changes: 29 additions & 34 deletions src/OpalCompiler-Core/OpalCompiler.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -447,13 +447,12 @@ OpalCompiler >> parse [
parser initializeParserWith: source contents.
ast := self semanticScope parseASTBy: parser.

self permitFaulty ifFalse: [ ast checkFaulty: nil ].

ast methodNode compilationContext: self compilationContext.
self callParsePlugins.
self doSemanticAnalysis.

self permitFaulty ifFalse: [ ast checkFaulty: nil ].
self permitFaulty ifFalse: [
ast allNotices do: [ :n | n isWarning ifFalse: [ n signalError ] ] ].

^ ast
]
Expand All @@ -480,37 +479,33 @@ OpalCompiler >> parseForRequestor [
"No requestor, easy path"
requestor ifNil: [ ^ self parse ].

^ [ [ self parse ]
on: OCUndeclaredVariableWarning
do: [ :notification |
| res |
self isInteractive ifFalse: [ notification pass ].
"The menu is in fact broken on 'noPattern' mode (expression/script/doit) because some reparation assume it's a method body, so just signal as an error (on: block bellow)"
self compilationContext noPattern ifTrue: [
CodeError new
notice: notification node notices first; "Ugly temporary hack"
signal.
].
"I do not like the API that much.
reparator can have 3 outcomes:
* reparation done, reparse. true
* reparation unneded, pass. nil
* operation cancelled, fail. false"
res := notification reparator
requestor: requestor;
openMenu.
res ifNil: [ notification pass ].
res ifFalse: [ ^ self compilationContext failBlock value ].
self source: requestor text.
notification retry ] ]
on: CodeError
do: [ :exception |
ast := nil. "Invalidate the AST to avoid compilation if failBlock do return"
requestor
notify: exception messageText , ' ->'
at: exception position
in: exception sourceCode.
self compilationContext failBlock value ]
^ [ self parse ]
on: OCUndeclaredVariableWarning , CodeError
do: [ :exception |
exception class = OCUndeclaredVariableWarning ifTrue: [
self isInteractive ifFalse: [ exception pass ].
"The menu is in fact broken on 'noPattern' mode (expression/script/doit) because some reparation assume it's a method body, so just continue as an error"
self compilationContext noPattern ifFalse: [
| res |
"I do not like the API that much.
reparator can have 3 outcomes:
* reparation done, reparse. true
* reparation unneded, pass. nil
* operation cancelled, fail. false"
res := exception reparator
requestor: requestor;
openMenu.
res ifNil: [ exception pass ].
res ifFalse: [ ^ self compilationContext failBlock value ].
self source: requestor text.
exception retry ] ].

ast := nil. "Invalidate the AST to avoid compilation if failBlock do return"
requestor
notify: exception messageText , ' ->'
at: exception position
in: exception sourceCode.
self compilationContext failBlock value ]
]

{ #category : #'public access' }
Expand Down